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 { sendVerificationEmail, generateVerificationCode } from '@/lib/email'; import { validateEmail } from '@/lib/password'; // 请求体验证 const sendCodeSchema = z.object({ email: z.string().email('邮箱格式不正确'), type: z.enum(['register', 'login', 'reset']), }); export async function POST(request: NextRequest) { try { const body = await request.json(); // 验证请求体 const result = sendCodeSchema.safeParse(body); if (!result.success) { return NextResponse.json( { success: false, error: result.error.issues[0].message }, { status: 400 } ); } const { email, type } = result.data; // 验证邮箱格式 if (!validateEmail(email)) { return NextResponse.json( { success: false, error: '邮箱格式不正确' }, { status: 400 } ); } // 检查邮箱是否已注册(仅注册时检查) if (type === 'register') { 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 } ); } } // 检查邮箱是否存在(登录和重置密码时检查) if (type === 'login' || type === 'reset') { 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 } ); } } // 检查是否频繁发送(1分钟内只能发送1次) const oneMinuteAgo = new Date(Date.now() - 60 * 1000); const recentCode = await db .select() .from(verificationCodes) .where( and( eq(verificationCodes.email, email), eq(verificationCodes.type, type), gt(verificationCodes.createdAt, oneMinuteAgo) ) ) .limit(1); if (recentCode.length > 0) { return NextResponse.json( { success: false, error: '发送太频繁,请稍后再试' }, { status: 429 } ); } // 生成验证码 const code = generateVerificationCode(); // 计算过期时间(5分钟后) const expiresAt = new Date(Date.now() + 5 * 60 * 1000); // 保存验证码到数据库 await db.insert(verificationCodes).values({ email, code, type, expiresAt, }); // 发送邮件 const emailResult = await sendVerificationEmail(email, code, type); if (!emailResult.success) { return NextResponse.json( { success: false, error: emailResult.error || '发送邮件失败' }, { status: 500 } ); } return NextResponse.json({ success: true, message: '验证码已发送,请查收邮件', expiresIn: 300, // 5分钟 }); } catch (error) { console.error('发送验证码失败:', error); return NextResponse.json( { success: false, error: '服务器错误' }, { status: 500 } ); } }