This repository has no description
Something went wrong. Try again.
17 kB · 485 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486// SPDX-License-Identifier: AGPL-3.0-or-later
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';import { BanGuildMemberRequest, ClearGuildFieldsRequest, DeleteGuildRequest, ForceAddUserToGuildRequest, KickGuildMemberRequest, ListGuildAuditLogsRequest, ListGuildAuditLogsResponse, ListGuildMembersRequest, LookupGuildRequest, ReloadGuildRequest, ShutdownGuildRequest, TransferGuildOwnershipRequest, UpdateGuildFeaturesRequest, UpdateGuildNameRequest, UpdateGuildSettingsRequest, UpdateGuildVanityRequest,} from '@fluxer/schema/src/domains/admin/AdminGuildSchemas';import { GuildUpdateResponse, ListGuildEmojisResponse, ListGuildMembersResponse, ListGuildStickersResponse, LookupGuildResponse, SuccessResponse,} from '@fluxer/schema/src/domains/admin/AdminSchemas';import {GuildIdParam} from '@fluxer/schema/src/domains/common/CommonParamSchemas';import {createGuildID} from '../../BrandedTypes';import {requireAdminACL} from '../../middleware/AdminMiddleware';import {RateLimitMiddleware} from '../../middleware/RateLimitMiddleware';import {OpenAPI} from '../../middleware/ResponseTypeMiddleware';import {RateLimitConfigs} from '../../RateLimitConfig';import {AdminRateLimitConfigs} from '../../rate_limit_configs/AdminRateLimitConfig';import type {HonoApp} from '../../types/HonoEnv';import {Validator} from '../../Validator';
export function GuildAdminController(app: HonoApp) { app.post( '/admin/guilds/lookup', RateLimitMiddleware(RateLimitConfigs.ADMIN_LOOKUP), requireAdminACL(AdminACLs.GUILD_LOOKUP), Validator('json', LookupGuildRequest), OpenAPI({ operationId: 'lookup_guild', summary: 'Look up guild', description: 'Retrieves complete guild details including metadata, settings, and statistics. Look up by guild ID or vanity slug. Requires GUILD_LOOKUP permission.', responseSchema: LookupGuildResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); return ctx.json(await adminService.guildServiceAggregate.lookupService.lookupGuild(ctx.req.valid('json'))); }, ); app.post( '/admin/guilds/list-members', RateLimitMiddleware(RateLimitConfigs.ADMIN_LOOKUP), requireAdminACL(AdminACLs.GUILD_LIST_MEMBERS), Validator('json', ListGuildMembersRequest), OpenAPI({ operationId: 'admin_list_guild_members', summary: 'List guild members', description: 'Lists all guild members with pagination. Returns member IDs, join dates, and roles. Requires GUILD_LIST_MEMBERS permission.', responseSchema: ListGuildMembersResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); return ctx.json(await adminService.guildServiceAggregate.lookupService.listGuildMembers(ctx.req.valid('json'))); }, ); app.get( '/admin/guilds/:guild_id/emojis', RateLimitMiddleware(AdminRateLimitConfigs.ADMIN_LOOKUP), requireAdminACL(AdminACLs.ASSET_PURGE), Validator('param', GuildIdParam), OpenAPI({ operationId: 'admin_list_guild_emojis', summary: 'List guild emojis', description: 'Lists all custom emojis in a guild. Returns ID, name, and creation date. Used for asset inventory and purge operations. Requires ASSET_PURGE permission.', responseSchema: ListGuildEmojisResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const guildId = createGuildID(ctx.req.valid('param').guild_id); return ctx.json(await adminService.guildServiceAggregate.lookupService.listGuildEmojis(guildId)); }, ); app.get( '/admin/guilds/:guild_id/stickers', RateLimitMiddleware(AdminRateLimitConfigs.ADMIN_LOOKUP), requireAdminACL(AdminACLs.ASSET_PURGE), Validator('param', GuildIdParam), OpenAPI({ operationId: 'admin_list_guild_stickers', summary: 'List guild stickers', description: 'Lists all stickers in a guild. Returns ID, name, and asset information. Used for asset inventory and purge operations. Requires ASSET_PURGE permission.', responseSchema: ListGuildStickersResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const guildId = createGuildID(ctx.req.valid('param').guild_id); return ctx.json(await adminService.guildServiceAggregate.lookupService.listGuildStickers(guildId)); }, ); app.post( '/admin/guilds/audit-logs', RateLimitMiddleware(AdminRateLimitConfigs.ADMIN_LOOKUP), requireAdminACL(AdminACLs.GUILD_AUDIT_LOG_VIEW), Validator('json', ListGuildAuditLogsRequest), OpenAPI({ operationId: 'list_guild_audit_logs_admin', summary: 'List guild audit logs', description: 'Returns in-app guild audit log entries for a guild without requiring VIEW_AUDIT_LOG membership permission. Supports pagination via before/after log IDs and filtering by user_id or action_type. Requires GUILD_AUDIT_LOG_VIEW permission.', responseSchema: ListGuildAuditLogsResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); return ctx.json(await adminService.guildServiceAggregate.listGuildAuditLogs(ctx.req.valid('json'))); }, ); app.post( '/admin/guilds/clear-fields', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_UPDATE_SETTINGS), Validator('json', ClearGuildFieldsRequest), OpenAPI({ operationId: 'clear_guild_fields', summary: 'Clear guild fields', description: 'Clears specified optional guild fields such as icon, banner, or description. Logged to audit log. Requires GUILD_UPDATE_SETTINGS permission.', responseSchema: null, statusCode: 204, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); await adminService.guildServiceAggregate.updateService.clearGuildFields( ctx.req.valid('json'), adminUserId, auditLogReason, ); return ctx.body(null, 204); }, ); app.post( '/admin/guilds/update-features', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_UPDATE_FEATURES), Validator('json', UpdateGuildFeaturesRequest), OpenAPI({ operationId: 'update_guild_features', summary: 'Update guild features', description: 'Enables or disables guild feature flags. Modifies verification levels and community settings. Changes are logged to audit log. Requires GUILD_UPDATE_FEATURES permission.', responseSchema: GuildUpdateResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); const body = ctx.req.valid('json'); const guildId = createGuildID(body.guild_id); return ctx.json( await adminService.guildServiceAggregate.updateService.updateGuildFeatures({ guildId, addFeatures: body.add_features, removeFeatures: body.remove_features, adminUserId, auditLogReason, }), ); }, ); app.post( '/admin/guilds/update-name', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_UPDATE_NAME), Validator('json', UpdateGuildNameRequest), OpenAPI({ operationId: 'update_guild_name', summary: 'Update guild name', description: 'Changes a guild name. Used for removing inappropriate names or correcting display issues. Logged to audit log. Requires GUILD_UPDATE_NAME permission.', responseSchema: GuildUpdateResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); return ctx.json( await adminService.guildServiceAggregate.updateService.updateGuildName( ctx.req.valid('json'), adminUserId, auditLogReason, ), ); }, ); app.post( '/admin/guilds/update-settings', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_UPDATE_SETTINGS), Validator('json', UpdateGuildSettingsRequest), OpenAPI({ operationId: 'update_guild_settings', summary: 'Update guild settings', description: 'Modifies guild configuration including description, region, language and other settings. Logged to audit log. Requires GUILD_UPDATE_SETTINGS permission.', responseSchema: GuildUpdateResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); return ctx.json( await adminService.guildServiceAggregate.updateService.updateGuildSettings( ctx.req.valid('json'), adminUserId, auditLogReason, ), ); }, ); app.post( '/admin/guilds/transfer-ownership', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_TRANSFER_OWNERSHIP), Validator('json', TransferGuildOwnershipRequest), OpenAPI({ operationId: 'admin_transfer_guild_ownership', summary: 'Transfer guild ownership', description: 'Transfers guild ownership to another user. Used when owner is inactive or for administrative recovery. Logged to audit log. Requires GUILD_TRANSFER_OWNERSHIP permission.', responseSchema: GuildUpdateResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); return ctx.json( await adminService.guildServiceAggregate.updateService.transferGuildOwnership( ctx.req.valid('json'), adminUserId, auditLogReason, ), ); }, ); app.post( '/admin/guilds/update-vanity', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_UPDATE_VANITY), Validator('json', UpdateGuildVanityRequest), OpenAPI({ operationId: 'update_guild_vanity', summary: 'Update guild vanity', description: 'Updates a guild vanity URL slug. Sets custom short URL and prevents duplicate slugs. Logged to audit log. Requires GUILD_UPDATE_VANITY permission.', responseSchema: GuildUpdateResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); return ctx.json( await adminService.guildServiceAggregate.vanityService.updateGuildVanity( ctx.req.valid('json'), adminUserId, auditLogReason, ), ); }, ); app.post( '/admin/guilds/force-add-user', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_FORCE_ADD_MEMBER), Validator('json', ForceAddUserToGuildRequest), OpenAPI({ operationId: 'force_add_user_to_guild', summary: 'Force add user to guild', description: 'Forcefully adds a user to a guild. Bypasses normal invite flow for administrative account recovery. Logged to audit log. Requires GUILD_FORCE_ADD_MEMBER permission.', responseSchema: SuccessResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); const requestCache = ctx.get('requestCache'); return ctx.json( await adminService.guildServiceAggregate.membershipService.forceAddUserToGuild({ data: ctx.req.valid('json'), requestCache, adminUserId, auditLogReason, }), ); }, ); app.post( '/admin/guilds/ban-member', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_BAN_MEMBER), Validator('json', BanGuildMemberRequest), OpenAPI({ operationId: 'admin_ban_guild_member', summary: 'Ban guild member', description: 'Permanently bans a user from a guild. Prevents user from joining. Logged to audit log. Requires GUILD_BAN_MEMBER permission.', responseSchema: null, statusCode: 204, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); await adminService.guildServiceAggregate.membershipService.banMember( ctx.req.valid('json'), adminUserId, auditLogReason, ); return ctx.body(null, 204); }, ); app.post( '/admin/guilds/kick-member', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_KICK_MEMBER), Validator('json', KickGuildMemberRequest), OpenAPI({ operationId: 'kick_guild_member', summary: 'Kick guild member', description: 'Temporarily removes a user from a guild. User can rejoin. Logged to audit log. Requires GUILD_KICK_MEMBER permission.', responseSchema: null, statusCode: 204, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); await adminService.guildServiceAggregate.membershipService.kickMember( ctx.req.valid('json'), adminUserId, auditLogReason, ); return ctx.body(null, 204); }, ); app.post( '/admin/guilds/reload', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_RELOAD), Validator('json', ReloadGuildRequest), OpenAPI({ operationId: 'reload_guild', summary: 'Reload guild', description: 'Reloads a single guild state from database. Used to recover from corruption or sync issues. Logged to audit log. Requires GUILD_RELOAD permission.', responseSchema: SuccessResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); const body = ctx.req.valid('json'); return ctx.json( await adminService.guildServiceAggregate.managementService.reloadGuild( body.guild_id, adminUserId, auditLogReason, ), ); }, ); app.post( '/admin/guilds/shutdown', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_SHUTDOWN), Validator('json', ShutdownGuildRequest), OpenAPI({ operationId: 'shutdown_guild', summary: 'Shutdown guild', description: 'Shuts down and unloads a guild from the gateway. Guild data remains in database. Used for emergency resource cleanup. Logged to audit log. Requires GUILD_SHUTDOWN permission.', responseSchema: SuccessResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); const body = ctx.req.valid('json'); return ctx.json( await adminService.guildServiceAggregate.managementService.shutdownGuild( body.guild_id, adminUserId, auditLogReason, ), ); }, ); app.post( '/admin/guilds/delete', RateLimitMiddleware(RateLimitConfigs.ADMIN_GUILD_MODIFY), requireAdminACL(AdminACLs.GUILD_DELETE), Validator('json', DeleteGuildRequest), OpenAPI({ operationId: 'admin_delete_guild', summary: 'Delete guild', description: 'Permanently deletes a guild. Deletes all channels, messages, and settings. Irreversible operation. Logged to audit log. Requires GUILD_DELETE permission.', responseSchema: SuccessResponse, statusCode: 200, security: 'adminApiKey', tags: 'Admin', }), async (ctx) => { const adminService = ctx.get('adminService'); const adminUserId = ctx.get('adminUserId'); const auditLogReason = ctx.get('auditLogReason'); const body = ctx.req.valid('json'); return ctx.json( await adminService.guildServiceAggregate.managementService.deleteGuild( body.guild_id, adminUserId, auditLogReason, ), ); }, );}