diff --git a/fluxer_admin/openapi-admin.json b/fluxer_admin/openapi-admin.json index 542614621..6bb42e9fd 100644 --- a/fluxer_admin/openapi-admin.json +++ b/fluxer_admin/openapi-admin.json @@ -6266,6 +6266,72 @@ } } }, + "/admin/users/{user_id}/bot-status": { + "put": { + "operationId": "set_admin_user_bot_status", + "summary": "Set user bot status", + "tags": ["Admin"], + "responses": { + "200": { + "description": "Success", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserMutationResponse"}}} + }, + "400": { + "description": "Bad Request - The request was malformed or contained invalid data", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + }, + "401": { + "description": "Unauthorized - Authentication is required or the token is invalid", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + }, + "403": { + "description": "Forbidden - You do not have permission to perform this action", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + }, + "429": { + "description": "Too Many Requests - You are being rate limited", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ThrottledError"}}}, + "headers": { + "Retry-After": { + "description": "Number of seconds to wait before retrying (only on 429)", + "schema": {"type": "integer"} + }, + "X-RateLimit-Limit": { + "description": "The number of requests that can be made in the current window", + "schema": {"type": "integer"} + }, + "X-RateLimit-Remaining": { + "description": "The number of remaining requests that can be made", + "schema": {"type": "integer"} + }, + "X-RateLimit-Reset": { + "description": "Unix timestamp when the rate limit resets", + "schema": {"type": "integer"} + } + } + }, + "500": { + "description": "Internal Server Error - An unexpected error occurred", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + } + }, + "description": "Mark or unmark a user account as a bot. Controls bot badge visibility and API permissions. Creates audit log entry. Requires USER_UPDATE_BOT_STATUS permission.", + "security": [{"adminApiKey": []}], + "parameters": [ + { + "name": "user_id", + "in": "path", + "required": true, + "schema": {"description": "The ID of the user", "allOf": [{"$ref": "#/components/schemas/SnowflakeType"}]}, + "description": "The ID of the user" + } + ], + "requestBody": { + "required": true, + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdminUserBotStatusRequest"}}} + } + } + }, "/admin/users/{user_id}/change-log": { "get": { "operationId": "list_admin_user_change_log", @@ -7967,6 +8033,72 @@ ] } }, + "/admin/users/{user_id}/system-status": { + "put": { + "operationId": "set_admin_user_system_status", + "summary": "Set user system status", + "tags": ["Admin"], + "responses": { + "200": { + "description": "Success", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserMutationResponse"}}} + }, + "400": { + "description": "Bad Request - The request was malformed or contained invalid data", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + }, + "401": { + "description": "Unauthorized - Authentication is required or the token is invalid", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + }, + "403": { + "description": "Forbidden - You do not have permission to perform this action", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + }, + "429": { + "description": "Too Many Requests - You are being rate limited", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ThrottledError"}}}, + "headers": { + "Retry-After": { + "description": "Number of seconds to wait before retrying (only on 429)", + "schema": {"type": "integer"} + }, + "X-RateLimit-Limit": { + "description": "The number of requests that can be made in the current window", + "schema": {"type": "integer"} + }, + "X-RateLimit-Remaining": { + "description": "The number of remaining requests that can be made", + "schema": {"type": "integer"} + }, + "X-RateLimit-Reset": { + "description": "Unix timestamp when the rate limit resets", + "schema": {"type": "integer"} + } + } + }, + "500": { + "description": "Internal Server Error - An unexpected error occurred", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + } + }, + "description": "Mark or unmark a user as a system account. System accounts have special permissions for automated operations. Creates audit log entry. Requires USER_UPDATE_BOT_STATUS permission.", + "security": [{"adminApiKey": []}], + "parameters": [ + { + "name": "user_id", + "in": "path", + "required": true, + "schema": {"description": "The ID of the user", "allOf": [{"$ref": "#/components/schemas/SnowflakeType"}]}, + "description": "The ID of the user" + } + ], + "requestBody": { + "required": true, + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdminUserSystemStatusRequest"}}} + } + } + }, "/admin/users/{user_id}/traits": { "put": { "operationId": "set_admin_user_traits", @@ -9413,6 +9545,13 @@ }, "required": ["traits"] }, + "AdminUserSystemStatusRequest": { + "type": "object", + "properties": { + "system": {"type": "boolean", "description": "Whether the user should be marked as a system user"} + }, + "required": ["system"] + }, "AdminStorePurchaseListResponse": { "type": "object", "properties": { @@ -9877,6 +10016,11 @@ "required": ["entries", "next_page_token"], "additionalProperties": false }, + "AdminUserBotStatusRequest": { + "type": "object", + "properties": {"bot": {"type": "boolean", "description": "Whether the user should be marked as a bot"}}, + "required": ["bot"] + }, "AdminUserBanNoteRequest": { "type": "object", "properties": { @@ -9991,7 +10135,7 @@ "type": "object", "properties": { "acls": { - "maxItems": 105, + "maxItems": 106, "type": "array", "items": {"$ref": "#/components/schemas/AdminAclType"}, "description": "List of access control permissions to assign" @@ -12892,7 +13036,7 @@ }, "acls": { "description": "Replacement list of access control permissions for the key", - "maxItems": 105, + "maxItems": 106, "type": "array", "items": {"$ref": "#/components/schemas/AdminAclType"} } @@ -12910,7 +13054,7 @@ "type": "string" }, "acls": { - "maxItems": 105, + "maxItems": 106, "type": "array", "items": {"type": "string"}, "description": "List of access control permissions for the key" @@ -12940,7 +13084,7 @@ "maximum": 365 }, "acls": { - "maxItems": 105, + "maxItems": 106, "type": "array", "items": {"$ref": "#/components/schemas/AdminAclType"}, "description": "List of access control permissions for the key" @@ -12961,7 +13105,7 @@ "type": "string" }, "acls": { - "maxItems": 105, + "maxItems": 106, "type": "array", "items": {"type": "string"}, "description": "List of access control permissions for the key" @@ -12974,7 +13118,7 @@ "type": "object", "properties": { "acls": { - "maxItems": 105, + "maxItems": 106, "type": "array", "items": {"type": "string", "minLength": 1, "maxLength": 64}, "description": "Every admin access control permission the admin API recognises" @@ -13076,6 +13220,7 @@ "user:view:email", "user:view:ip", "user:temp_ban", + "user:update:bot_status", "user:update:dob", "user:update:email", "user:update:flags", @@ -16123,7 +16268,7 @@ "description": "ISO 8601 timestamp when the pending deletion was scheduled", "type": "string" }, - "acls": {"maxItems": 105, "type": "array", "items": {"type": "string"}}, + "acls": {"maxItems": 106, "type": "array", "items": {"type": "string"}}, "traits": {"maxItems": 100, "type": "array", "items": {"type": "string"}}, "has_totp": {"type": "boolean"}, "authenticator_types": {"maxItems": 10, "type": "array", "items": {"$ref": "#/components/schemas/Int32Type"}}, diff --git a/fluxer_admin/src/acl.rs b/fluxer_admin/src/acl.rs index 9683da57d..2e8889579 100644 --- a/fluxer_admin/src/acl.rs +++ b/fluxer_admin/src/acl.rs @@ -90,6 +90,7 @@ pub const USER_VIEW_DOB: &str = "user:view:dob"; pub const USER_VIEW_EMAIL: &str = "user:view:email"; pub const USER_VIEW_IP: &str = "user:view:ip"; pub const USER_TEMP_BAN: &str = "user:temp_ban"; +pub const USER_UPDATE_BOT_STATUS: &str = "user:update:bot_status"; pub const USER_UPDATE_DOB: &str = "user:update:dob"; pub const USER_UPDATE_EMAIL: &str = "user:update:email"; pub const USER_UPDATE_FLAGS: &str = "user:update:flags"; @@ -196,6 +197,7 @@ pub const ALL_ACLS: &[&str] = &[ USER_VIEW_EMAIL, USER_VIEW_IP, USER_TEMP_BAN, + USER_UPDATE_BOT_STATUS, USER_UPDATE_DOB, USER_UPDATE_EMAIL, USER_UPDATE_FLAGS, diff --git a/fluxer_admin/src/api/users.rs b/fluxer_admin/src/api/users.rs index 578f910ab..43f5170d3 100644 --- a/fluxer_admin/src/api/users.rs +++ b/fluxer_admin/src/api/users.rs @@ -306,6 +306,28 @@ impl AdminApiClient { Ok(resp.user) } + pub async fn set_bot_status(&self, user_id: &str, is_bot: bool) -> ApiResult { + let body = generated_types::AdminUserBotStatusRequest { bot: is_bot }; + let response = self + .generated() + .set_admin_user_bot_status(&snowflake(user_id), &body) + .await + .map_err(|e| self.generated_error(e))?; + let resp: UserMutationResponse = self.generated_value(response.into_inner())?; + Ok(resp.user) + } + + pub async fn set_system_status(&self, user_id: &str, is_system: bool) -> ApiResult { + let body = generated_types::AdminUserSystemStatusRequest { system: is_system }; + let response = self + .generated() + .set_admin_user_system_status(&snowflake(user_id), &body) + .await + .map_err(|e| self.generated_error(e))?; + let resp: UserMutationResponse = self.generated_value(response.into_inner())?; + Ok(resp.user) + } + pub async fn change_username( &self, user_id: &str, diff --git a/fluxer_admin/src/routes/user_actions.rs b/fluxer_admin/src/routes/user_actions.rs index 59f2f1e1f..76a96a021 100644 --- a/fluxer_admin/src/routes/user_actions.rs +++ b/fluxer_admin/src/routes/user_actions.rs @@ -178,6 +178,22 @@ pub async fn dispatch( "Failed to clear user fields", ) } + "set_bot_status" => { + let val = form.bool_value("bot"); + DispatchOutcome::from_result( + client.set_bot_status(user_id, val).await, + "Bot status updated successfully", + "Failed to update bot status", + ) + } + "set_system_status" => { + let val = form.bool_value("system"); + DispatchOutcome::from_result( + client.set_system_status(user_id, val).await, + "System status updated successfully", + "Failed to update system status", + ) + } "change_username" => { let Some(username) = get("username") else { return DispatchOutcome::error("Username is required"); diff --git a/fluxer_admin/src/templates/pages/user_detail_tabs/account.rs b/fluxer_admin/src/templates/pages/user_detail_tabs/account.rs index 3839e4890..00a7244f6 100644 --- a/fluxer_admin/src/templates/pages/user_detail_tabs/account.rs +++ b/fluxer_admin/src/templates/pages/user_detail_tabs/account.rs @@ -52,6 +52,7 @@ pub fn account_tab( (sessions_card(config, sessions)) (quick_actions_card(base, user, csrf_token, username_sign_in, can_revoke_recovery_kit)) (clear_fields_card(base, user, csrf_token)) + (user_status_card(base, user, csrf_token)) (security_actions_card(base, user, csrf_token)) (webauthn_credentials_card(base, user, webauthn_credentials, csrf_token)) } @@ -310,6 +311,19 @@ fn clear_fields_card(base: &str, user: &AdminUser, csrf_token: &str) -> Markup { } } +fn user_status_card(base: &str, user: &AdminUser, csrf_token: &str) -> Markup { + let is_bot = user.bot; + let is_sys = user.system; + html! { + (card_with_header("User Status", html! { + div class="grid grid-cols-1 gap-4 md:grid-cols-2" { + (status_toggle(base, &user.id, "set_bot_status", is_bot, "bot", csrf_token)) + (status_toggle(base, &user.id, "set_system_status", is_sys, "system", csrf_token)) + } + })) + } +} + fn security_actions_card(base: &str, user: &AdminUser, csrf_token: &str) -> Markup { html! { (card_with_header("Security Actions", html! { @@ -450,3 +464,40 @@ fn action_form( } } } + +fn status_toggle( + base: &str, + uid: &str, + action: &str, + active: bool, + kind: &str, + csrf: &str, +) -> Markup { + let status_val = if active { "false" } else { "true" }; + let label = format!( + "{} {} Status", + if active { "Remove" } else { "Set" }, + capitalize(kind) + ); + let action_url = format!("{base}/users/{uid}?action={action}&status={status_val}&tab=account"); + html! { + form method="post" + action=(&action_url) + hx-post=(&action_url) + hx-target="#flash-container" + hx-swap="none" + hx-push-url="false" { + (csrf_input(csrf)) + input type="hidden" name=(kind) value=(status_val); + button type="submit" class=(BTN_CLS) { (label) } + } + } +} + +fn capitalize(s: &str) -> String { + let mut c = s.chars(); + match c.next() { + None => String::new(), + Some(f) => f.to_uppercase().chain(c).collect(), + } +} diff --git a/fluxer_admin/src/templates/pages/user_detail_tabs/overview.rs b/fluxer_admin/src/templates/pages/user_detail_tabs/overview.rs index d9ea1c0dd..92f0ab715 100644 --- a/fluxer_admin/src/templates/pages/user_detail_tabs/overview.rs +++ b/fluxer_admin/src/templates/pages/user_detail_tabs/overview.rs @@ -437,6 +437,11 @@ fn acls_card( (flag_checkbox("acls[]", item.to_string(), item, checked, true)) } } + @for item in &user.acls { + @if !acl::ALL_ACLS.iter().any(|known| known == &item.as_str()) { + input type="hidden" name="acls[]" value=(item); + } + } (form_actions(html! { (submit_button("Save ACLs")) })) diff --git a/fluxer_api/src/api/admin/controllers/UserAdminController.ts b/fluxer_api/src/api/admin/controllers/UserAdminController.ts index c42a68778..cb2340d53 100644 --- a/fluxer_api/src/api/admin/controllers/UserAdminController.ts +++ b/fluxer_api/src/api/admin/controllers/UserAdminController.ts @@ -24,6 +24,7 @@ import { AdminUserAclsRequest, AdminUserBanNoteRequest, AdminUserBanRequest, + AdminUserBotStatusRequest, AdminUserChangeLogQuery, AdminUserClearFieldsRequest, AdminUserDeletionCancelRequest, @@ -38,6 +39,7 @@ import { AdminUserPremiumFlagsUpdateRequest, AdminUserRelationshipCategoryQuery, AdminUserRelationshipParam, + AdminUserSystemStatusRequest, AdminUsersMeResponse, AdminUserTraitsRequest, AdminUserUnbanRequest, @@ -601,6 +603,70 @@ export function UserAdminController(app: HonoApp) { ); }, ); + app.put( + '/admin/users/:user_id/bot-status', + RateLimitMiddleware(RateLimitConfigs.ADMIN_USER_MODIFY), + requireAdminACL(AdminACLs.USER_UPDATE_BOT_STATUS), + Validator('param', UserIdParam), + Validator('json', AdminUserBotStatusRequest), + OpenAPI({ + operationId: 'set_admin_user_bot_status', + summary: 'Set user bot status', + responseSchema: UserMutationResponse, + statusCode: 200, + security: 'adminApiKey', + tags: 'Admin', + description: + 'Mark or unmark a user account as a bot. Controls bot badge visibility and API permissions. Creates audit log entry. Requires USER_UPDATE_BOT_STATUS permission.', + }), + async (ctx) => { + const adminService = ctx.get('adminService'); + const adminUserId = ctx.get('adminUserId'); + const auditLogReason = ctx.get('auditLogReason'); + const adminUserAcls = ctx.get('adminUserAcls'); + const {user_id: userId} = ctx.req.valid('param'); + return ctx.json( + await adminService.userService.profileService.setUserBotStatus( + {user_id: userId, ...ctx.req.valid('json')}, + adminUserId, + auditLogReason, + adminUserAcls, + ), + ); + }, + ); + app.put( + '/admin/users/:user_id/system-status', + RateLimitMiddleware(RateLimitConfigs.ADMIN_USER_MODIFY), + requireAdminACL(AdminACLs.USER_UPDATE_BOT_STATUS), + Validator('param', UserIdParam), + Validator('json', AdminUserSystemStatusRequest), + OpenAPI({ + operationId: 'set_admin_user_system_status', + summary: 'Set user system status', + responseSchema: UserMutationResponse, + statusCode: 200, + security: 'adminApiKey', + tags: 'Admin', + description: + 'Mark or unmark a user as a system account. System accounts have special permissions for automated operations. Creates audit log entry. Requires USER_UPDATE_BOT_STATUS permission.', + }), + async (ctx) => { + const adminService = ctx.get('adminService'); + const adminUserId = ctx.get('adminUserId'); + const auditLogReason = ctx.get('auditLogReason'); + const adminUserAcls = ctx.get('adminUserAcls'); + const {user_id: userId} = ctx.req.valid('param'); + return ctx.json( + await adminService.userService.profileService.setUserSystemStatus( + {user_id: userId, ...ctx.req.valid('json')}, + adminUserId, + auditLogReason, + adminUserAcls, + ), + ); + }, + ); app.patch( '/admin/users/:user_id/username', RateLimitMiddleware(RateLimitConfigs.ADMIN_USER_MODIFY), diff --git a/fluxer_api/src/api/admin/services/AdminUserProfileService.ts b/fluxer_api/src/api/admin/services/AdminUserProfileService.ts index 6ec3f4a3f..e32a6b333 100644 --- a/fluxer_api/src/api/admin/services/AdminUserProfileService.ts +++ b/fluxer_api/src/api/admin/services/AdminUserProfileService.ts @@ -15,6 +15,9 @@ import type {User} from '@app/api/models/User'; import {enqueueStripeCustomerEmailSync} from '@app/api/stripe/StripeCustomer'; import {assertNoDiscriminatorChange, reserveUsername, type UsernameReservation} from '@app/api/user/UniqueUsernames'; import {USERNAME_MODE_DISCRIMINATOR} from '@app/api/user/UserTag'; +import {ValidationErrorCodes} from '@fluxer/constants/src/ValidationErrorCodes'; +import {AccessDeniedError} from '@fluxer/errors/src/domains/core/AccessDeniedError'; +import {InputValidationError} from '@fluxer/errors/src/domains/core/InputValidationError'; import {TagAlreadyTakenError} from '@fluxer/errors/src/domains/user/TagAlreadyTakenError'; import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError'; import type { @@ -22,6 +25,8 @@ import type { ChangeEmailRequest, ChangeUsernameRequest, ClearUserFieldsRequest, + SetUserBotStatusRequest, + SetUserSystemStatusRequest, VerifyUserEmailRequest, } from '@fluxer/schema/src/domains/admin/AdminUserSchemas'; import {types} from 'cassandra-driver'; @@ -104,6 +109,75 @@ export class AdminUserProfileService { }; } + async setUserBotStatus( + data: SetUserBotStatusRequest, + adminUserId: UserID, + auditLogReason: string | null, + acls: ReadonlySet, + ) { + const {users: userRepository, cache: cacheService} = this.deps.apiContext.services; + const {auditService, updatePropagator} = this.deps; + const userId = createUserID(data.user_id); + const user = await userRepository.findUnique(userId); + if (!user) { + throw new UnknownUserError(); + } + if (data.bot && user.acls.size > 0) { + throw new AccessDeniedError(); + } + const updates: Record = {bot: data.bot}; + if (!data.bot) { + updates['system'] = false; + } + const updatedUser = await userRepository.patchUpsert(userId, updates, user.toRow()); + await updatePropagator.propagateUserUpdate({userId, oldUser: user, updatedUser: updatedUser}); + await auditService.createAuditLog({ + adminUserId, + targetType: 'user', + targetId: BigInt(userId), + action: 'set_bot_status', + auditLogReason, + metadata: new Map([['bot', data.bot.toString()]]), + }); + return { + user: await mapUserToAdminResponse(updatedUser, cacheService, acls), + }; + } + + async setUserSystemStatus( + data: SetUserSystemStatusRequest, + adminUserId: UserID, + auditLogReason: string | null, + acls: ReadonlySet, + ) { + const {users: userRepository, cache: cacheService} = this.deps.apiContext.services; + const {auditService, updatePropagator} = this.deps; + const userId = createUserID(data.user_id); + const user = await userRepository.findUnique(userId); + if (!user) { + throw new UnknownUserError(); + } + if (data.system && !user.isBot) { + throw InputValidationError.fromCode( + 'system', + ValidationErrorCodes.USER_MUST_BE_A_BOT_TO_BE_MARKED_AS_A_SYSTEM_USER, + ); + } + const updatedUser = await userRepository.patchUpsert(userId, {system: data.system}, user.toRow()); + await updatePropagator.propagateUserUpdate({userId, oldUser: user, updatedUser: updatedUser}); + await auditService.createAuditLog({ + adminUserId, + targetType: 'user', + targetId: BigInt(userId), + action: 'set_system_status', + auditLogReason, + metadata: new Map([['system', data.system.toString()]]), + }); + return { + user: await mapUserToAdminResponse(updatedUser, cacheService, acls), + }; + } + async verifyUserEmail( data: VerifyUserEmailRequest, adminUserId: UserID, diff --git a/fluxer_api/src/api/admin/tests/AdminEndpointsAuthorization.test.ts b/fluxer_api/src/api/admin/tests/AdminEndpointsAuthorization.test.ts index bbcb41450..c3e6f1377 100644 --- a/fluxer_api/src/api/admin/tests/AdminEndpointsAuthorization.test.ts +++ b/fluxer_api/src/api/admin/tests/AdminEndpointsAuthorization.test.ts @@ -78,6 +78,7 @@ const adminEndpoints: Array = [ {method: 'GET', path: '/admin/users/1/webauthn-credentials', requiredACL: 'user:update:mfa'}, {method: 'DELETE', path: '/admin/users/1/webauthn-credentials/credential', requiredACL: 'user:update:mfa'}, {method: 'DELETE', path: '/admin/users/1/profile-fields', requiredACL: 'user:update:profile'}, + {method: 'PUT', path: '/admin/users/1/bot-status', requiredACL: 'user:update:bot_status'}, {method: 'PUT', path: '/admin/users/1/acls', requiredACL: 'acl:set:user'}, {method: 'PUT', path: '/admin/users/1/deletion', requiredACL: 'user:delete'}, {method: 'POST', path: '/admin/users/1/avatar-block', requiredACL: 'ban:avatar_hash:add'}, diff --git a/fluxer_api/src/api/admin/tests/AdminSyntheticUserMutations.test.ts b/fluxer_api/src/api/admin/tests/AdminSyntheticUserMutations.test.ts index 9074b723f..a3113b5e4 100644 --- a/fluxer_api/src/api/admin/tests/AdminSyntheticUserMutations.test.ts +++ b/fluxer_api/src/api/admin/tests/AdminSyntheticUserMutations.test.ts @@ -20,6 +20,8 @@ const MUTATIONS: Array<{verb: 'put' | 'patch' | 'delete'; path: string; acl: str {verb: 'put', path: 'ban', acl: AdminACLs.USER_TEMP_BAN, body: {duration_hours: 1, reason: 'test'}}, {verb: 'put', path: 'deletion', acl: AdminACLs.USER_DELETE, body: {delay_days: 1}}, {verb: 'delete', path: 'profile-fields', acl: AdminACLs.USER_UPDATE_PROFILE, body: {fields: ['bio']}}, + {verb: 'put', path: 'bot-status', acl: AdminACLs.USER_UPDATE_BOT_STATUS, body: {bot: true}}, + {verb: 'put', path: 'system-status', acl: AdminACLs.USER_UPDATE_BOT_STATUS, body: {system: true}}, ]; const CASES = SYNTHETIC_USER_IDS.flatMap((userId) => diff --git a/fluxer_api/src/api/admin/tests/audit_coverage/UserWriteAdminAuditCases.ts b/fluxer_api/src/api/admin/tests/audit_coverage/UserWriteAdminAuditCases.ts index ce89639c6..12c8f3462 100644 --- a/fluxer_api/src/api/admin/tests/audit_coverage/UserWriteAdminAuditCases.ts +++ b/fluxer_api/src/api/admin/tests/audit_coverage/UserWriteAdminAuditCases.ts @@ -191,6 +191,39 @@ export const UserWriteAdminAuditCases: ReadonlyArray = [ }; }, }, + { + method: 'PUT', + route: '/admin/users/:user_id/bot-status', + async prepare({harness}) { + const target = await createTestAccount(harness); + return { + request: {path: `/admin/users/${target.userId}/bot-status`, body: {bot: true}}, + expected: { + action: 'set_bot_status', + targetType: 'user', + targetId: target.userId, + metadata: {bot: 'true'}, + }, + }; + }, + }, + { + method: 'PUT', + route: '/admin/users/:user_id/system-status', + async prepare(context) { + const target = await createTestAccount(context.harness); + await adminBuilder(context).put(`/admin/users/${target.userId}/bot-status`).body({bot: true}).execute(); + return { + request: {path: `/admin/users/${target.userId}/system-status`, body: {system: true}}, + expected: { + action: 'set_system_status', + targetType: 'user', + targetId: target.userId, + metadata: {system: 'true'}, + }, + }; + }, + }, { method: 'PATCH', route: '/admin/users/:user_id/username', diff --git a/fluxer_docs/src/content/docs/admin-api/api-keys.mdx b/fluxer_docs/src/content/docs/admin-api/api-keys.mdx index 7dafa01ea..ab934e16c 100644 --- a/fluxer_docs/src/content/docs/admin-api/api-keys.mdx +++ b/fluxer_docs/src/content/docs/admin-api/api-keys.mdx @@ -140,7 +140,7 @@ The acting credential must already have every value in `acls`, unless it has `*` | --- | --- | --- | | name1 | string | The name given to the key (1-100 characters) | | expires_in_days?2 | integer | The number of days until the key expires (1-365) | -| acls3 | array[string] | The [ACLs](/admin-api/#acl-registry) stored on the key, each a registry value (at most 103) | +| acls3 | array[string] | The [ACLs](/admin-api/#acl-registry) stored on the key, each a registry value (at most 106) | 1 A value that is empty after trimming is rejected, so whitespace alone is not a name @@ -218,7 +218,7 @@ An update never rotates the credential, and no field on this route changes the e | Field | Type | Description | | --- | --- | --- | | name?1 | string | The replacement name for the key (1-100 characters) | -| acls?2 | array[string] | The complete replacement set of [ACLs](/admin-api/#acl-registry), each a registry value (at most 103) | +| acls?2 | array[string] | The complete replacement set of [ACLs](/admin-api/#acl-registry), each a registry value (at most 106) | 1 A value that is empty after trimming is rejected diff --git a/fluxer_docs/src/content/docs/admin-api/index.mdx b/fluxer_docs/src/content/docs/admin-api/index.mdx index 7740b0ae3..6c45ec895 100644 --- a/fluxer_docs/src/content/docs/admin-api/index.mdx +++ b/fluxer_docs/src/content/docs/admin-api/index.mdx @@ -61,7 +61,7 @@ A body with none of those fields resolves to no ACL at all and applies no change Fluxer checks each ACL an Admin grants against the ACLs that Admin holds. [Set user ACLs](/admin-api/users/#set-user-acls) and [Create Admin API key](/admin-api/api-keys/#create-admin-api-key) both refuse to write an ACL the acting Admin does not itself hold, with 403 `MISSING_ACL`. A wildcard holder is exempt. Set user ACLs also refuses the acting Admin's own account with 403 `ACCESS_DENIED`, and it looks up the target account before it checks the granted ACLs, so an unknown ID fails first with 404 `UNKNOWN_USER`. -[Set user ACLs](/admin-api/users/#set-user-acls), [Create Admin API key](/admin-api/api-keys/#create-admin-api-key), and [Update Admin API key](/admin-api/api-keys/#update-admin-api-key) each accept at most 103 ACLs and validate every entry against the registry, so a value outside it returns 400 `INVALID_FORM_BODY`. +[Set user ACLs](/admin-api/users/#set-user-acls), [Create Admin API key](/admin-api/api-keys/#create-admin-api-key), and [Update Admin API key](/admin-api/api-keys/#update-admin-api-key) each accept at most 106 ACLs and validate every entry against the registry, so a value outside it returns 400 `INVALID_FORM_BODY`. :::caution[`*` satisfies every present and future ACL] A key whose owning account holds `*` skips the owner check. An Admin holding `*` can grant any ACL. @@ -375,6 +375,8 @@ An entry with any other action has `access` set to `write`. | schedule_deletion | Account deletion was scheduled | | send_password_reset | A password reset message was requested for an account | | set_acls | The Admin ACL set of an account was replaced | +| set_bot_status | The bot flag of an account was changed | +| set_system_status | The system flag of an account was changed | | set_traits | Account traits were replaced | | shutdown_guild | One guild was stopped on the main Gateway | | system_dm.send | A system DM broadcast was created | @@ -476,7 +478,7 @@ Returns every Admin permission string the instance recognises, in [ACL registry] | Field | Type | Description | | --- | --- | --- | -| acls1 | array[string] | The permission strings the Admin API recognises (at most 103 entries) | +| acls1 | array[string] | The permission strings the Admin API recognises (at most 106 entries) | 1 The response is the registry itself and does not vary with the caller's own ACL set @@ -591,6 +593,7 @@ The registry is returned in this order by [List ACLs](#list-acls). A value outsi | user:view:email6 | Unredacts user email addresses and email verification state | | user:view:ip6 | Unredacts the last active IP address and the location derived from it | | user:temp_ban | Applies and removes an account ban | +| user:update:bot_status | Updates bot and system account state | | user:update:dob | Updates dates of birth | | user:update:email | Updates the email address, marks the address verified, resends verification, and sends a password reset | | user:update:flags | Updates account flags and premium flags, refreshes in-app purchases, and ends every login session of an account | diff --git a/fluxer_docs/src/content/docs/admin-api/users.mdx b/fluxer_docs/src/content/docs/admin-api/users.mdx index 6b035e2bb..995b77a13 100644 --- a/fluxer_docs/src/content/docs/admin-api/users.mdx +++ b/fluxer_docs/src/content/docs/admin-api/users.mdx @@ -59,7 +59,7 @@ When the caller lacks `user:view:email`, `user:view:dob`, or `user:view:ip`, Flu | deletion_audit_log_reason | ?string | The private reason stored with the pending deletion, and null without `audit_log:view` | | deletion_scheduled_by | ?snowflake | The ID of the account that scheduled the pending deletion, or null when it was not recorded | | deletion_scheduled_at | ?ISO8601 timestamp | The time the pending deletion was scheduled, or null when it was not recorded | -| acls7 | array[string] | Effective [Admin ACLs](/admin-api/#acl-registry), with at most 103 entries | +| acls7 | array[string] | Effective [Admin ACLs](/admin-api/#acl-registry), with at most 106 entries | | traits8 | array[string] | The free-form operator labels set on the account, with at most 100 entries | | has_totp9 | boolean | Whether a TOTP authenticator is registered | | authenticator_types9 12 | array[integer] | Registered [authenticator types](/http-api/users/#authenticator-types), with at most 10 entries | @@ -1030,6 +1030,97 @@ The operation records one [Admin audit entry](/admin-api/#admin-audit-entry-obje 100 requests per minute for each authenticated user, on the `admin:user:modify` bucket. +## Set user bot status + + + +Marks the account as a bot or as an ordinary account, and returns the resulting account. Requires `user:update:bot_status`. + +### Path parameters + +| Field | Type | Description | +| --- | --- | --- | +| user_id | snowflake | The ID of the target account | + +### JSON body + +| Field | Type | Description | +| --- | --- | --- | +| bot1 | boolean | Whether the account is a bot | + +1 Required. Setting it to false also clears `system` in the same write + +### Response body + +| Field | Type | Description | +| --- | --- | --- | +| user | [Admin user](#admin-user-object) object | The resulting account | + +### Response + +| Status | Body | Condition | +| --- | --- | --- | +| 200 | response body | Bot status was set | +| 4031 | [error response](/admin-api/#error-response) | Credential type or ACL evaluation denies the request. `ACCESS_DENIED` when the target holds an Admin ACL and `bot` is true | +| 404 | [error response](/admin-api/#error-response) | `UNKNOWN_USER`, because the account does not exist | + +1 A staff account cannot be converted into a bot. Clear its ACL set with [Set user ACLs](#set-user-acls) first + +### Side effects + +[User Update](/gateway/events/#user-update) is emitted to the account's own sessions, and each guild the account is a member of receives [Guild Member Update](/gateway/events/#guild-member-update) when the write changes `bot` or `system`. + +The operation records one [Admin audit entry](/admin-api/#admin-audit-entry-object) with action `set_bot_status`, target type `user`, and a metadata key `bot`. Clearing `system` as a side effect records no second entry. + +### Rate limit + +100 requests per minute for each authenticated user, on the `admin:user:modify` bucket. + +## Set user system status + + + +Marks the account as an official system account or removes that marker, and returns the resulting account. Requires `user:update:bot_status`, the same ACL as [Set user bot status](#set-user-bot-status). + +### Path parameters + +| Field | Type | Description | +| --- | --- | --- | +| user_id | snowflake | The ID of the target account | + +### JSON body + +| Field | Type | Description | +| --- | --- | --- | +| system1 | boolean | Whether the account is a system account | + +1 Required. Setting it to true on an account that is not already a bot fails validation + +### Response body + +| Field | Type | Description | +| --- | --- | --- | +| user | [Admin user](#admin-user-object) object | The resulting account | + +### Response + +| Status | Body | Condition | +| --- | --- | --- | +| 200 | response body | System status was set | +| 404 | [error response](/admin-api/#error-response) | `UNKNOWN_USER`, because the account does not exist | + +1 The non-bot case is `INVALID_FORM_BODY` with the validation code `USER_MUST_BE_A_BOT_TO_BE_MARKED_AS_A_SYSTEM_USER` on the `system` path + +### Side effects + +[User Update](/gateway/events/#user-update) is emitted to the account's own sessions, and each guild the account is a member of receives [Guild Member Update](/gateway/events/#guild-member-update) when the write changes `system`. + +The operation records one [Admin audit entry](/admin-api/#admin-audit-entry-object) with action `set_system_status`, target type `user`, and a metadata key `system`. + +### Rate limit + +100 requests per minute for each authenticated user, on the `admin:user:modify` bucket. + ## Set user ACLs @@ -1056,7 +1147,7 @@ A path naming the acting account fails with 403 `ACCESS_DENIED` before the accou | Field | Type | Description | | --- | --- | --- | -| acls1 | array[string] | Replacement [Admin ACLs](/admin-api/#acl-registry), with at most 103 values | +| acls1 | array[string] | Replacement [Admin ACLs](/admin-api/#acl-registry), with at most 106 values | 1 Required. A value outside the [ACL registry](/admin-api/#acl-registry) fails body validation, and a repeated value is collapsed diff --git a/fluxer_docs/src/content/docs/http-api/errors.md b/fluxer_docs/src/content/docs/http-api/errors.md index 796d6783e..6c2aaf841 100644 --- a/fluxer_docs/src/content/docs/http-api/errors.md +++ b/fluxer_docs/src/content/docs/http-api/errors.md @@ -2081,6 +2081,10 @@ This user doesn't have an email address This user isn't banned +### `USER_MUST_BE_A_BOT_TO_BE_MARKED_AS_A_SYSTEM_USER` + +User must be a bot to be marked as a system user + ### `USER_NOT_IN_CHANNEL` This user isn't in the channel diff --git a/packages/constants/src/AdminACLs.ts b/packages/constants/src/AdminACLs.ts index 39aec7b28..14ae92145 100644 --- a/packages/constants/src/AdminACLs.ts +++ b/packages/constants/src/AdminACLs.ts @@ -91,6 +91,7 @@ export const AdminACLs = { USER_VIEW_EMAIL: 'user:view:email', USER_VIEW_IP: 'user:view:ip', USER_TEMP_BAN: 'user:temp_ban', + USER_UPDATE_BOT_STATUS: 'user:update:bot_status', USER_UPDATE_DOB: 'user:update:dob', USER_UPDATE_EMAIL: 'user:update:email', USER_UPDATE_FLAGS: 'user:update:flags', diff --git a/packages/constants/src/ValidationErrorCodes.ts b/packages/constants/src/ValidationErrorCodes.ts index 9b46f54d3..36c1c818d 100644 --- a/packages/constants/src/ValidationErrorCodes.ts +++ b/packages/constants/src/ValidationErrorCodes.ts @@ -213,6 +213,7 @@ export const ValidationErrorCodes = { URL_NOT_PUBLICLY_ROUTABLE: 'URL_NOT_PUBLICLY_ROUTABLE', USER_DOES_NOT_HAVE_AN_EMAIL_ADDRESS: 'USER_DOES_NOT_HAVE_AN_EMAIL_ADDRESS', USER_IS_NOT_BANNED: 'USER_IS_NOT_BANNED', + USER_MUST_BE_A_BOT_TO_BE_MARKED_AS_A_SYSTEM_USER: 'USER_MUST_BE_A_BOT_TO_BE_MARKED_AS_A_SYSTEM_USER', USER_NOT_IN_CHANNEL: 'USER_NOT_IN_CHANNEL', USERNAME_ALREADY_TAKEN: 'USERNAME_ALREADY_TAKEN', USERNAME_CANNOT_CONTAIN_RESERVED_TERMS: 'USERNAME_CANNOT_CONTAIN_RESERVED_TERMS', diff --git a/packages/errors/src/i18n/ErrorCodeMappings.ts b/packages/errors/src/i18n/ErrorCodeMappings.ts index bb1b5ea84..75368bcf8 100644 --- a/packages/errors/src/i18n/ErrorCodeMappings.ts +++ b/packages/errors/src/i18n/ErrorCodeMappings.ts @@ -432,6 +432,8 @@ export const ErrorCodeToI18nKey = { [ValidationErrorCodes.VISIONARY_REQUIRED_FOR_DISCRIMINATOR]: 'premium_and_plans.visionary_required_for_discriminator', [ValidationErrorCodes.BOT_DISCRIMINATOR_CANNOT_BE_CHANGED]: 'bots.bot_discriminator_cannot_be_changed', [ValidationErrorCodes.BOT_SEARCH_SCOPE_UNAVAILABLE]: 'bots.search_scope_unavailable', + [ValidationErrorCodes.USER_MUST_BE_A_BOT_TO_BE_MARKED_AS_A_SYSTEM_USER]: + 'admin_and_system.user_must_be_bot_for_system_user', [ValidationErrorCodes.USER_IS_NOT_BANNED]: 'moderation_and_reports.user_is_not_banned', [ValidationErrorCodes.NCMEC_ATTACHMENT_MUST_BE_IMAGE_OR_VIDEO]: 'moderation_and_reports.ncmec_attachment_must_be_image_or_video', diff --git a/packages/errors/src/i18n/ErrorI18nMessages.ts b/packages/errors/src/i18n/ErrorI18nMessages.ts index c10a27775..19e6fa554 100644 --- a/packages/errors/src/i18n/ErrorI18nMessages.ts +++ b/packages/errors/src/i18n/ErrorI18nMessages.ts @@ -44,6 +44,7 @@ export const ERROR_I18N_MESSAGES = { 'admin_and_system.test_harness_disabled': 'Test harness is disabled.', 'admin_and_system.test_harness_forbidden': 'Test harness is forbidden.', 'admin_and_system.update_failed': "We couldn't update the resource. Please try again.", + 'admin_and_system.user_must_be_bot_for_system_user': 'User must be a bot to be marked as a system user.', 'age_verification.already_verified': "You've already completed age verification.", 'attachments_and_uploads.attachment_fields_required': '`attachment_id`, `channel_id`, `message_id`, and `expires_at` are required.', diff --git a/packages/errors/src/i18n/locales/ar.ts b/packages/errors/src/i18n/locales/ar.ts index 73c550a4f..9cd874bb6 100644 --- a/packages/errors/src/i18n/locales/ar.ts +++ b/packages/errors/src/i18n/locales/ar.ts @@ -42,6 +42,7 @@ const ERROR_I18N_AR_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "أداة الاختبار معطلة.", "admin_and_system.test_harness_forbidden": "أداة الاختبار محظورة.", "admin_and_system.update_failed": "لم نتمكن من تحديث المورد. حاول مجددًا.", + "admin_and_system.user_must_be_bot_for_system_user": "يجب أن يكون المستخدم بوتًا ليتم تحديده كمستخدم نظام.", "age_verification.already_verified": "لقد أكملت التحقق من العمر بالفعل.", "attachments_and_uploads.attachment_fields_required": "`attachment_id` و`channel_id` و`message_id` و`expires_at` مطلوبة.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "يجب أن تكون `attachment_id` و`channel_id` و`message_id` أعدادًا صحيحة صالحة.", diff --git a/packages/errors/src/i18n/locales/bg.ts b/packages/errors/src/i18n/locales/bg.ts index 2291c6466..d381f119f 100644 --- a/packages/errors/src/i18n/locales/bg.ts +++ b/packages/errors/src/i18n/locales/bg.ts @@ -42,6 +42,7 @@ const ERROR_I18N_BG_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Тестовата система е деактивирана.", "admin_and_system.test_harness_forbidden": "Тестовата система е забранена.", "admin_and_system.update_failed": "Не успяхме да актуализираме ресурса. Опитай отново.", + "admin_and_system.user_must_be_bot_for_system_user": "Потребителят трябва да бъде бот, за да бъде маркиран като системен потребител.", "age_verification.already_verified": "Вече премина проверката за възраст.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` и `expires_at` са задължителни.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` и `message_id` трябва да са валидни цели числа.", diff --git a/packages/errors/src/i18n/locales/cs.ts b/packages/errors/src/i18n/locales/cs.ts index 13acd3169..477f90fea 100644 --- a/packages/errors/src/i18n/locales/cs.ts +++ b/packages/errors/src/i18n/locales/cs.ts @@ -42,6 +42,7 @@ const ERROR_I18N_CS_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Testovací prostředí je vypnuté.", "admin_and_system.test_harness_forbidden": "Přístup k testovacímu prostředí je zakázán.", "admin_and_system.update_failed": "Nepodařilo se aktualizovat zdroj. Zkuste to znovu.", + "admin_and_system.user_must_be_bot_for_system_user": "Uživatel musí být bot, aby mohl být označen jako systémový uživatel.", "age_verification.already_verified": "Ověření věku už bylo dokončeno.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` a `expires_at` jsou povinné.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` a `message_id` musí být platné celočíselné hodnoty.", diff --git a/packages/errors/src/i18n/locales/da.ts b/packages/errors/src/i18n/locales/da.ts index 5d5e4b5ea..782812756 100644 --- a/packages/errors/src/i18n/locales/da.ts +++ b/packages/errors/src/i18n/locales/da.ts @@ -42,6 +42,7 @@ const ERROR_I18N_DA_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Testmiljøet er deaktiveret.", "admin_and_system.test_harness_forbidden": "Adgang til testmiljøet er ikke tilladt.", "admin_and_system.update_failed": "Ressourcen kunne ikke opdateres. Prøv igen.", + "admin_and_system.user_must_be_bot_for_system_user": "Brugeren skal være en bot for at kunne markeres som systembruger.", "age_verification.already_verified": "Du har allerede gennemført aldersbekræftelse.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` og `expires_at` er påkrævet.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` og `message_id` skal være gyldige heltal.", diff --git a/packages/errors/src/i18n/locales/de.ts b/packages/errors/src/i18n/locales/de.ts index c672b1266..9633d5fbc 100644 --- a/packages/errors/src/i18n/locales/de.ts +++ b/packages/errors/src/i18n/locales/de.ts @@ -42,6 +42,7 @@ const ERROR_I18N_DE_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Test-Harness ist deaktiviert.", "admin_and_system.test_harness_forbidden": "Test-Harness ist verboten.", "admin_and_system.update_failed": "Wir konnten die Ressource nicht aktualisieren. Bitte versuche es erneut.", + "admin_and_system.user_must_be_bot_for_system_user": "Ein Benutzer muss ein Bot sein, um als Systembenutzer markiert zu werden.", "age_verification.already_verified": "Du hast die Altersbestätigung bereits abgeschlossen.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` und `expires_at` sind erforderlich.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` und `message_id` müssen gültige Ganzzahlen sein.", diff --git a/packages/errors/src/i18n/locales/el.ts b/packages/errors/src/i18n/locales/el.ts index 15a6c5360..ae1b880ae 100644 --- a/packages/errors/src/i18n/locales/el.ts +++ b/packages/errors/src/i18n/locales/el.ts @@ -42,6 +42,7 @@ const ERROR_I18N_EL_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Το test harness είναι απενεργοποιημένο.", "admin_and_system.test_harness_forbidden": "Το test harness απαγορεύεται.", "admin_and_system.update_failed": "Δεν μπορέσαμε να ενημερώσουμε τον πόρο. Δοκίμασε ξανά.", + "admin_and_system.user_must_be_bot_for_system_user": "Ο χρήστης πρέπει να είναι bot για να οριστεί ως χρήστης συστήματος.", "age_verification.already_verified": "Έχεις ήδη ολοκληρώσει την επαλήθευση ηλικίας.", "attachments_and_uploads.attachment_fields_required": "Τα `attachment_id`, `channel_id`, `message_id` και `expires_at` είναι υποχρεωτικά.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "Τα `attachment_id`, `channel_id` και `message_id` πρέπει να είναι έγκυροι ακέραιοι αριθμοί.", diff --git a/packages/errors/src/i18n/locales/en-GB.ts b/packages/errors/src/i18n/locales/en-GB.ts index 2b67e15e2..55cff2a89 100644 --- a/packages/errors/src/i18n/locales/en-GB.ts +++ b/packages/errors/src/i18n/locales/en-GB.ts @@ -42,6 +42,7 @@ const ERROR_I18N_EN_GB_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Test harness is disabled.", "admin_and_system.test_harness_forbidden": "Test harness is forbidden.", "admin_and_system.update_failed": "We couldn't update the resource. Please try again.", + "admin_and_system.user_must_be_bot_for_system_user": "User must be a bot to be marked as a system user.", "age_verification.already_verified": "You've already completed age verification.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, and `expires_at` are required.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, and `message_id` must be valid integers.", diff --git a/packages/errors/src/i18n/locales/es-419.ts b/packages/errors/src/i18n/locales/es-419.ts index 007c45186..214f7c014 100644 --- a/packages/errors/src/i18n/locales/es-419.ts +++ b/packages/errors/src/i18n/locales/es-419.ts @@ -42,6 +42,7 @@ const ERROR_I18N_ES_419_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "El entorno de prueba está deshabilitado.", "admin_and_system.test_harness_forbidden": "El entorno de prueba está prohibido.", "admin_and_system.update_failed": "No se pudo actualizar el recurso. Inténtalo de nuevo.", + "admin_and_system.user_must_be_bot_for_system_user": "El usuario debe ser un bot para ser marcado como usuario del sistema.", "age_verification.already_verified": "Ya completaste la verificación de edad.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` y `expires_at` son obligatorios.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` y `message_id` deben ser enteros válidos.", diff --git a/packages/errors/src/i18n/locales/es-ES.ts b/packages/errors/src/i18n/locales/es-ES.ts index 3d5852ee8..21fb1eb63 100644 --- a/packages/errors/src/i18n/locales/es-ES.ts +++ b/packages/errors/src/i18n/locales/es-ES.ts @@ -42,6 +42,7 @@ const ERROR_I18N_ES_ES_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "El entorno de pruebas está deshabilitado.", "admin_and_system.test_harness_forbidden": "El entorno de pruebas está prohibido.", "admin_and_system.update_failed": "No se pudo actualizar el recurso. Inténtalo de nuevo.", + "admin_and_system.user_must_be_bot_for_system_user": "El usuario debe ser un bot para ser marcado como usuario del sistema.", "age_verification.already_verified": "Ya has completado la verificación de edad.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` y `expires_at` son obligatorios.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` y `message_id` deben ser enteros válidos.", diff --git a/packages/errors/src/i18n/locales/fi.ts b/packages/errors/src/i18n/locales/fi.ts index 6a84424c1..faf85e1e6 100644 --- a/packages/errors/src/i18n/locales/fi.ts +++ b/packages/errors/src/i18n/locales/fi.ts @@ -42,6 +42,7 @@ const ERROR_I18N_FI_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Testausympäristö on poistettu käytöstä.", "admin_and_system.test_harness_forbidden": "Testausympäristö on kielletty.", "admin_and_system.update_failed": "Resurssia ei voitu päivittää. Yritä uudelleen.", + "admin_and_system.user_must_be_bot_for_system_user": "Käyttäjän on oltava botti, jotta sen voi merkitä järjestelmäkäyttäjäksi.", "age_verification.already_verified": "Olet jo suorittanut iän vahvistuksen.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` ja `expires_at` ovat pakollisia.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "Seuraavien kenttien arvojen on oltava kelvollisia kokonaislukuja: `attachment_id`, `channel_id` ja `message_id`.", diff --git a/packages/errors/src/i18n/locales/fr.ts b/packages/errors/src/i18n/locales/fr.ts index 8eae0bfe0..fa6511e17 100644 --- a/packages/errors/src/i18n/locales/fr.ts +++ b/packages/errors/src/i18n/locales/fr.ts @@ -42,6 +42,7 @@ const ERROR_I18N_FR_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Le banc de test est désactivé.", "admin_and_system.test_harness_forbidden": "Le banc de test est interdit.", "admin_and_system.update_failed": "Impossible de mettre à jour la ressource. Réessayez.", + "admin_and_system.user_must_be_bot_for_system_user": "L'utilisateur doit être un bot pour être marqué comme utilisateur système.", "age_verification.already_verified": "Vous avez déjà effectué la vérification de l’âge.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` et `expires_at` sont nécessaires.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` et `message_id` doivent être des entiers valides.", diff --git a/packages/errors/src/i18n/locales/he.ts b/packages/errors/src/i18n/locales/he.ts index 371b6ab07..e61652a9e 100644 --- a/packages/errors/src/i18n/locales/he.ts +++ b/packages/errors/src/i18n/locales/he.ts @@ -42,6 +42,7 @@ const ERROR_I18N_HE_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "כלי הבדיקה מושבת.", "admin_and_system.test_harness_forbidden": "השימוש בכלי הבדיקה אסור.", "admin_and_system.update_failed": "לא הצלחנו לעדכן את המשאב. ניתן לנסות שוב.", + "admin_and_system.user_must_be_bot_for_system_user": "המשתמש חייב להיות בוט כדי להיות מוגדר כמשתמש מערכת.", "age_verification.already_verified": "כבר השלמת את אימות הגיל.", "attachments_and_uploads.attachment_fields_required": "יש לציין את `attachment_id`, `channel_id`, `message_id` ו-`expires_at`.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` ו-`message_id` חייבים להיות מספרים שלמים תקינים.", diff --git a/packages/errors/src/i18n/locales/hi.ts b/packages/errors/src/i18n/locales/hi.ts index 3a16dba1f..282b2e55f 100644 --- a/packages/errors/src/i18n/locales/hi.ts +++ b/packages/errors/src/i18n/locales/hi.ts @@ -42,6 +42,7 @@ const ERROR_I18N_HI_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Test harness डिसेबल है।", "admin_and_system.test_harness_forbidden": "Test harness की अनुमति नहीं है।", "admin_and_system.update_failed": "रिसोर्स अपडेट नहीं किया जा सका। कृपया फिर से कोशिश करें।", + "admin_and_system.user_must_be_bot_for_system_user": "सिस्टम यूज़र के रूप में मार्क किए जाने के लिए यूज़र का बॉट होना ज़रूरी है।", "age_verification.already_verified": "आपने पहले ही एज वेरिफ़िकेशन पूरा कर लिया है।", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, और `expires_at` ज़रूरी हैं।", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, और `message_id` मान्य इंटीजर होने चाहिए।", diff --git a/packages/errors/src/i18n/locales/hr.ts b/packages/errors/src/i18n/locales/hr.ts index 50fce7503..1dbcff761 100644 --- a/packages/errors/src/i18n/locales/hr.ts +++ b/packages/errors/src/i18n/locales/hr.ts @@ -42,6 +42,7 @@ const ERROR_I18N_HR_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Testni sustav je onemogućen.", "admin_and_system.test_harness_forbidden": "Testni sustav je zabranjen.", "admin_and_system.update_failed": "Nismo mogli ažurirati resurs. Pokušaj ponovno.", + "admin_and_system.user_must_be_bot_for_system_user": "Korisnik mora biti bot da bi bio označen kao sistemski korisnik.", "age_verification.already_verified": "Provjera dobi je već završena.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` i `expires_at` su obavezni.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` i `message_id` moraju biti valjani cijeli brojevi.", diff --git a/packages/errors/src/i18n/locales/hu.ts b/packages/errors/src/i18n/locales/hu.ts index 4d278ac68..9f149285f 100644 --- a/packages/errors/src/i18n/locales/hu.ts +++ b/packages/errors/src/i18n/locales/hu.ts @@ -42,6 +42,7 @@ const ERROR_I18N_HU_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "A tesztkeretrendszer ki van kapcsolva.", "admin_and_system.test_harness_forbidden": "A tesztkeretrendszer használata nem engedélyezett.", "admin_and_system.update_failed": "Nem sikerült frissíteni az erőforrást. Próbáld újra.", + "admin_and_system.user_must_be_bot_for_system_user": "Csak botfelhasználó jelölhető meg rendszerfelhasználóként.", "age_verification.already_verified": "Már elvégezted a korhatár-ellenőrzést.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` és `expires_at` megadása kötelező.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` és `message_id` érvényes egész számoknak kell lenniük.", diff --git a/packages/errors/src/i18n/locales/id.ts b/packages/errors/src/i18n/locales/id.ts index 8d290b1b0..4d79f1bd7 100644 --- a/packages/errors/src/i18n/locales/id.ts +++ b/packages/errors/src/i18n/locales/id.ts @@ -42,6 +42,7 @@ const ERROR_I18N_ID_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Test harness dinonaktifkan.", "admin_and_system.test_harness_forbidden": "Test harness dilarang.", "admin_and_system.update_failed": "Tidak bisa memperbarui sumber daya. Coba lagi.", + "admin_and_system.user_must_be_bot_for_system_user": "Pengguna harus bot untuk ditandai sebagai pengguna sistem.", "age_verification.already_verified": "Kamu sudah menyelesaikan verifikasi usia.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, dan `expires_at` diperlukan.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, dan `message_id` harus berupa bilangan bulat yang valid.", diff --git a/packages/errors/src/i18n/locales/it.ts b/packages/errors/src/i18n/locales/it.ts index 6b4f10581..f2a617e31 100644 --- a/packages/errors/src/i18n/locales/it.ts +++ b/packages/errors/src/i18n/locales/it.ts @@ -42,6 +42,7 @@ const ERROR_I18N_IT_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Ambiente di test disabilitato.", "admin_and_system.test_harness_forbidden": "Ambiente di test vietato.", "admin_and_system.update_failed": "Non è stato possibile aggiornare la risorsa. Riprova.", + "admin_and_system.user_must_be_bot_for_system_user": "L'utente deve essere un bot per essere contrassegnato come utente di sistema.", "age_verification.already_verified": "Hai già completato la verifica dell'età.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` e `expires_at` sono richiesti.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` e `message_id` devono essere interi validi.", diff --git a/packages/errors/src/i18n/locales/ja.ts b/packages/errors/src/i18n/locales/ja.ts index 22707169f..1a83f62fd 100644 --- a/packages/errors/src/i18n/locales/ja.ts +++ b/packages/errors/src/i18n/locales/ja.ts @@ -42,6 +42,7 @@ const ERROR_I18N_JA_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "テストハーネスは無効です。", "admin_and_system.test_harness_forbidden": "テストハーネスは禁止されています。", "admin_and_system.update_failed": "リソースを更新できませんでした。もう一度お試しください。", + "admin_and_system.user_must_be_bot_for_system_user": "システムユーザーとしてマークするには、ユーザーはボットである必要があります。", "age_verification.already_verified": "年齢確認はすでに完了しています。", "attachments_and_uploads.attachment_fields_required": "`attachment_id`、`channel_id`、`message_id`、`expires_at`は必須です。", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`、`channel_id`、`message_id`は有効な整数である必要があります。", diff --git a/packages/errors/src/i18n/locales/ko.ts b/packages/errors/src/i18n/locales/ko.ts index d7a9695a5..7233896d6 100644 --- a/packages/errors/src/i18n/locales/ko.ts +++ b/packages/errors/src/i18n/locales/ko.ts @@ -42,6 +42,7 @@ const ERROR_I18N_KO_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "테스트 하네스가 비활성화되었어요.", "admin_and_system.test_harness_forbidden": "테스트 하네스 사용이 금지되어 있어요.", "admin_and_system.update_failed": "리소스를 업데이트하지 못했어요. 다시 시도해 주세요.", + "admin_and_system.user_must_be_bot_for_system_user": "시스템 사용자로 표시하려면 봇이어야 해요.", "age_verification.already_verified": "연령 인증을 이미 완료했어요.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, `expires_at`이 모두 필요해요.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, `message_id`는 모두 유효한 정수여야 해요.", diff --git a/packages/errors/src/i18n/locales/lt.ts b/packages/errors/src/i18n/locales/lt.ts index 5d593b38d..c3d286189 100644 --- a/packages/errors/src/i18n/locales/lt.ts +++ b/packages/errors/src/i18n/locales/lt.ts @@ -42,6 +42,7 @@ const ERROR_I18N_LT_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Testavimo sistema išjungta.", "admin_and_system.test_harness_forbidden": "Testavimo sistema draudžiama.", "admin_and_system.update_failed": "Ištekliaus atnaujinti nepavyko. Pabandyk dar kartą.", + "admin_and_system.user_must_be_bot_for_system_user": "Naudotojas turi būti botas, kad jį būtų galima pažymėti kaip sistemos naudotoją.", "age_verification.already_verified": "Amžiaus patvirtinimą jau atlikai.", "attachments_and_uploads.attachment_fields_required": "Reikalingi: `attachment_id`, `channel_id`, `message_id` ir `expires_at`.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` ir `message_id` turi būti galiojantys sveikieji skaičiai.", diff --git a/packages/errors/src/i18n/locales/nl.ts b/packages/errors/src/i18n/locales/nl.ts index 34a019781..6932b7dc7 100644 --- a/packages/errors/src/i18n/locales/nl.ts +++ b/packages/errors/src/i18n/locales/nl.ts @@ -42,6 +42,7 @@ const ERROR_I18N_NL_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Testfunctionaliteit is uitgeschakeld.", "admin_and_system.test_harness_forbidden": "Testfunctionaliteit is verboden.", "admin_and_system.update_failed": "We konden het item niet bijwerken. Probeer het opnieuw.", + "admin_and_system.user_must_be_bot_for_system_user": "Gebruiker moet een bot zijn om als systeemgebruiker te worden gemarkeerd.", "age_verification.already_verified": "Je hebt de leeftijdsverificatie al voltooid.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` en `expires_at` zijn verplicht.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` en `message_id` moeten geldige gehele getallen zijn.", diff --git a/packages/errors/src/i18n/locales/no.ts b/packages/errors/src/i18n/locales/no.ts index 558826903..ed3f9a845 100644 --- a/packages/errors/src/i18n/locales/no.ts +++ b/packages/errors/src/i18n/locales/no.ts @@ -42,6 +42,7 @@ const ERROR_I18N_NO_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Testrammeverket er deaktivert.", "admin_and_system.test_harness_forbidden": "Testrammeverket er ikke tillatt.", "admin_and_system.update_failed": "Vi kunne ikke oppdatere ressursen. Prøv på nytt.", + "admin_and_system.user_must_be_bot_for_system_user": "Brukeren må være en bot for å bli merket som en systembruker.", "age_verification.already_verified": "Du har allerede fullført aldersverifisering.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` og `expires_at` er påkrevd.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` og `message_id` må være gyldige heltall.", diff --git a/packages/errors/src/i18n/locales/pl.ts b/packages/errors/src/i18n/locales/pl.ts index 09e612c60..13602f105 100644 --- a/packages/errors/src/i18n/locales/pl.ts +++ b/packages/errors/src/i18n/locales/pl.ts @@ -42,6 +42,7 @@ const ERROR_I18N_PL_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Środowisko testowe wyłączone.", "admin_and_system.test_harness_forbidden": "Środowisko testowe zabronione.", "admin_and_system.update_failed": "Nie udało się zaktualizować zasobu. Spróbuj jeszcze raz.", + "admin_and_system.user_must_be_bot_for_system_user": "Użytkownik musi być botem, aby mógł być oznaczony jako użytkownik systemowy.", "age_verification.already_verified": "Weryfikacja wieku została już zakończona.", "attachments_and_uploads.attachment_fields_required": "Wymagane: `attachment_id`, `channel_id`, `message_id` i `expires_at`.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` i `message_id` muszą być prawidłowymi liczbami całkowitymi.", diff --git a/packages/errors/src/i18n/locales/pt-BR.ts b/packages/errors/src/i18n/locales/pt-BR.ts index 5ef215f97..2e807585b 100644 --- a/packages/errors/src/i18n/locales/pt-BR.ts +++ b/packages/errors/src/i18n/locales/pt-BR.ts @@ -42,6 +42,7 @@ const ERROR_I18N_PT_BR_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "A ferramenta de teste está desativada.", "admin_and_system.test_harness_forbidden": "A ferramenta de teste é proibida.", "admin_and_system.update_failed": "Não foi possível atualizar o recurso. Tente de novo.", + "admin_and_system.user_must_be_bot_for_system_user": "O usuário deve ser um bot para ser marcado como usuário de sistema.", "age_verification.already_verified": "Você já concluiu a verificação de idade.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` e `expires_at` são obrigatórios.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` e `message_id` devem ser números inteiros válidos.", diff --git a/packages/errors/src/i18n/locales/ro.ts b/packages/errors/src/i18n/locales/ro.ts index 98fd5e094..47474e436 100644 --- a/packages/errors/src/i18n/locales/ro.ts +++ b/packages/errors/src/i18n/locales/ro.ts @@ -42,6 +42,7 @@ const ERROR_I18N_RO_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Cadrul de testare este dezactivat.", "admin_and_system.test_harness_forbidden": "Cadrul de testare este interzis.", "admin_and_system.update_failed": "Resursa nu a putut fi actualizată. Încearcă din nou.", + "admin_and_system.user_must_be_bot_for_system_user": "Utilizatorul trebuie să fie un bot pentru a fi marcat ca utilizator de sistem.", "age_verification.already_verified": "Ai finalizat deja verificarea vârstei.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` și `expires_at` sunt obligatorii.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` și `message_id` trebuie să fie numere întregi valide.", diff --git a/packages/errors/src/i18n/locales/ru.ts b/packages/errors/src/i18n/locales/ru.ts index 68ecebd6f..60badaa30 100644 --- a/packages/errors/src/i18n/locales/ru.ts +++ b/packages/errors/src/i18n/locales/ru.ts @@ -42,6 +42,7 @@ const ERROR_I18N_RU_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Тестовый стенд отключён.", "admin_and_system.test_harness_forbidden": "Тестовый стенд запрещён.", "admin_and_system.update_failed": "Не удалось обновить ресурс. Попробуй ещё раз.", + "admin_and_system.user_must_be_bot_for_system_user": "Пользователь должен быть ботом, чтобы отметить его как системного пользователя.", "age_verification.already_verified": "Возраст уже подтверждён.", "attachments_and_uploads.attachment_fields_required": "Необходимо указать `attachment_id`, `channel_id`, `message_id` и `expires_at`.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` и `message_id` должны быть действительными целыми числами.", diff --git a/packages/errors/src/i18n/locales/sv-SE.ts b/packages/errors/src/i18n/locales/sv-SE.ts index ba9ed79b5..813825d9f 100644 --- a/packages/errors/src/i18n/locales/sv-SE.ts +++ b/packages/errors/src/i18n/locales/sv-SE.ts @@ -42,6 +42,7 @@ const ERROR_I18N_SV_SE_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Testverktyget är inaktiverat.", "admin_and_system.test_harness_forbidden": "Testverktyget är inte tillåtet.", "admin_and_system.update_failed": "Det gick inte att uppdatera resursen. Försök igen.", + "admin_and_system.user_must_be_bot_for_system_user": "Användaren måste vara en bot för att markeras som en systemanvändare.", "age_verification.already_verified": "Du har redan slutfört åldersverifieringen.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` och `expires_at` krävs.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` och `message_id` måste vara giltiga heltal.", diff --git a/packages/errors/src/i18n/locales/th.ts b/packages/errors/src/i18n/locales/th.ts index 1f4a50887..19d1c7cdc 100644 --- a/packages/errors/src/i18n/locales/th.ts +++ b/packages/errors/src/i18n/locales/th.ts @@ -42,6 +42,7 @@ const ERROR_I18N_TH_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "ปิดใช้งาน test harness แล้ว", "admin_and_system.test_harness_forbidden": "ไม่อนุญาตให้ใช้ test harness", "admin_and_system.update_failed": "ไม่สามารถอัปเดตทรัพยากรได้ โปรดลองอีกครั้ง", + "admin_and_system.user_must_be_bot_for_system_user": "ผู้ใช้ต้องเป็นบอทจึงจะสามารถระบุว่าเป็นผู้ใช้ระบบได้", "age_verification.already_verified": "คุณยืนยันอายุเรียบร้อยแล้ว", "attachments_and_uploads.attachment_fields_required": "ต้องระบุ `attachment_id`, `channel_id`, `message_id` และ `expires_at`", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` และ `message_id` ต้องเป็นจำนวนเต็มที่ถูกต้อง", diff --git a/packages/errors/src/i18n/locales/tr.ts b/packages/errors/src/i18n/locales/tr.ts index 2a0b43432..ead7ef883 100644 --- a/packages/errors/src/i18n/locales/tr.ts +++ b/packages/errors/src/i18n/locales/tr.ts @@ -42,6 +42,7 @@ const ERROR_I18N_TR_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Test altyapısı devre dışı.", "admin_and_system.test_harness_forbidden": "Test altyapısı yasak.", "admin_and_system.update_failed": "Kaynağı güncelleyemedik. Tekrar dene.", + "admin_and_system.user_must_be_bot_for_system_user": "Kullanıcı, sistem kullanıcısı olarak işaretlenmek için bot olmalı.", "age_verification.already_verified": "Yaş doğrulamasını zaten tamamladın.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` ve `expires_at` gerekli.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` ve `message_id` geçerli tam sayı olmalı.", diff --git a/packages/errors/src/i18n/locales/uk.ts b/packages/errors/src/i18n/locales/uk.ts index 1dbd56960..f54936c80 100644 --- a/packages/errors/src/i18n/locales/uk.ts +++ b/packages/errors/src/i18n/locales/uk.ts @@ -42,6 +42,7 @@ const ERROR_I18N_UK_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Тестову систему вимкнено.", "admin_and_system.test_harness_forbidden": "Тестову систему заборонено.", "admin_and_system.update_failed": "Не вдалося оновити ресурс. Спробуй ще раз.", + "admin_and_system.user_must_be_bot_for_system_user": "Користувач має бути ботом, щоб його можна було позначити як системного користувача.", "age_verification.already_verified": "Перевірку віку вже пройдено.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` та `expires_at` є обов'язковими.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` та `message_id` мають бути дійсними цілими числами.", diff --git a/packages/errors/src/i18n/locales/vi.ts b/packages/errors/src/i18n/locales/vi.ts index 79abb5d7e..cc4e0c38f 100644 --- a/packages/errors/src/i18n/locales/vi.ts +++ b/packages/errors/src/i18n/locales/vi.ts @@ -42,6 +42,7 @@ const ERROR_I18N_VI_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "Tính năng test harness đã bị tắt.", "admin_and_system.test_harness_forbidden": "Tính năng test harness bị cấm.", "admin_and_system.update_failed": "Không thể cập nhật tài nguyên. Vui lòng thử lại.", + "admin_and_system.user_must_be_bot_for_system_user": "Người dùng phải là bot mới được đánh dấu là người dùng hệ thống.", "age_verification.already_verified": "Bạn đã hoàn tất xác minh tuổi.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` và `expires_at` là bắt buộc.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` và `message_id` phải là các số nguyên hợp lệ.", diff --git a/packages/errors/src/i18n/locales/zh-CN.ts b/packages/errors/src/i18n/locales/zh-CN.ts index c096fe35a..8d43ae0fc 100644 --- a/packages/errors/src/i18n/locales/zh-CN.ts +++ b/packages/errors/src/i18n/locales/zh-CN.ts @@ -42,6 +42,7 @@ const ERROR_I18N_ZH_CN_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "测试工具已禁用。", "admin_and_system.test_harness_forbidden": "禁止使用测试工具。", "admin_and_system.update_failed": "无法更新资源。请重试。", + "admin_and_system.user_must_be_bot_for_system_user": "用户必须是机器人才能被标记为系统用户。", "age_verification.already_verified": "你已完成年龄验证。", "attachments_and_uploads.attachment_fields_required": "需要提供 `attachment_id`、`channel_id`、`message_id` 和 `expires_at`。", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`、`channel_id` 和 `message_id` 必须是有效的整数。", diff --git a/packages/errors/src/i18n/locales/zh-TW.ts b/packages/errors/src/i18n/locales/zh-TW.ts index e22bc24ba..32617b8c7 100644 --- a/packages/errors/src/i18n/locales/zh-TW.ts +++ b/packages/errors/src/i18n/locales/zh-TW.ts @@ -42,6 +42,7 @@ const ERROR_I18N_ZH_TW_MESSAGES = defineErrorI18nLocaleMessages({ "admin_and_system.test_harness_disabled": "測試工具已停用。", "admin_and_system.test_harness_forbidden": "禁止使用測試工具。", "admin_and_system.update_failed": "我們無法更新資源。請再試一次。", + "admin_and_system.user_must_be_bot_for_system_user": "使用者必須是機器人才能標記為系統使用者。", "age_verification.already_verified": "你已完成年齡驗證。", "attachments_and_uploads.attachment_fields_required": "`attachment_id`、`channel_id`、`message_id` 和 `expires_at` 為必填。", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`、`channel_id` 和 `message_id` 必須為有效的整數。", diff --git a/packages/errors/src/i18n/weblate/locales/ar.json b/packages/errors/src/i18n/weblate/locales/ar.json index 220654a06..2f4527c32 100644 --- a/packages/errors/src/i18n/weblate/locales/ar.json +++ b/packages/errors/src/i18n/weblate/locales/ar.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "أداة الاختبار معطلة.", "admin_and_system.test_harness_forbidden": "أداة الاختبار محظورة.", "admin_and_system.update_failed": "لم نتمكن من تحديث المورد. حاول مجددًا.", + "admin_and_system.user_must_be_bot_for_system_user": "يجب أن يكون المستخدم بوتًا ليتم تحديده كمستخدم نظام.", "age_verification.already_verified": "لقد أكملت التحقق من العمر بالفعل.", "attachments_and_uploads.attachment_fields_required": "`attachment_id` و`channel_id` و`message_id` و`expires_at` مطلوبة.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "يجب أن تكون `attachment_id` و`channel_id` و`message_id` أعدادًا صحيحة صالحة.", diff --git a/packages/errors/src/i18n/weblate/locales/bg.json b/packages/errors/src/i18n/weblate/locales/bg.json index dc74ab938..1afe222b0 100644 --- a/packages/errors/src/i18n/weblate/locales/bg.json +++ b/packages/errors/src/i18n/weblate/locales/bg.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Тестовата система е деактивирана.", "admin_and_system.test_harness_forbidden": "Тестовата система е забранена.", "admin_and_system.update_failed": "Не успяхме да актуализираме ресурса. Опитай отново.", + "admin_and_system.user_must_be_bot_for_system_user": "Потребителят трябва да бъде бот, за да бъде маркиран като системен потребител.", "age_verification.already_verified": "Вече премина проверката за възраст.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` и `expires_at` са задължителни.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` и `message_id` трябва да са валидни цели числа.", diff --git a/packages/errors/src/i18n/weblate/locales/cs.json b/packages/errors/src/i18n/weblate/locales/cs.json index 68b0f065c..2a4cb272c 100644 --- a/packages/errors/src/i18n/weblate/locales/cs.json +++ b/packages/errors/src/i18n/weblate/locales/cs.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Testovací prostředí je vypnuté.", "admin_and_system.test_harness_forbidden": "Přístup k testovacímu prostředí je zakázán.", "admin_and_system.update_failed": "Nepodařilo se aktualizovat zdroj. Zkuste to znovu.", + "admin_and_system.user_must_be_bot_for_system_user": "Uživatel musí být bot, aby mohl být označen jako systémový uživatel.", "age_verification.already_verified": "Ověření věku už bylo dokončeno.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` a `expires_at` jsou povinné.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` a `message_id` musí být platné celočíselné hodnoty.", diff --git a/packages/errors/src/i18n/weblate/locales/da.json b/packages/errors/src/i18n/weblate/locales/da.json index f08eef335..4e569d5d4 100644 --- a/packages/errors/src/i18n/weblate/locales/da.json +++ b/packages/errors/src/i18n/weblate/locales/da.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Testmiljøet er deaktiveret.", "admin_and_system.test_harness_forbidden": "Adgang til testmiljøet er ikke tilladt.", "admin_and_system.update_failed": "Ressourcen kunne ikke opdateres. Prøv igen.", + "admin_and_system.user_must_be_bot_for_system_user": "Brugeren skal være en bot for at kunne markeres som systembruger.", "age_verification.already_verified": "Du har allerede gennemført aldersbekræftelse.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` og `expires_at` er påkrævet.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` og `message_id` skal være gyldige heltal.", diff --git a/packages/errors/src/i18n/weblate/locales/de.json b/packages/errors/src/i18n/weblate/locales/de.json index 6a16bce2a..311cb75b3 100644 --- a/packages/errors/src/i18n/weblate/locales/de.json +++ b/packages/errors/src/i18n/weblate/locales/de.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Test-Harness ist deaktiviert.", "admin_and_system.test_harness_forbidden": "Test-Harness ist verboten.", "admin_and_system.update_failed": "Wir konnten die Ressource nicht aktualisieren. Bitte versuche es erneut.", + "admin_and_system.user_must_be_bot_for_system_user": "Ein Benutzer muss ein Bot sein, um als Systembenutzer markiert zu werden.", "age_verification.already_verified": "Du hast die Altersbestätigung bereits abgeschlossen.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` und `expires_at` sind erforderlich.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` und `message_id` müssen gültige Ganzzahlen sein.", diff --git a/packages/errors/src/i18n/weblate/locales/el.json b/packages/errors/src/i18n/weblate/locales/el.json index 30d7440a2..a2e362af8 100644 --- a/packages/errors/src/i18n/weblate/locales/el.json +++ b/packages/errors/src/i18n/weblate/locales/el.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Το test harness είναι απενεργοποιημένο.", "admin_and_system.test_harness_forbidden": "Το test harness απαγορεύεται.", "admin_and_system.update_failed": "Δεν μπορέσαμε να ενημερώσουμε τον πόρο. Δοκίμασε ξανά.", + "admin_and_system.user_must_be_bot_for_system_user": "Ο χρήστης πρέπει να είναι bot για να οριστεί ως χρήστης συστήματος.", "age_verification.already_verified": "Έχεις ήδη ολοκληρώσει την επαλήθευση ηλικίας.", "attachments_and_uploads.attachment_fields_required": "Τα `attachment_id`, `channel_id`, `message_id` και `expires_at` είναι υποχρεωτικά.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "Τα `attachment_id`, `channel_id` και `message_id` πρέπει να είναι έγκυροι ακέραιοι αριθμοί.", diff --git a/packages/errors/src/i18n/weblate/locales/en-GB.json b/packages/errors/src/i18n/weblate/locales/en-GB.json index 32a104736..43073fa05 100644 --- a/packages/errors/src/i18n/weblate/locales/en-GB.json +++ b/packages/errors/src/i18n/weblate/locales/en-GB.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Test harness is disabled.", "admin_and_system.test_harness_forbidden": "Test harness is forbidden.", "admin_and_system.update_failed": "We couldn't update the resource. Please try again.", + "admin_and_system.user_must_be_bot_for_system_user": "User must be a bot to be marked as a system user.", "age_verification.already_verified": "You've already completed age verification.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, and `expires_at` are required.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, and `message_id` must be valid integers.", diff --git a/packages/errors/src/i18n/weblate/locales/es-419.json b/packages/errors/src/i18n/weblate/locales/es-419.json index 5be46ef0f..f78750e02 100644 --- a/packages/errors/src/i18n/weblate/locales/es-419.json +++ b/packages/errors/src/i18n/weblate/locales/es-419.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "El entorno de prueba está deshabilitado.", "admin_and_system.test_harness_forbidden": "El entorno de prueba está prohibido.", "admin_and_system.update_failed": "No se pudo actualizar el recurso. Inténtalo de nuevo.", + "admin_and_system.user_must_be_bot_for_system_user": "El usuario debe ser un bot para ser marcado como usuario del sistema.", "age_verification.already_verified": "Ya completaste la verificación de edad.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` y `expires_at` son obligatorios.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` y `message_id` deben ser enteros válidos.", diff --git a/packages/errors/src/i18n/weblate/locales/es-ES.json b/packages/errors/src/i18n/weblate/locales/es-ES.json index 9cdbdb719..e5825d75b 100644 --- a/packages/errors/src/i18n/weblate/locales/es-ES.json +++ b/packages/errors/src/i18n/weblate/locales/es-ES.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "El entorno de pruebas está deshabilitado.", "admin_and_system.test_harness_forbidden": "El entorno de pruebas está prohibido.", "admin_and_system.update_failed": "No se pudo actualizar el recurso. Inténtalo de nuevo.", + "admin_and_system.user_must_be_bot_for_system_user": "El usuario debe ser un bot para ser marcado como usuario del sistema.", "age_verification.already_verified": "Ya has completado la verificación de edad.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` y `expires_at` son obligatorios.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` y `message_id` deben ser enteros válidos.", diff --git a/packages/errors/src/i18n/weblate/locales/fi.json b/packages/errors/src/i18n/weblate/locales/fi.json index 8fc170a6e..7ddf12291 100644 --- a/packages/errors/src/i18n/weblate/locales/fi.json +++ b/packages/errors/src/i18n/weblate/locales/fi.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Testausympäristö on poistettu käytöstä.", "admin_and_system.test_harness_forbidden": "Testausympäristö on kielletty.", "admin_and_system.update_failed": "Resurssia ei voitu päivittää. Yritä uudelleen.", + "admin_and_system.user_must_be_bot_for_system_user": "Käyttäjän on oltava botti, jotta sen voi merkitä järjestelmäkäyttäjäksi.", "age_verification.already_verified": "Olet jo suorittanut iän vahvistuksen.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` ja `expires_at` ovat pakollisia.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "Seuraavien kenttien arvojen on oltava kelvollisia kokonaislukuja: `attachment_id`, `channel_id` ja `message_id`.", diff --git a/packages/errors/src/i18n/weblate/locales/fr.json b/packages/errors/src/i18n/weblate/locales/fr.json index e9e7a6027..ead9c9e6d 100644 --- a/packages/errors/src/i18n/weblate/locales/fr.json +++ b/packages/errors/src/i18n/weblate/locales/fr.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Le banc de test est désactivé.", "admin_and_system.test_harness_forbidden": "Le banc de test est interdit.", "admin_and_system.update_failed": "Impossible de mettre à jour la ressource. Réessayez.", + "admin_and_system.user_must_be_bot_for_system_user": "L'utilisateur doit être un bot pour être marqué comme utilisateur système.", "age_verification.already_verified": "Vous avez déjà effectué la vérification de l’âge.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` et `expires_at` sont nécessaires.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` et `message_id` doivent être des entiers valides.", diff --git a/packages/errors/src/i18n/weblate/locales/he.json b/packages/errors/src/i18n/weblate/locales/he.json index c4fadd76a..8cfdb4aa8 100644 --- a/packages/errors/src/i18n/weblate/locales/he.json +++ b/packages/errors/src/i18n/weblate/locales/he.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "כלי הבדיקה מושבת.", "admin_and_system.test_harness_forbidden": "השימוש בכלי הבדיקה אסור.", "admin_and_system.update_failed": "לא הצלחנו לעדכן את המשאב. ניתן לנסות שוב.", + "admin_and_system.user_must_be_bot_for_system_user": "המשתמש חייב להיות בוט כדי להיות מוגדר כמשתמש מערכת.", "age_verification.already_verified": "כבר השלמת את אימות הגיל.", "attachments_and_uploads.attachment_fields_required": "יש לציין את `attachment_id`, `channel_id`, `message_id` ו-`expires_at`.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` ו-`message_id` חייבים להיות מספרים שלמים תקינים.", diff --git a/packages/errors/src/i18n/weblate/locales/hi.json b/packages/errors/src/i18n/weblate/locales/hi.json index 7029e5d5a..baaf253d1 100644 --- a/packages/errors/src/i18n/weblate/locales/hi.json +++ b/packages/errors/src/i18n/weblate/locales/hi.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Test harness डिसेबल है।", "admin_and_system.test_harness_forbidden": "Test harness की अनुमति नहीं है।", "admin_and_system.update_failed": "रिसोर्स अपडेट नहीं किया जा सका। कृपया फिर से कोशिश करें।", + "admin_and_system.user_must_be_bot_for_system_user": "सिस्टम यूज़र के रूप में मार्क किए जाने के लिए यूज़र का बॉट होना ज़रूरी है।", "age_verification.already_verified": "आपने पहले ही एज वेरिफ़िकेशन पूरा कर लिया है।", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, और `expires_at` ज़रूरी हैं।", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, और `message_id` मान्य इंटीजर होने चाहिए।", diff --git a/packages/errors/src/i18n/weblate/locales/hr.json b/packages/errors/src/i18n/weblate/locales/hr.json index f97618fce..0e6d3523c 100644 --- a/packages/errors/src/i18n/weblate/locales/hr.json +++ b/packages/errors/src/i18n/weblate/locales/hr.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Testni sustav je onemogućen.", "admin_and_system.test_harness_forbidden": "Testni sustav je zabranjen.", "admin_and_system.update_failed": "Nismo mogli ažurirati resurs. Pokušaj ponovno.", + "admin_and_system.user_must_be_bot_for_system_user": "Korisnik mora biti bot da bi bio označen kao sistemski korisnik.", "age_verification.already_verified": "Provjera dobi je već završena.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` i `expires_at` su obavezni.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` i `message_id` moraju biti valjani cijeli brojevi.", diff --git a/packages/errors/src/i18n/weblate/locales/hu.json b/packages/errors/src/i18n/weblate/locales/hu.json index 472a24dc0..2e4acb8f7 100644 --- a/packages/errors/src/i18n/weblate/locales/hu.json +++ b/packages/errors/src/i18n/weblate/locales/hu.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "A tesztkeretrendszer ki van kapcsolva.", "admin_and_system.test_harness_forbidden": "A tesztkeretrendszer használata nem engedélyezett.", "admin_and_system.update_failed": "Nem sikerült frissíteni az erőforrást. Próbáld újra.", + "admin_and_system.user_must_be_bot_for_system_user": "Csak botfelhasználó jelölhető meg rendszerfelhasználóként.", "age_verification.already_verified": "Már elvégezted a korhatár-ellenőrzést.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` és `expires_at` megadása kötelező.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` és `message_id` érvényes egész számoknak kell lenniük.", diff --git a/packages/errors/src/i18n/weblate/locales/id.json b/packages/errors/src/i18n/weblate/locales/id.json index 624c34b83..f2952c1bf 100644 --- a/packages/errors/src/i18n/weblate/locales/id.json +++ b/packages/errors/src/i18n/weblate/locales/id.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Test harness dinonaktifkan.", "admin_and_system.test_harness_forbidden": "Test harness dilarang.", "admin_and_system.update_failed": "Tidak bisa memperbarui sumber daya. Coba lagi.", + "admin_and_system.user_must_be_bot_for_system_user": "Pengguna harus bot untuk ditandai sebagai pengguna sistem.", "age_verification.already_verified": "Kamu sudah menyelesaikan verifikasi usia.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, dan `expires_at` diperlukan.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, dan `message_id` harus berupa bilangan bulat yang valid.", diff --git a/packages/errors/src/i18n/weblate/locales/it.json b/packages/errors/src/i18n/weblate/locales/it.json index f8b7e2977..27a56f4d4 100644 --- a/packages/errors/src/i18n/weblate/locales/it.json +++ b/packages/errors/src/i18n/weblate/locales/it.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Ambiente di test disabilitato.", "admin_and_system.test_harness_forbidden": "Ambiente di test vietato.", "admin_and_system.update_failed": "Non è stato possibile aggiornare la risorsa. Riprova.", + "admin_and_system.user_must_be_bot_for_system_user": "L'utente deve essere un bot per essere contrassegnato come utente di sistema.", "age_verification.already_verified": "Hai già completato la verifica dell'età.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` e `expires_at` sono richiesti.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` e `message_id` devono essere interi validi.", diff --git a/packages/errors/src/i18n/weblate/locales/ja.json b/packages/errors/src/i18n/weblate/locales/ja.json index ce8bdee8b..366090af7 100644 --- a/packages/errors/src/i18n/weblate/locales/ja.json +++ b/packages/errors/src/i18n/weblate/locales/ja.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "テストハーネスは無効です。", "admin_and_system.test_harness_forbidden": "テストハーネスは禁止されています。", "admin_and_system.update_failed": "リソースを更新できませんでした。もう一度お試しください。", + "admin_and_system.user_must_be_bot_for_system_user": "システムユーザーとしてマークするには、ユーザーはボットである必要があります。", "age_verification.already_verified": "年齢確認はすでに完了しています。", "attachments_and_uploads.attachment_fields_required": "`attachment_id`、`channel_id`、`message_id`、`expires_at`は必須です。", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`、`channel_id`、`message_id`は有効な整数である必要があります。", diff --git a/packages/errors/src/i18n/weblate/locales/ko.json b/packages/errors/src/i18n/weblate/locales/ko.json index e4894d44e..9725b76ad 100644 --- a/packages/errors/src/i18n/weblate/locales/ko.json +++ b/packages/errors/src/i18n/weblate/locales/ko.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "테스트 하네스가 비활성화되었어요.", "admin_and_system.test_harness_forbidden": "테스트 하네스 사용이 금지되어 있어요.", "admin_and_system.update_failed": "리소스를 업데이트하지 못했어요. 다시 시도해 주세요.", + "admin_and_system.user_must_be_bot_for_system_user": "시스템 사용자로 표시하려면 봇이어야 해요.", "age_verification.already_verified": "연령 인증을 이미 완료했어요.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, `expires_at`이 모두 필요해요.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, `message_id`는 모두 유효한 정수여야 해요.", diff --git a/packages/errors/src/i18n/weblate/locales/lt.json b/packages/errors/src/i18n/weblate/locales/lt.json index 63cf2fc76..92eef6b56 100644 --- a/packages/errors/src/i18n/weblate/locales/lt.json +++ b/packages/errors/src/i18n/weblate/locales/lt.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Testavimo sistema išjungta.", "admin_and_system.test_harness_forbidden": "Testavimo sistema draudžiama.", "admin_and_system.update_failed": "Ištekliaus atnaujinti nepavyko. Pabandyk dar kartą.", + "admin_and_system.user_must_be_bot_for_system_user": "Naudotojas turi būti botas, kad jį būtų galima pažymėti kaip sistemos naudotoją.", "age_verification.already_verified": "Amžiaus patvirtinimą jau atlikai.", "attachments_and_uploads.attachment_fields_required": "Reikalingi: `attachment_id`, `channel_id`, `message_id` ir `expires_at`.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` ir `message_id` turi būti galiojantys sveikieji skaičiai.", diff --git a/packages/errors/src/i18n/weblate/locales/nl.json b/packages/errors/src/i18n/weblate/locales/nl.json index cb6f855a7..73c63f6fa 100644 --- a/packages/errors/src/i18n/weblate/locales/nl.json +++ b/packages/errors/src/i18n/weblate/locales/nl.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Testfunctionaliteit is uitgeschakeld.", "admin_and_system.test_harness_forbidden": "Testfunctionaliteit is verboden.", "admin_and_system.update_failed": "We konden het item niet bijwerken. Probeer het opnieuw.", + "admin_and_system.user_must_be_bot_for_system_user": "Gebruiker moet een bot zijn om als systeemgebruiker te worden gemarkeerd.", "age_verification.already_verified": "Je hebt de leeftijdsverificatie al voltooid.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` en `expires_at` zijn verplicht.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` en `message_id` moeten geldige gehele getallen zijn.", diff --git a/packages/errors/src/i18n/weblate/locales/no.json b/packages/errors/src/i18n/weblate/locales/no.json index 3ee6a1e9c..d0b79be6a 100644 --- a/packages/errors/src/i18n/weblate/locales/no.json +++ b/packages/errors/src/i18n/weblate/locales/no.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Testrammeverket er deaktivert.", "admin_and_system.test_harness_forbidden": "Testrammeverket er ikke tillatt.", "admin_and_system.update_failed": "Vi kunne ikke oppdatere ressursen. Prøv på nytt.", + "admin_and_system.user_must_be_bot_for_system_user": "Brukeren må være en bot for å bli merket som en systembruker.", "age_verification.already_verified": "Du har allerede fullført aldersverifisering.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` og `expires_at` er påkrevd.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` og `message_id` må være gyldige heltall.", diff --git a/packages/errors/src/i18n/weblate/locales/pl.json b/packages/errors/src/i18n/weblate/locales/pl.json index 5ed772bbb..0b48182b7 100644 --- a/packages/errors/src/i18n/weblate/locales/pl.json +++ b/packages/errors/src/i18n/weblate/locales/pl.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Środowisko testowe wyłączone.", "admin_and_system.test_harness_forbidden": "Środowisko testowe zabronione.", "admin_and_system.update_failed": "Nie udało się zaktualizować zasobu. Spróbuj jeszcze raz.", + "admin_and_system.user_must_be_bot_for_system_user": "Użytkownik musi być botem, aby mógł być oznaczony jako użytkownik systemowy.", "age_verification.already_verified": "Weryfikacja wieku została już zakończona.", "attachments_and_uploads.attachment_fields_required": "Wymagane: `attachment_id`, `channel_id`, `message_id` i `expires_at`.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` i `message_id` muszą być prawidłowymi liczbami całkowitymi.", diff --git a/packages/errors/src/i18n/weblate/locales/pt-BR.json b/packages/errors/src/i18n/weblate/locales/pt-BR.json index 168966b5a..d42f0109f 100644 --- a/packages/errors/src/i18n/weblate/locales/pt-BR.json +++ b/packages/errors/src/i18n/weblate/locales/pt-BR.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "A ferramenta de teste está desativada.", "admin_and_system.test_harness_forbidden": "A ferramenta de teste é proibida.", "admin_and_system.update_failed": "Não foi possível atualizar o recurso. Tente de novo.", + "admin_and_system.user_must_be_bot_for_system_user": "O usuário deve ser um bot para ser marcado como usuário de sistema.", "age_verification.already_verified": "Você já concluiu a verificação de idade.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` e `expires_at` são obrigatórios.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` e `message_id` devem ser números inteiros válidos.", diff --git a/packages/errors/src/i18n/weblate/locales/ro.json b/packages/errors/src/i18n/weblate/locales/ro.json index 046dd8b01..a635e1c16 100644 --- a/packages/errors/src/i18n/weblate/locales/ro.json +++ b/packages/errors/src/i18n/weblate/locales/ro.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Cadrul de testare este dezactivat.", "admin_and_system.test_harness_forbidden": "Cadrul de testare este interzis.", "admin_and_system.update_failed": "Resursa nu a putut fi actualizată. Încearcă din nou.", + "admin_and_system.user_must_be_bot_for_system_user": "Utilizatorul trebuie să fie un bot pentru a fi marcat ca utilizator de sistem.", "age_verification.already_verified": "Ai finalizat deja verificarea vârstei.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` și `expires_at` sunt obligatorii.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` și `message_id` trebuie să fie numere întregi valide.", diff --git a/packages/errors/src/i18n/weblate/locales/ru.json b/packages/errors/src/i18n/weblate/locales/ru.json index dc8950623..cb2d8b674 100644 --- a/packages/errors/src/i18n/weblate/locales/ru.json +++ b/packages/errors/src/i18n/weblate/locales/ru.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Тестовый стенд отключён.", "admin_and_system.test_harness_forbidden": "Тестовый стенд запрещён.", "admin_and_system.update_failed": "Не удалось обновить ресурс. Попробуй ещё раз.", + "admin_and_system.user_must_be_bot_for_system_user": "Пользователь должен быть ботом, чтобы отметить его как системного пользователя.", "age_verification.already_verified": "Возраст уже подтверждён.", "attachments_and_uploads.attachment_fields_required": "Необходимо указать `attachment_id`, `channel_id`, `message_id` и `expires_at`.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` и `message_id` должны быть действительными целыми числами.", diff --git a/packages/errors/src/i18n/weblate/locales/sv-SE.json b/packages/errors/src/i18n/weblate/locales/sv-SE.json index ce06c0c79..f6776b3c8 100644 --- a/packages/errors/src/i18n/weblate/locales/sv-SE.json +++ b/packages/errors/src/i18n/weblate/locales/sv-SE.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Testverktyget är inaktiverat.", "admin_and_system.test_harness_forbidden": "Testverktyget är inte tillåtet.", "admin_and_system.update_failed": "Det gick inte att uppdatera resursen. Försök igen.", + "admin_and_system.user_must_be_bot_for_system_user": "Användaren måste vara en bot för att markeras som en systemanvändare.", "age_verification.already_verified": "Du har redan slutfört åldersverifieringen.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` och `expires_at` krävs.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` och `message_id` måste vara giltiga heltal.", diff --git a/packages/errors/src/i18n/weblate/locales/th.json b/packages/errors/src/i18n/weblate/locales/th.json index c5b998bae..76b07ed43 100644 --- a/packages/errors/src/i18n/weblate/locales/th.json +++ b/packages/errors/src/i18n/weblate/locales/th.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "ปิดใช้งาน test harness แล้ว", "admin_and_system.test_harness_forbidden": "ไม่อนุญาตให้ใช้ test harness", "admin_and_system.update_failed": "ไม่สามารถอัปเดตทรัพยากรได้ โปรดลองอีกครั้ง", + "admin_and_system.user_must_be_bot_for_system_user": "ผู้ใช้ต้องเป็นบอทจึงจะสามารถระบุว่าเป็นผู้ใช้ระบบได้", "age_verification.already_verified": "คุณยืนยันอายุเรียบร้อยแล้ว", "attachments_and_uploads.attachment_fields_required": "ต้องระบุ `attachment_id`, `channel_id`, `message_id` และ `expires_at`", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` และ `message_id` ต้องเป็นจำนวนเต็มที่ถูกต้อง", diff --git a/packages/errors/src/i18n/weblate/locales/tr.json b/packages/errors/src/i18n/weblate/locales/tr.json index b78a9fd85..bf044dc66 100644 --- a/packages/errors/src/i18n/weblate/locales/tr.json +++ b/packages/errors/src/i18n/weblate/locales/tr.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Test altyapısı devre dışı.", "admin_and_system.test_harness_forbidden": "Test altyapısı yasak.", "admin_and_system.update_failed": "Kaynağı güncelleyemedik. Tekrar dene.", + "admin_and_system.user_must_be_bot_for_system_user": "Kullanıcı, sistem kullanıcısı olarak işaretlenmek için bot olmalı.", "age_verification.already_verified": "Yaş doğrulamasını zaten tamamladın.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` ve `expires_at` gerekli.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` ve `message_id` geçerli tam sayı olmalı.", diff --git a/packages/errors/src/i18n/weblate/locales/uk.json b/packages/errors/src/i18n/weblate/locales/uk.json index 57f4e0299..de9b8a125 100644 --- a/packages/errors/src/i18n/weblate/locales/uk.json +++ b/packages/errors/src/i18n/weblate/locales/uk.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Тестову систему вимкнено.", "admin_and_system.test_harness_forbidden": "Тестову систему заборонено.", "admin_and_system.update_failed": "Не вдалося оновити ресурс. Спробуй ще раз.", + "admin_and_system.user_must_be_bot_for_system_user": "Користувач має бути ботом, щоб його можна було позначити як системного користувача.", "age_verification.already_verified": "Перевірку віку вже пройдено.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` та `expires_at` є обов'язковими.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` та `message_id` мають бути дійсними цілими числами.", diff --git a/packages/errors/src/i18n/weblate/locales/vi.json b/packages/errors/src/i18n/weblate/locales/vi.json index 223d8799c..f094b33b6 100644 --- a/packages/errors/src/i18n/weblate/locales/vi.json +++ b/packages/errors/src/i18n/weblate/locales/vi.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Tính năng test harness đã bị tắt.", "admin_and_system.test_harness_forbidden": "Tính năng test harness bị cấm.", "admin_and_system.update_failed": "Không thể cập nhật tài nguyên. Vui lòng thử lại.", + "admin_and_system.user_must_be_bot_for_system_user": "Người dùng phải là bot mới được đánh dấu là người dùng hệ thống.", "age_verification.already_verified": "Bạn đã hoàn tất xác minh tuổi.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id` và `expires_at` là bắt buộc.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id` và `message_id` phải là các số nguyên hợp lệ.", diff --git a/packages/errors/src/i18n/weblate/locales/zh-CN.json b/packages/errors/src/i18n/weblate/locales/zh-CN.json index e9028c4f6..4b3ada5bc 100644 --- a/packages/errors/src/i18n/weblate/locales/zh-CN.json +++ b/packages/errors/src/i18n/weblate/locales/zh-CN.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "测试工具已禁用。", "admin_and_system.test_harness_forbidden": "禁止使用测试工具。", "admin_and_system.update_failed": "无法更新资源。请重试。", + "admin_and_system.user_must_be_bot_for_system_user": "用户必须是机器人才能被标记为系统用户。", "age_verification.already_verified": "你已完成年龄验证。", "attachments_and_uploads.attachment_fields_required": "需要提供 `attachment_id`、`channel_id`、`message_id` 和 `expires_at`。", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`、`channel_id` 和 `message_id` 必须是有效的整数。", diff --git a/packages/errors/src/i18n/weblate/locales/zh-TW.json b/packages/errors/src/i18n/weblate/locales/zh-TW.json index 1c1c527a6..45fa9d943 100644 --- a/packages/errors/src/i18n/weblate/locales/zh-TW.json +++ b/packages/errors/src/i18n/weblate/locales/zh-TW.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "測試工具已停用。", "admin_and_system.test_harness_forbidden": "禁止使用測試工具。", "admin_and_system.update_failed": "我們無法更新資源。請再試一次。", + "admin_and_system.user_must_be_bot_for_system_user": "使用者必須是機器人才能標記為系統使用者。", "age_verification.already_verified": "你已完成年齡驗證。", "attachments_and_uploads.attachment_fields_required": "`attachment_id`、`channel_id`、`message_id` 和 `expires_at` 為必填。", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`、`channel_id` 和 `message_id` 必須為有效的整數。", diff --git a/packages/errors/src/i18n/weblate/messages.json b/packages/errors/src/i18n/weblate/messages.json index 3f831556e..5a164de2b 100644 --- a/packages/errors/src/i18n/weblate/messages.json +++ b/packages/errors/src/i18n/weblate/messages.json @@ -38,6 +38,7 @@ "admin_and_system.test_harness_disabled": "Test harness is disabled.", "admin_and_system.test_harness_forbidden": "Test harness is forbidden.", "admin_and_system.update_failed": "We couldn't update the resource. Please try again.", + "admin_and_system.user_must_be_bot_for_system_user": "User must be a bot to be marked as a system user.", "age_verification.already_verified": "You've already completed age verification.", "attachments_and_uploads.attachment_fields_required": "`attachment_id`, `channel_id`, `message_id`, and `expires_at` are required.", "attachments_and_uploads.attachment_ids_must_be_valid_integers": "`attachment_id`, `channel_id`, and `message_id` must be valid integers.", diff --git a/packages/schema/src/domains/admin/AdminUserSchemas.ts b/packages/schema/src/domains/admin/AdminUserSchemas.ts index bbd3f46ed..95c74bafa 100644 --- a/packages/schema/src/domains/admin/AdminUserSchemas.ts +++ b/packages/schema/src/domains/admin/AdminUserSchemas.ts @@ -247,6 +247,20 @@ export const ClearUserFieldsRequest = z.object({ export type ClearUserFieldsRequest = z.infer; +export const SetUserBotStatusRequest = z.object({ + user_id: SnowflakeType.describe('ID of the user to update'), + bot: z.boolean().describe('Whether the user should be marked as a bot'), +}); + +export type SetUserBotStatusRequest = z.infer; + +export const SetUserSystemStatusRequest = z.object({ + user_id: SnowflakeType.describe('ID of the user to update'), + system: z.boolean().describe('Whether the user should be marked as a system user'), +}); + +export type SetUserSystemStatusRequest = z.infer; + export const VerifyUserEmailRequest = z.object({ user_id: SnowflakeType.describe('ID of the user to verify email for'), }); @@ -561,6 +575,14 @@ export const AdminUserClearFieldsRequest = ClearUserFieldsRequest.omit({user_id: export type AdminUserClearFieldsRequest = z.infer; +export const AdminUserBotStatusRequest = SetUserBotStatusRequest.omit({user_id: true}); + +export type AdminUserBotStatusRequest = z.infer; + +export const AdminUserSystemStatusRequest = SetUserSystemStatusRequest.omit({user_id: true}); + +export type AdminUserSystemStatusRequest = z.infer; + export const AdminUserUsernameUpdateRequest = ChangeUsernameRequest.omit({user_id: true}); export type AdminUserUsernameUpdateRequest = z.infer;