feat(csms): add setup routes and pages for initial user creation

This commit is contained in:
2026-03-10 21:40:27 +08:00
parent fc18332cd5
commit 4f9fbe13fd
6 changed files with 317 additions and 24 deletions

View File

@@ -13,6 +13,7 @@ import chargePointRoutes from './routes/charge-points.ts'
import transactionRoutes from './routes/transactions.ts'
import idTagRoutes from './routes/id-tags.ts'
import userRoutes from './routes/users.ts'
import setupRoutes from './routes/setup.ts'
import type { HonoEnv } from './types/hono.ts'
@@ -54,6 +55,7 @@ app.route('/api/charge-points', chargePointRoutes)
app.route('/api/transactions', transactionRoutes)
app.route('/api/id-tags', idTagRoutes)
app.route('/api/users', userRoutes)
app.route('/api/setup', setupRoutes)
app.get('/api', (c) => {
const user = c.get('user')

View File

@@ -0,0 +1,56 @@
import { Hono } from "hono";
import { count, eq } from "drizzle-orm";
import { useDrizzle } from "@/lib/db.js";
import { user } from "@/db/schema.js";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { auth } from "@/lib/auth.js";
const app = new Hono();
/** GET /api/setup — 检查系统是否已初始化(存在用户) */
app.get("/", async (c) => {
const db = useDrizzle();
const [{ value }] = await db.select({ value: count() }).from(user);
return c.json({ initialized: value > 0 });
});
const setupSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
username: z
.string()
.min(3)
.max(50)
.regex(/^[a-zA-Z0-9_]+$/, "用户名只能包含字母、数字和下划线"),
password: z.string().min(8),
});
/** POST /api/setup — 仅在无用户时创建根管理员账号 */
app.post("/", zValidator("json", setupSchema), async (c) => {
const db = useDrizzle();
const [{ value }] = await db.select({ value: count() }).from(user);
if (value > 0) {
return c.json({ error: "系统已初始化,无法重复创建根管理员" }, 403);
}
const { name, email, username, password } = c.req.valid("json");
// 通过 better-auth 内部 API 注册账号
const signUpRes = await auth.api.signUpEmail({
body: { name, email, password, username },
asResponse: false,
});
if (!signUpRes?.user?.id) {
return c.json({ error: "账号创建失败" }, 500);
}
// 将角色提升为 admin
await db.update(user).set({ role: "admin" }).where(eq(user.id, signUpRes.user.id));
return c.json({ success: true, userId: signUpRes.user.id });
});
export default app;