import { getRequestIP } from "h3"; import { AuthConflictError, registerUser } from "#server/service/auth"; import { toPublicAuthError } from "#server/service/auth/errors"; import { captchaConsume } from "#server/service/captcha/store"; import { assertLoginRegisterCaptchaFieldsPresent } from "#server/service/captcha/validate-body"; import { assertUnderRateLimit } from "#server/utils/simple-rate-limit"; import { getConfigGlobal } from "#server/utils/context"; import log4js from "logger"; const logger = log4js.getLogger("AUTH"); export default defineWrappedResponseHandler(async (event) => { const ip = getRequestIP(event, { xForwardedFor: true }) ?? "unknown"; assertUnderRateLimit(`auth-register:${ip}`, 20, 60_000); const body = await readBody(event); assertLoginRegisterCaptchaFieldsPresent(body); if (!captchaConsume(body.captchaId, body.captchaAnswer)) { logger.warn("[REGISTER-FAIL] ip=%s username=%s — 验证码错误或已过期", ip, body?.username ?? "?"); throw createError({ statusCode: 400, statusMessage: "验证码错误或已过期,请重试", }); } const allowRegister = await getConfigGlobal("allowRegister"); if (!allowRegister) { logger.warn("[REGISTER-FAIL] ip=%s username=%s — 注册已关闭", ip, body?.username ?? "?"); throw createError({ statusCode: 403, statusMessage: "当前已关闭注册", }); } try { const user = await registerUser({ username: body.username, password: body.password, }); logger.info("[REGISTER-OK] ip=%s username=%s userId=%d", ip, body.username, user.id); return R.success({ user, }); } catch (err) { if (err instanceof AuthConflictError) { logger.warn("[REGISTER-FAIL] ip=%s username=%s — 用户名冲突", ip, body?.username ?? "?"); throw createError({ statusCode: 409, statusMessage: "注册未成功,请调整用户名或稍后再试", }); } logger.warn("[REGISTER-FAIL] ip=%s username=%s — %s", ip, body?.username ?? "?", err instanceof Error ? err.message : String(err)); throw toPublicAuthError(err); } });