Merge pull request #1318 from dank074/patch/bans-api

This commit is contained in:
Madeline 2025-07-22 08:55:02 +10:00 committed by GitHub
commit dc007c006b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 97 additions and 17 deletions

View File

@ -18,11 +18,13 @@
import { getIpAdress, route } from "@spacebar/api";
import {
APIBansArray,
Ban,
BanRegistrySchema,
DiscordApiErrors,
GuildBanAddEvent,
GuildBanRemoveEvent,
GuildBansResponse,
Member,
User,
emitEvent,
@ -40,7 +42,7 @@ router.get(
permission: "BAN_MEMBERS",
responses: {
200: {
body: "GuildBansResponse",
body: "APIBansArray",
},
403: {
body: "APIErrorResponse",
@ -50,27 +52,27 @@ router.get(
async (req: Request, res: Response) => {
const { guild_id } = req.params;
const bans = await Ban.find({ where: { guild_id: guild_id } });
const promisesToAwait: object[] = [];
const bansObj: object[] = [];
let bans = await Ban.find({ where: { guild_id: guild_id } });
const promisesToAwait: Promise<User>[] = [];
const bansObj: APIBansArray = [];
bans.filter((ban) => ban.user_id !== ban.executor_id); // pretend self-bans don't exist to prevent victim chasing
bans = bans.filter((ban) => ban.user_id !== ban.executor_id); // pretend self-bans don't exist to prevent victim chasing
bans.forEach((ban) => {
promisesToAwait.push(User.getPublicUser(ban.user_id));
});
const bannedUsers: object[] = await Promise.all(promisesToAwait);
const bannedUsers = await Promise.all(promisesToAwait);
bans.forEach((ban, index) => {
const user = bannedUsers[index] as User;
const user = bannedUsers[index];
bansObj.push({
reason: ban.reason,
reason: ban.reason ?? null,
user: {
username: user.username,
discriminator: user.discriminator,
id: user.id,
avatar: user.avatar,
avatar: user.avatar ?? null,
public_flags: user.public_flags,
},
});
@ -80,13 +82,83 @@ router.get(
},
);
router.get(
"/search",
route({
permission: "BAN_MEMBERS",
query: {
query: {
type: "string",
description:
"Query to match username(s) and display name(s) against (1-32 characters)",
required: true,
},
limit: {
type: "number",
description:
"Max number of members to return (1-10, default 10)",
required: false,
},
},
responses: {
200: {
body: "APIBansArray",
},
403: {
body: "APIErrorResponse",
},
},
}),
async (req: Request, res: Response) => {
const { guild_id } = req.params;
const limit = Number(req.query.limit) || 10;
if (limit > 10 || limit < 1)
throw new HTTPError("Limit must be between 1 and 10");
const query = String(req.query.query);
if (!query || query.trim().length === 0 || query.length > 32) {
throw new HTTPError(
"The query must be between 1 and 32 characters in length",
);
}
let bans = await Ban.createQueryBuilder("ban")
.leftJoinAndSelect("ban.user", "user")
.where("ban.guild_id = :guildId", { guildId: guild_id })
.andWhere("user.username LIKE :userName", {
userName: `%${query}%`,
})
.limit(limit)
.getMany();
bans = bans.filter((ban) => ban.user_id !== ban.executor_id); // pretend self-bans don't exist to prevent victim chasing
const bansObj: APIBansArray = bans.map((ban) => {
const user = ban.user;
return {
reason: ban.reason ?? null,
user: {
username: user.username,
discriminator: user.discriminator,
id: user.id,
avatar: user.avatar ?? null,
public_flags: user.public_flags,
},
};
});
return res.json(bansObj);
},
);
router.get(
"/:user_id",
route({
permission: "BAN_MEMBERS",
responses: {
200: {
body: "BanModeratorSchema",
body: "GuildBansResponse",
},
403: {
body: "APIErrorResponse",
@ -106,9 +178,17 @@ router.get(
if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN;
// pretend self-bans don't exist to prevent victim chasing
const banInfo = {
user: await User.getPublicUser(ban.user_id),
reason: ban.reason,
const user = await User.getPublicUser(ban.user_id);
const banInfo: GuildBansResponse = {
user: {
username: user.username,
discriminator: user.discriminator,
id: user.id,
avatar: user.avatar ?? null,
public_flags: user.public_flags,
},
reason: ban.reason ?? null,
};
return res.json(banInfo);
@ -121,9 +201,7 @@ router.put(
requestBody: "BanCreateSchema",
permission: "BAN_MEMBERS",
responses: {
200: {
body: "Ban",
},
204: {},
400: {
body: "APIErrorResponse",
},

View File

@ -16,7 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { GuildCreateResponse } from "@spacebar/util";
import { GuildBansResponse, GuildCreateResponse } from "@spacebar/util";
import { GeneralConfiguration, LimitsConfiguration } from "../../config";
import { DmChannelDTO } from "../../dtos";
import {
@ -73,6 +73,8 @@ export type ApplicationSkusResponse = unknown[];
export type APIApplicationArray = Application[];
export type APIBansArray = GuildBansResponse[];
export type APIInviteArray = Invite[];
export type APIMessageArray = Message[];