From e9167d96ec47bda91be991942cab675dae639c3f Mon Sep 17 00:00:00 2001 From: Hampus Date: Sat, 3 Oct 2026 14:41:00 +0200 Subject: [PATCH] feat(admin): add optional expiry to admin IP bans (#3163) --- fluxer_admin/openapi-admin.json | 21 ++- fluxer_admin/src/api/bans.rs | 16 +- fluxer_admin/src/api/types/common.rs | 2 + fluxer_admin/src/routes/bans.rs | 11 +- fluxer_admin/src/routes/bans_actions.rs | 47 +++++- fluxer_admin/src/routes/user_actions.rs | 5 +- fluxer_admin/src/templates/pages/bans.rs | 47 ++++++ fluxer_admin/tests/api_deserialization.rs | 8 + fluxer_api/src/api/admin/AdminRepository.ts | 58 ++++--- fluxer_api/src/api/admin/IAdminRepository.ts | 2 +- .../admin/controllers/BanAdminController.ts | 8 +- .../services/AdminBanManagementService.ts | 21 ++- .../api/admin/tests/AdminIpBanExpiry.test.ts | 142 ++++++++++++++++++ .../src/api/middleware/IpBanMiddleware.ts | 13 +- .../middleware/tests/IpBanMiddleware.test.ts | 23 ++- .../src/content/docs/admin-api/blocklists.mdx | 16 +- .../src/content/docs/http-api/errors.md | 6 +- .../docs/http-api/guild-moderation.mdx | 2 +- .../src/domains/moderation/IpBannedError.ts | 4 +- packages/errors/src/i18n/ErrorI18nMessages.ts | 2 +- packages/errors/src/i18n/locales/ar.ts | 2 +- packages/errors/src/i18n/locales/bg.ts | 2 +- packages/errors/src/i18n/locales/cs.ts | 2 +- packages/errors/src/i18n/locales/da.ts | 2 +- packages/errors/src/i18n/locales/de.ts | 2 +- packages/errors/src/i18n/locales/el.ts | 2 +- packages/errors/src/i18n/locales/en-GB.ts | 2 +- packages/errors/src/i18n/locales/es-419.ts | 2 +- packages/errors/src/i18n/locales/es-ES.ts | 2 +- packages/errors/src/i18n/locales/fi.ts | 2 +- packages/errors/src/i18n/locales/fr.ts | 2 +- packages/errors/src/i18n/locales/he.ts | 2 +- packages/errors/src/i18n/locales/hi.ts | 2 +- packages/errors/src/i18n/locales/hr.ts | 2 +- packages/errors/src/i18n/locales/hu.ts | 2 +- packages/errors/src/i18n/locales/id.ts | 2 +- packages/errors/src/i18n/locales/it.ts | 2 +- packages/errors/src/i18n/locales/ja.ts | 2 +- packages/errors/src/i18n/locales/ko.ts | 2 +- packages/errors/src/i18n/locales/lt.ts | 2 +- packages/errors/src/i18n/locales/nl.ts | 2 +- packages/errors/src/i18n/locales/no.ts | 2 +- packages/errors/src/i18n/locales/pl.ts | 2 +- packages/errors/src/i18n/locales/pt-BR.ts | 2 +- packages/errors/src/i18n/locales/ro.ts | 2 +- packages/errors/src/i18n/locales/ru.ts | 2 +- packages/errors/src/i18n/locales/sv-SE.ts | 2 +- packages/errors/src/i18n/locales/th.ts | 2 +- packages/errors/src/i18n/locales/tr.ts | 2 +- packages/errors/src/i18n/locales/uk.ts | 2 +- packages/errors/src/i18n/locales/vi.ts | 2 +- packages/errors/src/i18n/locales/zh-CN.ts | 2 +- packages/errors/src/i18n/locales/zh-TW.ts | 2 +- .../errors/src/i18n/weblate/locales/ar.json | 2 +- .../errors/src/i18n/weblate/locales/bg.json | 2 +- .../errors/src/i18n/weblate/locales/cs.json | 2 +- .../errors/src/i18n/weblate/locales/da.json | 2 +- .../errors/src/i18n/weblate/locales/de.json | 2 +- .../errors/src/i18n/weblate/locales/el.json | 2 +- .../src/i18n/weblate/locales/en-GB.json | 2 +- .../src/i18n/weblate/locales/es-419.json | 2 +- .../src/i18n/weblate/locales/es-ES.json | 2 +- .../errors/src/i18n/weblate/locales/fi.json | 2 +- .../errors/src/i18n/weblate/locales/fr.json | 2 +- .../errors/src/i18n/weblate/locales/he.json | 2 +- .../errors/src/i18n/weblate/locales/hi.json | 2 +- .../errors/src/i18n/weblate/locales/hr.json | 2 +- .../errors/src/i18n/weblate/locales/hu.json | 2 +- .../errors/src/i18n/weblate/locales/id.json | 2 +- .../errors/src/i18n/weblate/locales/it.json | 2 +- .../errors/src/i18n/weblate/locales/ja.json | 2 +- .../errors/src/i18n/weblate/locales/ko.json | 2 +- .../errors/src/i18n/weblate/locales/lt.json | 2 +- .../errors/src/i18n/weblate/locales/nl.json | 2 +- .../errors/src/i18n/weblate/locales/no.json | 2 +- .../errors/src/i18n/weblate/locales/pl.json | 2 +- .../src/i18n/weblate/locales/pt-BR.json | 2 +- .../errors/src/i18n/weblate/locales/ro.json | 2 +- .../errors/src/i18n/weblate/locales/ru.json | 2 +- .../src/i18n/weblate/locales/sv-SE.json | 2 +- .../errors/src/i18n/weblate/locales/th.json | 2 +- .../errors/src/i18n/weblate/locales/tr.json | 2 +- .../errors/src/i18n/weblate/locales/uk.json | 2 +- .../errors/src/i18n/weblate/locales/vi.json | 2 +- .../src/i18n/weblate/locales/zh-CN.json | 2 +- .../src/i18n/weblate/locales/zh-TW.json | 2 +- .../errors/src/i18n/weblate/messages.json | 2 +- .../schema/src/domains/admin/AdminSchemas.ts | 13 ++ 88 files changed, 462 insertions(+), 139 deletions(-) create mode 100644 fluxer_api/src/api/admin/tests/AdminIpBanExpiry.test.ts diff --git a/fluxer_admin/openapi-admin.json b/fluxer_admin/openapi-admin.json index 3657902ef..d341e4472 100644 --- a/fluxer_admin/openapi-admin.json +++ b/fluxer_admin/openapi-admin.json @@ -12181,8 +12181,15 @@ }, "BanCheckResponseSchema": { "type": "object", - "properties": {"banned": {"type": "boolean"}}, - "required": ["banned"], + "properties": { + "banned": {"type": "boolean"}, + "expires_at": { + "nullable": true, + "description": "ISO 8601 timestamp when the matching ban expires. Null when the ban is permanent, when nothing matches, and on every blocklist other than ip.", + "type": "string" + } + }, + "required": ["banned", "expires_at"], "additionalProperties": false }, "AdminBlocklistBulkDeleteRequest": { @@ -13017,7 +13024,15 @@ }, "BanIpRequest": { "type": "object", - "properties": {"ip": {"description": "IPv4/IPv6 address or CIDR range to ban", "type": "string"}}, + "properties": { + "ip": {"description": "IPv4/IPv6 address or CIDR range to ban", "type": "string"}, + "duration_hours": { + "description": "Hours until the ban expires and its entry is removed. Omit it or use 0 for a permanent ban.", + "type": "integer", + "minimum": 0, + "maximum": 8760 + } + }, "required": ["ip"] }, "EmailBlocklistEntryType": {"type": "string"}, diff --git a/fluxer_admin/src/api/bans.rs b/fluxer_admin/src/api/bans.rs index 9c0c53456..171b4115d 100644 --- a/fluxer_admin/src/api/bans.rs +++ b/fluxer_admin/src/api/bans.rs @@ -28,11 +28,23 @@ impl AdminApiClient { self.check_blocklist_entry("email", email, None).await } - pub async fn ban_ip(&self, ip: &str, audit_log_reason: Option<&str>) -> ApiResult<()> { + pub async fn ban_ip( + &self, + ip: &str, + duration_hours: u32, + audit_log_reason: Option<&str>, + ) -> ApiResult<()> { self.create_blocklist_entry( "ip", generated_types::AdminBlocklistEntryCreateRequest::from( - generated_types::BanIpRequest { ip: ip.to_owned() }, + generated_types::BanIpRequest { + duration_hours: Some( + i32::try_from(duration_hours) + .map_err(|e| ApiError::Parse(e.to_string()))? + .into(), + ), + ip: ip.to_owned(), + }, ), audit_log_reason, ) diff --git a/fluxer_admin/src/api/types/common.rs b/fluxer_admin/src/api/types/common.rs index 80ff0902f..397297733 100644 --- a/fluxer_admin/src/api/types/common.rs +++ b/fluxer_admin/src/api/types/common.rs @@ -255,6 +255,8 @@ pub enum FlashLevel { pub struct BanCheckResult { pub banned: bool, #[serde(default)] + pub expires_at: Option, + #[serde(default)] pub entries: Vec, } diff --git a/fluxer_admin/src/routes/bans.rs b/fluxer_admin/src/routes/bans.rs index 387873ade..9ba21e701 100644 --- a/fluxer_admin/src/routes/bans.rs +++ b/fluxer_admin/src/routes/bans.rs @@ -90,16 +90,7 @@ async fn generic_ban_post( }; let value = extract_value(form, ban_cfg.input_name); let is_htmx = htmx::is_htmx_request(headers); - let (level, msg) = execute_ban( - &client, - ban_key, - action, - &value, - form.hashes.as_deref(), - form.sha256_list.as_deref(), - form.audit_log_reason.as_deref(), - ) - .await; + let (level, msg) = execute_ban(&client, ban_key, action, &value, form).await; flash_response(config, auth, is_htmx, level, &msg, ban_cfg, csrf_token) } diff --git a/fluxer_admin/src/routes/bans_actions.rs b/fluxer_admin/src/routes/bans_actions.rs index 666f521dc..d827fce62 100644 --- a/fluxer_admin/src/routes/bans_actions.rs +++ b/fluxer_admin/src/routes/bans_actions.rs @@ -34,6 +34,8 @@ pub struct BanFormData { #[serde(default)] pub substring: Option, #[serde(default)] + pub duration_hours: Option, + #[serde(default)] pub audit_log_reason: Option, #[serde(default)] pub _csrf: Option, @@ -58,10 +60,12 @@ pub async fn execute_ban( ban_type: &str, action: &str, value: &str, - bulk_hashes: Option<&str>, - bulk_sha256_list: Option<&str>, - audit_log_reason: Option<&str>, + form: &BanFormData, ) -> (&'static str, String) { + let bulk_hashes = form.hashes.as_deref(); + let bulk_sha256_list = form.sha256_list.as_deref(); + let duration_hours = form.duration_hours.as_deref(); + let audit_log_reason = form.audit_log_reason.as_deref(); if (action == "bulk-ban" || action == "bulk-ban-files") && ban_type == "file-sha-bans" { let raw_hashes = if action == "bulk-ban-files" { bulk_sha256_list @@ -74,6 +78,9 @@ pub async fn execute_ban( return ("error", "Value is required".into()); } match action { + "ban" if ban_type == "ip-bans" => { + execute_ip_ban(client, value, duration_hours, audit_log_reason).await + } "ban" => execute_single_ban(client, ban_type, value, audit_log_reason).await, "unban" => execute_single_unban(client, ban_type, value, audit_log_reason).await, "check" => execute_check(client, ban_type, value).await, @@ -107,6 +114,34 @@ async fn execute_bulk_ban( } } +async fn execute_ip_ban( + client: &AdminApiClient, + value: &str, + duration_hours: Option<&str>, + audit_log_reason: Option<&str>, +) -> (&'static str, String) { + let duration_hours = match duration_hours.map(str::trim).filter(|v| !v.is_empty()) { + None => 0, + Some(raw) => match raw.parse::() { + Ok(hours) => hours, + Err(_) => return ("error", "Invalid ban duration".into()), + }, + }; + let success_message = if duration_hours == 0 { + format!("{value} banned permanently") + } else { + format!( + "{value} banned for {}", + crate::templates::pages::bans::ip_ban_duration_label(duration_hours) + ) + }; + ban_action_result( + client.ban_ip(value, duration_hours, audit_log_reason).await, + success_message, + format!("Failed to ban {value}"), + ) +} + async fn execute_single_ban( client: &AdminApiClient, ban_type: &str, @@ -114,7 +149,6 @@ async fn execute_single_ban( audit_log_reason: Option<&str>, ) -> (&'static str, String) { let result = match ban_type { - "ip-bans" => client.ban_ip(value, audit_log_reason).await, "email-bans" => client.ban_email(value, audit_log_reason).await, "phrase-bans" => client.ban_phrase(value, audit_log_reason).await, "url-bans" => client.ban_url(value, audit_log_reason).await, @@ -166,7 +200,10 @@ async fn execute_check( _ => return ("error", "Unknown ban type".into()), }; match result { - Ok(r) if r.banned => ("info", format!("{value} is banned")), + Ok(r) if r.banned => match r.expires_at { + Some(expires_at) => ("info", format!("{value} is banned until {expires_at}")), + None => ("info", format!("{value} is banned")), + }, Ok(_) => ("info", format!("{value} is NOT banned")), Err(error) => { tracing::warn!(%error, ban_type, value, "admin API request failed: check ban status"); diff --git a/fluxer_admin/src/routes/user_actions.rs b/fluxer_admin/src/routes/user_actions.rs index e7bb09bdd..8f9181bf2 100644 --- a/fluxer_admin/src/routes/user_actions.rs +++ b/fluxer_admin/src/routes/user_actions.rs @@ -243,8 +243,11 @@ pub async fn dispatch( let Some(ip) = get("ip") else { return DispatchOutcome::error("IP address is required"); }; + let Ok(duration) = form.parse_value::("duration_hours") else { + return DispatchOutcome::error("Invalid ban duration"); + }; DispatchOutcome::from_result( - client.ban_ip(&ip, None).await, + client.ban_ip(&ip, duration.unwrap_or(0), None).await, "IP banned successfully", "Failed to ban IP", ) diff --git a/fluxer_admin/src/templates/pages/bans.rs b/fluxer_admin/src/templates/pages/bans.rs index 5e22ce2a1..ab4fa6fb3 100644 --- a/fluxer_admin/src/templates/pages/bans.rs +++ b/fluxer_admin/src/templates/pages/bans.rs @@ -20,6 +20,24 @@ pub struct BanConfig { pub entity_name: &'static str, pub active_page: &'static str, pub show_bulk_tools: bool, + pub show_duration: bool, +} + +const IP_BAN_DURATIONS: &[(u32, &str)] = &[ + (24, "1 day"), + (168, "7 days"), + (720, "30 days"), + (0, "Permanent"), +]; + +pub fn ip_ban_duration_label(hours: u32) -> String { + IP_BAN_DURATIONS + .iter() + .find(|(value, _)| *value == hours) + .map_or_else( + || format!("{hours} hours"), + |(_, label)| (*label).to_owned(), + ) } pub const BAN_CONFIGS: &[BanConfig] = &[ @@ -33,6 +51,7 @@ pub const BAN_CONFIGS: &[BanConfig] = &[ entity_name: "IP/CIDR", active_page: "ip-bans", show_bulk_tools: false, + show_duration: true, }, BanConfig { title: "Email Bans", @@ -44,6 +63,7 @@ pub const BAN_CONFIGS: &[BanConfig] = &[ entity_name: "Email", active_page: "email-bans", show_bulk_tools: false, + show_duration: false, }, BanConfig { title: "Phrase Bans", @@ -55,6 +75,7 @@ pub const BAN_CONFIGS: &[BanConfig] = &[ entity_name: "Phrase", active_page: "phrase-bans", show_bulk_tools: false, + show_duration: false, }, BanConfig { title: "URL Blocklist", @@ -66,6 +87,7 @@ pub const BAN_CONFIGS: &[BanConfig] = &[ entity_name: "URL", active_page: "url-bans", show_bulk_tools: false, + show_duration: false, }, BanConfig { title: "File SHA Blocklist", @@ -77,6 +99,7 @@ pub const BAN_CONFIGS: &[BanConfig] = &[ entity_name: "SHA-256", active_page: "file-sha-bans", show_bulk_tools: true, + show_duration: false, }, BanConfig { title: "Avatar Hash Blocklist", @@ -88,6 +111,7 @@ pub const BAN_CONFIGS: &[BanConfig] = &[ entity_name: "Avatar Hash", active_page: "avatar-hash-bans", show_bulk_tools: false, + show_duration: false, }, BanConfig { title: "URL Domain Blocklist", @@ -99,6 +123,7 @@ pub const BAN_CONFIGS: &[BanConfig] = &[ entity_name: "Domain", active_page: "url-domain-bans", show_bulk_tools: false, + show_duration: false, }, BanConfig { title: "Profile Substring Blocklist", @@ -110,6 +135,7 @@ pub const BAN_CONFIGS: &[BanConfig] = &[ entity_name: "Substring", active_page: "profile-substring-bans", show_bulk_tools: false, + show_duration: false, }, ]; @@ -163,6 +189,9 @@ fn ban_card(base: &str, cfg: &BanConfig, csrf_token: &str) -> Markup { (csrf_input(csrf_token)) div class="space-y-4" { (form_field(cfg.input_name, cfg.input_label, cfg.input_type, cfg.placeholder, true)) + @if cfg.show_duration { + (duration_field()) + } (form_field("audit_log_reason", "Private reason (audit log, optional)", "text", "Why is this ban being applied?", false)) (submit_btn("Ban", cfg.entity_name, false)) } @@ -394,6 +423,24 @@ fn form_field( } } +fn duration_field() -> Markup { + html! { + div class="space-y-1" { + label for="duration_hours" class="block text-sm font-medium text-neutral-700" { + "Duration" + } + select id="duration_hours" name="duration_hours" + class="block w-full rounded-md border border-neutral-300 px-3 py-2 text-sm \ + shadow-sm focus:border-brand-primary focus:outline-none focus:ring-1 \ + focus:ring-brand-primary" { + @for &(value, label) in IP_BAN_DURATIONS { + option value=(value) { (label) } + } + } + } + } +} + fn textarea_field(name: &str, label: &str, required: bool) -> Markup { html! { div class="space-y-1" { diff --git a/fluxer_admin/tests/api_deserialization.rs b/fluxer_admin/tests/api_deserialization.rs index bcb6890c3..020f2982a 100644 --- a/fluxer_admin/tests/api_deserialization.rs +++ b/fluxer_admin/tests/api_deserialization.rs @@ -859,6 +859,14 @@ fn deserialize_ban_check_response() { assert!(resp.banned); } +#[test] +fn deserialize_ban_check_response_with_expiry() { + let json = r#"{"banned": true, "expires_at": "2026-10-04T12:00:00.000Z"}"#; + let resp: types::BanCheckResult = serde_json::from_str(json).unwrap(); + assert!(resp.banned); + assert_eq!(resp.expires_at.as_deref(), Some("2026-10-04T12:00:00.000Z")); +} + #[test] fn deserialize_codes_response() { let json = r#"{"codes": ["ABC-DEF", "GHI-JKL"]}"#; diff --git a/fluxer_api/src/api/admin/AdminRepository.ts b/fluxer_api/src/api/admin/AdminRepository.ts index bf3da79b1..2fd325bd3 100644 --- a/fluxer_api/src/api/admin/AdminRepository.ts +++ b/fluxer_api/src/api/admin/AdminRepository.ts @@ -161,38 +161,43 @@ export class AdminRepository implements IAdminRepository { return false; } - async banIp(ip: string): Promise { - if (isIpBanExempt(ip)) { - return; - } - const canonicalIp = canonicalizeBannedIpEntry(ip); - await upsertOne( - BannedIps.insert({ - ip: canonicalIp, - ban_kind: 'permanent', - reason: 'platform_admin_enforcement', - expires_at: null, - created_at: new Date(), - }), - ); + async banIp(ip: string, ttlSeconds: number | null = null): Promise { + await this.writeIpBan(ip, 'platform_admin_enforcement', ttlSeconds); } async banIpTemp(ip: string, ttlSeconds: number): Promise { - if (!Number.isInteger(ttlSeconds) || ttlSeconds <= 0) { + await this.writeIpBan(ip, 'abusive_api_access_patterns', ttlSeconds); + } + + private async writeIpBan(ip: string, reason: string, ttlSeconds: number | null): Promise { + if (ttlSeconds !== null && (!Number.isInteger(ttlSeconds) || ttlSeconds <= 0)) { throw new RangeError('Temporary IP ban TTL must be a positive integer'); } if (isIpBanExempt(ip)) { return; } const canonicalIp = canonicalizeBannedIpEntry(ip); + const createdAt = new Date(); + if (ttlSeconds === null) { + await upsertOne( + BannedIps.insert({ + ip: canonicalIp, + ban_kind: 'permanent', + reason, + expires_at: null, + created_at: createdAt, + }), + ); + return; + } await upsertOne( BannedIps.insertWithTtl( { ip: canonicalIp, ban_kind: 'temporary_24h', - reason: 'abusive_api_access_patterns', - expires_at: new Date(Date.now() + ttlSeconds * 1000), - created_at: new Date(), + reason, + expires_at: new Date(createdAt.getTime() + ttlSeconds * 1000), + created_at: createdAt, }, ttlSeconds, ), @@ -228,13 +233,16 @@ export class AdminRepository implements IAdminRepository { expires_at?: Date | null; created_at?: Date | null; }>(LOAD_ALL_BANNED_IPS_QUERY.bind({})); - return rows.map((row) => ({ - ip: row.ip, - kind: parseBannedIpKind(row.ban_kind), - reason: row.reason ?? null, - expiresAt: row.expires_at ?? null, - createdAt: row.created_at ?? null, - })); + const now = Date.now(); + return rows + .filter((row) => !row.expires_at || row.expires_at.getTime() > now) + .map((row) => ({ + ip: row.ip, + kind: parseBannedIpKind(row.ban_kind), + reason: row.reason ?? null, + expiresAt: row.expires_at ?? null, + createdAt: row.created_at ?? null, + })); } async isEmailBanned(email: string): Promise { diff --git a/fluxer_api/src/api/admin/IAdminRepository.ts b/fluxer_api/src/api/admin/IAdminRepository.ts index 5b0214260..f8d832e93 100644 --- a/fluxer_api/src/api/admin/IAdminRepository.ts +++ b/fluxer_api/src/api/admin/IAdminRepository.ts @@ -43,7 +43,7 @@ export abstract class IAdminRepository { abstract isIpBanned(ip: string): Promise; - abstract banIp(ip: string): Promise; + abstract banIp(ip: string, ttlSeconds?: number | null): Promise; abstract banIpTemp(ip: string, ttlSeconds: number): Promise; diff --git a/fluxer_api/src/api/admin/controllers/BanAdminController.ts b/fluxer_api/src/api/admin/controllers/BanAdminController.ts index 95e4e9b8b..3b50c6451 100644 --- a/fluxer_api/src/api/admin/controllers/BanAdminController.ts +++ b/fluxer_api/src/api/admin/controllers/BanAdminController.ts @@ -57,9 +57,9 @@ const BLOCKLIST_CATALOG = [ { list_type: 'ip' as const, description: - 'IPv4/IPv6 addresses and CIDR ranges denied service. Applies to live connections and can be applied retroactively.', + 'IPv4/IPv6 addresses and CIDR ranges denied service. Applies to live connections and can be applied retroactively. An entry can carry an expiry, after which it stops applying and is removed.', value_field: 'ip', - fields: [], + fields: ['duration_hours'], scoped: false, supports_bulk_create: false, supports_bulk_delete: false, @@ -232,7 +232,7 @@ async function checkBlocklistEntry( listType: AdminBlocklistListType, entryValue: string, scope: ProfileSubstringScope | undefined, -): Promise<{banned: boolean}> { +): Promise<{banned: boolean; expires_at?: string | null}> { switch (listType) { case 'ip': return bans.checkIpBan({ip: entryValue}); @@ -507,7 +507,7 @@ export function BanAdminController(app: HonoApp) { banned: result.banned, }, }); - return ctx.json(result); + return ctx.json({banned: result.banned, expires_at: result.expires_at ?? null}); }, ); app.patch( diff --git a/fluxer_api/src/api/admin/services/AdminBanManagementService.ts b/fluxer_api/src/api/admin/services/AdminBanManagementService.ts index dfcbf2e9d..a1e5a30dd 100644 --- a/fluxer_api/src/api/admin/services/AdminBanManagementService.ts +++ b/fluxer_api/src/api/admin/services/AdminBanManagementService.ts @@ -122,6 +122,7 @@ export class AdminBanManagementService { async banIp( data: { ip: string; + duration_hours?: number; }, adminUserId: UserID, auditLogReason: string | null, @@ -142,15 +143,24 @@ export class AdminBanManagementService { message: 'This IP address is on the instance exemption list', }); } - await adminRepository.banIp(data.ip); - ipBanCache.ban(data.ip); + const durationHours = data.duration_hours ?? 0; + const metadata = new Map([['ip', data.ip]]); + if (durationHours > 0) { + const ttlSeconds = durationHours * 3600; + await adminRepository.banIp(data.ip, ttlSeconds); + metadata.set('duration_hours', durationHours.toString()); + metadata.set('expires_at', new Date(Date.now() + ttlSeconds * 1000).toISOString()); + } else { + await adminRepository.banIp(data.ip); + } + await ipBanCache.refresh(); await cacheService.publish(IP_BAN_REFRESH_CHANNEL, 'refresh'); await this.createBlocklistAuditLog({ adminUserId, targetType: 'ip', action: 'ban_ip', auditLogReason, - metadata: new Map([['ip', data.ip]]), + metadata, }); } @@ -177,9 +187,10 @@ export class AdminBanManagementService { async checkIpBan(data: {ip: string}): Promise<{ banned: boolean; + expires_at: string | null; }> { - const banned = ipBanCache.isBanned(data.ip); - return {banned}; + const match = ipBanCache.getMatch(data.ip); + return {banned: match !== null, expires_at: toIsoString(match?.expiresAt)}; } async banEmail( diff --git a/fluxer_api/src/api/admin/tests/AdminIpBanExpiry.test.ts b/fluxer_api/src/api/admin/tests/AdminIpBanExpiry.test.ts new file mode 100644 index 000000000..46e0b1624 --- /dev/null +++ b/fluxer_api/src/api/admin/tests/AdminIpBanExpiry.test.ts @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import {AdminRepository} from '@app/api/admin/AdminRepository'; +import type {AdminAuditLog} from '@app/api/admin/IAdminRepository'; +import {createTestAccount, setUserACLs, type TestAccount} from '@app/api/auth/tests/AuthTestUtils'; +import {ipBanCache} from '@app/api/middleware/IpBanMiddleware'; +import {getAdminRepository} from '@app/api/middleware/ServiceSingletons'; +import {type ApiTestHarness, createApiTestHarness} from '@app/api/test/ApiTestHarness'; +import {HTTP_STATUS} from '@app/api/test/TestConstants'; +import {createBuilder} from '@app/api/test/TestRequestBuilder'; +import {AdminACLs} from '@fluxer/constants/src/AdminACLs'; +import {afterAll, beforeAll, beforeEach, describe, expect, it} from 'vitest'; + +interface BlocklistEntryPage { + items: Array<{value: string; reason: string | null; expires_at: string | null; created_at: string | null}>; +} + +interface BlocklistCheck { + banned: boolean; + expires_at: string | null; +} + +const HOUR_MS = 3_600_000; + +describe('Admin IP bans with an expiry', () => { + let harness: ApiTestHarness; + let admin: TestAccount; + + beforeAll(async () => { + harness = await createApiTestHarness(); + }); + + beforeEach(async () => { + await harness.reset(); + admin = await setUserACLs(harness, await createTestAccount(harness), [ + AdminACLs.AUTHENTICATE, + AdminACLs.BAN_IP_ADD, + AdminACLs.BAN_IP_CHECK, + AdminACLs.BAN_IP_REMOVE, + ]); + }); + + afterAll(async () => { + await harness.shutdown(); + }); + + async function addIpBan(body: Record, status: number = HTTP_STATUS.NO_CONTENT): Promise { + await createBuilder(harness, admin.token).post('/admin/blocklists/ip/entries').body(body).expect(status).execute(); + } + + async function listIpBans(): Promise { + const page = await createBuilder(harness, admin.token) + .get('/admin/blocklists/ip/entries') + .expect(HTTP_STATUS.OK) + .execute(); + return page.items; + } + + async function checkIpBan(ip: string): Promise { + return createBuilder(harness, admin.token) + .get(`/admin/blocklists/ip/entries/${encodeURIComponent(ip)}`) + .expect(HTTP_STATUS.OK) + .execute(); + } + + async function banIpAuditLogs(): Promise> { + const logs = await getAdminRepository().listAllAuditLogsPaginated(1000); + return logs.filter((log) => log.action === 'ban_ip'); + } + + it('stores an expiring ban that the listing and the check both report', async () => { + const before = Date.now(); + await addIpBan({ip: '198.51.100.7', duration_hours: 24}); + + const [entry] = await listIpBans(); + expect(entry?.value).toBe('198.51.100.7'); + expect(entry?.reason).toBe('platform_admin_enforcement'); + const expiresAt = Date.parse(entry?.expires_at ?? ''); + expect(expiresAt).toBeGreaterThanOrEqual(before + 24 * HOUR_MS); + expect(expiresAt).toBeLessThanOrEqual(Date.now() + 24 * HOUR_MS); + + const check = await checkIpBan('198.51.100.7'); + expect(check.banned).toBe(true); + expect(Date.parse(check.expires_at ?? '')).toBe(expiresAt); + }); + + it('records the duration and expiry in the audit log', async () => { + await addIpBan({ip: '198.51.100.8', duration_hours: 168}); + + const [log] = await banIpAuditLogs(); + const metadata = Object.fromEntries(log!.metadata); + expect(metadata['ip']).toBe('198.51.100.8'); + expect(metadata['duration_hours']).toBe('168'); + expect(Date.parse(metadata['expires_at'] ?? '')).toBeGreaterThan(Date.now() + 167 * HOUR_MS); + }); + + it('keeps a ban permanent when no duration is given', async () => { + await addIpBan({ip: '198.51.100.9'}); + await addIpBan({ip: '198.51.100.10', duration_hours: 0}); + + const entries = await listIpBans(); + expect(entries.map((entry) => entry.expires_at)).toEqual([null, null]); + expect(await checkIpBan('198.51.100.9')).toEqual({banned: true, expires_at: null}); + const [log] = await banIpAuditLogs(); + expect(log!.metadata.has('duration_hours')).toBe(false); + }); + + it('replaces a permanent ban with an expiring one when the address is banned again', async () => { + await addIpBan({ip: '198.51.100.11'}); + await addIpBan({ip: '198.51.100.11', duration_hours: 24}); + + const [entry] = await listIpBans(); + expect(entry?.expires_at).not.toBeNull(); + const check = await checkIpBan('198.51.100.11'); + expect(check.banned).toBe(true); + expect(check.expires_at).not.toBeNull(); + }); + + it('rejects a duration beyond one year', async () => { + await addIpBan({ip: '198.51.100.12', duration_hours: 8761}, HTTP_STATUS.BAD_REQUEST); + await addIpBan({ip: '198.51.100.12', duration_hours: 1.5}, HTTP_STATUS.BAD_REQUEST); + + expect(await listIpBans()).toEqual([]); + }); + + it('reports a check with no match as not banned with no expiry', async () => { + expect(await checkIpBan('198.51.100.13')).toEqual({banned: false, expires_at: null}); + }); + + it('stops applying an expiring ban once its expiry has passed', async () => { + await new AdminRepository().banIp('198.51.100.14', 1); + await ipBanCache.refresh(); + expect(ipBanCache.isBanned('198.51.100.14')).toBe(true); + + await new Promise((resolve) => setTimeout(resolve, 1100)); + + expect(ipBanCache.isBanned('198.51.100.14')).toBe(false); + await ipBanCache.refresh(); + expect(ipBanCache.isBanned('198.51.100.14')).toBe(false); + expect(await listIpBans()).toEqual([]); + }); +}); diff --git a/fluxer_api/src/api/middleware/IpBanMiddleware.ts b/fluxer_api/src/api/middleware/IpBanMiddleware.ts index 9804d0437..90c2fecc9 100644 --- a/fluxer_api/src/api/middleware/IpBanMiddleware.ts +++ b/fluxer_api/src/api/middleware/IpBanMiddleware.ts @@ -127,7 +127,7 @@ class IpBanCache { const sameIpDecisionKey = getSameIpDecisionKey(parsed.canonical); if (sameIpDecisionKey) { const decisionCount = this.sameIpDecisionBans.get(sameIpDecisionKey); - if (decisionCount) { + if (decisionCount && this.isActive(decisionCount)) { return { ipAddress: parsed.canonical, matchedEntry: sameIpDecisionKey, @@ -137,7 +137,7 @@ class IpBanCache { } const singleMap = this.singleIpBans[parsed.family]; const single = singleMap.get(parsed.canonical); - if (single) { + if (single && this.isActive(single.count)) { return { ipAddress: parsed.canonical, matchedEntry: parsed.canonical, @@ -146,7 +146,7 @@ class IpBanCache { } const rangeMap = this.rangeIpBans[parsed.family]; for (const [canonical, range] of rangeMap.entries()) { - if (parsed.value >= range.start && parsed.value <= range.end) { + if (parsed.value >= range.start && parsed.value <= range.end && this.isActive(range.count)) { return { ipAddress: parsed.canonical, matchedEntry: canonical, @@ -232,6 +232,13 @@ class IpBanCache { return count.permanent <= 0 && count.temporary <= 0; } + private isActive(count: IpBanCount): boolean { + if (count.permanent > 0 || !count.temporaryExpiresAt) { + return true; + } + return count.temporaryExpiresAt.getTime() > Date.now(); + } + private resolveCount(count: IpBanCount): { kind: BannedIpKind; expiresAt: Date | null; diff --git a/fluxer_api/src/api/middleware/tests/IpBanMiddleware.test.ts b/fluxer_api/src/api/middleware/tests/IpBanMiddleware.test.ts index 2076a3590..9113322b4 100644 --- a/fluxer_api/src/api/middleware/tests/IpBanMiddleware.test.ts +++ b/fluxer_api/src/api/middleware/tests/IpBanMiddleware.test.ts @@ -1,12 +1,16 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import {ipBanCache} from '@app/api/middleware/IpBanMiddleware'; -import {beforeEach, describe, expect, it} from 'vitest'; +import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'; beforeEach(() => { ipBanCache.resetCaches(); }); +afterEach(() => { + vi.useRealTimers(); +}); + describe('IpBanCache', () => { it('blocks IPv4-mapped IPv6 when a single IPv4 address is banned', () => { ipBanCache.ban('127.0.0.1'); @@ -44,4 +48,21 @@ describe('IpBanCache', () => { expect(match?.kind).toBe('permanent'); expect(match?.expiresAt).toBe(null); }); + it('stops matching a temporary ban once it has expired', () => { + vi.useFakeTimers({toFake: ['Date']}); + ipBanCache.banTemp('203.0.113.52', 3600); + ipBanCache.banTemp('203.0.113.0/24', 3600); + expect(ipBanCache.isBanned('203.0.113.52')).toBe(true); + expect(ipBanCache.isBanned('203.0.113.53')).toBe(true); + vi.advanceTimersByTime(3_600_001); + expect(ipBanCache.getMatch('203.0.113.52')).toBe(null); + expect(ipBanCache.getMatch('203.0.113.53')).toBe(null); + }); + it('keeps matching a permanent ban that shares an address with an expired temporary one', () => { + vi.useFakeTimers({toFake: ['Date']}); + ipBanCache.banTemp('203.0.113.54', 3600); + ipBanCache.ban('203.0.113.54'); + vi.advanceTimersByTime(3_600_001); + expect(ipBanCache.getMatch('203.0.113.54')?.kind).toBe('permanent'); + }); }); diff --git a/fluxer_docs/src/content/docs/admin-api/blocklists.mdx b/fluxer_docs/src/content/docs/admin-api/blocklists.mdx index fe48ac7b3..b4e2f9e00 100644 --- a/fluxer_docs/src/content/docs/admin-api/blocklists.mdx +++ b/fluxer_docs/src/content/docs/admin-api/blocklists.mdx @@ -14,7 +14,7 @@ Fluxer builds each permission name from `ban:`, the list name with each hyphen w ## Blocklist types -`ip` and `email` gate account access and registration. `phrase`, `url`, `url-domain`, `file-sha`, `avatar-hash`, and `profile-substring` gate what an account may post, link, upload, or display. `email` stores nothing but the value. An `ip` row also stores a ban kind, a reason, an expiry, and its creation time. +`ip` and `email` gate account access and registration. `phrase`, `url`, `url-domain`, `file-sha`, `avatar-hash`, and `profile-substring` gate what an account may post, link, upload, or display. `email` stores nothing but the value. An `ip` row also stores a ban kind, a reason, an expiry, and its creation time. An `ip` row with an expiry stops applying when it expires, and Fluxer then deletes it. | Value | Description | | --- | --- | @@ -104,7 +104,7 @@ One entry of the blocklist catalogue returned by [List blocklists](#list-blockli 1 `ip` names `ip`, `email` names `email`, `url-domain` names `domain`, `phrase` names `phrase`, `url` names `url`, `file-sha` names `sha256_hex`, `avatar-hash` names `hashes`, and `profile-substring` names `substrings` -2 Empty for `ip`, `email`, and `phrase`. `url` names `category`, `severity`, `source_url`, and `notes`. `url-domain` adds `match_subdomains`, `file-sha` adds `content_type`, and `avatar-hash` adds `reason`. `profile-substring` names `scope`, `reason`, and `notes` +2 `ip` names `duration_hours`. Empty for `email` and `phrase`. `url` names `category`, `severity`, `source_url`, and `notes`. `url-domain` adds `match_subdomains`, `file-sha` adds `content_type`, and `avatar-hash` adds `reason`. `profile-substring` names `scope`, `reason`, and `notes` 3 True only for `profile-substring` @@ -112,7 +112,7 @@ One entry of the blocklist catalogue returned by [List blocklists](#list-blockli 5 True only for `avatar-hash` and `profile-substring` -6 True for `url`, `url-domain`, `file-sha`, `avatar-hash`, and `profile-substring`, which is exactly the set whose `fields` array is non-empty +6 True for `url`, `url-domain`, `file-sha`, `avatar-hash`, and `profile-substring` ### Example @@ -163,7 +163,7 @@ One stored row of one blocklist. Every field is present on every entry, and a fi 6 Non-null only on `url-domain` -7 Non-null only on `ip`. An address added through [Add blocklist entry](#add-blocklist-entry) is written as a permanent ban, so it reads back with the reason `platform_admin_enforcement` and a null `expires_at` +7 Non-null only on `ip`. An address added through [Add blocklist entry](#add-blocklist-entry) reads back with the reason `platform_admin_enforcement`. Its `expires_at` is null unless it was added with a positive `duration_hours`. A row past its `expires_at` is not listed 8 Both null on `email` and `phrase`, which store nothing but the value. `created_by_user_id` is also null on `ip` @@ -200,9 +200,12 @@ The decision [Check blocklist entry](#check-blocklist-entry) returns for one val | Field | Type | Description | | --- | --- | --- | | banned1 | boolean | Whether the value is currently blocked by the named blocklist | +| expires_at2 | ?ISO8601 timestamp | When the matching ban expires | 1 Reports the decision the enforcement path would make for this value +2 Non-null only on `ip` when the matching ban has an expiry. Null when the ban is permanent, when nothing matches, and on every other blocklist + :::note[A block and a row are different things] A value can be blocked with no row of its own, as a single address covered by a stored CIDR range is. A row can exist while the value reads as not blocked, as an exempt address or an exempt email domain does. ::: @@ -244,6 +247,7 @@ Each field is a string, except `hashes` and `substrings`, which are `array[strin | source_url?4 | string | The feed or evidence URL (1-2048 characters) | | reason?7 | string | The reason (1-1024 characters) | | notes?8 | string | The internal note (1-1024 characters) | +| duration_hours?9 | integer | Hours until the row expires (0-8760, default 0) | 3 Required by `profile-substring`. Every other blocklist strips `scope` @@ -257,6 +261,8 @@ Each field is a string, except `hashes` and `substrings`, which are `array[strin 8 Accepted only by `url`, `url-domain`, `file-sha`, `avatar-hash`, and `profile-substring` +9 Accepted only by `ip`. `0` writes a permanent row. A positive value writes a row that stops applying after that many hours, and Fluxer then deletes it. Adding an address again replaces its expiry, so a permanent row can become temporary and a temporary row can become permanent + ## List blocklists @@ -375,7 +381,7 @@ The response has no body, so it does not report the canonical form that was stor Fluxer checks later requests against the written rows. For every list except `email`, other nodes see the rows after a short propagation delay. No Gateway Dispatch is emitted. -Fluxer records one [Admin audit entry](/admin-api/#admin-audit-entry-object) per written value, with that value in its metadata. It records an entry for a refused `ip` too, under the action `ban_ip_skipped_exempt`, before it returns the 400. +Fluxer records one [Admin audit entry](/admin-api/#admin-audit-entry-object) per written value, with that value in its metadata. An `ip` added with a positive `duration_hours` adds the metadata keys `duration_hours` and `expires_at`. Fluxer records an entry for a refused `ip` too, under the action `ban_ip_skipped_exempt`, before it returns the 400. ### Rate limit diff --git a/fluxer_docs/src/content/docs/http-api/errors.md b/fluxer_docs/src/content/docs/http-api/errors.md index 5030c3d56..0274a4728 100644 --- a/fluxer_docs/src/content/docs/http-api/errors.md +++ b/fluxer_docs/src/content/docs/http-api/errors.md @@ -26,8 +26,8 @@ The error code determines which supplementary members a failure has, and most co - `ip_address` is the normalised client address. - `appeal_email` is the address an appeal is sent to. -- `appeals_supported` is `true` only for the permanent ban. -- `ban_kind` is `permanent` or `temporary_24h`. +- `appeals_supported` is `true` for both kinds of ban. +- `ban_kind` is `permanent` or `temporary_24h`. `temporary_24h` covers every ban that records an expiry, whatever its length. - `expires_at` is an ISO 8601 timestamp when the ban records an expiry, and `null` otherwise, including on every permanent ban. ## Validation failure codes @@ -462,7 +462,7 @@ Your IP address {ipAddress} has been permanently blocked from the Fluxer API by ### `GLOBAL_IP_TEMPORARILY_BANNED` -Your IP address {ipAddress} has been temporarily blocked from the Fluxer API for 24 hours because of abusive or unusual access patterns +Your IP address {ipAddress} has been temporarily blocked from the Fluxer API ### `GONE` diff --git a/fluxer_docs/src/content/docs/http-api/guild-moderation.mdx b/fluxer_docs/src/content/docs/http-api/guild-moderation.mdx index b344e020f..581c0a921 100644 --- a/fluxer_docs/src/content/docs/http-api/guild-moderation.mdx +++ b/fluxer_docs/src/content/docs/http-api/guild-moderation.mdx @@ -197,7 +197,7 @@ The operation deletes the ban together with the address and email blocks it had. It does not restore the removed membership, the guild profile fields and roles that membership had, or the deleted messages. The unbanned account can rejoin through an ordinary invite. -An instance-wide IP ban is a separate mechanism this operation does not touch. Every request from an address it covers is still refused with 403 `GLOBAL_IP_BANNED` for a permanent ban and 403 `GLOBAL_IP_TEMPORARILY_BANNED` for a 24 hour one. +An instance-wide IP ban is a separate mechanism this operation does not touch. Every request from an address it covers is still refused with 403 `GLOBAL_IP_BANNED` for a permanent ban and 403 `GLOBAL_IP_TEMPORARILY_BANNED` for a temporary one. ### Rate limit diff --git a/packages/errors/src/domains/moderation/IpBannedError.ts b/packages/errors/src/domains/moderation/IpBannedError.ts index 9609775f1..bf8bc80ff 100644 --- a/packages/errors/src/domains/moderation/IpBannedError.ts +++ b/packages/errors/src/domains/moderation/IpBannedError.ts @@ -11,7 +11,7 @@ interface IpBannedErrorOptions { expiresAt?: Date | null; } -const SUPPORT_EMAIL = 'support@fluxer.app'; +const SUPPORT_EMAIL = 'support@fluxer.com'; export class IpBannedError extends ForbiddenError { constructor(options: IpBannedErrorOptions) { @@ -21,7 +21,7 @@ export class IpBannedError extends ForbiddenError { data: { ip_address: options.ipAddress, appeal_email: SUPPORT_EMAIL, - appeals_supported: !isTemporary, + appeals_supported: true, ban_kind: options.kind, expires_at: options.expiresAt?.toISOString() ?? null, }, diff --git a/packages/errors/src/i18n/ErrorI18nMessages.ts b/packages/errors/src/i18n/ErrorI18nMessages.ts index bc6c8a293..efcebc87f 100644 --- a/packages/errors/src/i18n/ErrorI18nMessages.ts +++ b/packages/errors/src/i18n/ErrorI18nMessages.ts @@ -446,7 +446,7 @@ export const ERROR_I18N_MESSAGES = { 'permissions.global_ip_banned': 'Your IP address {ipAddress} has been permanently blocked from the Fluxer API by platform administrators. If you believe this is a mistake, contact support@fluxer.app to appeal. Include this IP address in your appeal.', 'permissions.global_ip_temporarily_banned': - 'Your IP address {ipAddress} has been temporarily blocked from the Fluxer API for 24 hours because of abusive or unusual access patterns. We usually do not provide appeals for temporary API bans. Change IP addresses or wait for the ban to expire, and review the Fluxer API access patterns coming from your client.', + 'Your IP address {ipAddress} has been temporarily blocked from the Fluxer API. The block lifts on its own when it expires. If you think this is a mistake, contact support@fluxer.com and include this IP address.', 'permissions.missing_access': "You don't have access to this resource or feature.", 'permissions.missing_permissions': "You don't have the permissions required to perform this action.", 'permissions.user_banned_from_guild': 'This user is banned from this community.', diff --git a/packages/errors/src/i18n/locales/ar.ts b/packages/errors/src/i18n/locales/ar.ts index c3d5f5821..3cbf3a0ab 100644 --- a/packages/errors/src/i18n/locales/ar.ts +++ b/packages/errors/src/i18n/locales/ar.ts @@ -381,7 +381,7 @@ const ERROR_I18N_AR_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "المستخدم غير محظور.", "names_and_normalization.name_empty_after_normalization": "لا يمكن أن يكون الاسم فارغًا بعد التسوية.", "permissions.global_ip_banned": "تم حظر عنوان IP الخاص بك {ipAddress} نهائيًا من Fluxer API بواسطة مسؤولي المنصة. إذا كنت تعتقد أن هذا خطأ، فتواصل مع support@fluxer.app للاستئناف. اذكر عنوان IP هذا في الاستئناف.", - "permissions.global_ip_temporarily_banned": "تم حظر عنوان IP الخاص بك {ipAddress} مؤقتًا من Fluxer API لمدة 24 ساعة بسبب أنماط وصول مسيئة أو غير معتادة. لا نوفر عادةً استئنافات لحظر API المؤقت. غيّر عنوان IP أو انتظر انتهاء الحظر، وراجع أنماط الوصول إلى Fluxer API القادمة من عميلك.", + "permissions.global_ip_temporarily_banned": "تم حظر عنوان IP الخاص بك {ipAddress} مؤقتًا من Fluxer API. يُرفع الحظر تلقائيًا عند انتهاء مدته. إذا كنت تعتقد أن هذا خطأ، فتواصل مع support@fluxer.com واذكر عنوان IP هذا.", "permissions.missing_access": "ليس لديك وصول إلى هذا المورد أو الميزة.", "permissions.missing_permissions": "لا تملك الأذونات المطلوبة لتنفيذ هذا الإجراء.", "permissions.user_banned_from_guild": "المستخدم محظور من هذا المجتمع.", diff --git a/packages/errors/src/i18n/locales/bg.ts b/packages/errors/src/i18n/locales/bg.ts index 7a45bc644..ca9ea33de 100644 --- a/packages/errors/src/i18n/locales/bg.ts +++ b/packages/errors/src/i18n/locales/bg.ts @@ -381,7 +381,7 @@ const ERROR_I18N_BG_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Този потребител няма наложена забрана.", "names_and_normalization.name_empty_after_normalization": "Името не може да бъде празно след нормализиране.", "permissions.global_ip_banned": "IP адресът ти {ipAddress} е блокиран за постоянно за достъп до Fluxer API от администраторите на платформата. Ако смяташ, че това е грешка, свържи се със support@fluxer.app, за да обжалваш. Включи този IP адрес в обжалването.", - "permissions.global_ip_temporarily_banned": "IP адресът ти {ipAddress} е временно блокиран за достъп до Fluxer API за 24 часа поради злоупотреба или необичайни модели на достъп. Обикновено не разглеждаме обжалвания за временни забрани за API. Смени IP адреса си или изчакай забраната да изтече и прегледай моделите на достъп до Fluxer API от твоя клиент.", + "permissions.global_ip_temporarily_banned": "IP адресът ти {ipAddress} е временно блокиран за достъп до Fluxer API. Блокирането се премахва автоматично, когато изтече. Ако смяташ, че това е грешка, свържи се със support@fluxer.com и посочи този IP адрес.", "permissions.missing_access": "Нямаш достъп до този ресурс или функция.", "permissions.missing_permissions": "Нямаш необходимите разрешения, за да изпълниш това действие.", "permissions.user_banned_from_guild": "Този потребител има наложена забрана в тази общност.", diff --git a/packages/errors/src/i18n/locales/cs.ts b/packages/errors/src/i18n/locales/cs.ts index b4db79c3e..b9e79e402 100644 --- a/packages/errors/src/i18n/locales/cs.ts +++ b/packages/errors/src/i18n/locales/cs.ts @@ -381,7 +381,7 @@ const ERROR_I18N_CS_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Tento uživatel není zabanován.", "names_and_normalization.name_empty_after_normalization": "Název nemůže být po normalizaci prázdný.", "permissions.global_ip_banned": "Vaše IP adresa {ipAddress} byla správci platformy trvale zablokována pro Fluxer API. Pokud se domníváte, že jde o chybu, podejte odvolání na adrese support@fluxer.app. V odvolání uveďte tuto IP adresu.", - "permissions.global_ip_temporarily_banned": "Vaše IP adresa {ipAddress} byla na 24 hodin zablokována pro Fluxer API kvůli zneužívajícímu nebo neobvyklému způsobu přístupu. Odvolání proti dočasným blokacím API obvykle nevyřizujeme. Změňte IP adresu nebo počkejte na vypršení blokace a zkontrolujte, jak váš klient přistupuje k Fluxer API.", + "permissions.global_ip_temporarily_banned": "Vaše IP adresa {ipAddress} byla dočasně zablokována pro Fluxer API. Blokace se po vypršení sama zruší. Pokud se domníváte, že jde o chybu, napište na adresu support@fluxer.com a uveďte tuto IP adresu.", "permissions.missing_access": "Nemáte přístup k tomuto zdroji nebo funkci.", "permissions.missing_permissions": "Nemáte potřebná oprávnění k provedení této akce.", "permissions.user_banned_from_guild": "Tento uživatel má v této komunitě ban.", diff --git a/packages/errors/src/i18n/locales/da.ts b/packages/errors/src/i18n/locales/da.ts index 3a2207ebc..4b48c274d 100644 --- a/packages/errors/src/i18n/locales/da.ts +++ b/packages/errors/src/i18n/locales/da.ts @@ -381,7 +381,7 @@ const ERROR_I18N_DA_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Denne bruger er ikke udelukket.", "names_and_normalization.name_empty_after_normalization": "Navnet må ikke være tomt efter normalisering.", "permissions.global_ip_banned": "Din IP-adresse {ipAddress} er permanent blokeret fra Fluxer API af platformadministratorer. Hvis du mener, at dette er en fejl, kan du kontakte support@fluxer.app for at klage. Medtag denne IP-adresse i klagen.", - "permissions.global_ip_temporarily_banned": "Din IP-adresse {ipAddress} er midlertidigt blokeret fra Fluxer API i 24 timer på grund af misbrug eller usædvanlige adgangsmønstre. Vi behandler normalt ikke klager over midlertidige API-blokeringer. Skift IP-adresse, eller vent på, at blokeringen udløber, og gennemgå din klients adgangsmønstre til Fluxer API.", + "permissions.global_ip_temporarily_banned": "Din IP-adresse {ipAddress} er midlertidigt blokeret fra Fluxer API. Blokeringen ophæves automatisk, når den udløber. Hvis du mener, at dette er en fejl, kan du kontakte support@fluxer.com og oplyse denne IP-adresse.", "permissions.missing_access": "Du har ikke adgang til denne ressource eller funktion.", "permissions.missing_permissions": "Du har ikke de nødvendige tilladelser til at udføre denne handling.", "permissions.user_banned_from_guild": "Denne bruger er udelukket fra dette fællesskab.", diff --git a/packages/errors/src/i18n/locales/de.ts b/packages/errors/src/i18n/locales/de.ts index a1d272f20..4beba0375 100644 --- a/packages/errors/src/i18n/locales/de.ts +++ b/packages/errors/src/i18n/locales/de.ts @@ -381,7 +381,7 @@ const ERROR_I18N_DE_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Dieser Benutzer ist nicht gebannt.", "names_and_normalization.name_empty_after_normalization": "Der Name darf nach der Normalisierung nicht leer bleiben.", "permissions.global_ip_banned": "Deine IP-Adresse {ipAddress} wurde von Plattformadministratoren dauerhaft von der Fluxer API gesperrt. Wenn du glaubst, dass dies ein Fehler ist, kontaktiere support@fluxer.app, um Einspruch einzulegen. Gib diese IP-Adresse in deinem Einspruch an.", - "permissions.global_ip_temporarily_banned": "Deine IP-Adresse {ipAddress} wurde wegen missbräuchlicher oder ungewöhnlicher Zugriffsmuster für 24 Stunden von der Fluxer API gesperrt. Für vorübergehende API-Sperren ist normalerweise kein Einspruchsverfahren vorgesehen. Wechsle die IP-Adresse oder warte, bis die Sperre abläuft, und überprüfe die Zugriffsmuster deines Clients auf die Fluxer API.", + "permissions.global_ip_temporarily_banned": "Deine IP-Adresse {ipAddress} wurde vorübergehend von der Fluxer API gesperrt. Die Sperre wird automatisch aufgehoben, sobald sie abläuft. Wenn du glaubst, dass dies ein Fehler ist, kontaktiere support@fluxer.com und gib diese IP-Adresse an.", "permissions.missing_access": "Du hast keinen Zugriff auf diese Ressource oder Funktion.", "permissions.missing_permissions": "Du hast nicht die erforderlichen Berechtigungen, um diese Aktion auszuführen.", "permissions.user_banned_from_guild": "Dieser Benutzer ist aus dieser Community gebannt.", diff --git a/packages/errors/src/i18n/locales/el.ts b/packages/errors/src/i18n/locales/el.ts index 235246dc5..fb9115a0e 100644 --- a/packages/errors/src/i18n/locales/el.ts +++ b/packages/errors/src/i18n/locales/el.ts @@ -381,7 +381,7 @@ const ERROR_I18N_EL_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Αυτός ο χρήστης δεν έχει αποκλειστεί.", "names_and_normalization.name_empty_after_normalization": "Το όνομα δεν μπορεί να είναι κενό μετά την κανονικοποίηση.", "permissions.global_ip_banned": "Η διεύθυνση IP σου {ipAddress} έχει αποκλειστεί μόνιμα από το Fluxer API από τους διαχειριστές της πλατφόρμας. Αν πιστεύεις ότι πρόκειται για λάθος, επικοινώνησε με support@fluxer.app για να υποβάλεις προσφυγή. Συμπερίλαβε αυτήν τη διεύθυνση IP στην προσφυγή σου.", - "permissions.global_ip_temporarily_banned": "Η διεύθυνση IP σου {ipAddress} έχει αποκλειστεί προσωρινά από το Fluxer API για 24 ώρες λόγω καταχρηστικών ή ασυνήθιστων μοτίβων πρόσβασης. Συνήθως δεν παρέχουμε δυνατότητα προσφυγής για προσωρινούς αποκλεισμούς API. Άλλαξε διεύθυνση IP ή περίμενε να λήξει ο αποκλεισμός και έλεγξε τα μοτίβα πρόσβασης στο Fluxer API από τον client σου.", + "permissions.global_ip_temporarily_banned": "Η διεύθυνση IP σου {ipAddress} έχει αποκλειστεί προσωρινά από το Fluxer API. Ο αποκλεισμός αίρεται αυτόματα όταν λήξει. Αν πιστεύεις ότι πρόκειται για λάθος, επικοινώνησε με support@fluxer.com και συμπερίλαβε αυτήν τη διεύθυνση IP.", "permissions.missing_access": "Δεν έχεις πρόσβαση σε αυτόν τον πόρο ή σε αυτήν τη λειτουργία.", "permissions.missing_permissions": "Δεν έχεις τα απαραίτητα δικαιώματα για να εκτελέσεις αυτήν την ενέργεια.", "permissions.user_banned_from_guild": "Αυτός ο χρήστης έχει αποκλειστεί από αυτήν την κοινότητα.", diff --git a/packages/errors/src/i18n/locales/en-GB.ts b/packages/errors/src/i18n/locales/en-GB.ts index b71559da1..c92c4c82c 100644 --- a/packages/errors/src/i18n/locales/en-GB.ts +++ b/packages/errors/src/i18n/locales/en-GB.ts @@ -381,7 +381,7 @@ const ERROR_I18N_EN_GB_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "This user isn't banned.", "names_and_normalization.name_empty_after_normalization": "Name can't be empty after normalisation.", "permissions.global_ip_banned": "Your IP address {ipAddress} has been permanently blocked from the Fluxer API by platform administrators. If you believe this is a mistake, contact support@fluxer.app to appeal. Include this IP address in your appeal.", - "permissions.global_ip_temporarily_banned": "Your IP address {ipAddress} has been temporarily blocked from the Fluxer API for 24 hours because of abusive or unusual access patterns. We usually do not provide appeals for temporary API bans. Change IP addresses or wait for the ban to expire, and review the Fluxer API access patterns coming from your client.", + "permissions.global_ip_temporarily_banned": "Your IP address {ipAddress} has been temporarily blocked from the Fluxer API. The block lifts on its own when it expires. If you think this is a mistake, contact support@fluxer.com and include this IP address.", "permissions.missing_access": "You don't have access to this resource or feature.", "permissions.missing_permissions": "You don't have the permissions required to perform this action.", "permissions.user_banned_from_guild": "This user is banned from this community.", diff --git a/packages/errors/src/i18n/locales/es-419.ts b/packages/errors/src/i18n/locales/es-419.ts index c934067a5..fc94ebcb4 100644 --- a/packages/errors/src/i18n/locales/es-419.ts +++ b/packages/errors/src/i18n/locales/es-419.ts @@ -381,7 +381,7 @@ const ERROR_I18N_ES_419_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Este usuario no ha sido baneado.", "names_and_normalization.name_empty_after_normalization": "El nombre no puede quedar vacío después de la normalización.", "permissions.global_ip_banned": "Tu dirección IP {ipAddress} fue bloqueada permanentemente de la API de Fluxer por administradores de la plataforma. Si crees que es un error, escribe a support@fluxer.app para apelar. Incluye esta dirección IP en tu apelación.", - "permissions.global_ip_temporarily_banned": "Tu dirección IP {ipAddress} fue bloqueada temporalmente de la API de Fluxer durante 24 horas por patrones de acceso abusivos o inusuales. Por lo general no ofrecemos apelaciones para bloqueos temporales de la API. Cambia de dirección IP o espera a que termine el bloqueo, y revisa los patrones de acceso a la API de Fluxer que provienen de tu cliente.", + "permissions.global_ip_temporarily_banned": "Tu dirección IP {ipAddress} fue bloqueada temporalmente de la API de Fluxer. El bloqueo se levanta automáticamente cuando vence. Si crees que es un error, escribe a support@fluxer.com e incluye esta dirección IP.", "permissions.missing_access": "No tienes acceso a este recurso o función.", "permissions.missing_permissions": "No tienes los permisos necesarios para realizar esta acción.", "permissions.user_banned_from_guild": "Este usuario ha sido baneado de esta comunidad.", diff --git a/packages/errors/src/i18n/locales/es-ES.ts b/packages/errors/src/i18n/locales/es-ES.ts index dd869b7e6..6546395af 100644 --- a/packages/errors/src/i18n/locales/es-ES.ts +++ b/packages/errors/src/i18n/locales/es-ES.ts @@ -381,7 +381,7 @@ const ERROR_I18N_ES_ES_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Este usuario no está baneado.", "names_and_normalization.name_empty_after_normalization": "El nombre no puede quedar vacío tras la normalización.", "permissions.global_ip_banned": "Tu dirección IP {ipAddress} ha sido bloqueada permanentemente de la API de Fluxer por administradores de la plataforma. Si crees que es un error, contacta con support@fluxer.app para apelar. Incluye esta dirección IP en la apelación.", - "permissions.global_ip_temporarily_banned": "Tu dirección IP {ipAddress} ha sido bloqueada temporalmente de la API de Fluxer durante 24 horas por patrones de acceso abusivos o inusuales. Normalmente no ofrecemos apelaciones para baneos temporales de la API. Cambia de dirección IP o espera a que expire el bloqueo, y revisa los patrones de acceso a la API de Fluxer que provienen de tu cliente.", + "permissions.global_ip_temporarily_banned": "Tu dirección IP {ipAddress} ha sido bloqueada temporalmente de la API de Fluxer. El bloqueo se levantará automáticamente cuando caduque. Si crees que es un error, contacta con support@fluxer.com e incluye esta dirección IP.", "permissions.missing_access": "No tienes acceso a este recurso o función.", "permissions.missing_permissions": "No tienes los permisos necesarios para realizar esta acción.", "permissions.user_banned_from_guild": "Este usuario está baneado de esta comunidad.", diff --git a/packages/errors/src/i18n/locales/fi.ts b/packages/errors/src/i18n/locales/fi.ts index ae8fbcf28..9ef46ff17 100644 --- a/packages/errors/src/i18n/locales/fi.ts +++ b/packages/errors/src/i18n/locales/fi.ts @@ -381,7 +381,7 @@ const ERROR_I18N_FI_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Tällä käyttäjällä ei ole porttikieltoa.", "names_and_normalization.name_empty_after_normalization": "Normalisoinnin jälkeen nimi ei voi olla tyhjä.", "permissions.global_ip_banned": "Alustan ylläpitäjät ovat estäneet IP-osoitteelta {ipAddress} pääsyn Fluxer API -rajapintaan pysyvästi. Jos uskot tämän olevan virhe, lähetä valitus osoitteeseen support@fluxer.app. Liitä tämä IP-osoite valitukseesi.", - "permissions.global_ip_temporarily_banned": "IP-osoitteeltasi {ipAddress} on estetty pääsy Fluxer API -rajapintaan 24 tunniksi väärinkäytön tai epätavallisten käyttötapojen vuoksi. Emme yleensä käsittele väliaikaisia API-estoja koskevia valituksia. Vaihda IP-osoitetta tai odota eston päättymistä ja tarkista, miten asiakasohjelmasi käyttää Fluxer API -rajapintaa.", + "permissions.global_ip_temporarily_banned": "IP-osoitteeltasi {ipAddress} on estetty väliaikaisesti pääsy Fluxer API -rajapintaan. Esto poistuu automaattisesti, kun sen voimassaolo päättyy. Jos uskot tämän olevan virhe, ota yhteyttä osoitteeseen support@fluxer.com ja mainitse tämä IP-osoite.", "permissions.missing_access": "Ei oikeutta tähän resurssiin tai ominaisuuteen.", "permissions.missing_permissions": "Ei tarvittavia oikeuksia tämän toiminnon tekemiseen.", "permissions.user_banned_from_guild": "Tällä käyttäjällä on porttikielto tähän yhteisöön.", diff --git a/packages/errors/src/i18n/locales/fr.ts b/packages/errors/src/i18n/locales/fr.ts index fe9c77a3e..5391c1793 100644 --- a/packages/errors/src/i18n/locales/fr.ts +++ b/packages/errors/src/i18n/locales/fr.ts @@ -381,7 +381,7 @@ const ERROR_I18N_FR_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Cet utilisateur n'est pas banni.", "names_and_normalization.name_empty_after_normalization": "Le nom ne peut pas être vide une fois normalisé.", "permissions.global_ip_banned": "Les administrateurs de la plateforme ont définitivement bloqué l’accès à Fluxer API depuis votre adresse IP {ipAddress}. Si vous pensez qu’il s’agit d’une erreur, écrivez à support@fluxer.app pour déposer un recours. Indiquez cette adresse IP dans votre recours.", - "permissions.global_ip_temporarily_banned": "L’accès à Fluxer API depuis votre adresse IP {ipAddress} a été bloqué pendant 24 heures en raison d’une utilisation abusive ou inhabituelle. Nous ne proposons généralement pas de recours pour les blocages temporaires de l’API. Changez d’adresse IP ou attendez la fin du blocage, et vérifiez la façon dont votre client accède à Fluxer API.", + "permissions.global_ip_temporarily_banned": "L’accès à Fluxer API depuis votre adresse IP {ipAddress} a été temporairement bloqué. Le blocage sera levé automatiquement à son expiration. Si vous pensez qu’il s’agit d’une erreur, écrivez à support@fluxer.com en indiquant cette adresse IP.", "permissions.missing_access": "Vous n’avez pas accès à cette ressource ou fonctionnalité.", "permissions.missing_permissions": "Vous n’avez pas les permissions requises pour effectuer cette action.", "permissions.user_banned_from_guild": "Cet utilisateur est banni de cette communauté.", diff --git a/packages/errors/src/i18n/locales/he.ts b/packages/errors/src/i18n/locales/he.ts index c4cef43e3..d61e921e2 100644 --- a/packages/errors/src/i18n/locales/he.ts +++ b/packages/errors/src/i18n/locales/he.ts @@ -381,7 +381,7 @@ const ERROR_I18N_HE_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "משתמש זה לא חסום.", "names_and_normalization.name_empty_after_normalization": "השם לא יכול להיות ריק לאחר נורמליזציה.", "permissions.global_ip_banned": "כתובת ה-IP שלך {ipAddress} נחסמה לצמיתות מ-Fluxer API על ידי מנהלי הפלטפורמה. אם לדעתך זו טעות, אפשר לפנות אל support@fluxer.app כדי לערער. יש לכלול את כתובת ה-IP הזו בערעור.", - "permissions.global_ip_temporarily_banned": "כתובת ה-IP שלך {ipAddress} נחסמה זמנית מ-Fluxer API למשך 24 שעות בגלל דפוסי גישה פוגעניים או חריגים. בדרך כלל איננו מאפשרים ערעורים על חסימות API זמניות. אפשר להחליף כתובת IP או להמתין לסיום החסימה, ולבדוק את דפוסי הגישה ל-Fluxer API שמגיעים מהלקוח שלך.", + "permissions.global_ip_temporarily_banned": "כתובת ה-IP שלך {ipAddress} נחסמה זמנית מ-Fluxer API. החסימה תוסר אוטומטית כשתפוג. אם לדעתך זו טעות, אפשר לפנות אל support@fluxer.com ולציין את כתובת ה-IP הזו.", "permissions.missing_access": "אין לך גישה למשאב או לתכונה הזו.", "permissions.missing_permissions": "אין לך את ההרשאות הנדרשות לביצוע פעולה זו.", "permissions.user_banned_from_guild": "משתמש זה חסום בקהילה זו.", diff --git a/packages/errors/src/i18n/locales/hi.ts b/packages/errors/src/i18n/locales/hi.ts index 30cca9204..8eaa7ba83 100644 --- a/packages/errors/src/i18n/locales/hi.ts +++ b/packages/errors/src/i18n/locales/hi.ts @@ -381,7 +381,7 @@ const ERROR_I18N_HI_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "यह यूज़र बैन नहीं है।", "names_and_normalization.name_empty_after_normalization": "नॉर्मलाइज़ेशन के बाद नाम खाली नहीं हो सकता।", "permissions.global_ip_banned": "आपका IP पता {ipAddress} प्लेटफ़ॉर्म एडमिनों द्वारा Fluxer API से स्थायी रूप से ब्लॉक कर दिया गया है। अगर आपको लगता है कि यह गलती है, तो अपील के लिए support@fluxer.app से संपर्क करें। अपनी अपील में यह IP पता शामिल करें।", - "permissions.global_ip_temporarily_banned": "गलत इस्तेमाल या असामान्य एक्सेस पैटर्न के कारण आपका IP पता {ipAddress} Fluxer API से 24 घंटे के लिए अस्थायी रूप से ब्लॉक कर दिया गया है। अस्थायी API बैन के लिए हम आम तौर पर अपील स्वीकार नहीं करते। IP पता बदलें या बैन खत्म होने का इंतज़ार करें, और अपने क्लाइंट से Fluxer API पर आने वाले एक्सेस पैटर्न की जाँच करें।", + "permissions.global_ip_temporarily_banned": "आपका IP पता {ipAddress} Fluxer API से अस्थायी रूप से ब्लॉक कर दिया गया है। समय पूरा होने पर ब्लॉक अपने-आप हट जाएगा। अगर आपको लगता है कि यह गलती है, तो support@fluxer.com से संपर्क करें और यह IP पता शामिल करें।", "permissions.missing_access": "आपके पास इस रिसोर्स या फ़ीचर का एक्सेस नहीं है।", "permissions.missing_permissions": "आपके पास यह एक्शन करने के लिए ज़रूरी अनुमति नहीं है।", "permissions.user_banned_from_guild": "इस यूज़र को इस कम्युनिटी से बैन कर दिया गया है।", diff --git a/packages/errors/src/i18n/locales/hr.ts b/packages/errors/src/i18n/locales/hr.ts index c0dbf1219..7a7ff3c1d 100644 --- a/packages/errors/src/i18n/locales/hr.ts +++ b/packages/errors/src/i18n/locales/hr.ts @@ -381,7 +381,7 @@ const ERROR_I18N_HR_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Ovaj korisnik nema zabranu.", "names_and_normalization.name_empty_after_normalization": "Ime ne može biti prazno nakon normalizacije.", "permissions.global_ip_banned": "Administratori platforme trajno su blokirali pristup Fluxer API-ju s tvoje IP adrese {ipAddress}. Ako smatraš da je to pogreška, javi se na support@fluxer.app i uloži žalbu. U žalbu uključi ovu IP adresu.", - "permissions.global_ip_temporarily_banned": "Pristup Fluxer API-ju s tvoje IP adrese {ipAddress} privremeno je blokiran na 24 sata zbog zlouporabe ili neuobičajenih obrazaca pristupa. Za privremene zabrane pristupa API-ju obično ne razmatramo žalbe. Promijeni IP adresu ili pričekaj da zabrana istekne te provjeri obrasce pristupa Fluxer API-ju koji dolaze iz tvog klijenta.", + "permissions.global_ip_temporarily_banned": "Pristup Fluxer API-ju s tvoje IP adrese {ipAddress} privremeno je blokiran. Blokada se automatski uklanja kada istekne. Ako smatraš da je to pogreška, javi se na support@fluxer.com i navedi ovu IP adresu.", "permissions.missing_access": "Nemaš pristup ovom resursu ili značajci.", "permissions.missing_permissions": "Nemaš potrebna dopuštenja za ovu radnju.", "permissions.user_banned_from_guild": "Ovaj korisnik ima zabranu pristupa ovoj zajednici.", diff --git a/packages/errors/src/i18n/locales/hu.ts b/packages/errors/src/i18n/locales/hu.ts index 35c75867a..3882d72ed 100644 --- a/packages/errors/src/i18n/locales/hu.ts +++ b/packages/errors/src/i18n/locales/hu.ts @@ -381,7 +381,7 @@ const ERROR_I18N_HU_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Ez a felhasználó nincs kitiltva.", "names_and_normalization.name_empty_after_normalization": "Normalizálás után a név nem lehet üres.", "permissions.global_ip_banned": "Az IP-címedet ({ipAddress}) a platform adminisztrátorai véglegesen letiltották a Fluxer API használatáról. Ha úgy gondolod, hogy ez tévedés, a support@fluxer.app címre írhatsz fellebbezést. Add meg benne ezt az IP-címet.", - "permissions.global_ip_temporarily_banned": "Az IP-címedet ({ipAddress}) visszaélésszerű vagy szokatlan hozzáférési minták miatt ideiglenesen, 24 órára letiltottuk a Fluxer API használatáról. Az ideiglenes API-tiltások ellen általában nem lehet fellebbezni. Válts IP-címet, vagy várd meg a tiltás lejártát, és vizsgáld meg, hogyan használja a kliensed a Fluxer API-t.", + "permissions.global_ip_temporarily_banned": "Az IP-címedet ({ipAddress}) ideiglenesen letiltottuk a Fluxer API használatáról. A tiltás a lejártakor magától megszűnik. Ha úgy gondolod, hogy ez tévedés, írj a support@fluxer.com címre, és add meg ezt az IP-címet.", "permissions.missing_access": "Nem férsz hozzá ehhez az erőforráshoz vagy funkcióhoz.", "permissions.missing_permissions": "Nincs meg a művelet elvégzéséhez szükséges jogosultságod.", "permissions.user_banned_from_guild": "Ez a felhasználó ki van tiltva a közösségből.", diff --git a/packages/errors/src/i18n/locales/id.ts b/packages/errors/src/i18n/locales/id.ts index 05a353046..47a80ca66 100644 --- a/packages/errors/src/i18n/locales/id.ts +++ b/packages/errors/src/i18n/locales/id.ts @@ -381,7 +381,7 @@ const ERROR_I18N_ID_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Pengguna ini tidak diblokir.", "names_and_normalization.name_empty_after_normalization": "Nama tidak bisa kosong setelah normalisasi.", "permissions.global_ip_banned": "Alamat IP kamu {ipAddress} telah diblokir permanen dari Fluxer API oleh admin platform. Jika kamu merasa ini keliru, hubungi support@fluxer.app untuk mengajukan banding. Sertakan alamat IP ini dalam bandingmu.", - "permissions.global_ip_temporarily_banned": "Alamat IP kamu {ipAddress} diblokir sementara dari Fluxer API selama 24 jam karena pola akses yang menyalahgunakan atau tidak wajar. Biasanya kami tidak menyediakan banding untuk pemblokiran API sementara. Ganti alamat IP atau tunggu sampai pemblokiran berakhir, dan tinjau pola akses ke Fluxer API yang berasal dari klienmu.", + "permissions.global_ip_temporarily_banned": "Alamat IP kamu {ipAddress} diblokir sementara dari Fluxer API. Pemblokiran akan dicabut secara otomatis saat masa berlakunya habis. Jika kamu merasa ini keliru, hubungi support@fluxer.com dan sertakan alamat IP ini.", "permissions.missing_access": "Kamu tidak memiliki akses ke sumber daya atau fitur ini.", "permissions.missing_permissions": "Kamu tidak memiliki izin yang diperlukan untuk melakukan tindakan ini.", "permissions.user_banned_from_guild": "Pengguna ini diblokir dari komunitas ini.", diff --git a/packages/errors/src/i18n/locales/it.ts b/packages/errors/src/i18n/locales/it.ts index b597f1573..998d09eda 100644 --- a/packages/errors/src/i18n/locales/it.ts +++ b/packages/errors/src/i18n/locales/it.ts @@ -381,7 +381,7 @@ const ERROR_I18N_IT_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "L'utente non è bannato.", "names_and_normalization.name_empty_after_normalization": "Il nome non può essere vuoto dopo la normalizzazione.", "permissions.global_ip_banned": "Il tuo indirizzo IP {ipAddress} è stato bloccato in modo permanente dall'API Fluxer dagli amministratori della piattaforma. Se pensi che sia un errore, contatta support@fluxer.app per fare ricorso. Includi questo indirizzo IP nel ricorso.", - "permissions.global_ip_temporarily_banned": "Il tuo indirizzo IP {ipAddress} è stato bloccato temporaneamente dall'API Fluxer per 24 ore a causa di schemi di accesso abusivi o insoliti. Di solito non offriamo ricorsi per i ban temporanei dell'API. Cambia indirizzo IP o attendi la scadenza del ban, e controlla gli schemi di accesso all'API Fluxer provenienti dal tuo client.", + "permissions.global_ip_temporarily_banned": "Il tuo indirizzo IP {ipAddress} è stato bloccato temporaneamente dall'API Fluxer. Il blocco verrà rimosso automaticamente alla scadenza. Se pensi che sia un errore, contatta support@fluxer.com indicando questo indirizzo IP.", "permissions.missing_access": "Non hai accesso a questa risorsa o funzionalità.", "permissions.missing_permissions": "Non hai le autorizzazioni necessarie per eseguire questa azione.", "permissions.user_banned_from_guild": "L'utente è bannato da questa community.", diff --git a/packages/errors/src/i18n/locales/ja.ts b/packages/errors/src/i18n/locales/ja.ts index a5e59f7b5..6eb6bf5b0 100644 --- a/packages/errors/src/i18n/locales/ja.ts +++ b/packages/errors/src/i18n/locales/ja.ts @@ -381,7 +381,7 @@ const ERROR_I18N_JA_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "このユーザーはBANされていません。", "names_and_normalization.name_empty_after_normalization": "正規化後、名前は空にできません。", "permissions.global_ip_banned": "IPアドレス{ipAddress}は、プラットフォーム管理者によりFluxer APIから永久にブロックされました。誤りだと思う場合は、support@fluxer.appに連絡して異議申し立てをしてください。申し立てにはこのIPアドレスを記載してください。", - "permissions.global_ip_temporarily_banned": "IPアドレス{ipAddress}は、悪質または通常と異なるアクセスパターンのため、Fluxer APIから24時間一時的にブロックされました。一時的なAPIのBANについては通常、異議申し立てを受け付けていません。IPアドレスを変更するかBANの期限切れを待ち、クライアントからFluxer APIへのアクセスパターンを確認してください。", + "permissions.global_ip_temporarily_banned": "IPアドレス{ipAddress}は、Fluxer APIから一時的にブロックされました。ブロックは期限が切れると自動的に解除されます。誤りだと思う場合は、このIPアドレスを記載のうえ、support@fluxer.comに連絡してください。", "permissions.missing_access": "このリソースや機能にアクセスする権限がありません。", "permissions.missing_permissions": "この操作を実行するために必要な権限がありません。", "permissions.user_banned_from_guild": "このユーザーはこのコミュニティでBANされています。", diff --git a/packages/errors/src/i18n/locales/ko.ts b/packages/errors/src/i18n/locales/ko.ts index ba489e3e1..c2874f620 100644 --- a/packages/errors/src/i18n/locales/ko.ts +++ b/packages/errors/src/i18n/locales/ko.ts @@ -381,7 +381,7 @@ const ERROR_I18N_KO_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "이 사용자는 차단되지 않았어요.", "names_and_normalization.name_empty_after_normalization": "정규화 후 이름은 비워둘 수 없어요.", "permissions.global_ip_banned": "회원님의 IP 주소 {ipAddress}는 플랫폼 관리자가 Fluxer API에서 영구 차단했어요. 오류라고 생각한다면 support@fluxer.app으로 문의해 이의를 제기해 주세요. 이의 제기에는 이 IP 주소를 포함해 주세요.", - "permissions.global_ip_temporarily_banned": "회원님의 IP 주소 {ipAddress}는 악용 또는 비정상적인 접근 패턴으로 인해 Fluxer API에서 24시간 동안 일시 차단되었어요. 일시적인 API 차단은 보통 이의 제기를 받지 않아요. IP 주소를 변경하거나 차단이 만료될 때까지 기다리고, 클라이언트에서 Fluxer API로 발생하는 접근 패턴을 검토해 주세요.", + "permissions.global_ip_temporarily_banned": "회원님의 IP 주소 {ipAddress}는 Fluxer API에서 일시 차단되었어요. 차단은 기간이 끝나면 자동으로 해제돼요. 오류라고 생각한다면 이 IP 주소를 포함해 support@fluxer.com으로 문의해 주세요.", "permissions.missing_access": "이 리소스 또는 기능에 접근할 권한이 없어요.", "permissions.missing_permissions": "이 작업을 수행하는 데 필요한 권한이 없어요.", "permissions.user_banned_from_guild": "이 사용자는 이 커뮤니티에서 차단되었어요.", diff --git a/packages/errors/src/i18n/locales/lt.ts b/packages/errors/src/i18n/locales/lt.ts index bd7f9c143..63e19d112 100644 --- a/packages/errors/src/i18n/locales/lt.ts +++ b/packages/errors/src/i18n/locales/lt.ts @@ -381,7 +381,7 @@ const ERROR_I18N_LT_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Šis naudotojas nėra užblokuotas.", "names_and_normalization.name_empty_after_normalization": "Po normalizavimo pavadinimas negali būti tuščias.", "permissions.global_ip_banned": "Tavo IP adresas {ipAddress} platformos administratorių visam laikui užblokuotas Fluxer API. Jei manai, kad tai klaida, dėl apeliacijos susisiek adresu support@fluxer.app. Apeliacijoje nurodyk šį IP adresą.", - "permissions.global_ip_temporarily_banned": "Tavo IP adresas {ipAddress} 24 valandoms laikinai užblokuotas Fluxer API dėl piktnaudžiaujamo arba neįprasto naudojimo. Dėl laikinų API blokavimų apeliacijų paprastai nepriimame. Pakeisk IP adresą arba palauk, kol blokavimas baigsis, ir peržiūrėk, kaip tavo klientas kreipiasi į Fluxer API.", + "permissions.global_ip_temporarily_banned": "Tavo IP adresas {ipAddress} laikinai užblokuotas Fluxer API. Blokavimas bus panaikintas automatiškai, kai baigsis jo laikas. Jei manai, kad tai klaida, susisiek adresu support@fluxer.com ir nurodyk šį IP adresą.", "permissions.missing_access": "Neturi prieigos prie šio ištekliaus ar funkcijos.", "permissions.missing_permissions": "Neturi reikiamų leidimų atlikti šį veiksmą.", "permissions.user_banned_from_guild": "Šis naudotojas užblokuotas šioje bendruomenėje.", diff --git a/packages/errors/src/i18n/locales/nl.ts b/packages/errors/src/i18n/locales/nl.ts index bf160382d..e683d9eb0 100644 --- a/packages/errors/src/i18n/locales/nl.ts +++ b/packages/errors/src/i18n/locales/nl.ts @@ -381,7 +381,7 @@ const ERROR_I18N_NL_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Deze gebruiker is niet verbannen.", "names_and_normalization.name_empty_after_normalization": "Naam kan niet leeg zijn na normalisatie.", "permissions.global_ip_banned": "Je IP-adres {ipAddress} is door platformbeheerders permanent geblokkeerd voor de Fluxer API. Als je denkt dat dit een fout is, neem dan contact op met support@fluxer.app om bezwaar te maken. Vermeld dit IP-adres in je bezwaar.", - "permissions.global_ip_temporarily_banned": "Je IP-adres {ipAddress} is vanwege misbruik of ongebruikelijke toegangspatronen voor 24 uur geblokkeerd voor de Fluxer API. We bieden meestal geen bezwaarprocedure voor tijdelijke API-blokkades. Gebruik een ander IP-adres of wacht tot de blokkade verloopt en controleer hoe je client de Fluxer API benadert.", + "permissions.global_ip_temporarily_banned": "Je IP-adres {ipAddress} is tijdelijk geblokkeerd voor de Fluxer API. De blokkade wordt automatisch opgeheven zodra deze verloopt. Als je denkt dat dit een fout is, neem dan contact op met support@fluxer.com en vermeld dit IP-adres.", "permissions.missing_access": "Je hebt geen toegang tot dit item of deze functie.", "permissions.missing_permissions": "Je hebt niet de benodigde machtigingen om deze actie uit te voeren.", "permissions.user_banned_from_guild": "Deze gebruiker is verbannen uit deze community.", diff --git a/packages/errors/src/i18n/locales/no.ts b/packages/errors/src/i18n/locales/no.ts index ffcd08587..d80df53a4 100644 --- a/packages/errors/src/i18n/locales/no.ts +++ b/packages/errors/src/i18n/locales/no.ts @@ -381,7 +381,7 @@ const ERROR_I18N_NO_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Denne brukeren er ikke utestengt.", "names_and_normalization.name_empty_after_normalization": "Navnet kan ikke være tomt etter normalisering.", "permissions.global_ip_banned": "IP-adressen din {ipAddress} er permanent blokkert fra Fluxer-API-et av plattformadministratorene. Hvis du mener dette er en feil, kan du kontakte support@fluxer.app for å klage. Ta med denne IP-adressen i klagen.", - "permissions.global_ip_temporarily_banned": "IP-adressen din {ipAddress} er midlertidig blokkert fra Fluxer-API-et i 24 timer på grunn av misbruk eller uvanlige tilgangsmønstre. Vi tilbyr vanligvis ikke mulighet til å klage på midlertidige API-utestengelser. Bytt IP-adresse eller vent til utestengelsen utløper, og gjennomgå hvordan klienten din bruker Fluxer-API-et.", + "permissions.global_ip_temporarily_banned": "IP-adressen din {ipAddress} er midlertidig blokkert fra Fluxer-API-et. Blokkeringen oppheves automatisk når den utløper. Hvis du mener dette er en feil, kan du kontakte support@fluxer.com og oppgi denne IP-adressen.", "permissions.missing_access": "Du har ikke tilgang til denne ressursen eller funksjonen.", "permissions.missing_permissions": "Du har ikke de nødvendige tillatelsene til å utføre denne handlingen.", "permissions.user_banned_from_guild": "Denne brukeren er utestengt fra dette fellesskapet.", diff --git a/packages/errors/src/i18n/locales/pl.ts b/packages/errors/src/i18n/locales/pl.ts index 439e31dde..5c11713f5 100644 --- a/packages/errors/src/i18n/locales/pl.ts +++ b/packages/errors/src/i18n/locales/pl.ts @@ -381,7 +381,7 @@ const ERROR_I18N_PL_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Ten użytkownik nie ma bana.", "names_and_normalization.name_empty_after_normalization": "Nazwa nie może być pusta po normalizacji.", "permissions.global_ip_banned": "Twój adres IP {ipAddress} został trwale zablokowany w Fluxer API przez administratorów platformy. Jeśli uważasz, że to błąd, skontaktuj się z support@fluxer.app, aby się odwołać. Podaj ten adres IP w odwołaniu.", - "permissions.global_ip_temporarily_banned": "Twój adres IP {ipAddress} został tymczasowo zablokowany w API Fluxer na 24 godziny z powodu nadużyć lub nietypowego sposobu korzystania z API. Zazwyczaj nie umożliwiamy odwołań od tymczasowych banów API. Zmień adres IP albo poczekaj na wygaśnięcie bana i sprawdź, w jaki sposób Twoja aplikacja kliencka korzysta z API Fluxer.", + "permissions.global_ip_temporarily_banned": "Twój adres IP {ipAddress} został tymczasowo zablokowany w Fluxer API. Blokada zostanie zdjęta automatycznie po jej wygaśnięciu. Jeśli uważasz, że to błąd, skontaktuj się z support@fluxer.com i podaj ten adres IP.", "permissions.missing_access": "Brak dostępu do tego zasobu lub funkcji.", "permissions.missing_permissions": "Brak wymaganych uprawnień do wykonania tej akcji.", "permissions.user_banned_from_guild": "Ten użytkownik ma bana w tej społeczności.", diff --git a/packages/errors/src/i18n/locales/pt-BR.ts b/packages/errors/src/i18n/locales/pt-BR.ts index 2f5a26e27..525b1c679 100644 --- a/packages/errors/src/i18n/locales/pt-BR.ts +++ b/packages/errors/src/i18n/locales/pt-BR.ts @@ -381,7 +381,7 @@ const ERROR_I18N_PT_BR_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Este usuário não está banido.", "names_and_normalization.name_empty_after_normalization": "O nome não pode ficar vazio após a normalização.", "permissions.global_ip_banned": "Seu endereço IP {ipAddress} foi bloqueado permanentemente na Fluxer API pelos administradores da plataforma. Se você acredita que isso é um erro, entre em contato com support@fluxer.app para recorrer. Inclua este endereço IP no recurso.", - "permissions.global_ip_temporarily_banned": "Seu endereço IP {ipAddress} foi bloqueado temporariamente na Fluxer API por 24 horas devido a padrões de acesso abusivos ou incomuns. Normalmente não aceitamos recursos para banimentos temporários da API. Troque de endereço IP ou aguarde o fim do banimento e revise os padrões de acesso do seu cliente à Fluxer API.", + "permissions.global_ip_temporarily_banned": "Seu endereço IP {ipAddress} foi bloqueado temporariamente na Fluxer API. O bloqueio será removido automaticamente quando expirar. Se você acredita que isso é um erro, entre em contato com support@fluxer.com e informe este endereço IP.", "permissions.missing_access": "Você não tem acesso a este recurso ou funcionalidade.", "permissions.missing_permissions": "Você não tem as permissões necessárias para executar esta ação.", "permissions.user_banned_from_guild": "Este usuário está banido desta comunidade.", diff --git a/packages/errors/src/i18n/locales/ro.ts b/packages/errors/src/i18n/locales/ro.ts index 06c97b09c..8cc6c4774 100644 --- a/packages/errors/src/i18n/locales/ro.ts +++ b/packages/errors/src/i18n/locales/ro.ts @@ -381,7 +381,7 @@ const ERROR_I18N_RO_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Acest utilizator nu este banat.", "names_and_normalization.name_empty_after_normalization": "Numele nu poate fi gol după normalizare.", "permissions.global_ip_banned": "Accesul adresei tale IP {ipAddress} la Fluxer API a fost blocat permanent de administratorii platformei. Dacă crezi că este o greșeală, contactează support@fluxer.app pentru a depune o contestație. Include această adresă IP în contestație.", - "permissions.global_ip_temporarily_banned": "Accesul adresei tale IP {ipAddress} la Fluxer API a fost blocat temporar timp de 24 de ore din cauza unor tipare de acces abuzive sau neobișnuite. De obicei nu acceptăm contestații pentru banurile temporare ale API-ului. Schimbă adresa IP sau așteaptă expirarea banului și verifică tiparele de acces la Fluxer API provenite de la clientul tău.", + "permissions.global_ip_temporarily_banned": "Accesul adresei tale IP {ipAddress} la Fluxer API a fost blocat temporar. Blocarea se ridică automat când expiră. Dacă crezi că este o greșeală, contactează support@fluxer.com și include această adresă IP.", "permissions.missing_access": "Nu ai acces la această resursă sau funcție.", "permissions.missing_permissions": "Nu ai permisiunile necesare pentru a efectua această acțiune.", "permissions.user_banned_from_guild": "Acest utilizator este banat din această comunitate.", diff --git a/packages/errors/src/i18n/locales/ru.ts b/packages/errors/src/i18n/locales/ru.ts index 330ce83d2..88af40b3f 100644 --- a/packages/errors/src/i18n/locales/ru.ts +++ b/packages/errors/src/i18n/locales/ru.ts @@ -381,7 +381,7 @@ const ERROR_I18N_RU_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Этот пользователь не забанен.", "names_and_normalization.name_empty_after_normalization": "Имя не может быть пустым после нормализации.", "permissions.global_ip_banned": "Твой IP-адрес {ipAddress} навсегда заблокирован в Fluxer API администраторами платформы. Если считаешь, что это ошибка, напиши на support@fluxer.app, чтобы подать апелляцию. Укажи в ней этот IP-адрес.", - "permissions.global_ip_temporarily_banned": "Твой IP-адрес {ipAddress} временно заблокирован в Fluxer API на 24 часа из-за злоупотреблений или необычного характера запросов. Апелляции по временным блокировкам API мы обычно не рассматриваем. Смени IP-адрес или дождись окончания блокировки и проверь, как твой клиент обращается к Fluxer API.", + "permissions.global_ip_temporarily_banned": "Твой IP-адрес {ipAddress} временно заблокирован в Fluxer API. Блокировка снимется автоматически, когда истечёт её срок. Если считаешь, что это ошибка, напиши на support@fluxer.com и укажи этот IP-адрес.", "permissions.missing_access": "У тебя нет доступа к этому ресурсу или функции.", "permissions.missing_permissions": "У тебя нет необходимых разрешений для выполнения этого действия.", "permissions.user_banned_from_guild": "Этот пользователь забанен в этом сообществе.", diff --git a/packages/errors/src/i18n/locales/sv-SE.ts b/packages/errors/src/i18n/locales/sv-SE.ts index f74b61e02..b65b15c65 100644 --- a/packages/errors/src/i18n/locales/sv-SE.ts +++ b/packages/errors/src/i18n/locales/sv-SE.ts @@ -381,7 +381,7 @@ const ERROR_I18N_SV_SE_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Den här användaren är inte bannlyst.", "names_and_normalization.name_empty_after_normalization": "Namnet kan inte vara tomt efter att ha normaliserats.", "permissions.global_ip_banned": "Din IP-adress {ipAddress} har blockerats permanent från Fluxers API av plattformsadministratörerna. Om du anser att detta är ett misstag kan du kontakta support@fluxer.app för att överklaga. Ange den här IP-adressen i ditt överklagande.", - "permissions.global_ip_temporarily_banned": "Din IP-adress {ipAddress} har blockerats tillfälligt från Fluxers API i 24 timmar på grund av missbruk eller ovanliga åtkomstmönster. Tillfälliga API-blockeringar kan vanligtvis inte överklagas. Byt IP-adress eller vänta tills blockeringen löper ut och granska hur din klient använder Fluxers API.", + "permissions.global_ip_temporarily_banned": "Din IP-adress {ipAddress} har blockerats tillfälligt från Fluxers API. Blockeringen hävs automatiskt när den löper ut. Om du anser att detta är ett misstag kan du kontakta support@fluxer.com och ange den här IP-adressen.", "permissions.missing_access": "Du har inte åtkomst till denna resurs eller funktion.", "permissions.missing_permissions": "Du har inte de behörigheter som krävs för att utföra denna åtgärd.", "permissions.user_banned_from_guild": "Den här användaren är bannlyst från den här communityn.", diff --git a/packages/errors/src/i18n/locales/th.ts b/packages/errors/src/i18n/locales/th.ts index 30d91b9b5..f7800704c 100644 --- a/packages/errors/src/i18n/locales/th.ts +++ b/packages/errors/src/i18n/locales/th.ts @@ -381,7 +381,7 @@ const ERROR_I18N_TH_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "ผู้ใช้รายนี้ไม่ได้ถูกแบน", "names_and_normalization.name_empty_after_normalization": "ชื่อต้องไม่ว่างเปล่าหลังจากการปรับให้เป็นมาตรฐาน", "permissions.global_ip_banned": "ที่อยู่ IP ของคุณ {ipAddress} ถูกบล็อกจาก Fluxer API อย่างถาวรโดยผู้ดูแลแพลตฟอร์ม หากคุณเชื่อว่านี่เป็นข้อผิดพลาด โปรดติดต่อ support@fluxer.app เพื่ออุทธรณ์ โปรดแนบที่อยู่ IP นี้ในการอุทธรณ์", - "permissions.global_ip_temporarily_banned": "ที่อยู่ IP ของคุณ {ipAddress} ถูกบล็อกจาก Fluxer API ชั่วคราวเป็นเวลา 24 ชั่วโมงเนื่องจากรูปแบบการเข้าถึงที่ผิดปกติหรือมีลักษณะละเมิด โดยปกติเราไม่รับอุทธรณ์สำหรับการแบน API ชั่วคราว โปรดเปลี่ยนที่อยู่ IP หรือรอให้การแบนหมดอายุ และตรวจสอบรูปแบบการเข้าถึง Fluxer API ที่มาจากไคลเอนต์ของคุณ", + "permissions.global_ip_temporarily_banned": "ที่อยู่ IP ของคุณ {ipAddress} ถูกบล็อกจาก Fluxer API ชั่วคราว การบล็อกจะถูกยกเลิกโดยอัตโนมัติเมื่อหมดเวลา หากคุณเชื่อว่านี่เป็นข้อผิดพลาด โปรดติดต่อ support@fluxer.com และแนบที่อยู่ IP นี้มาด้วย", "permissions.missing_access": "คุณไม่มีสิทธิ์เข้าถึงทรัพยากรหรือฟีเจอร์นี้", "permissions.missing_permissions": "คุณไม่มีสิทธิ์ที่จำเป็นในการดำเนินการนี้", "permissions.user_banned_from_guild": "ผู้ใช้รายนี้ถูกแบนจากคอมมูนิตี้นี้", diff --git a/packages/errors/src/i18n/locales/tr.ts b/packages/errors/src/i18n/locales/tr.ts index 31b4fc698..a2fb855c9 100644 --- a/packages/errors/src/i18n/locales/tr.ts +++ b/packages/errors/src/i18n/locales/tr.ts @@ -381,7 +381,7 @@ const ERROR_I18N_TR_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Bu kullanıcı yasaklı değil.", "names_and_normalization.name_empty_after_normalization": "Ad, normalleştirildikten sonra boş olamaz.", "permissions.global_ip_banned": "IP adresin {ipAddress}, platform yöneticileri tarafından Fluxer API'den kalıcı olarak engellendi. Bunun bir hata olduğunu düşünüyorsan itiraz etmek için support@fluxer.app ile iletişime geç. İtirazına bu IP adresini ekle.", - "permissions.global_ip_temporarily_banned": "IP adresin {ipAddress}, kötüye kullanım niteliğindeki veya olağan dışı erişim kalıpları nedeniyle Fluxer API'den 24 saatliğine geçici olarak engellendi. Geçici API engellemeleri için genellikle itiraz kabul etmiyoruz. IP adresini değiştir ya da engellemenin süresi dolana kadar bekle ve istemcinden Fluxer API'ye gelen erişim kalıplarını gözden geçir.", + "permissions.global_ip_temporarily_banned": "IP adresin {ipAddress}, Fluxer API'den geçici olarak engellendi. Engelleme süresi dolduğunda kendiliğinden kalkar. Bunun bir hata olduğunu düşünüyorsan support@fluxer.com ile iletişime geç ve bu IP adresini belirt.", "permissions.missing_access": "Bu kaynağa veya özelliğe erişimin yok.", "permissions.missing_permissions": "Bu eylemi gerçekleştirmek için gerekli izinlere sahip değilsin.", "permissions.user_banned_from_guild": "Bu kullanıcı bu topluluktan yasaklandı.", diff --git a/packages/errors/src/i18n/locales/uk.ts b/packages/errors/src/i18n/locales/uk.ts index 5c1367f25..87d5a822c 100644 --- a/packages/errors/src/i18n/locales/uk.ts +++ b/packages/errors/src/i18n/locales/uk.ts @@ -381,7 +381,7 @@ const ERROR_I18N_UK_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Цей користувач не забанений.", "names_and_normalization.name_empty_after_normalization": "Ім'я не може бути порожнім після нормалізації.", "permissions.global_ip_banned": "Адміністратори платформи назавжди заблокували твоїй IP-адресі {ipAddress} доступ до Fluxer API. Якщо ти вважаєш, що це помилка, напиши на support@fluxer.app, щоб подати апеляцію. Вкажи цю IP-адресу в апеляції.", - "permissions.global_ip_temporarily_banned": "Твоїй IP-адресі {ipAddress} тимчасово заблоковано доступ до Fluxer API на 24 години через зловживання або незвичну активність. Зазвичай ми не розглядаємо апеляції щодо тимчасових банів API. Зміни IP-адресу або дочекайся завершення бану та перевір, як твій клієнт звертається до Fluxer API.", + "permissions.global_ip_temporarily_banned": "Твоїй IP-адресі {ipAddress} тимчасово заблоковано доступ до Fluxer API. Блокування зніметься автоматично, коли завершиться його строк. Якщо ти вважаєш, що це помилка, напиши на support@fluxer.com і вкажи цю IP-адресу.", "permissions.missing_access": "Ти не маєш доступу до цього ресурсу або функції.", "permissions.missing_permissions": "Ти не маєш потрібних дозволів для цієї дії.", "permissions.user_banned_from_guild": "Цей користувач забанений у цій спільноті.", diff --git a/packages/errors/src/i18n/locales/vi.ts b/packages/errors/src/i18n/locales/vi.ts index 51d504d1a..3a29aaf61 100644 --- a/packages/errors/src/i18n/locales/vi.ts +++ b/packages/errors/src/i18n/locales/vi.ts @@ -381,7 +381,7 @@ const ERROR_I18N_VI_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "Người dùng này không bị cấm.", "names_and_normalization.name_empty_after_normalization": "Tên không được để trống sau khi chuẩn hóa.", "permissions.global_ip_banned": "Địa chỉ IP của bạn {ipAddress} đã bị quản trị viên nền tảng chặn vĩnh viễn khỏi Fluxer API. Nếu bạn cho rằng đây là nhầm lẫn, hãy liên hệ support@fluxer.app để khiếu nại. Hãy kèm địa chỉ IP này trong khiếu nại.", - "permissions.global_ip_temporarily_banned": "Địa chỉ IP của bạn {ipAddress} đã bị chặn tạm thời khỏi Fluxer API trong 24 giờ do hành vi truy cập lạm dụng hoặc bất thường. Chúng tôi thường không tiếp nhận khiếu nại cho các lệnh cấm API tạm thời. Hãy đổi địa chỉ IP hoặc chờ lệnh cấm hết hạn, và xem lại cách client của bạn truy cập Fluxer API.", + "permissions.global_ip_temporarily_banned": "Địa chỉ IP của bạn {ipAddress} đã bị chặn tạm thời khỏi Fluxer API. Lệnh chặn sẽ tự động được gỡ khi hết hạn. Nếu bạn cho rằng đây là nhầm lẫn, hãy liên hệ support@fluxer.com và kèm theo địa chỉ IP này.", "permissions.missing_access": "Bạn không có quyền truy cập vào tài nguyên hoặc tính năng này.", "permissions.missing_permissions": "Bạn không có quyền cần thiết để thực hiện hành động này.", "permissions.user_banned_from_guild": "Người dùng này đã bị cấm khỏi cộng đồng này.", diff --git a/packages/errors/src/i18n/locales/zh-CN.ts b/packages/errors/src/i18n/locales/zh-CN.ts index d6e204134..df0d0d0a2 100644 --- a/packages/errors/src/i18n/locales/zh-CN.ts +++ b/packages/errors/src/i18n/locales/zh-CN.ts @@ -381,7 +381,7 @@ const ERROR_I18N_ZH_CN_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "此用户未被封禁。", "names_and_normalization.name_empty_after_normalization": "规范化后名称不能为空。", "permissions.global_ip_banned": "你的 IP 地址 {ipAddress} 已被平台管理员永久禁止访问 Fluxer API。如果你认为这是误判,请联系 support@fluxer.app 申诉。请在申诉中附上此 IP 地址。", - "permissions.global_ip_temporarily_banned": "你的 IP 地址 {ipAddress} 因存在滥用或异常访问模式,已被临时禁止访问 Fluxer API,为期 24 小时。临时 API 封禁通常不提供申诉。请更换 IP 地址或等待封禁到期,并检查你的客户端对 Fluxer API 的访问模式。", + "permissions.global_ip_temporarily_banned": "你的 IP 地址 {ipAddress} 已被临时禁止访问 Fluxer API。限制到期后会自动解除。如果你认为这是误判,请联系 support@fluxer.com 并附上此 IP 地址。", "permissions.missing_access": "你无权访问此资源或功能。", "permissions.missing_permissions": "你没有执行此操作所需的权限。", "permissions.user_banned_from_guild": "此用户已被此社区封禁。", diff --git a/packages/errors/src/i18n/locales/zh-TW.ts b/packages/errors/src/i18n/locales/zh-TW.ts index 0a1b3fd18..036ccb275 100644 --- a/packages/errors/src/i18n/locales/zh-TW.ts +++ b/packages/errors/src/i18n/locales/zh-TW.ts @@ -381,7 +381,7 @@ const ERROR_I18N_ZH_TW_MESSAGES = defineErrorI18nLocaleMessages({ "moderation_and_reports.user_is_not_banned": "此使用者未被封鎖。", "names_and_normalization.name_empty_after_normalization": "名稱正規化後不能為空。", "permissions.global_ip_banned": "你的 IP 位址 {ipAddress} 已被平台管理員永久禁止存取 Fluxer API。如果你認為這是誤判,請聯絡 support@fluxer.app 申訴。請在申訴中附上此 IP 位址。", - "permissions.global_ip_temporarily_banned": "你的 IP 位址 {ipAddress} 因濫用或異常存取模式,已被暫時禁止存取 Fluxer API 24 小時。暫時性的 API 封鎖通常不提供申訴。請更換 IP 位址或等待封鎖到期,並檢查你的用戶端對 Fluxer API 的存取模式。", + "permissions.global_ip_temporarily_banned": "你的 IP 位址 {ipAddress} 已被暫時禁止存取 Fluxer API。限制到期後會自動解除。如果你認為這是誤判,請聯絡 support@fluxer.com 並附上此 IP 位址。", "permissions.missing_access": "你沒有權限使用此資源或功能。", "permissions.missing_permissions": "你沒有執行此動作所需的權限。", "permissions.user_banned_from_guild": "此使用者已被此社群封鎖。", diff --git a/packages/errors/src/i18n/weblate/locales/ar.json b/packages/errors/src/i18n/weblate/locales/ar.json index aee769d57..dce122a52 100644 --- a/packages/errors/src/i18n/weblate/locales/ar.json +++ b/packages/errors/src/i18n/weblate/locales/ar.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "المستخدم غير محظور.", "names_and_normalization.name_empty_after_normalization": "لا يمكن أن يكون الاسم فارغًا بعد التسوية.", "permissions.global_ip_banned": "تم حظر عنوان IP الخاص بك {ipAddress} نهائيًا من Fluxer API بواسطة مسؤولي المنصة. إذا كنت تعتقد أن هذا خطأ، فتواصل مع support@fluxer.app للاستئناف. اذكر عنوان IP هذا في الاستئناف.", - "permissions.global_ip_temporarily_banned": "تم حظر عنوان IP الخاص بك {ipAddress} مؤقتًا من Fluxer API لمدة 24 ساعة بسبب أنماط وصول مسيئة أو غير معتادة. لا نوفر عادةً استئنافات لحظر API المؤقت. غيّر عنوان IP أو انتظر انتهاء الحظر، وراجع أنماط الوصول إلى Fluxer API القادمة من عميلك.", + "permissions.global_ip_temporarily_banned": "تم حظر عنوان IP الخاص بك {ipAddress} مؤقتًا من Fluxer API. يُرفع الحظر تلقائيًا عند انتهاء مدته. إذا كنت تعتقد أن هذا خطأ، فتواصل مع support@fluxer.com واذكر عنوان IP هذا.", "permissions.missing_access": "ليس لديك وصول إلى هذا المورد أو الميزة.", "permissions.missing_permissions": "لا تملك الأذونات المطلوبة لتنفيذ هذا الإجراء.", "permissions.user_banned_from_guild": "المستخدم محظور من هذا المجتمع.", diff --git a/packages/errors/src/i18n/weblate/locales/bg.json b/packages/errors/src/i18n/weblate/locales/bg.json index 24b743051..50aceddee 100644 --- a/packages/errors/src/i18n/weblate/locales/bg.json +++ b/packages/errors/src/i18n/weblate/locales/bg.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Този потребител няма наложена забрана.", "names_and_normalization.name_empty_after_normalization": "Името не може да бъде празно след нормализиране.", "permissions.global_ip_banned": "IP адресът ти {ipAddress} е блокиран за постоянно за достъп до Fluxer API от администраторите на платформата. Ако смяташ, че това е грешка, свържи се със support@fluxer.app, за да обжалваш. Включи този IP адрес в обжалването.", - "permissions.global_ip_temporarily_banned": "IP адресът ти {ipAddress} е временно блокиран за достъп до Fluxer API за 24 часа поради злоупотреба или необичайни модели на достъп. Обикновено не разглеждаме обжалвания за временни забрани за API. Смени IP адреса си или изчакай забраната да изтече и прегледай моделите на достъп до Fluxer API от твоя клиент.", + "permissions.global_ip_temporarily_banned": "IP адресът ти {ipAddress} е временно блокиран за достъп до Fluxer API. Блокирането се премахва автоматично, когато изтече. Ако смяташ, че това е грешка, свържи се със support@fluxer.com и посочи този IP адрес.", "permissions.missing_access": "Нямаш достъп до този ресурс или функция.", "permissions.missing_permissions": "Нямаш необходимите разрешения, за да изпълниш това действие.", "permissions.user_banned_from_guild": "Този потребител има наложена забрана в тази общност.", diff --git a/packages/errors/src/i18n/weblate/locales/cs.json b/packages/errors/src/i18n/weblate/locales/cs.json index 608db8f0d..066bdffe2 100644 --- a/packages/errors/src/i18n/weblate/locales/cs.json +++ b/packages/errors/src/i18n/weblate/locales/cs.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Tento uživatel není zabanován.", "names_and_normalization.name_empty_after_normalization": "Název nemůže být po normalizaci prázdný.", "permissions.global_ip_banned": "Vaše IP adresa {ipAddress} byla správci platformy trvale zablokována pro Fluxer API. Pokud se domníváte, že jde o chybu, podejte odvolání na adrese support@fluxer.app. V odvolání uveďte tuto IP adresu.", - "permissions.global_ip_temporarily_banned": "Vaše IP adresa {ipAddress} byla na 24 hodin zablokována pro Fluxer API kvůli zneužívajícímu nebo neobvyklému způsobu přístupu. Odvolání proti dočasným blokacím API obvykle nevyřizujeme. Změňte IP adresu nebo počkejte na vypršení blokace a zkontrolujte, jak váš klient přistupuje k Fluxer API.", + "permissions.global_ip_temporarily_banned": "Vaše IP adresa {ipAddress} byla dočasně zablokována pro Fluxer API. Blokace se po vypršení sama zruší. Pokud se domníváte, že jde o chybu, napište na adresu support@fluxer.com a uveďte tuto IP adresu.", "permissions.missing_access": "Nemáte přístup k tomuto zdroji nebo funkci.", "permissions.missing_permissions": "Nemáte potřebná oprávnění k provedení této akce.", "permissions.user_banned_from_guild": "Tento uživatel má v této komunitě ban.", diff --git a/packages/errors/src/i18n/weblate/locales/da.json b/packages/errors/src/i18n/weblate/locales/da.json index 0ce6875d5..cdca5424a 100644 --- a/packages/errors/src/i18n/weblate/locales/da.json +++ b/packages/errors/src/i18n/weblate/locales/da.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Denne bruger er ikke udelukket.", "names_and_normalization.name_empty_after_normalization": "Navnet må ikke være tomt efter normalisering.", "permissions.global_ip_banned": "Din IP-adresse {ipAddress} er permanent blokeret fra Fluxer API af platformadministratorer. Hvis du mener, at dette er en fejl, kan du kontakte support@fluxer.app for at klage. Medtag denne IP-adresse i klagen.", - "permissions.global_ip_temporarily_banned": "Din IP-adresse {ipAddress} er midlertidigt blokeret fra Fluxer API i 24 timer på grund af misbrug eller usædvanlige adgangsmønstre. Vi behandler normalt ikke klager over midlertidige API-blokeringer. Skift IP-adresse, eller vent på, at blokeringen udløber, og gennemgå din klients adgangsmønstre til Fluxer API.", + "permissions.global_ip_temporarily_banned": "Din IP-adresse {ipAddress} er midlertidigt blokeret fra Fluxer API. Blokeringen ophæves automatisk, når den udløber. Hvis du mener, at dette er en fejl, kan du kontakte support@fluxer.com og oplyse denne IP-adresse.", "permissions.missing_access": "Du har ikke adgang til denne ressource eller funktion.", "permissions.missing_permissions": "Du har ikke de nødvendige tilladelser til at udføre denne handling.", "permissions.user_banned_from_guild": "Denne bruger er udelukket fra dette fællesskab.", diff --git a/packages/errors/src/i18n/weblate/locales/de.json b/packages/errors/src/i18n/weblate/locales/de.json index e7020000c..90114c71f 100644 --- a/packages/errors/src/i18n/weblate/locales/de.json +++ b/packages/errors/src/i18n/weblate/locales/de.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Dieser Benutzer ist nicht gebannt.", "names_and_normalization.name_empty_after_normalization": "Der Name darf nach der Normalisierung nicht leer bleiben.", "permissions.global_ip_banned": "Deine IP-Adresse {ipAddress} wurde von Plattformadministratoren dauerhaft von der Fluxer API gesperrt. Wenn du glaubst, dass dies ein Fehler ist, kontaktiere support@fluxer.app, um Einspruch einzulegen. Gib diese IP-Adresse in deinem Einspruch an.", - "permissions.global_ip_temporarily_banned": "Deine IP-Adresse {ipAddress} wurde wegen missbräuchlicher oder ungewöhnlicher Zugriffsmuster für 24 Stunden von der Fluxer API gesperrt. Für vorübergehende API-Sperren ist normalerweise kein Einspruchsverfahren vorgesehen. Wechsle die IP-Adresse oder warte, bis die Sperre abläuft, und überprüfe die Zugriffsmuster deines Clients auf die Fluxer API.", + "permissions.global_ip_temporarily_banned": "Deine IP-Adresse {ipAddress} wurde vorübergehend von der Fluxer API gesperrt. Die Sperre wird automatisch aufgehoben, sobald sie abläuft. Wenn du glaubst, dass dies ein Fehler ist, kontaktiere support@fluxer.com und gib diese IP-Adresse an.", "permissions.missing_access": "Du hast keinen Zugriff auf diese Ressource oder Funktion.", "permissions.missing_permissions": "Du hast nicht die erforderlichen Berechtigungen, um diese Aktion auszuführen.", "permissions.user_banned_from_guild": "Dieser Benutzer ist aus dieser Community gebannt.", diff --git a/packages/errors/src/i18n/weblate/locales/el.json b/packages/errors/src/i18n/weblate/locales/el.json index e8dbb14a4..054a4af3e 100644 --- a/packages/errors/src/i18n/weblate/locales/el.json +++ b/packages/errors/src/i18n/weblate/locales/el.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Αυτός ο χρήστης δεν έχει αποκλειστεί.", "names_and_normalization.name_empty_after_normalization": "Το όνομα δεν μπορεί να είναι κενό μετά την κανονικοποίηση.", "permissions.global_ip_banned": "Η διεύθυνση IP σου {ipAddress} έχει αποκλειστεί μόνιμα από το Fluxer API από τους διαχειριστές της πλατφόρμας. Αν πιστεύεις ότι πρόκειται για λάθος, επικοινώνησε με support@fluxer.app για να υποβάλεις προσφυγή. Συμπερίλαβε αυτήν τη διεύθυνση IP στην προσφυγή σου.", - "permissions.global_ip_temporarily_banned": "Η διεύθυνση IP σου {ipAddress} έχει αποκλειστεί προσωρινά από το Fluxer API για 24 ώρες λόγω καταχρηστικών ή ασυνήθιστων μοτίβων πρόσβασης. Συνήθως δεν παρέχουμε δυνατότητα προσφυγής για προσωρινούς αποκλεισμούς API. Άλλαξε διεύθυνση IP ή περίμενε να λήξει ο αποκλεισμός και έλεγξε τα μοτίβα πρόσβασης στο Fluxer API από τον client σου.", + "permissions.global_ip_temporarily_banned": "Η διεύθυνση IP σου {ipAddress} έχει αποκλειστεί προσωρινά από το Fluxer API. Ο αποκλεισμός αίρεται αυτόματα όταν λήξει. Αν πιστεύεις ότι πρόκειται για λάθος, επικοινώνησε με support@fluxer.com και συμπερίλαβε αυτήν τη διεύθυνση IP.", "permissions.missing_access": "Δεν έχεις πρόσβαση σε αυτόν τον πόρο ή σε αυτήν τη λειτουργία.", "permissions.missing_permissions": "Δεν έχεις τα απαραίτητα δικαιώματα για να εκτελέσεις αυτήν την ενέργεια.", "permissions.user_banned_from_guild": "Αυτός ο χρήστης έχει αποκλειστεί από αυτήν την κοινότητα.", diff --git a/packages/errors/src/i18n/weblate/locales/en-GB.json b/packages/errors/src/i18n/weblate/locales/en-GB.json index 7048c3eed..8280313ce 100644 --- a/packages/errors/src/i18n/weblate/locales/en-GB.json +++ b/packages/errors/src/i18n/weblate/locales/en-GB.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "This user isn't banned.", "names_and_normalization.name_empty_after_normalization": "Name can't be empty after normalisation.", "permissions.global_ip_banned": "Your IP address {ipAddress} has been permanently blocked from the Fluxer API by platform administrators. If you believe this is a mistake, contact support@fluxer.app to appeal. Include this IP address in your appeal.", - "permissions.global_ip_temporarily_banned": "Your IP address {ipAddress} has been temporarily blocked from the Fluxer API for 24 hours because of abusive or unusual access patterns. We usually do not provide appeals for temporary API bans. Change IP addresses or wait for the ban to expire, and review the Fluxer API access patterns coming from your client.", + "permissions.global_ip_temporarily_banned": "Your IP address {ipAddress} has been temporarily blocked from the Fluxer API. The block lifts on its own when it expires. If you think this is a mistake, contact support@fluxer.com and include this IP address.", "permissions.missing_access": "You don't have access to this resource or feature.", "permissions.missing_permissions": "You don't have the permissions required to perform this action.", "permissions.user_banned_from_guild": "This user is banned from this community.", diff --git a/packages/errors/src/i18n/weblate/locales/es-419.json b/packages/errors/src/i18n/weblate/locales/es-419.json index d5bf8e156..14878f942 100644 --- a/packages/errors/src/i18n/weblate/locales/es-419.json +++ b/packages/errors/src/i18n/weblate/locales/es-419.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Este usuario no ha sido baneado.", "names_and_normalization.name_empty_after_normalization": "El nombre no puede quedar vacío después de la normalización.", "permissions.global_ip_banned": "Tu dirección IP {ipAddress} fue bloqueada permanentemente de la API de Fluxer por administradores de la plataforma. Si crees que es un error, escribe a support@fluxer.app para apelar. Incluye esta dirección IP en tu apelación.", - "permissions.global_ip_temporarily_banned": "Tu dirección IP {ipAddress} fue bloqueada temporalmente de la API de Fluxer durante 24 horas por patrones de acceso abusivos o inusuales. Por lo general no ofrecemos apelaciones para bloqueos temporales de la API. Cambia de dirección IP o espera a que termine el bloqueo, y revisa los patrones de acceso a la API de Fluxer que provienen de tu cliente.", + "permissions.global_ip_temporarily_banned": "Tu dirección IP {ipAddress} fue bloqueada temporalmente de la API de Fluxer. El bloqueo se levanta automáticamente cuando vence. Si crees que es un error, escribe a support@fluxer.com e incluye esta dirección IP.", "permissions.missing_access": "No tienes acceso a este recurso o función.", "permissions.missing_permissions": "No tienes los permisos necesarios para realizar esta acción.", "permissions.user_banned_from_guild": "Este usuario ha sido baneado de esta comunidad.", diff --git a/packages/errors/src/i18n/weblate/locales/es-ES.json b/packages/errors/src/i18n/weblate/locales/es-ES.json index 341081bd7..2316285cd 100644 --- a/packages/errors/src/i18n/weblate/locales/es-ES.json +++ b/packages/errors/src/i18n/weblate/locales/es-ES.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Este usuario no está baneado.", "names_and_normalization.name_empty_after_normalization": "El nombre no puede quedar vacío tras la normalización.", "permissions.global_ip_banned": "Tu dirección IP {ipAddress} ha sido bloqueada permanentemente de la API de Fluxer por administradores de la plataforma. Si crees que es un error, contacta con support@fluxer.app para apelar. Incluye esta dirección IP en la apelación.", - "permissions.global_ip_temporarily_banned": "Tu dirección IP {ipAddress} ha sido bloqueada temporalmente de la API de Fluxer durante 24 horas por patrones de acceso abusivos o inusuales. Normalmente no ofrecemos apelaciones para baneos temporales de la API. Cambia de dirección IP o espera a que expire el bloqueo, y revisa los patrones de acceso a la API de Fluxer que provienen de tu cliente.", + "permissions.global_ip_temporarily_banned": "Tu dirección IP {ipAddress} ha sido bloqueada temporalmente de la API de Fluxer. El bloqueo se levantará automáticamente cuando caduque. Si crees que es un error, contacta con support@fluxer.com e incluye esta dirección IP.", "permissions.missing_access": "No tienes acceso a este recurso o función.", "permissions.missing_permissions": "No tienes los permisos necesarios para realizar esta acción.", "permissions.user_banned_from_guild": "Este usuario está baneado de esta comunidad.", diff --git a/packages/errors/src/i18n/weblate/locales/fi.json b/packages/errors/src/i18n/weblate/locales/fi.json index 05fc26c59..5fab5b15c 100644 --- a/packages/errors/src/i18n/weblate/locales/fi.json +++ b/packages/errors/src/i18n/weblate/locales/fi.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Tällä käyttäjällä ei ole porttikieltoa.", "names_and_normalization.name_empty_after_normalization": "Normalisoinnin jälkeen nimi ei voi olla tyhjä.", "permissions.global_ip_banned": "Alustan ylläpitäjät ovat estäneet IP-osoitteelta {ipAddress} pääsyn Fluxer API -rajapintaan pysyvästi. Jos uskot tämän olevan virhe, lähetä valitus osoitteeseen support@fluxer.app. Liitä tämä IP-osoite valitukseesi.", - "permissions.global_ip_temporarily_banned": "IP-osoitteeltasi {ipAddress} on estetty pääsy Fluxer API -rajapintaan 24 tunniksi väärinkäytön tai epätavallisten käyttötapojen vuoksi. Emme yleensä käsittele väliaikaisia API-estoja koskevia valituksia. Vaihda IP-osoitetta tai odota eston päättymistä ja tarkista, miten asiakasohjelmasi käyttää Fluxer API -rajapintaa.", + "permissions.global_ip_temporarily_banned": "IP-osoitteeltasi {ipAddress} on estetty väliaikaisesti pääsy Fluxer API -rajapintaan. Esto poistuu automaattisesti, kun sen voimassaolo päättyy. Jos uskot tämän olevan virhe, ota yhteyttä osoitteeseen support@fluxer.com ja mainitse tämä IP-osoite.", "permissions.missing_access": "Ei oikeutta tähän resurssiin tai ominaisuuteen.", "permissions.missing_permissions": "Ei tarvittavia oikeuksia tämän toiminnon tekemiseen.", "permissions.user_banned_from_guild": "Tällä käyttäjällä on porttikielto tähän yhteisöön.", diff --git a/packages/errors/src/i18n/weblate/locales/fr.json b/packages/errors/src/i18n/weblate/locales/fr.json index 9ae1eb30e..5e1809aaa 100644 --- a/packages/errors/src/i18n/weblate/locales/fr.json +++ b/packages/errors/src/i18n/weblate/locales/fr.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Cet utilisateur n'est pas banni.", "names_and_normalization.name_empty_after_normalization": "Le nom ne peut pas être vide une fois normalisé.", "permissions.global_ip_banned": "Les administrateurs de la plateforme ont définitivement bloqué l’accès à Fluxer API depuis votre adresse IP {ipAddress}. Si vous pensez qu’il s’agit d’une erreur, écrivez à support@fluxer.app pour déposer un recours. Indiquez cette adresse IP dans votre recours.", - "permissions.global_ip_temporarily_banned": "L’accès à Fluxer API depuis votre adresse IP {ipAddress} a été bloqué pendant 24 heures en raison d’une utilisation abusive ou inhabituelle. Nous ne proposons généralement pas de recours pour les blocages temporaires de l’API. Changez d’adresse IP ou attendez la fin du blocage, et vérifiez la façon dont votre client accède à Fluxer API.", + "permissions.global_ip_temporarily_banned": "L’accès à Fluxer API depuis votre adresse IP {ipAddress} a été temporairement bloqué. Le blocage sera levé automatiquement à son expiration. Si vous pensez qu’il s’agit d’une erreur, écrivez à support@fluxer.com en indiquant cette adresse IP.", "permissions.missing_access": "Vous n’avez pas accès à cette ressource ou fonctionnalité.", "permissions.missing_permissions": "Vous n’avez pas les permissions requises pour effectuer cette action.", "permissions.user_banned_from_guild": "Cet utilisateur est banni de cette communauté.", diff --git a/packages/errors/src/i18n/weblate/locales/he.json b/packages/errors/src/i18n/weblate/locales/he.json index c0b359ed0..29154607d 100644 --- a/packages/errors/src/i18n/weblate/locales/he.json +++ b/packages/errors/src/i18n/weblate/locales/he.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "משתמש זה לא חסום.", "names_and_normalization.name_empty_after_normalization": "השם לא יכול להיות ריק לאחר נורמליזציה.", "permissions.global_ip_banned": "כתובת ה-IP שלך {ipAddress} נחסמה לצמיתות מ-Fluxer API על ידי מנהלי הפלטפורמה. אם לדעתך זו טעות, אפשר לפנות אל support@fluxer.app כדי לערער. יש לכלול את כתובת ה-IP הזו בערעור.", - "permissions.global_ip_temporarily_banned": "כתובת ה-IP שלך {ipAddress} נחסמה זמנית מ-Fluxer API למשך 24 שעות בגלל דפוסי גישה פוגעניים או חריגים. בדרך כלל איננו מאפשרים ערעורים על חסימות API זמניות. אפשר להחליף כתובת IP או להמתין לסיום החסימה, ולבדוק את דפוסי הגישה ל-Fluxer API שמגיעים מהלקוח שלך.", + "permissions.global_ip_temporarily_banned": "כתובת ה-IP שלך {ipAddress} נחסמה זמנית מ-Fluxer API. החסימה תוסר אוטומטית כשתפוג. אם לדעתך זו טעות, אפשר לפנות אל support@fluxer.com ולציין את כתובת ה-IP הזו.", "permissions.missing_access": "אין לך גישה למשאב או לתכונה הזו.", "permissions.missing_permissions": "אין לך את ההרשאות הנדרשות לביצוע פעולה זו.", "permissions.user_banned_from_guild": "משתמש זה חסום בקהילה זו.", diff --git a/packages/errors/src/i18n/weblate/locales/hi.json b/packages/errors/src/i18n/weblate/locales/hi.json index b11653997..2164bbf6b 100644 --- a/packages/errors/src/i18n/weblate/locales/hi.json +++ b/packages/errors/src/i18n/weblate/locales/hi.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "यह यूज़र बैन नहीं है।", "names_and_normalization.name_empty_after_normalization": "नॉर्मलाइज़ेशन के बाद नाम खाली नहीं हो सकता।", "permissions.global_ip_banned": "आपका IP पता {ipAddress} प्लेटफ़ॉर्म एडमिनों द्वारा Fluxer API से स्थायी रूप से ब्लॉक कर दिया गया है। अगर आपको लगता है कि यह गलती है, तो अपील के लिए support@fluxer.app से संपर्क करें। अपनी अपील में यह IP पता शामिल करें।", - "permissions.global_ip_temporarily_banned": "गलत इस्तेमाल या असामान्य एक्सेस पैटर्न के कारण आपका IP पता {ipAddress} Fluxer API से 24 घंटे के लिए अस्थायी रूप से ब्लॉक कर दिया गया है। अस्थायी API बैन के लिए हम आम तौर पर अपील स्वीकार नहीं करते। IP पता बदलें या बैन खत्म होने का इंतज़ार करें, और अपने क्लाइंट से Fluxer API पर आने वाले एक्सेस पैटर्न की जाँच करें।", + "permissions.global_ip_temporarily_banned": "आपका IP पता {ipAddress} Fluxer API से अस्थायी रूप से ब्लॉक कर दिया गया है। समय पूरा होने पर ब्लॉक अपने-आप हट जाएगा। अगर आपको लगता है कि यह गलती है, तो support@fluxer.com से संपर्क करें और यह IP पता शामिल करें।", "permissions.missing_access": "आपके पास इस रिसोर्स या फ़ीचर का एक्सेस नहीं है।", "permissions.missing_permissions": "आपके पास यह एक्शन करने के लिए ज़रूरी अनुमति नहीं है।", "permissions.user_banned_from_guild": "इस यूज़र को इस कम्युनिटी से बैन कर दिया गया है।", diff --git a/packages/errors/src/i18n/weblate/locales/hr.json b/packages/errors/src/i18n/weblate/locales/hr.json index 4ff8c72ea..6c1788c29 100644 --- a/packages/errors/src/i18n/weblate/locales/hr.json +++ b/packages/errors/src/i18n/weblate/locales/hr.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Ovaj korisnik nema zabranu.", "names_and_normalization.name_empty_after_normalization": "Ime ne može biti prazno nakon normalizacije.", "permissions.global_ip_banned": "Administratori platforme trajno su blokirali pristup Fluxer API-ju s tvoje IP adrese {ipAddress}. Ako smatraš da je to pogreška, javi se na support@fluxer.app i uloži žalbu. U žalbu uključi ovu IP adresu.", - "permissions.global_ip_temporarily_banned": "Pristup Fluxer API-ju s tvoje IP adrese {ipAddress} privremeno je blokiran na 24 sata zbog zlouporabe ili neuobičajenih obrazaca pristupa. Za privremene zabrane pristupa API-ju obično ne razmatramo žalbe. Promijeni IP adresu ili pričekaj da zabrana istekne te provjeri obrasce pristupa Fluxer API-ju koji dolaze iz tvog klijenta.", + "permissions.global_ip_temporarily_banned": "Pristup Fluxer API-ju s tvoje IP adrese {ipAddress} privremeno je blokiran. Blokada se automatski uklanja kada istekne. Ako smatraš da je to pogreška, javi se na support@fluxer.com i navedi ovu IP adresu.", "permissions.missing_access": "Nemaš pristup ovom resursu ili značajci.", "permissions.missing_permissions": "Nemaš potrebna dopuštenja za ovu radnju.", "permissions.user_banned_from_guild": "Ovaj korisnik ima zabranu pristupa ovoj zajednici.", diff --git a/packages/errors/src/i18n/weblate/locales/hu.json b/packages/errors/src/i18n/weblate/locales/hu.json index 4ff9e3854..6ea5b8030 100644 --- a/packages/errors/src/i18n/weblate/locales/hu.json +++ b/packages/errors/src/i18n/weblate/locales/hu.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Ez a felhasználó nincs kitiltva.", "names_and_normalization.name_empty_after_normalization": "Normalizálás után a név nem lehet üres.", "permissions.global_ip_banned": "Az IP-címedet ({ipAddress}) a platform adminisztrátorai véglegesen letiltották a Fluxer API használatáról. Ha úgy gondolod, hogy ez tévedés, a support@fluxer.app címre írhatsz fellebbezést. Add meg benne ezt az IP-címet.", - "permissions.global_ip_temporarily_banned": "Az IP-címedet ({ipAddress}) visszaélésszerű vagy szokatlan hozzáférési minták miatt ideiglenesen, 24 órára letiltottuk a Fluxer API használatáról. Az ideiglenes API-tiltások ellen általában nem lehet fellebbezni. Válts IP-címet, vagy várd meg a tiltás lejártát, és vizsgáld meg, hogyan használja a kliensed a Fluxer API-t.", + "permissions.global_ip_temporarily_banned": "Az IP-címedet ({ipAddress}) ideiglenesen letiltottuk a Fluxer API használatáról. A tiltás a lejártakor magától megszűnik. Ha úgy gondolod, hogy ez tévedés, írj a support@fluxer.com címre, és add meg ezt az IP-címet.", "permissions.missing_access": "Nem férsz hozzá ehhez az erőforráshoz vagy funkcióhoz.", "permissions.missing_permissions": "Nincs meg a művelet elvégzéséhez szükséges jogosultságod.", "permissions.user_banned_from_guild": "Ez a felhasználó ki van tiltva a közösségből.", diff --git a/packages/errors/src/i18n/weblate/locales/id.json b/packages/errors/src/i18n/weblate/locales/id.json index 89f6ffe71..8efc7632c 100644 --- a/packages/errors/src/i18n/weblate/locales/id.json +++ b/packages/errors/src/i18n/weblate/locales/id.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Pengguna ini tidak diblokir.", "names_and_normalization.name_empty_after_normalization": "Nama tidak bisa kosong setelah normalisasi.", "permissions.global_ip_banned": "Alamat IP kamu {ipAddress} telah diblokir permanen dari Fluxer API oleh admin platform. Jika kamu merasa ini keliru, hubungi support@fluxer.app untuk mengajukan banding. Sertakan alamat IP ini dalam bandingmu.", - "permissions.global_ip_temporarily_banned": "Alamat IP kamu {ipAddress} diblokir sementara dari Fluxer API selama 24 jam karena pola akses yang menyalahgunakan atau tidak wajar. Biasanya kami tidak menyediakan banding untuk pemblokiran API sementara. Ganti alamat IP atau tunggu sampai pemblokiran berakhir, dan tinjau pola akses ke Fluxer API yang berasal dari klienmu.", + "permissions.global_ip_temporarily_banned": "Alamat IP kamu {ipAddress} diblokir sementara dari Fluxer API. Pemblokiran akan dicabut secara otomatis saat masa berlakunya habis. Jika kamu merasa ini keliru, hubungi support@fluxer.com dan sertakan alamat IP ini.", "permissions.missing_access": "Kamu tidak memiliki akses ke sumber daya atau fitur ini.", "permissions.missing_permissions": "Kamu tidak memiliki izin yang diperlukan untuk melakukan tindakan ini.", "permissions.user_banned_from_guild": "Pengguna ini diblokir dari komunitas ini.", diff --git a/packages/errors/src/i18n/weblate/locales/it.json b/packages/errors/src/i18n/weblate/locales/it.json index 766abb90b..95af0e0bc 100644 --- a/packages/errors/src/i18n/weblate/locales/it.json +++ b/packages/errors/src/i18n/weblate/locales/it.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "L'utente non è bannato.", "names_and_normalization.name_empty_after_normalization": "Il nome non può essere vuoto dopo la normalizzazione.", "permissions.global_ip_banned": "Il tuo indirizzo IP {ipAddress} è stato bloccato in modo permanente dall'API Fluxer dagli amministratori della piattaforma. Se pensi che sia un errore, contatta support@fluxer.app per fare ricorso. Includi questo indirizzo IP nel ricorso.", - "permissions.global_ip_temporarily_banned": "Il tuo indirizzo IP {ipAddress} è stato bloccato temporaneamente dall'API Fluxer per 24 ore a causa di schemi di accesso abusivi o insoliti. Di solito non offriamo ricorsi per i ban temporanei dell'API. Cambia indirizzo IP o attendi la scadenza del ban, e controlla gli schemi di accesso all'API Fluxer provenienti dal tuo client.", + "permissions.global_ip_temporarily_banned": "Il tuo indirizzo IP {ipAddress} è stato bloccato temporaneamente dall'API Fluxer. Il blocco verrà rimosso automaticamente alla scadenza. Se pensi che sia un errore, contatta support@fluxer.com indicando questo indirizzo IP.", "permissions.missing_access": "Non hai accesso a questa risorsa o funzionalità.", "permissions.missing_permissions": "Non hai le autorizzazioni necessarie per eseguire questa azione.", "permissions.user_banned_from_guild": "L'utente è bannato da questa community.", diff --git a/packages/errors/src/i18n/weblate/locales/ja.json b/packages/errors/src/i18n/weblate/locales/ja.json index 274651aa6..33afb9b94 100644 --- a/packages/errors/src/i18n/weblate/locales/ja.json +++ b/packages/errors/src/i18n/weblate/locales/ja.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "このユーザーはBANされていません。", "names_and_normalization.name_empty_after_normalization": "正規化後、名前は空にできません。", "permissions.global_ip_banned": "IPアドレス{ipAddress}は、プラットフォーム管理者によりFluxer APIから永久にブロックされました。誤りだと思う場合は、support@fluxer.appに連絡して異議申し立てをしてください。申し立てにはこのIPアドレスを記載してください。", - "permissions.global_ip_temporarily_banned": "IPアドレス{ipAddress}は、悪質または通常と異なるアクセスパターンのため、Fluxer APIから24時間一時的にブロックされました。一時的なAPIのBANについては通常、異議申し立てを受け付けていません。IPアドレスを変更するかBANの期限切れを待ち、クライアントからFluxer APIへのアクセスパターンを確認してください。", + "permissions.global_ip_temporarily_banned": "IPアドレス{ipAddress}は、Fluxer APIから一時的にブロックされました。ブロックは期限が切れると自動的に解除されます。誤りだと思う場合は、このIPアドレスを記載のうえ、support@fluxer.comに連絡してください。", "permissions.missing_access": "このリソースや機能にアクセスする権限がありません。", "permissions.missing_permissions": "この操作を実行するために必要な権限がありません。", "permissions.user_banned_from_guild": "このユーザーはこのコミュニティでBANされています。", diff --git a/packages/errors/src/i18n/weblate/locales/ko.json b/packages/errors/src/i18n/weblate/locales/ko.json index ce7d5f991..de2c03354 100644 --- a/packages/errors/src/i18n/weblate/locales/ko.json +++ b/packages/errors/src/i18n/weblate/locales/ko.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "이 사용자는 차단되지 않았어요.", "names_and_normalization.name_empty_after_normalization": "정규화 후 이름은 비워둘 수 없어요.", "permissions.global_ip_banned": "회원님의 IP 주소 {ipAddress}는 플랫폼 관리자가 Fluxer API에서 영구 차단했어요. 오류라고 생각한다면 support@fluxer.app으로 문의해 이의를 제기해 주세요. 이의 제기에는 이 IP 주소를 포함해 주세요.", - "permissions.global_ip_temporarily_banned": "회원님의 IP 주소 {ipAddress}는 악용 또는 비정상적인 접근 패턴으로 인해 Fluxer API에서 24시간 동안 일시 차단되었어요. 일시적인 API 차단은 보통 이의 제기를 받지 않아요. IP 주소를 변경하거나 차단이 만료될 때까지 기다리고, 클라이언트에서 Fluxer API로 발생하는 접근 패턴을 검토해 주세요.", + "permissions.global_ip_temporarily_banned": "회원님의 IP 주소 {ipAddress}는 Fluxer API에서 일시 차단되었어요. 차단은 기간이 끝나면 자동으로 해제돼요. 오류라고 생각한다면 이 IP 주소를 포함해 support@fluxer.com으로 문의해 주세요.", "permissions.missing_access": "이 리소스 또는 기능에 접근할 권한이 없어요.", "permissions.missing_permissions": "이 작업을 수행하는 데 필요한 권한이 없어요.", "permissions.user_banned_from_guild": "이 사용자는 이 커뮤니티에서 차단되었어요.", diff --git a/packages/errors/src/i18n/weblate/locales/lt.json b/packages/errors/src/i18n/weblate/locales/lt.json index f2771da8e..049705857 100644 --- a/packages/errors/src/i18n/weblate/locales/lt.json +++ b/packages/errors/src/i18n/weblate/locales/lt.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Šis naudotojas nėra užblokuotas.", "names_and_normalization.name_empty_after_normalization": "Po normalizavimo pavadinimas negali būti tuščias.", "permissions.global_ip_banned": "Tavo IP adresas {ipAddress} platformos administratorių visam laikui užblokuotas Fluxer API. Jei manai, kad tai klaida, dėl apeliacijos susisiek adresu support@fluxer.app. Apeliacijoje nurodyk šį IP adresą.", - "permissions.global_ip_temporarily_banned": "Tavo IP adresas {ipAddress} 24 valandoms laikinai užblokuotas Fluxer API dėl piktnaudžiaujamo arba neįprasto naudojimo. Dėl laikinų API blokavimų apeliacijų paprastai nepriimame. Pakeisk IP adresą arba palauk, kol blokavimas baigsis, ir peržiūrėk, kaip tavo klientas kreipiasi į Fluxer API.", + "permissions.global_ip_temporarily_banned": "Tavo IP adresas {ipAddress} laikinai užblokuotas Fluxer API. Blokavimas bus panaikintas automatiškai, kai baigsis jo laikas. Jei manai, kad tai klaida, susisiek adresu support@fluxer.com ir nurodyk šį IP adresą.", "permissions.missing_access": "Neturi prieigos prie šio ištekliaus ar funkcijos.", "permissions.missing_permissions": "Neturi reikiamų leidimų atlikti šį veiksmą.", "permissions.user_banned_from_guild": "Šis naudotojas užblokuotas šioje bendruomenėje.", diff --git a/packages/errors/src/i18n/weblate/locales/nl.json b/packages/errors/src/i18n/weblate/locales/nl.json index 54a1406b0..636b9a871 100644 --- a/packages/errors/src/i18n/weblate/locales/nl.json +++ b/packages/errors/src/i18n/weblate/locales/nl.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Deze gebruiker is niet verbannen.", "names_and_normalization.name_empty_after_normalization": "Naam kan niet leeg zijn na normalisatie.", "permissions.global_ip_banned": "Je IP-adres {ipAddress} is door platformbeheerders permanent geblokkeerd voor de Fluxer API. Als je denkt dat dit een fout is, neem dan contact op met support@fluxer.app om bezwaar te maken. Vermeld dit IP-adres in je bezwaar.", - "permissions.global_ip_temporarily_banned": "Je IP-adres {ipAddress} is vanwege misbruik of ongebruikelijke toegangspatronen voor 24 uur geblokkeerd voor de Fluxer API. We bieden meestal geen bezwaarprocedure voor tijdelijke API-blokkades. Gebruik een ander IP-adres of wacht tot de blokkade verloopt en controleer hoe je client de Fluxer API benadert.", + "permissions.global_ip_temporarily_banned": "Je IP-adres {ipAddress} is tijdelijk geblokkeerd voor de Fluxer API. De blokkade wordt automatisch opgeheven zodra deze verloopt. Als je denkt dat dit een fout is, neem dan contact op met support@fluxer.com en vermeld dit IP-adres.", "permissions.missing_access": "Je hebt geen toegang tot dit item of deze functie.", "permissions.missing_permissions": "Je hebt niet de benodigde machtigingen om deze actie uit te voeren.", "permissions.user_banned_from_guild": "Deze gebruiker is verbannen uit deze community.", diff --git a/packages/errors/src/i18n/weblate/locales/no.json b/packages/errors/src/i18n/weblate/locales/no.json index b54ca0683..7fee4fd4c 100644 --- a/packages/errors/src/i18n/weblate/locales/no.json +++ b/packages/errors/src/i18n/weblate/locales/no.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Denne brukeren er ikke utestengt.", "names_and_normalization.name_empty_after_normalization": "Navnet kan ikke være tomt etter normalisering.", "permissions.global_ip_banned": "IP-adressen din {ipAddress} er permanent blokkert fra Fluxer-API-et av plattformadministratorene. Hvis du mener dette er en feil, kan du kontakte support@fluxer.app for å klage. Ta med denne IP-adressen i klagen.", - "permissions.global_ip_temporarily_banned": "IP-adressen din {ipAddress} er midlertidig blokkert fra Fluxer-API-et i 24 timer på grunn av misbruk eller uvanlige tilgangsmønstre. Vi tilbyr vanligvis ikke mulighet til å klage på midlertidige API-utestengelser. Bytt IP-adresse eller vent til utestengelsen utløper, og gjennomgå hvordan klienten din bruker Fluxer-API-et.", + "permissions.global_ip_temporarily_banned": "IP-adressen din {ipAddress} er midlertidig blokkert fra Fluxer-API-et. Blokkeringen oppheves automatisk når den utløper. Hvis du mener dette er en feil, kan du kontakte support@fluxer.com og oppgi denne IP-adressen.", "permissions.missing_access": "Du har ikke tilgang til denne ressursen eller funksjonen.", "permissions.missing_permissions": "Du har ikke de nødvendige tillatelsene til å utføre denne handlingen.", "permissions.user_banned_from_guild": "Denne brukeren er utestengt fra dette fellesskapet.", diff --git a/packages/errors/src/i18n/weblate/locales/pl.json b/packages/errors/src/i18n/weblate/locales/pl.json index 5517f4677..b3dcdba34 100644 --- a/packages/errors/src/i18n/weblate/locales/pl.json +++ b/packages/errors/src/i18n/weblate/locales/pl.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Ten użytkownik nie ma bana.", "names_and_normalization.name_empty_after_normalization": "Nazwa nie może być pusta po normalizacji.", "permissions.global_ip_banned": "Twój adres IP {ipAddress} został trwale zablokowany w Fluxer API przez administratorów platformy. Jeśli uważasz, że to błąd, skontaktuj się z support@fluxer.app, aby się odwołać. Podaj ten adres IP w odwołaniu.", - "permissions.global_ip_temporarily_banned": "Twój adres IP {ipAddress} został tymczasowo zablokowany w API Fluxer na 24 godziny z powodu nadużyć lub nietypowego sposobu korzystania z API. Zazwyczaj nie umożliwiamy odwołań od tymczasowych banów API. Zmień adres IP albo poczekaj na wygaśnięcie bana i sprawdź, w jaki sposób Twoja aplikacja kliencka korzysta z API Fluxer.", + "permissions.global_ip_temporarily_banned": "Twój adres IP {ipAddress} został tymczasowo zablokowany w Fluxer API. Blokada zostanie zdjęta automatycznie po jej wygaśnięciu. Jeśli uważasz, że to błąd, skontaktuj się z support@fluxer.com i podaj ten adres IP.", "permissions.missing_access": "Brak dostępu do tego zasobu lub funkcji.", "permissions.missing_permissions": "Brak wymaganych uprawnień do wykonania tej akcji.", "permissions.user_banned_from_guild": "Ten użytkownik ma bana w tej społeczności.", diff --git a/packages/errors/src/i18n/weblate/locales/pt-BR.json b/packages/errors/src/i18n/weblate/locales/pt-BR.json index dbdd7d801..4e8ad38e2 100644 --- a/packages/errors/src/i18n/weblate/locales/pt-BR.json +++ b/packages/errors/src/i18n/weblate/locales/pt-BR.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Este usuário não está banido.", "names_and_normalization.name_empty_after_normalization": "O nome não pode ficar vazio após a normalização.", "permissions.global_ip_banned": "Seu endereço IP {ipAddress} foi bloqueado permanentemente na Fluxer API pelos administradores da plataforma. Se você acredita que isso é um erro, entre em contato com support@fluxer.app para recorrer. Inclua este endereço IP no recurso.", - "permissions.global_ip_temporarily_banned": "Seu endereço IP {ipAddress} foi bloqueado temporariamente na Fluxer API por 24 horas devido a padrões de acesso abusivos ou incomuns. Normalmente não aceitamos recursos para banimentos temporários da API. Troque de endereço IP ou aguarde o fim do banimento e revise os padrões de acesso do seu cliente à Fluxer API.", + "permissions.global_ip_temporarily_banned": "Seu endereço IP {ipAddress} foi bloqueado temporariamente na Fluxer API. O bloqueio será removido automaticamente quando expirar. Se você acredita que isso é um erro, entre em contato com support@fluxer.com e informe este endereço IP.", "permissions.missing_access": "Você não tem acesso a este recurso ou funcionalidade.", "permissions.missing_permissions": "Você não tem as permissões necessárias para executar esta ação.", "permissions.user_banned_from_guild": "Este usuário está banido desta comunidade.", diff --git a/packages/errors/src/i18n/weblate/locales/ro.json b/packages/errors/src/i18n/weblate/locales/ro.json index 7fd4dfe7e..81a0548c7 100644 --- a/packages/errors/src/i18n/weblate/locales/ro.json +++ b/packages/errors/src/i18n/weblate/locales/ro.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Acest utilizator nu este banat.", "names_and_normalization.name_empty_after_normalization": "Numele nu poate fi gol după normalizare.", "permissions.global_ip_banned": "Accesul adresei tale IP {ipAddress} la Fluxer API a fost blocat permanent de administratorii platformei. Dacă crezi că este o greșeală, contactează support@fluxer.app pentru a depune o contestație. Include această adresă IP în contestație.", - "permissions.global_ip_temporarily_banned": "Accesul adresei tale IP {ipAddress} la Fluxer API a fost blocat temporar timp de 24 de ore din cauza unor tipare de acces abuzive sau neobișnuite. De obicei nu acceptăm contestații pentru banurile temporare ale API-ului. Schimbă adresa IP sau așteaptă expirarea banului și verifică tiparele de acces la Fluxer API provenite de la clientul tău.", + "permissions.global_ip_temporarily_banned": "Accesul adresei tale IP {ipAddress} la Fluxer API a fost blocat temporar. Blocarea se ridică automat când expiră. Dacă crezi că este o greșeală, contactează support@fluxer.com și include această adresă IP.", "permissions.missing_access": "Nu ai acces la această resursă sau funcție.", "permissions.missing_permissions": "Nu ai permisiunile necesare pentru a efectua această acțiune.", "permissions.user_banned_from_guild": "Acest utilizator este banat din această comunitate.", diff --git a/packages/errors/src/i18n/weblate/locales/ru.json b/packages/errors/src/i18n/weblate/locales/ru.json index abdc59cb2..ec89ab472 100644 --- a/packages/errors/src/i18n/weblate/locales/ru.json +++ b/packages/errors/src/i18n/weblate/locales/ru.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Этот пользователь не забанен.", "names_and_normalization.name_empty_after_normalization": "Имя не может быть пустым после нормализации.", "permissions.global_ip_banned": "Твой IP-адрес {ipAddress} навсегда заблокирован в Fluxer API администраторами платформы. Если считаешь, что это ошибка, напиши на support@fluxer.app, чтобы подать апелляцию. Укажи в ней этот IP-адрес.", - "permissions.global_ip_temporarily_banned": "Твой IP-адрес {ipAddress} временно заблокирован в Fluxer API на 24 часа из-за злоупотреблений или необычного характера запросов. Апелляции по временным блокировкам API мы обычно не рассматриваем. Смени IP-адрес или дождись окончания блокировки и проверь, как твой клиент обращается к Fluxer API.", + "permissions.global_ip_temporarily_banned": "Твой IP-адрес {ipAddress} временно заблокирован в Fluxer API. Блокировка снимется автоматически, когда истечёт её срок. Если считаешь, что это ошибка, напиши на support@fluxer.com и укажи этот IP-адрес.", "permissions.missing_access": "У тебя нет доступа к этому ресурсу или функции.", "permissions.missing_permissions": "У тебя нет необходимых разрешений для выполнения этого действия.", "permissions.user_banned_from_guild": "Этот пользователь забанен в этом сообществе.", diff --git a/packages/errors/src/i18n/weblate/locales/sv-SE.json b/packages/errors/src/i18n/weblate/locales/sv-SE.json index 8fca5049c..faec2daf5 100644 --- a/packages/errors/src/i18n/weblate/locales/sv-SE.json +++ b/packages/errors/src/i18n/weblate/locales/sv-SE.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Den här användaren är inte bannlyst.", "names_and_normalization.name_empty_after_normalization": "Namnet kan inte vara tomt efter att ha normaliserats.", "permissions.global_ip_banned": "Din IP-adress {ipAddress} har blockerats permanent från Fluxers API av plattformsadministratörerna. Om du anser att detta är ett misstag kan du kontakta support@fluxer.app för att överklaga. Ange den här IP-adressen i ditt överklagande.", - "permissions.global_ip_temporarily_banned": "Din IP-adress {ipAddress} har blockerats tillfälligt från Fluxers API i 24 timmar på grund av missbruk eller ovanliga åtkomstmönster. Tillfälliga API-blockeringar kan vanligtvis inte överklagas. Byt IP-adress eller vänta tills blockeringen löper ut och granska hur din klient använder Fluxers API.", + "permissions.global_ip_temporarily_banned": "Din IP-adress {ipAddress} har blockerats tillfälligt från Fluxers API. Blockeringen hävs automatiskt när den löper ut. Om du anser att detta är ett misstag kan du kontakta support@fluxer.com och ange den här IP-adressen.", "permissions.missing_access": "Du har inte åtkomst till denna resurs eller funktion.", "permissions.missing_permissions": "Du har inte de behörigheter som krävs för att utföra denna åtgärd.", "permissions.user_banned_from_guild": "Den här användaren är bannlyst från den här communityn.", diff --git a/packages/errors/src/i18n/weblate/locales/th.json b/packages/errors/src/i18n/weblate/locales/th.json index 9200412ac..dfbe0302e 100644 --- a/packages/errors/src/i18n/weblate/locales/th.json +++ b/packages/errors/src/i18n/weblate/locales/th.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "ผู้ใช้รายนี้ไม่ได้ถูกแบน", "names_and_normalization.name_empty_after_normalization": "ชื่อต้องไม่ว่างเปล่าหลังจากการปรับให้เป็นมาตรฐาน", "permissions.global_ip_banned": "ที่อยู่ IP ของคุณ {ipAddress} ถูกบล็อกจาก Fluxer API อย่างถาวรโดยผู้ดูแลแพลตฟอร์ม หากคุณเชื่อว่านี่เป็นข้อผิดพลาด โปรดติดต่อ support@fluxer.app เพื่ออุทธรณ์ โปรดแนบที่อยู่ IP นี้ในการอุทธรณ์", - "permissions.global_ip_temporarily_banned": "ที่อยู่ IP ของคุณ {ipAddress} ถูกบล็อกจาก Fluxer API ชั่วคราวเป็นเวลา 24 ชั่วโมงเนื่องจากรูปแบบการเข้าถึงที่ผิดปกติหรือมีลักษณะละเมิด โดยปกติเราไม่รับอุทธรณ์สำหรับการแบน API ชั่วคราว โปรดเปลี่ยนที่อยู่ IP หรือรอให้การแบนหมดอายุ และตรวจสอบรูปแบบการเข้าถึง Fluxer API ที่มาจากไคลเอนต์ของคุณ", + "permissions.global_ip_temporarily_banned": "ที่อยู่ IP ของคุณ {ipAddress} ถูกบล็อกจาก Fluxer API ชั่วคราว การบล็อกจะถูกยกเลิกโดยอัตโนมัติเมื่อหมดเวลา หากคุณเชื่อว่านี่เป็นข้อผิดพลาด โปรดติดต่อ support@fluxer.com และแนบที่อยู่ IP นี้มาด้วย", "permissions.missing_access": "คุณไม่มีสิทธิ์เข้าถึงทรัพยากรหรือฟีเจอร์นี้", "permissions.missing_permissions": "คุณไม่มีสิทธิ์ที่จำเป็นในการดำเนินการนี้", "permissions.user_banned_from_guild": "ผู้ใช้รายนี้ถูกแบนจากคอมมูนิตี้นี้", diff --git a/packages/errors/src/i18n/weblate/locales/tr.json b/packages/errors/src/i18n/weblate/locales/tr.json index b9e3b0417..6fd1d64ff 100644 --- a/packages/errors/src/i18n/weblate/locales/tr.json +++ b/packages/errors/src/i18n/weblate/locales/tr.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Bu kullanıcı yasaklı değil.", "names_and_normalization.name_empty_after_normalization": "Ad, normalleştirildikten sonra boş olamaz.", "permissions.global_ip_banned": "IP adresin {ipAddress}, platform yöneticileri tarafından Fluxer API'den kalıcı olarak engellendi. Bunun bir hata olduğunu düşünüyorsan itiraz etmek için support@fluxer.app ile iletişime geç. İtirazına bu IP adresini ekle.", - "permissions.global_ip_temporarily_banned": "IP adresin {ipAddress}, kötüye kullanım niteliğindeki veya olağan dışı erişim kalıpları nedeniyle Fluxer API'den 24 saatliğine geçici olarak engellendi. Geçici API engellemeleri için genellikle itiraz kabul etmiyoruz. IP adresini değiştir ya da engellemenin süresi dolana kadar bekle ve istemcinden Fluxer API'ye gelen erişim kalıplarını gözden geçir.", + "permissions.global_ip_temporarily_banned": "IP adresin {ipAddress}, Fluxer API'den geçici olarak engellendi. Engelleme süresi dolduğunda kendiliğinden kalkar. Bunun bir hata olduğunu düşünüyorsan support@fluxer.com ile iletişime geç ve bu IP adresini belirt.", "permissions.missing_access": "Bu kaynağa veya özelliğe erişimin yok.", "permissions.missing_permissions": "Bu eylemi gerçekleştirmek için gerekli izinlere sahip değilsin.", "permissions.user_banned_from_guild": "Bu kullanıcı bu topluluktan yasaklandı.", diff --git a/packages/errors/src/i18n/weblate/locales/uk.json b/packages/errors/src/i18n/weblate/locales/uk.json index 24f85dd6f..2350ddba0 100644 --- a/packages/errors/src/i18n/weblate/locales/uk.json +++ b/packages/errors/src/i18n/weblate/locales/uk.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Цей користувач не забанений.", "names_and_normalization.name_empty_after_normalization": "Ім'я не може бути порожнім після нормалізації.", "permissions.global_ip_banned": "Адміністратори платформи назавжди заблокували твоїй IP-адресі {ipAddress} доступ до Fluxer API. Якщо ти вважаєш, що це помилка, напиши на support@fluxer.app, щоб подати апеляцію. Вкажи цю IP-адресу в апеляції.", - "permissions.global_ip_temporarily_banned": "Твоїй IP-адресі {ipAddress} тимчасово заблоковано доступ до Fluxer API на 24 години через зловживання або незвичну активність. Зазвичай ми не розглядаємо апеляції щодо тимчасових банів API. Зміни IP-адресу або дочекайся завершення бану та перевір, як твій клієнт звертається до Fluxer API.", + "permissions.global_ip_temporarily_banned": "Твоїй IP-адресі {ipAddress} тимчасово заблоковано доступ до Fluxer API. Блокування зніметься автоматично, коли завершиться його строк. Якщо ти вважаєш, що це помилка, напиши на support@fluxer.com і вкажи цю IP-адресу.", "permissions.missing_access": "Ти не маєш доступу до цього ресурсу або функції.", "permissions.missing_permissions": "Ти не маєш потрібних дозволів для цієї дії.", "permissions.user_banned_from_guild": "Цей користувач забанений у цій спільноті.", diff --git a/packages/errors/src/i18n/weblate/locales/vi.json b/packages/errors/src/i18n/weblate/locales/vi.json index 8d9e75df8..fa1a852dc 100644 --- a/packages/errors/src/i18n/weblate/locales/vi.json +++ b/packages/errors/src/i18n/weblate/locales/vi.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "Người dùng này không bị cấm.", "names_and_normalization.name_empty_after_normalization": "Tên không được để trống sau khi chuẩn hóa.", "permissions.global_ip_banned": "Địa chỉ IP của bạn {ipAddress} đã bị quản trị viên nền tảng chặn vĩnh viễn khỏi Fluxer API. Nếu bạn cho rằng đây là nhầm lẫn, hãy liên hệ support@fluxer.app để khiếu nại. Hãy kèm địa chỉ IP này trong khiếu nại.", - "permissions.global_ip_temporarily_banned": "Địa chỉ IP của bạn {ipAddress} đã bị chặn tạm thời khỏi Fluxer API trong 24 giờ do hành vi truy cập lạm dụng hoặc bất thường. Chúng tôi thường không tiếp nhận khiếu nại cho các lệnh cấm API tạm thời. Hãy đổi địa chỉ IP hoặc chờ lệnh cấm hết hạn, và xem lại cách client của bạn truy cập Fluxer API.", + "permissions.global_ip_temporarily_banned": "Địa chỉ IP của bạn {ipAddress} đã bị chặn tạm thời khỏi Fluxer API. Lệnh chặn sẽ tự động được gỡ khi hết hạn. Nếu bạn cho rằng đây là nhầm lẫn, hãy liên hệ support@fluxer.com và kèm theo địa chỉ IP này.", "permissions.missing_access": "Bạn không có quyền truy cập vào tài nguyên hoặc tính năng này.", "permissions.missing_permissions": "Bạn không có quyền cần thiết để thực hiện hành động này.", "permissions.user_banned_from_guild": "Người dùng này đã bị cấm khỏi cộng đồng này.", diff --git a/packages/errors/src/i18n/weblate/locales/zh-CN.json b/packages/errors/src/i18n/weblate/locales/zh-CN.json index 2096c359e..30cdba17b 100644 --- a/packages/errors/src/i18n/weblate/locales/zh-CN.json +++ b/packages/errors/src/i18n/weblate/locales/zh-CN.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "此用户未被封禁。", "names_and_normalization.name_empty_after_normalization": "规范化后名称不能为空。", "permissions.global_ip_banned": "你的 IP 地址 {ipAddress} 已被平台管理员永久禁止访问 Fluxer API。如果你认为这是误判,请联系 support@fluxer.app 申诉。请在申诉中附上此 IP 地址。", - "permissions.global_ip_temporarily_banned": "你的 IP 地址 {ipAddress} 因存在滥用或异常访问模式,已被临时禁止访问 Fluxer API,为期 24 小时。临时 API 封禁通常不提供申诉。请更换 IP 地址或等待封禁到期,并检查你的客户端对 Fluxer API 的访问模式。", + "permissions.global_ip_temporarily_banned": "你的 IP 地址 {ipAddress} 已被临时禁止访问 Fluxer API。限制到期后会自动解除。如果你认为这是误判,请联系 support@fluxer.com 并附上此 IP 地址。", "permissions.missing_access": "你无权访问此资源或功能。", "permissions.missing_permissions": "你没有执行此操作所需的权限。", "permissions.user_banned_from_guild": "此用户已被此社区封禁。", diff --git a/packages/errors/src/i18n/weblate/locales/zh-TW.json b/packages/errors/src/i18n/weblate/locales/zh-TW.json index ffd8ee187..4998c6505 100644 --- a/packages/errors/src/i18n/weblate/locales/zh-TW.json +++ b/packages/errors/src/i18n/weblate/locales/zh-TW.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "此使用者未被封鎖。", "names_and_normalization.name_empty_after_normalization": "名稱正規化後不能為空。", "permissions.global_ip_banned": "你的 IP 位址 {ipAddress} 已被平台管理員永久禁止存取 Fluxer API。如果你認為這是誤判,請聯絡 support@fluxer.app 申訴。請在申訴中附上此 IP 位址。", - "permissions.global_ip_temporarily_banned": "你的 IP 位址 {ipAddress} 因濫用或異常存取模式,已被暫時禁止存取 Fluxer API 24 小時。暫時性的 API 封鎖通常不提供申訴。請更換 IP 位址或等待封鎖到期,並檢查你的用戶端對 Fluxer API 的存取模式。", + "permissions.global_ip_temporarily_banned": "你的 IP 位址 {ipAddress} 已被暫時禁止存取 Fluxer API。限制到期後會自動解除。如果你認為這是誤判,請聯絡 support@fluxer.com 並附上此 IP 位址。", "permissions.missing_access": "你沒有權限使用此資源或功能。", "permissions.missing_permissions": "你沒有執行此動作所需的權限。", "permissions.user_banned_from_guild": "此使用者已被此社群封鎖。", diff --git a/packages/errors/src/i18n/weblate/messages.json b/packages/errors/src/i18n/weblate/messages.json index 42e9630a7..45012d1ef 100644 --- a/packages/errors/src/i18n/weblate/messages.json +++ b/packages/errors/src/i18n/weblate/messages.json @@ -377,7 +377,7 @@ "moderation_and_reports.user_is_not_banned": "This user isn't banned.", "names_and_normalization.name_empty_after_normalization": "Name can't be empty after normalization.", "permissions.global_ip_banned": "Your IP address {ipAddress} has been permanently blocked from the Fluxer API by platform administrators. If you believe this is a mistake, contact support@fluxer.app to appeal. Include this IP address in your appeal.", - "permissions.global_ip_temporarily_banned": "Your IP address {ipAddress} has been temporarily blocked from the Fluxer API for 24 hours because of abusive or unusual access patterns. We usually do not provide appeals for temporary API bans. Change IP addresses or wait for the ban to expire, and review the Fluxer API access patterns coming from your client.", + "permissions.global_ip_temporarily_banned": "Your IP address {ipAddress} has been temporarily blocked from the Fluxer API. The block lifts on its own when it expires. If you think this is a mistake, contact support@fluxer.com and include this IP address.", "permissions.missing_access": "You don't have access to this resource or feature.", "permissions.missing_permissions": "You don't have the permissions required to perform this action.", "permissions.user_banned_from_guild": "This user is banned from this community.", diff --git a/packages/schema/src/domains/admin/AdminSchemas.ts b/packages/schema/src/domains/admin/AdminSchemas.ts index 0e1fd55b6..fff0f291d 100644 --- a/packages/schema/src/domains/admin/AdminSchemas.ts +++ b/packages/schema/src/domains/admin/AdminSchemas.ts @@ -294,6 +294,13 @@ export const BanIpRequest = z.object({ ip: createStringType(1, 45) .refine((value) => IpOrCidrType.safeParse(value).success, 'Must be a valid IPv4/IPv6 address or CIDR range') .describe('IPv4/IPv6 address or CIDR range to ban'), + duration_hours: z + .number() + .int() + .min(0) + .max(8760) + .optional() + .describe('Hours until the ban expires and its entry is removed. Omit it or use 0 for a permanent ban.'), }); export type BanIpRequest = z.infer; @@ -1072,6 +1079,12 @@ export const AuditLogsListResponseSchema = z.object({ export type AuditLogsListResponse = z.infer; export const BanCheckResponseSchema = z.object({ banned: z.boolean(), + expires_at: z + .string() + .nullable() + .describe( + 'ISO 8601 timestamp when the matching ban expires. Null when the ban is permanent, when nothing matches, and on every blocklist other than ip.', + ), }); export const BulkJobResponse = z.object({ job_id: SnowflakeStringType,