You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

83 lines
2.1 KiB

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;
}
});