diff --git a/apps/server/src/app.ts b/apps/server/src/app.ts index 819a299..bfe9b10 100644 --- a/apps/server/src/app.ts +++ b/apps/server/src/app.ts @@ -40,8 +40,11 @@ export function createApp(opts: CreateAppOptions) { app.use("*", async (c, next) => { const start = Date.now(); - await next(); - appLogger("http").info`${c.req.method} ${c.req.path} → ${c.res.status} · ${Date.now() - start}ms`; + try { + await next(); + } finally { + appLogger("http").info`${c.req.method} ${c.req.path} → ${c.res.status} · ${Date.now() - start}ms`; + } }); app.use("*", async (c, next) => { c.set("repos", repos); diff --git a/apps/server/src/routes/admin-keys.ts b/apps/server/src/routes/admin-keys.ts index daf64bb..ef53a80 100644 --- a/apps/server/src/routes/admin-keys.ts +++ b/apps/server/src/routes/admin-keys.ts @@ -133,10 +133,18 @@ export function adminKeyRoutes() { if (guard) return guard; const body = await c.req.json().catch(() => null); const sk_key = typeof body?.sk_key === "string" ? body.sk_key.trim() : ""; - const member_id = - body?.member_id === undefined || body?.member_id === null - ? null - : Number(body.member_id); + let member_id: number | null = null; + if (body?.member_id !== undefined && body?.member_id !== null) { + const n = Number(body.member_id); + if (!Number.isInteger(n) || n <= 0) { + return jsonError( + c, + 422, + ERR.validation_failed({ member_id: "成员 id 无效" }), + ); + } + member_id = n; + } if (!sk_key || !sk_key.startsWith("sk-")) { return jsonError( c, @@ -276,8 +284,18 @@ export function adminKeyRoutes() { } } if (body && "member_id" in body) { - const nextMember = - body.member_id == null ? null : Number(body.member_id); + let nextMember: number | null = null; + if (body.member_id != null) { + const n = Number(body.member_id); + if (!Number.isInteger(n) || n <= 0) { + return jsonError( + c, + 422, + ERR.validation_failed({ member_id: "成员 id 无效" }), + ); + } + nextMember = n; + } if (nextMember !== before.member_id) { patch.member_id = nextMember; actions.push({ diff --git a/apps/server/src/routes/admin-session.ts b/apps/server/src/routes/admin-session.ts index ec80a91..892a15f 100644 --- a/apps/server/src/routes/admin-session.ts +++ b/apps/server/src/routes/admin-session.ts @@ -74,14 +74,18 @@ export function adminSessionRoutes() { const initUser = c.get("adminInitUsername"); const initPass = c.get("adminInitPassword"); if (initUser && initPass) { - const password_hash = await hashPassword(initPass); - await repos.users.insert(initUser, password_hash); - await repos.audit.insert({ - operator: null, - domain: "account", - action: "account.init", - summary: "空库 env 静默重建管理员", - }); + try { + const password_hash = await hashPassword(initPass); + await repos.users.insert(initUser, password_hash); + await repos.audit.insert({ + operator: null, + domain: "account", + action: "account.init", + summary: "空库 env 静默重建管理员", + }); + } catch { + // 并发/重复初始化:唯一约束冲突时视为已初始化 + } return c.json({ initialized: true }, 200); } return c.json({ initialized: false }, 200); diff --git a/apps/server/src/routes/admin-usage.ts b/apps/server/src/routes/admin-usage.ts index 2c6ab23..a31890a 100644 --- a/apps/server/src/routes/admin-usage.ts +++ b/apps/server/src/routes/admin-usage.ts @@ -15,7 +15,6 @@ import { err401, err422, logPageSchema, - keyItemSchema, } from "../api-schemas.ts"; import { z } from "zod";