fix: server 审查修复——member_id 校验、访问日志 finally、静默初始化并发
非法 member_id 不再以 NaN 入库;HTTP 访问日志覆盖异常路径;setup-state 静默建管理员遇唯一冲突视为已初始化。
This commit is contained in:
@@ -40,8 +40,11 @@ export function createApp(opts: CreateAppOptions) {
|
|||||||
|
|
||||||
app.use("*", async (c, next) => {
|
app.use("*", async (c, next) => {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
await next();
|
try {
|
||||||
appLogger("http").info`${c.req.method} ${c.req.path} → ${c.res.status} · ${Date.now() - start}ms`;
|
await next();
|
||||||
|
} finally {
|
||||||
|
appLogger("http").info`${c.req.method} ${c.req.path} → ${c.res.status} · ${Date.now() - start}ms`;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
app.use("*", async (c, next) => {
|
app.use("*", async (c, next) => {
|
||||||
c.set("repos", repos);
|
c.set("repos", repos);
|
||||||
|
|||||||
@@ -133,10 +133,18 @@ export function adminKeyRoutes() {
|
|||||||
if (guard) return guard;
|
if (guard) return guard;
|
||||||
const body = await c.req.json().catch(() => null);
|
const body = await c.req.json().catch(() => null);
|
||||||
const sk_key = typeof body?.sk_key === "string" ? body.sk_key.trim() : "";
|
const sk_key = typeof body?.sk_key === "string" ? body.sk_key.trim() : "";
|
||||||
const member_id =
|
let member_id: number | null = null;
|
||||||
body?.member_id === undefined || body?.member_id === null
|
if (body?.member_id !== undefined && body?.member_id !== null) {
|
||||||
? null
|
const n = Number(body.member_id);
|
||||||
: 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-")) {
|
if (!sk_key || !sk_key.startsWith("sk-")) {
|
||||||
return jsonError(
|
return jsonError(
|
||||||
c,
|
c,
|
||||||
@@ -276,8 +284,18 @@ export function adminKeyRoutes() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (body && "member_id" in body) {
|
if (body && "member_id" in body) {
|
||||||
const nextMember =
|
let nextMember: number | null = null;
|
||||||
body.member_id == null ? null : Number(body.member_id);
|
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) {
|
if (nextMember !== before.member_id) {
|
||||||
patch.member_id = nextMember;
|
patch.member_id = nextMember;
|
||||||
actions.push({
|
actions.push({
|
||||||
|
|||||||
@@ -74,14 +74,18 @@ export function adminSessionRoutes() {
|
|||||||
const initUser = c.get("adminInitUsername");
|
const initUser = c.get("adminInitUsername");
|
||||||
const initPass = c.get("adminInitPassword");
|
const initPass = c.get("adminInitPassword");
|
||||||
if (initUser && initPass) {
|
if (initUser && initPass) {
|
||||||
const password_hash = await hashPassword(initPass);
|
try {
|
||||||
await repos.users.insert(initUser, password_hash);
|
const password_hash = await hashPassword(initPass);
|
||||||
await repos.audit.insert({
|
await repos.users.insert(initUser, password_hash);
|
||||||
operator: null,
|
await repos.audit.insert({
|
||||||
domain: "account",
|
operator: null,
|
||||||
action: "account.init",
|
domain: "account",
|
||||||
summary: "空库 env 静默重建管理员",
|
action: "account.init",
|
||||||
});
|
summary: "空库 env 静默重建管理员",
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// 并发/重复初始化:唯一约束冲突时视为已初始化
|
||||||
|
}
|
||||||
return c.json({ initialized: true }, 200);
|
return c.json({ initialized: true }, 200);
|
||||||
}
|
}
|
||||||
return c.json({ initialized: false }, 200);
|
return c.json({ initialized: false }, 200);
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import {
|
|||||||
err401,
|
err401,
|
||||||
err422,
|
err422,
|
||||||
logPageSchema,
|
logPageSchema,
|
||||||
keyItemSchema,
|
|
||||||
} from "../api-schemas.ts";
|
} from "../api-schemas.ts";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user