import { NextRequest, NextResponse } from 'next/server'; import { z } from 'zod'; import { db } from '@/drizzle/db'; import { users, verificationCodes } from '@/drizzle/schema'; import { eq, and, gt } from 'drizzle-orm'; import { hashPassword, validatePassword, validateEmail } from '@/lib/password'; // 请求体验证 const resetPasswordSchema = z.object({ email: z.string().email('邮箱格式不正确'), code: z.string().length(6, '验证码必须是6位'), newPassword: z.string().min(8, '密码长度不能少于8位'), confirmPassword: z.string(), }).refine((data) => data.newPassword === data.confirmPassword, { message: '两次输入的密码不一致', path: ['confirmPassword'], }); export async function POST(request: NextRequest) { try { const body = await request.json(); // 验证请求体 const result = resetPasswordSchema.safeParse(body); if (!result.success) { return NextResponse.json( { success: false, error: result.error.issues[0].message }, { status: 400 } ); } const { email, code, newPassword } = result.data; // 验证邮箱格式 if (!validateEmail(email)) { return NextResponse.json( { success: false, error: '邮箱格式不正确' }, { status: 400 } ); } // 验证密码格式 const passwordValidation = validatePassword(newPassword); if (!passwordValidation.valid) { return NextResponse.json( { success: false, error: passwordValidation.errors[0] }, { status: 400 } ); } // 查找用户 const [user] = await db .select() .from(users) .where(eq(users.email, email)) .limit(1); if (!user) { 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, 'reset'), 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(newPassword); // 更新密码 await db .update(users) .set({ password: hashedPassword, updatedAt: now }) .where(eq(users.userId, user.userId)); return NextResponse.json({ success: true, message: '密码重置成功', }); } catch (error) { console.error('重置密码失败:', error); return NextResponse.json( { success: false, error: '服务器错误' }, { status: 500 } ); } }