import { hash } from "bcryptjs"; import { dbGlobal } from "drizzle-pkg/lib/db"; import { users } from "drizzle-pkg/lib/schema/auth"; import { isUniqueConflictOnField } from "#server/utils/db-unique-constraint"; import log4js from "logger"; const logger = log4js.getLogger("USERS"); export default defineWrappedResponseHandler(async (event) => { const body = await readBody(event); if (!body?.username || !body?.password) { throw createError({ statusCode: 400, statusMessage: "用户名和密码不能为空", }); } const username = body.username.trim(); const password = body.password; const email = body.email?.trim() || undefined; const role = body.role === "admin" ? "admin" : "user"; if (username.length < 3 || username.length > 20) { throw createError({ statusCode: 400, statusMessage: "用户名长度需在 3-20 个字符之间", }); } if (!/^[a-zA-Z0-9_]+$/.test(username)) { throw createError({ statusCode: 400, statusMessage: "用户名只能包含字母、数字和下划线", }); } if (password.length < 6) { throw createError({ statusCode: 400, statusMessage: "密码长度至少 6 位", }); } if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { throw createError({ statusCode: 400, statusMessage: "邮箱格式不正确", }); } const passwordHash = await hash(password, 12); try { const [newUser] = await dbGlobal .insert(users) .values({ username, password: passwordHash, email: email || null, role, }) .returning({ id: users.id, username: users.username, email: users.email, role: users.role, nickname: users.nickname, avatar: users.avatar, }); logger.info("user created by admin: %s (role: %s)", username, role); return R.success(newUser); } catch (err) { if (isUniqueConflictOnField(err, "username")) { throw createError({ statusCode: 409, statusMessage: "用户名已存在", }); } throw err; } });