import { createPasswordRecord, getRequestPrincipal, managerForbidden, normalizeUsername, type UserRole, validatePassword, validateUsername, } from "../../../lib/user-auth"; import { ensureSchema, getRawDb } from "../../../lib/mvp-db"; export const runtime = "edge"; type UserRow = { id: string; username: string; role: UserRole; created_at: string; updated_at: string; }; async function manager(request: Request) { const principal = await getRequestPrincipal(request); if (!principal || principal.kind !== "user") return null; return ["super_admin", "admin"].includes(principal.user.role) ? principal.user : null; } async function listUsers() { const result = await getRawDb() .prepare( `SELECT id, username, role, created_at, updated_at FROM users ORDER BY CASE role WHEN 'super_admin' THEN 1 WHEN 'admin' THEN 2 ELSE 3 END, created_at ASC`, ) .all(); return result.results; } export async function GET(request: Request) { await ensureSchema(); if (!(await manager(request))) return managerForbidden(); return Response.json({ users: await listUsers() }); } export async function POST(request: Request) { await ensureSchema(); const currentUser = await manager(request); if (!currentUser) return managerForbidden(); try { const body = (await request.json()) as { action?: string; username?: string; password?: string; role?: UserRole; userId?: string; }; const password = String(body.password ?? ""); if (!validatePassword(password)) { return Response.json({ error: "密码需为8—72位" }, { status: 400 }); } const db = getRawDb(); const passwordRecord = await createPasswordRecord(password); if (body.action === "create") { const username = normalizeUsername(body.username); const role = body.role === "admin" ? "admin" : "user"; if (!validateUsername(username)) { return Response.json( { error: "账号需为2—32位中文、字母、数字或 _ . @ + -" }, { status: 400 }, ); } if (currentUser.role !== "super_admin" && role !== "user") { return managerForbidden(); } await db .prepare( `INSERT INTO users (id, username, password_hash, password_salt, password_iterations, role) VALUES (?, ?, ?, ?, ?, ?)`, ) .bind( crypto.randomUUID(), username, passwordRecord.passwordHash, passwordRecord.passwordSalt, passwordRecord.passwordIterations, role, ) .run(); } else if (body.action === "reset_password") { const target = await db .prepare("SELECT id, role FROM users WHERE id = ?") .bind(String(body.userId ?? "")) .first<{ id: string; role: UserRole }>(); if (!target) { return Response.json({ error: "没有找到这个账号" }, { status: 404 }); } if ( target.role === "super_admin" && !(currentUser.role === "super_admin" && target.id === currentUser.id) ) { return Response.json({ error: "不能修改其他超级管理员账号" }, { status: 403 }); } if (currentUser.role !== "super_admin" && target.role !== "user") { return managerForbidden(); } await db.batch([ db .prepare( `UPDATE users SET password_hash = ?, password_salt = ?, password_iterations = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`, ) .bind( passwordRecord.passwordHash, passwordRecord.passwordSalt, passwordRecord.passwordIterations, target.id, ), db.prepare("DELETE FROM auth_sessions WHERE user_id = ?").bind(target.id), ]); } else { return Response.json({ error: "不支持的操作" }, { status: 400 }); } return Response.json({ users: await listUsers() }); } catch (error) { const message = error instanceof Error ? error.message : "操作失败"; return Response.json( { error: message.includes("UNIQUE") ? "这个登录账号已存在" : message }, { status: message.includes("UNIQUE") ? 409 : 500 }, ); } }