From e2de706abff59381754ead6887bbe5fd324274fa Mon Sep 17 00:00:00 2001 From: Rory& Date: Thu, 18 Dec 2025 01:24:37 +0100 Subject: [PATCH] Avoid re-fetching user if not requesting extra fields --- src/api/middlewares/Authentication.ts | 11 ++++++++--- .../routes/applications/#application_id/bot/index.ts | 2 +- src/api/routes/applications/index.ts | 6 ++---- src/api/routes/auth/logout.ts | 4 +--- src/api/routes/channels/#channel_id/attachments.ts | 4 ++-- src/api/routes/guilds/#guild_id/emojis.ts | 2 +- src/api/routes/interactions/index.ts | 2 +- src/api/routes/invites/index.ts | 4 +--- src/api/routes/teams.ts | 2 +- src/api/routes/users/@me/mentions.ts | 4 +--- src/api/routes/users/@me/mfa/codes-verification.ts | 2 +- src/api/routes/users/@me/notes.ts | 2 +- 12 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/api/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts index 078a566b2..865d1aa34 100644 --- a/src/api/middlewares/Authentication.ts +++ b/src/api/middlewares/Authentication.ts @@ -16,7 +16,7 @@ along with this program. If not, see . */ -import { checkToken, Rights } from "@spacebar/util"; +import { checkToken, Rights, Session, User, UserTokenData } from "@spacebar/util"; import { NextFunction, Request, Response } from "express"; import { HTTPError } from "lambert-server"; @@ -68,7 +68,10 @@ declare global { interface Request { user_id: string; user_bot: boolean; + tokenData: UserTokenData; token: { id: string; iat: number; ver?: number; did?: string }; + user: User; + session?: Session; rights: Rights; fingerprint?: string; } @@ -116,14 +119,16 @@ export async function Authentication(req: Request, res: Response, next: NextFunc if (!req.headers.authorization) return next(new HTTPError("Missing Authorization Header", 401)); try { - const { decoded, user, session, tokenVersion } = await checkToken(req.headers.authorization, { + const { decoded, user, session, tokenVersion } = (req.tokenData = await checkToken(req.headers.authorization, { ipAddress: req.ip, fingerprint: req.fingerprint, - }); + })); req.token = decoded; req.user_id = decoded.id; req.user_bot = user.bot; + req.user = user; + req.session = session; req.rights = new Rights(Number(user.rights)); return next(); } catch (error) { diff --git a/src/api/routes/applications/#application_id/bot/index.ts b/src/api/routes/applications/#application_id/bot/index.ts index 83b4fc61f..835225e04 100644 --- a/src/api/routes/applications/#application_id/bot/index.ts +++ b/src/api/routes/applications/#application_id/bot/index.ts @@ -67,7 +67,7 @@ router.post( }), async (req: Request, res: Response) => { const bot = await User.findOneOrFail({ where: { id: req.params.application_id } }); - const owner = await User.findOneOrFail({ where: { id: req.user_id } }); + const owner = req.user; if (owner.id != req.user_id) throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; diff --git a/src/api/routes/applications/index.ts b/src/api/routes/applications/index.ts index ff89f03d0..e719e4435 100644 --- a/src/api/routes/applications/index.ts +++ b/src/api/routes/applications/index.ts @@ -53,20 +53,18 @@ router.post( }), async (req: Request, res: Response) => { const body = req.body as ApplicationCreateSchema; - const user = await User.findOneOrFail({ where: { id: req.user_id } }); const app = Application.create({ name: trimSpecial(body.name), description: "", bot_public: true, - owner: user, + owner: req.user, verify_key: "IMPLEMENTME", flags: 0, }); // april 14, 2023: discord made bot users be automatically added to all new apps - const { autoCreateBotUsers } = Config.get().general; - if (autoCreateBotUsers) { + if (Config.get().general.autoCreateBotUsers) { await createAppBotUser(app, req); } else await app.save(); diff --git a/src/api/routes/auth/logout.ts b/src/api/routes/auth/logout.ts index b460e31a9..b4df13a0b 100644 --- a/src/api/routes/auth/logout.ts +++ b/src/api/routes/auth/logout.ts @@ -39,9 +39,7 @@ router.post( if (Object.keys(req.body).length != 0) console.log(`[LOGOUT]: Extra fields sent in logout!`, req.body); } - if (req.token.did) { - await Session.delete({ user_id: req.user_id, session_id: req.token.did }); - } + if (req.session) await Session.remove(req.session); res.status(204).send(); }, diff --git a/src/api/routes/channels/#channel_id/attachments.ts b/src/api/routes/channels/#channel_id/attachments.ts index 30fd2c63f..0d5daa4cc 100644 --- a/src/api/routes/channels/#channel_id/attachments.ts +++ b/src/api/routes/channels/#channel_id/attachments.ts @@ -42,7 +42,7 @@ router.post( const payload = req.body as UploadAttachmentRequestSchema; const { channel_id } = req.params; - const user = await User.findOneOrFail({ where: { id: req.user_id } }); + const user = req.user; const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); if (!(await channel.getUserPermissions({ user_id: req.user_id })).has(Permissions.FLAGS.ATTACH_FILES)) { @@ -102,7 +102,7 @@ router.post( router.delete("/:cloud_attachment_url", async (req: Request, res: Response) => { const { channel_id, cloud_attachment_url } = req.params; - const user = await User.findOneOrFail({ where: { id: req.user_id } }); + const user = req.user; const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); const att = await CloudAttachment.findOneOrFail({ where: { uploadFilename: decodeURI(cloud_attachment_url) } }); if (att.userId !== user.id) { diff --git a/src/api/routes/guilds/#guild_id/emojis.ts b/src/api/routes/guilds/#guild_id/emojis.ts index 5b07380f6..f256ce337 100644 --- a/src/api/routes/guilds/#guild_id/emojis.ts +++ b/src/api/routes/guilds/#guild_id/emojis.ts @@ -108,7 +108,7 @@ router.post( if (emoji_count >= maxEmojis) throw DiscordApiErrors.MAXIMUM_NUMBER_OF_EMOJIS_REACHED.withParams(maxEmojis); if (body.require_colons == null) body.require_colons = true; - const user = await User.findOneOrFail({ where: { id: req.user_id } }); + const user = req.user; await handleFile(`/emojis/${id}`, body.image); const mimeType = body.image.split(":")[1].split(";")[0]; diff --git a/src/api/routes/interactions/index.ts b/src/api/routes/interactions/index.ts index eb516ced5..e997964e0 100644 --- a/src/api/routes/interactions/index.ts +++ b/src/api/routes/interactions/index.ts @@ -41,7 +41,7 @@ router.post("/", route({}), async (req: Request, res: Response) => { }, } as InteractionCreateEvent); - const user = await User.findOneOrFail({ where: { id: req.user_id } }); + const user = req.user; const interactionData: Partial = { id: interactionId, diff --git a/src/api/routes/invites/index.ts b/src/api/routes/invites/index.ts index 26b0ad903..b4fa8a5db 100644 --- a/src/api/routes/invites/index.ts +++ b/src/api/routes/invites/index.ts @@ -71,15 +71,13 @@ router.post( if (req.user_bot) throw DiscordApiErrors.BOT_PROHIBITED_ENDPOINT; const { invite_code } = req.params; + const { public_flags } = req.user; const { guild_id } = await Invite.findOneOrFail({ where: { code: invite_code }, }); const { features } = await Guild.findOneOrFail({ where: { id: guild_id }, }); - const { public_flags } = await User.findOneOrFail({ - where: { id: req.user_id }, - }); const ban = await Ban.findOne({ where: [ { guild_id: guild_id, user_id: req.user_id }, diff --git a/src/api/routes/teams.ts b/src/api/routes/teams.ts index 27ccabf24..090807d59 100644 --- a/src/api/routes/teams.ts +++ b/src/api/routes/teams.ts @@ -63,7 +63,7 @@ router.post( }), async (req: Request, res: Response) => { const user = await User.findOneOrFail({ - where: [{ id: req.user_id }], + where: { id: req.user_id }, select: ["mfa_enabled"], }); if (!user.mfa_enabled) throw new HTTPError("You must enable MFA to create a team"); diff --git a/src/api/routes/users/@me/mentions.ts b/src/api/routes/users/@me/mentions.ts index 2d631e90b..c2985ca4e 100644 --- a/src/api/routes/users/@me/mentions.ts +++ b/src/api/routes/users/@me/mentions.ts @@ -43,9 +43,7 @@ router.get( const before = req.query.before !== undefined ? String(req.query.before as string) : undefined; const guild_id = req.query.guild_id !== undefined ? req.query.guild_id : undefined; - const user = await User.findOneOrFail({ - where: { id: req.user_id }, - }); + const user = req.user; const memberships = await Member.find({ where: { id: req.user_id, ...(guild_id === undefined ? {} : { guild_id: String(guild_id) }) }, diff --git a/src/api/routes/users/@me/mfa/codes-verification.ts b/src/api/routes/users/@me/mfa/codes-verification.ts index 4cc4c072e..942130375 100644 --- a/src/api/routes/users/@me/mfa/codes-verification.ts +++ b/src/api/routes/users/@me/mfa/codes-verification.ts @@ -46,7 +46,7 @@ router.post( // TODO: We don't have email/etc etc, so can't send a verification code. // Once that's done, this route can verify `key` - // const user = await User.findOneOrFail({ where: { id: req.user_id } }); + // const user = req.user; if ((await User.count({ where: { id: req.user_id } })) === 0) throw DiscordApiErrors.UNKNOWN_USER; let codes: BackupCode[]; diff --git a/src/api/routes/users/@me/notes.ts b/src/api/routes/users/@me/notes.ts index 8cd333042..f25aca796 100644 --- a/src/api/routes/users/@me/notes.ts +++ b/src/api/routes/users/@me/notes.ts @@ -65,7 +65,7 @@ router.put( }), async (req: Request, res: Response) => { const { user_id } = req.params; - const owner = await User.findOneOrFail({ where: { id: req.user_id } }); + const owner = req.user; const target = await User.findOneOrFail({ where: { id: user_id } }); //if noted user does not exist throw const { note } = req.body;