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 { verifyPassword, validateEmail } from '@/lib/password'; import { generateToken, setAuthCookie } from '@/lib/auth'; // 请求体验证 const loginSchema = z.object({ email: z.string().email('邮箱格式不正确'), loginType: z.enum(['password', 'code']), password: z.string().optional(), code: z.string().optional(), }).refine((data) => { if (data.loginType === 'password') { return !!data.password; } if (data.loginType === 'code') { return !!data.code && data.code.length === 6; } return false; }, { message: '请提供密码或验证码', }); export async function POST(request: NextRequest) { try { const body = await request.json(); // 验证请求体 const result = loginSchema.safeParse(body); if (!result.success) { return NextResponse.json( { success: false, error: result.error.issues[0].message }, { status: 400 } ); } const { email, loginType, password, code } = result.data; // 验证邮箱格式 if (!validateEmail(email)) { return NextResponse.json( { success: false, error: '邮箱格式不正确' }, { 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 } ); } // 检查用户状态 if (user.status === 'banned') { return NextResponse.json( { success: false, error: '账号已被禁用' }, { status: 403 } ); } if (user.status === 'inactive') { return NextResponse.json( { success: false, error: '账号未激活' }, { status: 403 } ); } // 密码登录 if (loginType === 'password') { if (!password) { return NextResponse.json( { success: false, error: '请输入密码' }, { status: 400 } ); } const isValidPassword = await verifyPassword(password, user.password); if (!isValidPassword) { return NextResponse.json( { success: false, error: '密码错误' }, { status: 400 } ); } } // 验证码登录 if (loginType === 'code') { if (!code) { 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, 'login'), 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)); } // 更新最后登录时间 await db .update(users) .set({ lastLoginAt: new Date(), updatedAt: new Date() }) .where(eq(users.userId, user.userId)); // 生成 JWT Token const token = await generateToken({ userId: user.userId, email: user.email, nickname: user.nickname, plan: user.plan || 'free', }); // 设置认证 Cookie await setAuthCookie(token); return NextResponse.json({ success: true, user: { id: user.userId, email: user.email, nickname: user.nickname, plan: user.plan, avatar: user.avatar, }, message: '登录成功', }); } catch (error) { console.error('登录失败:', error); return NextResponse.json( { success: false, error: '服务器错误' }, { status: 500 } ); } }