From f8a6893f016ed134a1f25a7cbdb0613eaf050f0a Mon Sep 17 00:00:00 2001 From: imnyang Date: Thu, 25 Jun 2026 21:13:29 +0900 Subject: [PATCH] feat: enhance authentication flow by adding API key support and refactoring user session retrieval --- apps/backend/src/routes/auth.ts | 135 ++++++++++---------------------- 1 file changed, 40 insertions(+), 95 deletions(-) diff --git a/apps/backend/src/routes/auth.ts b/apps/backend/src/routes/auth.ts index abc7f2f..2bac1c4 100644 --- a/apps/backend/src/routes/auth.ts +++ b/apps/backend/src/routes/auth.ts @@ -5,7 +5,7 @@ import { AuditLog } from "@/models/audit"; import { ApiKey } from "@/models/api-key"; import { USER_ROLES, User } from "@/models/user"; import { createAuditLog } from "@/lib/audit"; -import { createPlainApiKey } from "@/lib/api-key"; +import { authenticateApiKey, createPlainApiKey } from "@/lib/api-key"; import { ulid } from "ulid"; const hardcodedOwners = new Set( @@ -14,6 +14,8 @@ const hardcodedOwners = new Set( : [], ); +type HeaderBag = Record; + async function getSessionUser(jwt: { verify: (token: string) => Promise }, mizuki: { value?: unknown }) { const rawToken = mizuki.value; if (typeof rawToken !== "string" || rawToken.length === 0) { @@ -28,8 +30,23 @@ async function getSessionUser(jwt: { verify: (token: string) => Promise return await User.findOne({ userId: payload.id }); } -async function getAdminSessionUser(jwt: { verify: (token: string) => Promise }, mizuki: { value?: unknown }) { - const requester = await getSessionUser(jwt, mizuki); +async function getAuthenticatedUser( + jwt: { verify: (token: string) => Promise }, + mizuki: { value?: unknown }, + headers: HeaderBag, +) { + const sessionUser = await getSessionUser(jwt, mizuki); + if (sessionUser) return sessionUser; + + return await authenticateApiKey(headers); +} + +async function getAdminAuthenticatedUser( + jwt: { verify: (token: string) => Promise }, + mizuki: { value?: unknown }, + headers: HeaderBag, +) { + const requester = await getAuthenticatedUser(jwt, mizuki, headers); if (!requester || requester.role !== "admin") { return null; } @@ -44,20 +61,10 @@ export default new Elysia({ prefix: "/auth" }) secret: config.auth.jwt_secret, }) ) - .get("/me", async ({ jwt, cookie: { mizuki }, status }) => { - const rawToken = mizuki.value; - if (typeof rawToken !== "string" || rawToken.length === 0) { - return status(401, "Unauthorized"); - } - - const payload = await jwt.verify(rawToken); - if (!payload || typeof payload !== "object" || !("id" in payload) || typeof payload.id !== "string") { - return status(401, "Unauthorized"); - } - - const user = await User.findOne({ userId: payload.id }); + .get("/me", async ({ jwt, cookie: { mizuki }, headers, status }) => { + const user = await getAuthenticatedUser(jwt, mizuki, headers); if (!user) { - return status(404, "User not found"); + return status(401, "Unauthorized"); } return { @@ -197,18 +204,8 @@ export default new Elysia({ prefix: "/auth" }) }) }) - .post("/role", async ({ jwt, body, cookie: { mizuki }, status }) => { - const rawToken = mizuki.value; - if (typeof rawToken !== "string" || rawToken.length === 0) { - return status(401, "Unauthorized"); - } - - const payload = await jwt.verify(rawToken); - if (!payload || typeof payload !== "object" || !("id" in payload) || typeof payload.id !== "string") { - return status(401, "Unauthorized"); - } - - const requester = await User.findOne({ userId: payload.id }); + .post("/role", async ({ jwt, body, cookie: { mizuki }, headers, status }) => { + const requester = await getAuthenticatedUser(jwt, mizuki, headers); if (!requester) { return status(401, "Unauthorized"); } @@ -288,19 +285,9 @@ export default new Elysia({ prefix: "/auth" }) }), }) - .delete("/user/:id", async ({ params, jwt, cookie: { mizuki }, status }) => { - const rawToken = mizuki.value; - if (typeof rawToken !== "string" || rawToken.length === 0) { - return status(401, "Unauthorized"); - } - - const payload = await jwt.verify(rawToken); - if (!payload || typeof payload !== "object" || !("id" in payload) || typeof payload.id !== "string") { - return status(401, "Unauthorized"); - } - - const requester = await User.findOne({ userId: payload.id }); - if (!requester || requester.role !== "admin") { + .delete("/user/:id", async ({ params, jwt, cookie: { mizuki }, headers, status }) => { + const requester = await getAdminAuthenticatedUser(jwt, mizuki, headers); + if (!requester) { return status(403, "Forbidden"); } @@ -339,23 +326,9 @@ export default new Elysia({ prefix: "/auth" }) }) }) - .get("/users", async ({ jwt, cookie: { mizuki }, status }) => { - const rawToken = mizuki.value; - if (typeof rawToken !== "string" || rawToken.length === 0) { - return status(401, "Unauthorized"); - } - - const payload = await jwt.verify(rawToken); - if (!payload || typeof payload !== "object" || !("id" in payload) || typeof payload.id !== "string") { - return status(401, "Unauthorized"); - } - - const requester = await User.findOne({ userId: payload.id }); + .get("/users", async ({ jwt, cookie: { mizuki }, headers, status }) => { + const requester = await getAdminAuthenticatedUser(jwt, mizuki, headers); if (!requester) { - return status(401, "Unauthorized"); - } - - if (requester.role !== "admin") { return status(403, "Forbidden"); } @@ -370,23 +343,9 @@ export default new Elysia({ prefix: "/auth" }) })); }) - .post("/user", async ({ jwt, body, cookie: { mizuki }, status }) => { - const rawToken = mizuki.value; - if (typeof rawToken !== "string" || rawToken.length === 0) { - return status(401, "Unauthorized"); - } - - const payload = await jwt.verify(rawToken); - if (!payload || typeof payload !== "object" || !("id" in payload) || typeof payload.id !== "string") { - return status(401, "Unauthorized"); - } - - const requester = await User.findOne({ userId: payload.id }); + .post("/user", async ({ jwt, body, cookie: { mizuki }, headers, status }) => { + const requester = await getAdminAuthenticatedUser(jwt, mizuki, headers); if (!requester) { - return status(401, "Unauthorized"); - } - - if (requester.role !== "admin") { return status(403, "Forbidden"); } @@ -443,8 +402,8 @@ export default new Elysia({ prefix: "/auth" }) }), }) - .get("/api-keys", async ({ jwt, cookie: { mizuki }, status }) => { - const requester = await getAdminSessionUser(jwt, mizuki); + .get("/api-keys", async ({ jwt, cookie: { mizuki }, headers, status }) => { + const requester = await getAdminAuthenticatedUser(jwt, mizuki, headers); if (!requester) { return status(403, "Forbidden"); } @@ -461,8 +420,8 @@ export default new Elysia({ prefix: "/auth" }) })); }) - .post("/api-keys", async ({ jwt, body, cookie: { mizuki }, status }) => { - const requester = await getAdminSessionUser(jwt, mizuki); + .post("/api-keys", async ({ jwt, body, cookie: { mizuki }, headers, status }) => { + const requester = await getAdminAuthenticatedUser(jwt, mizuki, headers); if (!requester) { return status(403, "Forbidden"); } @@ -512,8 +471,8 @@ export default new Elysia({ prefix: "/auth" }) }), }) - .delete("/api-keys/:id", async ({ jwt, params, cookie: { mizuki }, status }) => { - const requester = await getAdminSessionUser(jwt, mizuki); + .delete("/api-keys/:id", async ({ jwt, params, cookie: { mizuki }, headers, status }) => { + const requester = await getAdminAuthenticatedUser(jwt, mizuki, headers); if (!requester) { return status(403, "Forbidden"); } @@ -552,23 +511,9 @@ export default new Elysia({ prefix: "/auth" }) }), }) - .get("/audit-logs", async ({ jwt, cookie: { mizuki }, query, status }) => { - const rawToken = mizuki.value; - if (typeof rawToken !== "string" || rawToken.length === 0) { - return status(401, "Unauthorized"); - } - - const payload = await jwt.verify(rawToken); - if (!payload || typeof payload !== "object" || !("id" in payload) || typeof payload.id !== "string") { - return status(401, "Unauthorized"); - } - - const requester = await User.findOne({ userId: payload.id }); + .get("/audit-logs", async ({ jwt, cookie: { mizuki }, headers, query, status }) => { + const requester = await getAdminAuthenticatedUser(jwt, mizuki, headers); if (!requester) { - return status(401, "Unauthorized"); - } - - if (requester.role !== "admin") { return status(403, "Forbidden"); }