This repository has no description
Something went wrong. Try again.
14 kB · 365 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366// SPDX-License-Identifier: AGPL-3.0-or-later
import {SudoVerificationSchema} from '@fluxer/schema/src/domains/auth/AuthSchemas';import { GuildIdParam, GuildIdUserIdParam, GuildIdUserIdRoleIdParam,} from '@fluxer/schema/src/domains/common/CommonParamSchemas';import {GuildBanResponse, GuildMemberResponse} from '@fluxer/schema/src/domains/guild/GuildMemberSchemas';import { GuildBanCreateRequest, GuildMemberListQuery, GuildMemberUpdateRequest, GuildTransferOwnershipRequest, MyGuildMemberUpdateRequest,} from '@fluxer/schema/src/domains/guild/GuildRequestSchemas';import {GuildResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';import {z} from 'zod';import {requireSudoMode} from '../../auth/services/SudoVerificationService';import {createGuildID, createRoleID, createUserID} from '../../BrandedTypes';import {LoginRequired} from '../../middleware/AuthMiddleware';import {RateLimitMiddleware} from '../../middleware/RateLimitMiddleware';import {OpenAPI} from '../../middleware/ResponseTypeMiddleware';import {SudoModeMiddleware} from '../../middleware/SudoModeMiddleware';import {RateLimitConfigs} from '../../RateLimitConfig';import type {HonoApp} from '../../types/HonoEnv';import {Validator} from '../../Validator';
export function GuildMemberController(app: HonoApp) { app.get( '/guilds/:guild_id/members', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBERS), LoginRequired, Validator('param', GuildIdParam), Validator('query', GuildMemberListQuery), OpenAPI({ operationId: 'list_guild_members', summary: 'List guild members', responseSchema: z.array(GuildMemberResponse), statusCode: 200, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'List guild members. Supports pagination with limit and after cursor. Returns member information for the specified guild.', }), async (ctx) => { const userId = ctx.get('user').id; const guildId = createGuildID(ctx.req.valid('param').guild_id); const {limit, after} = ctx.req.valid('query'); const requestCache = ctx.get('requestCache'); return ctx.json( await ctx.get('guildService').members.getMembers({ userId, guildId, limit, after: after != null ? createUserID(after) : undefined, requestCache, }), ); }, ); app.get( '/guilds/:guild_id/members/@me', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBERS), LoginRequired, Validator('param', GuildIdParam), OpenAPI({ operationId: 'get_current_guild_member', summary: 'Get current user guild member', responseSchema: GuildMemberResponse, statusCode: 200, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Get current user guild member. Returns the member information for the authenticated user in the specified guild.', }), async (ctx) => { const userId = ctx.get('user').id; const guildId = createGuildID(ctx.req.valid('param').guild_id); const requestCache = ctx.get('requestCache'); return ctx.json( await ctx.get('guildService').members.getMember({userId, targetId: userId, guildId, requestCache}), ); }, ); app.get( '/guilds/:guild_id/members/:user_id', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBERS), LoginRequired, Validator('param', GuildIdUserIdParam), OpenAPI({ operationId: 'get_guild_member', summary: 'Get guild member by user ID', responseSchema: GuildMemberResponse, statusCode: 200, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Get guild member by user ID. Returns member information including roles, nickname, and join date for the specified user in the guild.', }), async (ctx) => { const {guild_id, user_id} = ctx.req.valid('param'); const userId = ctx.get('user').id; const targetId = createUserID(user_id); const guildId = createGuildID(guild_id); const requestCache = ctx.get('requestCache'); return ctx.json(await ctx.get('guildService').members.getMember({userId, targetId, guildId, requestCache})); }, ); app.patch( '/guilds/:guild_id/members/@me', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBER_UPDATE), LoginRequired, Validator('param', GuildIdParam), Validator('json', MyGuildMemberUpdateRequest), OpenAPI({ operationId: 'update_current_guild_member', summary: 'Update current user guild member', responseSchema: GuildMemberResponse, statusCode: 200, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Update current user guild member. User can modify their own nickname within the guild.', }), async (ctx) => { const userId = ctx.get('user').id; const guildId = createGuildID(ctx.req.valid('param').guild_id); const requestCache = ctx.get('requestCache'); const data = ctx.req.valid('json'); const auditLogReason = ctx.get('auditLogReason') ?? null; const result = await ctx .get('guildService') .members.updateMember({userId, targetId: userId, guildId, data, requestCache}, auditLogReason); return ctx.json(result); }, ); app.patch( '/guilds/:guild_id/members/:user_id', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBER_UPDATE), LoginRequired, Validator('param', GuildIdUserIdParam), Validator('json', GuildMemberUpdateRequest), OpenAPI({ operationId: 'update_guild_member', summary: 'Update guild member', responseSchema: GuildMemberResponse, statusCode: 200, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Update guild member. Requires manage_members permission. Can modify member nickname, voice state, and other member properties.', }), async (ctx) => { const {guild_id, user_id} = ctx.req.valid('param'); const userId = ctx.get('user').id; const targetId = createUserID(user_id); const guildId = createGuildID(guild_id); const data = ctx.req.valid('json'); const requestCache = ctx.get('requestCache'); const auditLogReason = ctx.get('auditLogReason') ?? null; const result = await ctx .get('guildService') .members.updateMember({userId, targetId, guildId, data, requestCache}, auditLogReason); return ctx.json(result); }, ); app.delete( '/guilds/:guild_id/members/:user_id', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBER_REMOVE), LoginRequired, Validator('param', GuildIdUserIdParam), OpenAPI({ operationId: 'remove_guild_member', summary: 'Remove guild member', responseSchema: null, statusCode: 204, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Remove guild member. Requires kick_members permission. Removes the specified user from the guild.', }), async (ctx) => { const {guild_id, user_id} = ctx.req.valid('param'); const userId = ctx.get('user').id; const targetId = createUserID(user_id); const guildId = createGuildID(guild_id); const auditLogReason = ctx.get('auditLogReason') ?? null; await ctx.get('guildService').members.removeMember({userId, targetId, guildId}, auditLogReason); return ctx.body(null, 204); }, ); app.post( '/guilds/:guild_id/transfer-ownership', RateLimitMiddleware(RateLimitConfigs.GUILD_UPDATE), LoginRequired, Validator('param', GuildIdParam), SudoModeMiddleware, Validator('json', GuildTransferOwnershipRequest.merge(SudoVerificationSchema)), OpenAPI({ operationId: 'transfer_guild_ownership', summary: 'Transfer guild ownership', responseSchema: GuildResponse, statusCode: 200, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Transfer guild ownership. Only current owner can transfer. Requires sudo mode verification (MFA). Transfers all guild permissions to a new owner.', }), async (ctx) => { const user = ctx.get('user'); const userId = user.id; const guildId = createGuildID(ctx.req.valid('param').guild_id); const body = ctx.req.valid('json'); await requireSudoMode(ctx, user, body); const {new_owner_id} = body; const newOwnerId = createUserID(new_owner_id); const auditLogReason = ctx.get('auditLogReason') ?? null; return ctx.json( await ctx.get('guildService').data.transferOwnership({userId, guildId, newOwnerId}, auditLogReason), ); }, ); app.get( '/guilds/:guild_id/bans', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBERS), LoginRequired, Validator('param', GuildIdParam), OpenAPI({ operationId: 'list_guild_bans', summary: 'List guild bans', responseSchema: z.array(GuildBanResponse), statusCode: 200, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'List guild bans. Requires ban_members permission. Returns all banned users for the guild including ban reasons and expiry times.', }), async (ctx) => { const userId = ctx.get('user').id; const guildId = createGuildID(ctx.req.valid('param').guild_id); const requestCache = ctx.get('requestCache'); return ctx.json(await ctx.get('guildService').moderation.listBans({userId, guildId, requestCache})); }, ); app.put( '/guilds/:guild_id/bans/:user_id', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBER_REMOVE), LoginRequired, Validator('param', GuildIdUserIdParam), Validator('json', GuildBanCreateRequest), OpenAPI({ operationId: 'ban_guild_member', summary: 'Ban guild member', responseSchema: null, statusCode: 204, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Ban guild member. Requires ban_members permission. Prevents user from joining; optionally deletes recent messages and sets ban expiry duration.', }), async (ctx) => { const {guild_id, user_id} = ctx.req.valid('param'); const userId = ctx.get('user').id; const targetId = createUserID(user_id); const guildId = createGuildID(guild_id); const {delete_message_days, reason, ban_duration_seconds} = ctx.req.valid('json'); const auditLogReason = ctx.get('auditLogReason') ?? null; const effectiveReason = reason ?? auditLogReason ?? undefined; await ctx.get('guildService').moderation.banMember( { userId, guildId, targetId, deleteMessageDays: delete_message_days, reason: effectiveReason, banDurationSeconds: ban_duration_seconds, }, auditLogReason, ); return ctx.body(null, 204); }, ); app.delete( '/guilds/:guild_id/bans/:user_id', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBER_REMOVE), LoginRequired, Validator('param', GuildIdUserIdParam), OpenAPI({ operationId: 'unban_guild_member', summary: 'Unban guild member', responseSchema: null, statusCode: 204, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Unban guild member. Requires ban_members permission. Removes ban and allows user to rejoin the guild.', }), async (ctx) => { const {guild_id, user_id} = ctx.req.valid('param'); const userId = ctx.get('user').id; const targetId = createUserID(user_id); const guildId = createGuildID(guild_id); const auditLogReason = ctx.get('auditLogReason') ?? null; await ctx.get('guildService').moderation.unbanMember({userId, guildId, targetId}, auditLogReason); return ctx.body(null, 204); }, ); app.put( '/guilds/:guild_id/members/:user_id/roles/:role_id', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBER_ROLE_ADD), LoginRequired, Validator('param', GuildIdUserIdRoleIdParam), OpenAPI({ operationId: 'add_guild_member_role', summary: 'Add role to guild member', responseSchema: null, statusCode: 204, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Add role to guild member. Requires manage_roles permission. Grants the specified role to the user in the guild.', }), async (ctx) => { const {guild_id, user_id, role_id} = ctx.req.valid('param'); const userId = ctx.get('user').id; const targetId = createUserID(user_id); const guildId = createGuildID(guild_id); const roleId = createRoleID(role_id); const requestCache = ctx.get('requestCache'); const auditLogReason = ctx.get('auditLogReason') ?? null; await ctx .get('guildService') .members.addMemberRole({userId, targetId, guildId, roleId, requestCache}, auditLogReason); return ctx.body(null, 204); }, ); app.delete( '/guilds/:guild_id/members/:user_id/roles/:role_id', RateLimitMiddleware(RateLimitConfigs.GUILD_MEMBER_ROLE_REMOVE), LoginRequired, Validator('param', GuildIdUserIdRoleIdParam), OpenAPI({ operationId: 'remove_guild_member_role', summary: 'Remove role from guild member', responseSchema: null, statusCode: 204, security: ['botToken', 'bearerToken', 'sessionToken'], tags: ['Guilds'], description: 'Remove role from guild member. Requires manage_roles permission. Revokes the specified role from the user in the guild.', }), async (ctx) => { const {guild_id, user_id, role_id} = ctx.req.valid('param'); const userId = ctx.get('user').id; const targetId = createUserID(user_id); const guildId = createGuildID(guild_id); const roleId = createRoleID(role_id); const requestCache = ctx.get('requestCache'); const auditLogReason = ctx.get('auditLogReason') ?? null; await ctx .get('guildService') .members.removeMemberRole({userId, targetId, guildId, roleId, requestCache}, auditLogReason); return ctx.body(null, 204); }, );}