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