import { NextRequest, NextResponse } from 'next/server'; import { z } from 'zod'; import { nanoid } from 'nanoid'; import { db } from '@/drizzle/db'; import { users, verificationCodes, userSettings } from '@/drizzle/schema'; import { eq, and, gt } from 'drizzle-orm'; import { hashPassword, validatePassword, validateEmail, validateNickname } from '@/lib/password'; import { generateToken, setAuthCookie } from '@/lib/auth'; // 请求体验证 const registerSchema = z.object({ email: z.string().email('邮箱格式不正确'), password: z.string().min(8, '密码长度不能少于8位'), confirmPassword: z.string(), nickname: z.string().min(2, '昵称长度不能少于2位').max(20, '昵称长度不能超过20位'), code: z.string().length(6, '验证码必须是6位'), }).refine((data) => data.password === data.confirmPassword, { message: '两次输入的密码不一致', path: ['confirmPassword'], }); export async function POST(request: NextRequest) { try { const body = await request.json(); // 验证请求体 const result = registerSchema.safeParse(body); if (!result.success) { return NextResponse.json( { success: false, error: result.error.issues[0].message }, { status: 400 } ); } const { email, password, nickname, code } = result.data; // 验证邮箱格式 if (!validateEmail(email)) { return NextResponse.json( { success: false, error: '邮箱格式不正确' }, { status: 400 } ); } // 验证密码格式 const passwordValidation = validatePassword(password); if (!passwordValidation.valid) { return NextResponse.json( { success: false, error: passwordValidation.errors[0] }, { status: 400 } ); } // 验证昵称格式 const nicknameValidation = validateNickname(nickname); if (!nicknameValidation.valid) { return NextResponse.json( { success: false, error: nicknameValidation.error }, { status: 400 } ); } // 检查邮箱是否已注册 const existingUser = await db .select() .from(users) .where(eq(users.email, email)) .limit(1); if (existingUser.length > 0) { return NextResponse.json( { success: false, error: '该邮箱已被注册' }, { status: 400 } ); } // 验证验证码 const now = new Date(); const validCode = await db .select() .from(verificationCodes) .where( and( eq(verificationCodes.email, email), eq(verificationCodes.code, code), eq(verificationCodes.type, 'register'), eq(verificationCodes.used, false), gt(verificationCodes.expiresAt, now) ) ) .limit(1); if (validCode.length === 0) { return NextResponse.json( { success: false, error: '验证码无效或已过期' }, { status: 400 } ); } // 标记验证码为已使用 await db .update(verificationCodes) .set({ used: true }) .where(eq(verificationCodes.id, validCode[0].id)); // 加密密码 const hashedPassword = await hashPassword(password); // 生成用户ID const userId = nanoid(); // 创建用户 const [newUser] = await db .insert(users) .values({ userId, email, password: hashedPassword, nickname, emailVerified: true, // 已通过邮箱验证 lastLoginAt: now, }) .returning(); // 创建默认用户设置 await db.insert(userSettings).values({ userId, }); // 生成 JWT Token const token = await generateToken({ userId: newUser.userId, email: newUser.email, nickname: newUser.nickname, plan: newUser.plan || 'free', }); // 设置认证 Cookie await setAuthCookie(token); return NextResponse.json({ success: true, user: { id: newUser.userId, email: newUser.email, nickname: newUser.nickname, plan: newUser.plan, }, message: '注册成功', }); } catch (error) { console.error('注册失败:', error); return NextResponse.json( { success: false, error: '服务器错误' }, { status: 500 } ); } }