diff --git a/src/api/middlewares/CORS.ts b/src/api/middlewares/CORS.ts
index 6cb2b1d8c..c4aa9cc08 100644
--- a/src/api/middlewares/CORS.ts
+++ b/src/api/middlewares/CORS.ts
@@ -18,8 +18,6 @@
import { NextFunction, Request, Response } from "express";
-// TODO: config settings
-
export function CORS(req: Request, res: Response, next: NextFunction) {
res.set("Access-Control-Allow-Credentials", "true");
res.set("Access-Control-Allow-Headers", req.header("Access-Control-Request-Headers") || "*");
diff --git a/src/api/routes/applications/#application_id/commands/#command_id/index.ts b/src/api/routes/applications/#application_id/commands/#command_id/index.ts
index 6fc4e28ed..3e4df62ff 100644
--- a/src/api/routes/applications/#application_id/commands/#command_id/index.ts
+++ b/src/api/routes/applications/#application_id/commands/#command_id/index.ts
@@ -19,7 +19,7 @@
import { Request, Response, Router } from "express";
import { route } from "@spacebar/api/middlewares";
import { Application, ApplicationCommand } from "@spacebar/database";
-import { FieldErrors, Snowflake } from "@spacebar/util";
+import { Config, FieldErrors, Snowflake } from "@spacebar/util";
import { ApplicationCommandCreateSchema, ApplicationCommandSchema } from "@spacebar/schemas";
const router = Router({ mergeParams: true });
@@ -68,12 +68,11 @@ router.patch(
body.type = 1;
}
- if (body.name.trim().length < 1 || body.name.trim().length > 32) {
- // TODO: configurable?
+ if (body.name.trim().length < 1 || body.name.trim().length > Config.get().limits.application.commandLimits.maxNameLength) {
throw FieldErrors({
name: {
code: "BASE_TYPE_BAD_LENGTH",
- message: `Must be between 1 and 32 in length.`,
+ message: `Must be between 1 and ${Config.get().limits.application.commandLimits.maxNameLength} in length.`,
},
});
}
diff --git a/src/api/routes/applications/#application_id/commands/index.ts b/src/api/routes/applications/#application_id/commands/index.ts
index 4891a180f..538ea7ea8 100644
--- a/src/api/routes/applications/#application_id/commands/index.ts
+++ b/src/api/routes/applications/#application_id/commands/index.ts
@@ -21,7 +21,7 @@ import { IsNull } from "typeorm";
import { ApplicationCommandCreateSchema, ApplicationCommandSchema } from "@spacebar/schemas";
import { route } from "@spacebar/api/middlewares";
import { Application, ApplicationCommand } from "@spacebar/database";
-import { FieldErrors, Snowflake } from "@spacebar/util";
+import { Config, FieldErrors, Snowflake } from "@spacebar/util";
const router = Router({ mergeParams: true });
@@ -56,12 +56,11 @@ router.post(
body.type = 1;
}
- if (body.name.trim().length < 1 || body.name.trim().length > 32) {
- // TODO: configurable?
+ if (body.name.trim().length < 1 || body.name.trim().length > Config.get().limits.application.commandLimits.maxNameLength) {
throw FieldErrors({
name: {
code: "BASE_TYPE_BAD_LENGTH",
- message: `Must be between 1 and 32 in length.`,
+ message: `Must be between 1 and ${Config.get().limits.application.commandLimits.maxNameLength} in length.`,
},
});
}
@@ -127,12 +126,11 @@ router.put(
command.type = 1;
}
- if (command.name.trim().length < 1 || command.name.trim().length > 32) {
- // TODO: configurable?
+ if (command.name.trim().length < 1 || command.name.trim().length > Config.get().limits.application.commandLimits.maxNameLength) {
throw FieldErrors({
name: {
code: "BASE_TYPE_BAD_LENGTH",
- message: `Must be between 1 and 32 in length.`,
+ message: `Must be between 1 and ${Config.get().limits.application.commandLimits.maxNameLength} in length.`,
},
});
}
diff --git a/src/api/routes/applications/#application_id/guilds/#guild_id/commands/#command_id/index.ts b/src/api/routes/applications/#application_id/guilds/#guild_id/commands/#command_id/index.ts
index 6cbd4ae06..eea17006f 100644
--- a/src/api/routes/applications/#application_id/guilds/#guild_id/commands/#command_id/index.ts
+++ b/src/api/routes/applications/#application_id/guilds/#guild_id/commands/#command_id/index.ts
@@ -19,7 +19,7 @@
import { Request, Response, Router } from "express";
import { route } from "@spacebar/api/middlewares";
import { Application, ApplicationCommand, Guild, Member } from "@spacebar/database";
-import { FieldErrors, Snowflake } from "@spacebar/util";
+import { Config, FieldErrors, Snowflake } from "@spacebar/util";
import { ApplicationCommandCreateSchema, ApplicationCommandSchema } from "@spacebar/schemas";
const router = Router({ mergeParams: true });
@@ -87,12 +87,11 @@ router.patch(
body.type = 1;
}
- if (body.name.trim().length < 1 || body.name.trim().length > 32) {
- // TODO: configurable?
+ if (body.name.trim().length < 1 || body.name.trim().length > Config.get().limits.application.commandLimits.maxNameLength) {
throw FieldErrors({
name: {
code: "BASE_TYPE_BAD_LENGTH",
- message: `Must be between 1 and 32 in length.`,
+ message: `Must be between 1 and ${Config.get().limits.application.commandLimits.maxNameLength} in length.`,
},
});
}
diff --git a/src/api/routes/applications/#application_id/guilds/#guild_id/commands/index.ts b/src/api/routes/applications/#application_id/guilds/#guild_id/commands/index.ts
index 19444d3a8..520ca9995 100644
--- a/src/api/routes/applications/#application_id/guilds/#guild_id/commands/index.ts
+++ b/src/api/routes/applications/#application_id/guilds/#guild_id/commands/index.ts
@@ -19,7 +19,7 @@
import { Request, Response, Router } from "express";
import { route } from "@spacebar/api/middlewares";
import { Application, ApplicationCommand, Guild, Member } from "@spacebar/database";
-import { FieldErrors, Snowflake } from "@spacebar/util";
+import { Config, FieldErrors, Snowflake } from "@spacebar/util";
import { ApplicationCommandCreateSchema, ApplicationCommandSchema } from "@spacebar/schemas";
const router = Router({ mergeParams: true });
@@ -79,12 +79,11 @@ router.post(
body.type = 1;
}
- if (body.name.trim().length < 1 || body.name.trim().length > 32) {
- // TODO: configurable?
+ if (body.name.trim().length < 1 || body.name.trim().length > Config.get().limits.application.commandLimits.maxNameLength) {
throw FieldErrors({
name: {
code: "BASE_TYPE_BAD_LENGTH",
- message: `Must be between 1 and 32 in length.`,
+ message: `Must be between 1 and ${Config.get().limits.application.commandLimits.maxNameLength} in length.`,
},
});
}
@@ -165,12 +164,11 @@ router.put(
command.type = 1;
}
- if (command.name.trim().length < 1 || command.name.trim().length > 32) {
- // TODO: configurable?
+ if (command.name.trim().length < 1 || command.name.trim().length > Config.get().limits.application.commandLimits.maxNameLength) {
throw FieldErrors({
name: {
code: "BASE_TYPE_BAD_LENGTH",
- message: `Must be between 1 and 32 in length.`,
+ message: `Must be between 1 and ${Config.get().limits.application.commandLimits.maxNameLength} in length.`,
},
});
}
diff --git a/src/api/routes/beaker.ts b/src/api/routes/beaker.ts
index 88cc72c09..393c89d64 100644
--- a/src/api/routes/beaker.ts
+++ b/src/api/routes/beaker.ts
@@ -31,7 +31,6 @@ router.post(
spacebarOnly: false, // Not part of public openapi
}),
(req: Request, res: Response) => {
- // TODO:
res.sendStatus(204);
},
);
diff --git a/src/api/routes/channels/#channel_id/invites.ts b/src/api/routes/channels/#channel_id/invites.ts
index c16b9f955..d57b4f2be 100644
--- a/src/api/routes/channels/#channel_id/invites.ts
+++ b/src/api/routes/channels/#channel_id/invites.ts
@@ -21,9 +21,9 @@ import { HTTPError } from "lambert-server/HTTPError";
import { route } from "@spacebar/api/middlewares";
import { Channel, Guild, Invite, PublicInviteRelation, User } from "@spacebar/database";
import { InviteCreateEvent, emitEvent } from "@spacebar/util";
-import { InviteCreateSchema, isTextChannel } from "@spacebar/schemas";
+import { InviteCreateSchema, isTextChannel, PublicUserProjection } from "@spacebar/schemas";
import { Random } from "@spacebar/extensions";
-import { InviteListResponse } from "@spacebar/schemas/api/guilds/Invite";
+import { InviteListResponse, PublicInvite } from "@spacebar/schemas/api/guilds/Invite";
const router: Router = Router({ mergeParams: true });
@@ -35,7 +35,7 @@ router.post(
right: "CREATE_INVITES",
responses: {
201: {
- body: "Invite",
+ body: "PublicInvite",
},
404: {},
400: {
@@ -71,21 +71,20 @@ router.post(
guild_id,
channel_id: channel_id,
inviter_id: user_id,
+ inviter: await User.findOneOrFail({
+ where: { id: req.user_id },
+ select: Object.fromEntries(PublicUserProjection.map((i) => [i, true])), // TODO: clean up
+ }),
flags: body.flags ?? 0,
}).save();
- const data = invite.toJSON();
- data.inviter = await User.getPublicUser(req.user_id);
- data.guild = await Guild.findOne({ where: { id: guild_id } });
- data.channel = channel;
-
await emitEvent({
event: "INVITE_CREATE",
- data,
+ data: invite.toGatewayInviteCreateData(),
guild_id,
} satisfies InviteCreateEvent);
- res.status(201).send(data);
+ res.status(201).send(invite.toPublicJSON());
},
);
diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts
index 1816aa6db..d85b05119 100644
--- a/src/api/routes/channels/#channel_id/messages/index.ts
+++ b/src/api/routes/channels/#channel_id/messages/index.ts
@@ -18,7 +18,7 @@
import { handleMessage, postHandleMessage } from "@spacebar/api/util";
import { route } from "@spacebar/api/middlewares";
-import { Attachment, Channel, Member, Message, ReadState, Relationship, User, ThreadMember, ThreadMemberFlags } from "@spacebar/database";
+import { Attachment, Channel, Member, Message, ReadState, Relationship, User, ThreadMember } from "@spacebar/database";
import {
Config,
DiscordApiErrors,
@@ -52,6 +52,7 @@ import {
Reaction,
ReadStateType,
RelationshipType,
+ ThreadMemberFlags,
} from "@spacebar/schemas";
const router: Router = Router({ mergeParams: true });
diff --git a/src/api/routes/channels/#channel_id/post-data.ts b/src/api/routes/channels/#channel_id/post-data.ts
index 202cce99b..72d582546 100644
--- a/src/api/routes/channels/#channel_id/post-data.ts
+++ b/src/api/routes/channels/#channel_id/post-data.ts
@@ -21,7 +21,7 @@ import { messageUpload } from "./messages";
import { In } from "typeorm";
import { route } from "@spacebar/api/middlewares";
import { Channel, Member, Message } from "@spacebar/database";
-import { PostDataSchema, PublicMessage } from "@spacebar/schemas";
+import { PostDataResponse, PostDataSchema, PublicMessage } from "@spacebar/schemas";
const router = Router({ mergeParams: true });
@@ -43,7 +43,9 @@ router.post(
requestBody: "PostDataSchema",
permission: "VIEW_CHANNEL",
responses: {
- 200: {},
+ 200: {
+ body: "PostDataResponse",
+ },
403: {},
},
}),
@@ -54,6 +56,7 @@ router.post(
id: In(body),
},
});
+
const [messages, members] = await Promise.all([
Message.find({
where: {
@@ -81,17 +84,18 @@ router.post(
},
}),
]);
+
await Message.fillReplies(messages);
- const objRet: { threads: Record<string, { first_message: null | PublicMessage; owner: null | Member }> } = { threads: {} };
+ const threadPostData: PostDataResponse = { threads: {} };
for (const thread of threads) {
- const owner = members.find(({ id }) => id === thread.owner_id)?.toJSON() || null;
- const first_message = messages.find(({ channel_id }) => channel_id === thread.id)?.toJSON() || null;
- objRet.threads[thread.id] = {
+ const owner = members.find(({ id }) => id === thread.owner_id)?.toPublicMember() ?? null;
+ const first_message = messages.find(({ channel_id }) => channel_id === thread.id)?.toJSON() ?? null;
+ threadPostData.threads[thread.id] = {
owner,
first_message,
};
}
- return res.json(objRet);
+ return res.json(threadPostData);
},
);
diff --git a/src/api/routes/channels/#channel_id/thread-members.ts b/src/api/routes/channels/#channel_id/thread-members.ts
index f1d2a6cf1..f6ed628ec 100644
--- a/src/api/routes/channels/#channel_id/thread-members.ts
+++ b/src/api/routes/channels/#channel_id/thread-members.ts
@@ -19,9 +19,9 @@
import { Request, Response, Router } from "express";
import { MoreThan } from "typeorm";
import { route } from "@spacebar/api/middlewares";
-import { Channel, Member, ThreadMember, ThreadMemberFlags } from "@spacebar/database";
+import { Channel, Member, ThreadMember } from "@spacebar/database";
import { emitEvent, Permissions, ThreadCreateEvent, ThreadDeleteEvent, ThreadMembersUpdateEvent } from "@spacebar/util";
-import { ChannelType, Snowflake } from "@spacebar/schemas";
+import { ChannelType, Snowflake, ThreadMemberFlags } from "@spacebar/schemas";
const router = Router({ mergeParams: true });
@@ -29,7 +29,9 @@ router.get(
"/",
route({
responses: {
- 200: {},
+ 200: {
+ body: "PublicThreadMembersResponse",
+ },
403: {},
},
permission: "VIEW_CHANNEL",
@@ -51,12 +53,14 @@ router.get(
}
return res.send(
- await ThreadMember.find({
- where: { channel: { id: channel_id }, ...(after ? { user_id: MoreThan(after) } : {}) },
- take: limit ? parseInt(limit) : 50,
- order: { member_idx: "ASC" },
- relations: { ...(with_member ? { member: true } : {}) },
- }),
+ (
+ await ThreadMember.find({
+ where: { channel: { id: channel_id }, ...(after ? { user_id: MoreThan(after) } : {}) },
+ take: limit ? parseInt(limit) : 50,
+ order: { member_idx: "ASC" },
+ relations: { ...(with_member ? { member: true } : {}) },
+ })
+ ).map((m) => m.toJSON()),
);
},
);
diff --git a/src/api/routes/guilds/#guild_id/application-command-index.ts b/src/api/routes/guilds/#guild_id/application-command-index.ts
index 758392fe8..10f404e47 100644
--- a/src/api/routes/guilds/#guild_id/application-command-index.ts
+++ b/src/api/routes/guilds/#guild_id/application-command-index.ts
@@ -64,10 +64,11 @@ router.get("/", route({}), async (req: Request, res: Response) => {
guild_id: command.guild_id,
name: command.name,
name_localizations: command.name_localizations,
- // name_localized: // TODO: make this work
+ name_localized: (command.name_localizations && req.user.settings?.locale ? command.name_localizations[req.user.settings.locale] : null) ?? command.name,
description: command.description,
description_localizations: command.description_localizations,
- // description_localized: // TODO: make this work
+ description_localized:
+ (command.description_localizations && req.user.settings?.locale ? command.description_localizations[req.user.settings.locale] : null) ?? command.description,
options: command.type === ApplicationCommandType.CHAT_INPUT ? command.options : undefined,
default_member_permissions: command.default_member_permissions,
dm_permission: command.dm_permission,
diff --git a/src/api/routes/guilds/#guild_id/bans.ts b/src/api/routes/guilds/#guild_id/bans.ts
index 821746654..1a4890b8a 100644
--- a/src/api/routes/guilds/#guild_id/bans.ts
+++ b/src/api/routes/guilds/#guild_id/bans.ts
@@ -26,6 +26,7 @@ import { BanCreateSchema, BanRegistrySchema, GuildBanResponse, GuildBansResponse
const router: Router = Router({ mergeParams: true });
/* TODO: Deleting the secrets is just a temporary go-around. Views should be implemented for both safety and better handling. */
+// Emma [it/its] @ Rory& - 2026-11-01 - what secrets?
router.get(
"/",
diff --git a/src/api/routes/guilds/#guild_id/index.ts b/src/api/routes/guilds/#guild_id/index.ts
index 9fa61a4d3..c4eb05515 100644
--- a/src/api/routes/guilds/#guild_id/index.ts
+++ b/src/api/routes/guilds/#guild_id/index.ts
@@ -109,7 +109,6 @@ router.patch(
if (body.features) {
const diff = guild.features.filter((x) => !body.features?.includes(x)).concat(body.features.filter((x) => !guild.features.includes(x)));
- // TODO move these
const MUTABLE_FEATURES = ["COMMUNITY", "INVITES_DISABLED", "DISCOVERABLE"];
for (const feature of diff) {
diff --git a/src/api/routes/guilds/#guild_id/regions.ts b/src/api/routes/guilds/#guild_id/regions.ts
index 025ea7c44..8709c9c00 100644
--- a/src/api/routes/guilds/#guild_id/regions.ts
+++ b/src/api/routes/guilds/#guild_id/regions.ts
@@ -38,7 +38,6 @@ router.get(
async (req: Request, res: Response) => {
const { guild_id } = req.params as { [key: string]: string };
const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
- //TODO we should use an enum for guild's features and not hardcoded strings
return res.json(await getVoiceRegions(req.ip!, guild.features.includes("VIP_REGIONS")));
},
);
diff --git a/src/api/routes/guilds/index.ts b/src/api/routes/guilds/index.ts
index 231ba9041..6e6bf2099 100644
--- a/src/api/routes/guilds/index.ts
+++ b/src/api/routes/guilds/index.ts
@@ -24,8 +24,6 @@ import { GuildCreateSchema } from "@spacebar/schemas";
const router: Router = Router({ mergeParams: true });
-//TODO: create default channel
-
router.post(
"/",
route({
diff --git a/src/api/routes/read-states/ack-bulk.ts b/src/api/routes/read-states/ack-bulk.ts
index 5a1cef184..07fcec962 100644
--- a/src/api/routes/read-states/ack-bulk.ts
+++ b/src/api/routes/read-states/ack-bulk.ts
@@ -37,8 +37,6 @@ router.post(
async (req: Request, res: Response) => {
const body = req.body as AckBulkSchema;
- // TODO: what is read_state_type ?
-
await Promise.all([
// for every new state
...body.read_states.map(async (x) => {
diff --git a/src/api/routes/science.ts b/src/api/routes/science.ts
index 34f342883..012a78989 100644
--- a/src/api/routes/science.ts
+++ b/src/api/routes/science.ts
@@ -30,7 +30,6 @@ router.post(
authentication: "never",
}),
(req: Request, res: Response) => {
- // TODO:
res.sendStatus(204);
},
);
diff --git a/src/api/routes/teams.ts b/src/api/routes/teams.ts
index 16fd5d3a5..1370c1eea 100644
--- a/src/api/routes/teams.ts
+++ b/src/api/routes/teams.ts
@@ -84,7 +84,7 @@ router.post(
role: TeamMemberRole.ADMIN,
}).save();
- res.json(team.toJSON() satisfies Team);
+ res.json(team.toJSON());
},
);
diff --git a/src/api/routes/users/@me/billing/payment-sources.ts b/src/api/routes/users/@me/billing/payment-sources.ts
index 3c6008cf7..ec68efd12 100644
--- a/src/api/routes/users/@me/billing/payment-sources.ts
+++ b/src/api/routes/users/@me/billing/payment-sources.ts
@@ -47,34 +47,63 @@ const example = {
default: false,
};
-router.get("/", route({}), (req: Request, res: Response) => {
- // TODO: schema
- res.json([example]).status(200);
-});
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: { body: "PaymentSourceListResponse" },
+ },
+ }),
+ (req: Request, res: Response) => {
+ res.json([example]).status(200);
+ },
+);
-router.post("/", route({}), (req: Request, res: Response) => {
- // TODO: schema
- res.json([example]).status(200);
-});
+router.post(
+ "/",
+ route({
+ responses: {
+ 200: { body: "PaymentSourceListResponse" },
+ },
+ }),
+ // TODO: request schema
+ (req: Request, res: Response) => {
+ res.json([example]).status(200);
+ },
+);
-router.get("/:payment_source_id", route({}), (req: Request, res: Response) => {
- // TODO: schema
- res.json({
- ...example,
- id: req.route.payment_source_id,
- }).status(200);
-});
+router.get(
+ "/:payment_source_id",
+ route({
+ responses: {
+ 200: { body: "PaymentSource" },
+ },
+ }),
+ (req: Request, res: Response) => {
+ res.json({
+ ...example,
+ id: req.route.payment_source_id,
+ }).status(200);
+ },
+);
-router.patch("/:payment_source_id", route({}), (req: Request, res: Response) => {
- // TODO: schema
- res.json({
- ...example,
- id: req.route.payment_source_id,
- }).status(200);
-});
+router.patch(
+ "/:payment_source_id",
+ route({
+ responses: {
+ 200: { body: "PaymentSourceListResponse" },
+ },
+ }),
+ (req: Request, res: Response) => {
+ // TODO: request schema
+ res.json({
+ ...example,
+ id: req.route.payment_source_id,
+ }).status(200);
+ },
+);
router.delete("/:payment_source_id", route({}), (req: Request, res: Response) => {
- // TODO: schema
res.status(204);
});
diff --git a/src/api/routes/users/@me/delete.ts b/src/api/routes/users/@me/delete.ts
index e0887900a..ec29a5fa6 100644
--- a/src/api/routes/users/@me/delete.ts
+++ b/src/api/routes/users/@me/delete.ts
@@ -52,8 +52,6 @@ router.post(
}
}
- // TODO: decrement guild member count
-
if (correctpass) {
// Check if the user owns any guilds.
const ownedGuilds = await Guild.findOne({ where: { owner_id: req.user_id } });
diff --git a/src/api/routes/users/@me/guilds/#guild_id/settings.ts b/src/api/routes/users/@me/guilds/#guild_id/settings.ts
index eb3694b59..fb2f794ed 100644
--- a/src/api/routes/users/@me/guilds/#guild_id/settings.ts
+++ b/src/api/routes/users/@me/guilds/#guild_id/settings.ts
@@ -21,6 +21,8 @@ import { route } from "@spacebar/api/middlewares";
import { Channel, Member } from "@spacebar/database";
import { OrmUtils } from "@spacebar/util";
import { UserGuildSettingsSchema } from "@spacebar/schemas";
+import { In } from "typeorm";
+import { HTTPError } from "lambert-server";
const router = Router({ mergeParams: true });
@@ -60,10 +62,8 @@ router.patch(
const body = req.body as UserGuildSettingsSchema;
if (body.channel_overrides) {
- // TODO: rewrite to a single query?
- for (const channel in body.channel_overrides) {
- await Channel.findOneOrFail({ where: { id: channel } });
- }
+ const channels = await Channel.find({ where: { id: In(Object.keys(body.channel_overrides)), guild_id: req.params.guild_id as string } });
+ if (channels.length != Object.keys(body.channel_overrides).length) throw new HTTPError("Could not find one or more channels.", 404);
}
const user = await Member.findOneOrFail({
diff --git a/src/api/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts
index 341dbf1f3..59565480e 100644
--- a/src/api/routes/users/@me/index.ts
+++ b/src/api/routes/users/@me/index.ts
@@ -153,7 +153,6 @@ router.patch(
}
if (body.discriminator) {
- // TODO: HACK - maybe make this optional?
if (!/^\d{4}$/.test(body.discriminator)) {
throw FieldErrors({
discriminator: {
diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts
index a55a9ff65..660778c8e 100644
--- a/src/api/routes/users/@me/mfa/totp/enable.ts
+++ b/src/api/routes/users/@me/mfa/totp/enable.ts
@@ -51,12 +51,11 @@ router.post(
select: { id: true, data: true, email: true },
});
- // TODO: Are guests allowed to enable 2fa?
if (user.data.hash) {
if (!(await bcrypt.compare(body.password, user.data.hash))) {
throw new HTTPError(req.t("auth:login.INVALID_PASSWORD"));
}
- }
+ } else throw new HTTPError("Guests cannot enable 2FA, please set a password first!", 403);
if (!body.secret) throw new HTTPError(req.t("auth:login.INVALID_TOTP_SECRET"), 60005);
diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts
index 2940b3064..3be73067e 100644
--- a/src/api/util/handlers/Message.ts
+++ b/src/api/util/handlers/Message.ts
@@ -558,7 +558,6 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
return message;
}
-// TODO: cache link result in db
export async function postHandleMessage(message: Message) {
message.clean_data();
@@ -773,25 +772,21 @@ async function handleMessageMentionsAsync(message: Message) {
mention_roles: true,
},
});
+
if (referencedMessage && referencedMessage.author_id !== message.author_id) {
- message.mentions.push(
- // @ts-expect-error it does not like the .toPublicUser() lol
- (await User.findOne({ where: { id: referencedMessage.author_id } }))!.toPublicUser(),
- );
+ const user = await User.findOne({ where: { id: referencedMessage.author_id } });
+ if (user) message.mentions.push(user);
}
if (message.embeds[0]?.type === EmbedType.poll_result) {
- message.mentions.push(
- // @ts-expect-error it does not like the .toPublicUser() lol
- (await User.findOne({ where: { id: message.author_id } }))!.toPublicUser(),
- );
+ const user = await User.findOne({ where: { id: message.author_id } });
+ if (user) message.mentions.push(user);
}
if (message.message_reference.type === MessageReferenceType.FORWARD) {
message.type = MessageType.DEFAULT;
if (message.referenced_message) {
- // TODO: mention_roles and mentions arrays - not needed it seems, but discord still returns that
message.message_snapshots = [message.referenced_message.toSnapshot()];
}
}
|