82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
// server/api/auth/register.post.ts
|
|
import type { IUserRegisterData, IUserRegisterRequest } from "#shared/types";
|
|
import {
|
|
createApiLogger,
|
|
createErrorResponse,
|
|
createSuccessResponse,
|
|
createUpstreamErrorResponse,
|
|
newApiFetch,
|
|
toSafeLogError
|
|
} from "~~/server/utils";
|
|
|
|
/**
|
|
* 允许从请求体透传给上游的字段列表。
|
|
* 只有在这里声明过的字段才会被转发,其余字段一律丢弃,防止参数污染。
|
|
*/
|
|
const REGISTER_FIELDS = [
|
|
"username",
|
|
"password",
|
|
"email",
|
|
"verification_code",
|
|
"aff_code"
|
|
] as const satisfies ReadonlyArray<keyof IUserRegisterRequest>;
|
|
|
|
/**
|
|
* POST /api/auth/register
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const logger = createApiLogger("auth.register");
|
|
const requestBody = await readBody<Partial<IUserRegisterRequest> | null>(
|
|
event
|
|
);
|
|
|
|
logger.info("开始", {
|
|
bodyType: requestBody === null ? "null" : typeof requestBody,
|
|
hasUsername: typeof requestBody?.username === "string",
|
|
hasPassword: typeof requestBody?.password === "string",
|
|
hasEmail: typeof requestBody?.email === "string",
|
|
hasVerificationCode: typeof requestBody?.verification_code === "string",
|
|
hasAffCode: typeof requestBody?.aff_code === "string"
|
|
});
|
|
|
|
// 只接受 JSON 对象或 null,避免数组/字符串等无效 body 被透传到上游。
|
|
if (
|
|
requestBody !== null &&
|
|
(typeof requestBody !== "object" || Array.isArray(requestBody))
|
|
) {
|
|
logger.warn("请求体格式错误", {
|
|
bodyType: Array.isArray(requestBody) ? "array" : typeof requestBody
|
|
});
|
|
return createErrorResponse(400, "请求体必须是 JSON 对象");
|
|
}
|
|
|
|
const payload: IUserRegisterRequest = {};
|
|
for (const field of REGISTER_FIELDS) {
|
|
const value = requestBody?.[field];
|
|
if (typeof value === "string") {
|
|
payload[field] = value;
|
|
}
|
|
}
|
|
|
|
try {
|
|
const result = await newApiFetch<IUserRegisterData>("/api/user/register", {
|
|
method: "POST",
|
|
body: payload,
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
}
|
|
});
|
|
|
|
logger.done("成功", {
|
|
hasResult: Boolean(result)
|
|
});
|
|
|
|
return createSuccessResponse(result, "注册成功");
|
|
} catch (error) {
|
|
logger.error("失败", {
|
|
error: toSafeLogError(error)
|
|
});
|
|
return createUpstreamErrorResponse(error, "注册失败");
|
|
}
|
|
});
|