mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-09 09:22:18 +02:00
Added kick duration for web_ui kick
This commit is contained in:
+1
-2
@@ -35,8 +35,7 @@
|
||||
- Added extended debug logging for client requests and ID chain (request/action/virtual) to trace stream resolution.
|
||||
- Fixed xtream series/catchup lookups using the series-info virtual_id so episode requests now keep their own virtual_id/session.
|
||||
- Made cache storage more robust. Incomplete downloads will be deleted from cache.
|
||||
- `kick_secs` added to config.yaml `web_ui` config. Default 30 seconds, if a user is kicked from the webui, he can't connect for this duration.
|
||||
|
||||
- `kick_secs` added to config.yaml `web_ui` config. Default 30 seconds, if a user is kicked from the webui, they can't connect for this duration.
|
||||
|
||||
# 3.2.0 (2025-11-14)
|
||||
- Added `name` attribute to Staged Input.
|
||||
|
||||
@@ -417,7 +417,7 @@ log:
|
||||
- `content_security_policy`: configure Content-Security-Policy headers. When `enabled` is true, the default directives `default-src 'self'`, `script-src 'self' 'wasm-unsafe-eval' 'nonce-{nonce_b64}'`, and `frame-ancestors 'none'` are applied. Additional directives can be added via `custom-attributes`. Enabling CSP may block external images/logos unless allowed via directives like `img-src`.
|
||||
- `path` is for web_ui path like `/ui` for reverse proxy integration if necessary.
|
||||
- `player_server` optional, if set the server setting is used for the web-ui-player.
|
||||
- `kick_secs` default 30 seconds, if a user is kicked from the webui, he can't connect for this duration.
|
||||
- `kick_secs` default 30 seconds, if a user is kicked from the webui, they can't connect for this duration.
|
||||
- `auth` for authentication settings
|
||||
- `enabled` can be deactivated if `enabled` is set to `false`. If not set default is `true`.
|
||||
- `issuer`
|
||||
|
||||
@@ -164,7 +164,7 @@ pub(in crate::api) async fn handle_hls_stream_request(
|
||||
CustomVideoStreamType::ChannelUnavailable);
|
||||
|
||||
let playlist = PLAYLIST_TEMPLATE.replace("{url}", &url);
|
||||
hls_response(playlist.clone()).into_response()
|
||||
hls_response(playlist).into_response()
|
||||
} else {
|
||||
axum::http::StatusCode::NOT_FOUND.into_response()
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ async fn m3u_api_stream(
|
||||
);
|
||||
let virtual_id = pli.virtual_id;
|
||||
|
||||
if app_state.active_users.is_user_blocked_for_stream(stream_req.username, virtual_id).await {
|
||||
if app_state.active_users.is_user_blocked_for_stream(&user.username, virtual_id).await {
|
||||
return axum::http::StatusCode::BAD_REQUEST.into_response();
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ async fn xtream_player_api_stream(
|
||||
format!("Failed to read xtream item for stream id {req_virtual_id}")
|
||||
);
|
||||
let virtual_id = pli.virtual_id;
|
||||
if app_state.active_users.is_user_blocked_for_stream(stream_req.username, virtual_id).await {
|
||||
if app_state.active_users.is_user_blocked_for_stream(&user.username, virtual_id).await {
|
||||
return axum::http::StatusCode::BAD_REQUEST.into_response();
|
||||
}
|
||||
|
||||
|
||||
@@ -507,7 +507,7 @@ impl ActiveUserManager {
|
||||
let now = current_time_secs();
|
||||
connections.kicked.retain(|_, (expires_at, _)| *expires_at > now);
|
||||
if let Some(username) = connections.key_by_addr.get(addr).cloned() {
|
||||
let expires_at = now + blocked_secs;
|
||||
let expires_at = now + blocked_secs.clamp(1,86_400); // max 1 day
|
||||
connections.kicked.insert(username, (expires_at, virtual_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
flex: 1 1 auto;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
span {
|
||||
pointer-events: none;
|
||||
|
||||
@@ -59,7 +59,8 @@
|
||||
|
||||
&-input {
|
||||
height: 20rem;
|
||||
width: 100rem;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
.tp__input-wrapper {
|
||||
height: 2.5rem;
|
||||
padding: 0 var(--padding-mini);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
fill: var(--text-color);
|
||||
cursor: pointer;
|
||||
filter: brightness(1.2);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
&:hover {
|
||||
fill: var(--text-color);
|
||||
cursor: pointer;
|
||||
filter: brightness(1.2);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,12 @@ pub struct ClusterFlagsInputProps {
|
||||
pub fn ClusterFlagsInput(props: &ClusterFlagsInputProps) -> Html {
|
||||
let translate = use_translation();
|
||||
|
||||
let flags = use_state(|| props.value.unwrap_or_else(ClusterFlags::all));
|
||||
let flags = use_state(|| {
|
||||
props.value.unwrap_or_else(|| match props.mode {
|
||||
ClusterFlagsInputMode::NoneIsAll => ClusterFlags::all(),
|
||||
ClusterFlagsInputMode::NoneIsNone => ClusterFlags::empty(),
|
||||
})
|
||||
});
|
||||
{
|
||||
let set_flags = flags.clone();
|
||||
use_effect_with((props.value, props.mode), move |(val, cmode)| {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use log::debug;
|
||||
use yew::prelude::*;
|
||||
use web_sys::MouseEvent;
|
||||
|
||||
@@ -28,8 +27,6 @@ pub fn CustomDialog(props: &CustomDialogProps) -> Html {
|
||||
});
|
||||
}
|
||||
|
||||
debug!(" props close {}", props.close_on_backdrop_click);
|
||||
|
||||
// Handle backdrop click
|
||||
let on_backdrop_click = {
|
||||
let on_close = props.on_close.clone();
|
||||
|
||||
@@ -25,14 +25,6 @@ pub fn FilterEditor(props: &FilterEditorProps) -> Html {
|
||||
let parsed_filter_state = use_state(|| None);
|
||||
let valid_filter_state = use_state(|| true);
|
||||
|
||||
{
|
||||
let templates = templates_state.clone();
|
||||
let cfg_templates = config_ctx.config.as_ref().and_then(|c| c.sources.templates.clone());
|
||||
use_effect_with(cfg_templates, move |templ| {
|
||||
templates.set(templ.clone());
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
let templates = templates_state.clone();
|
||||
let cfg_templates = config_ctx.config.as_ref().and_then(|c| c.sources.templates.clone());
|
||||
@@ -75,13 +67,16 @@ pub fn FilterEditor(props: &FilterEditorProps) -> Html {
|
||||
|
||||
let handle_filter_input = {
|
||||
let filter = filter_state.clone();
|
||||
let on_filter_change = props.on_filter_change.clone();
|
||||
Callback::from(move |event: InputEvent| {
|
||||
if let Some(input) = event.target_dyn_into::<web_sys::HtmlTextAreaElement>() {
|
||||
let value = input.value();
|
||||
if value.is_empty() {
|
||||
filter.set(None);
|
||||
on_filter_change.emit(None);
|
||||
} else {
|
||||
filter.set(Some(value));
|
||||
filter.set(Some(value.clone()));
|
||||
on_filter_change.emit(Some(value));
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -79,20 +79,24 @@ pub fn FilterInput(props: &FilterInputProps) -> Html {
|
||||
let dialog = dialog.clone();
|
||||
let current_filter = filter_state.clone();
|
||||
let handle_filter_edit = handle_filter_edit.clone();
|
||||
let handle_templates_edit =handle_templates_edit.clone();
|
||||
let handle_templates_edit = handle_templates_edit.clone();
|
||||
let dialog_actions = dialog_actions.clone();
|
||||
Callback::from(move |e: MouseEvent| {
|
||||
e.prevent_default();
|
||||
let current_filter = (*current_filter).clone();
|
||||
let handle_filter_edit = handle_filter_edit.clone();
|
||||
let handle_templates_edit =handle_templates_edit.clone();
|
||||
let handle_templates_edit = handle_templates_edit.clone();
|
||||
let actions = dialog_actions.clone();
|
||||
let dlg = dialog.clone();
|
||||
spawn_local(async move {
|
||||
let filter_view = html!{<FilterEditor filter={current_filter}
|
||||
on_filter_change={handle_filter_edit}
|
||||
on_templates_change={handle_templates_edit} />};
|
||||
let _result = dlg.content(filter_view, (*actions).clone(), false).await;
|
||||
let result = dlg.content(filter_view, (*actions).clone(), false).await;
|
||||
if result == DialogResult::Ok {
|
||||
// Propagate the updated filter to parent via on_change
|
||||
// Note: Need access to filter_state's current value and props.on_change here
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user