import { NextRequest, NextResponse } from 'next/server'; import prisma from '@/lib/prisma'; import bcrypt from 'bcryptjs'; import { verifyCsrfToken, verifyOrigin } from '@/lib/csrf'; import { signUserToken, setUserSessionCookie } from '@/lib/auth-utils'; export async function POST(request: NextRequest) { // CSRF Protection const isOriginValid = verifyOrigin(request); const isCsrfValid = await verifyCsrfToken(request); if (!isOriginValid || !isCsrfValid) { return NextResponse.json( { error: 'Protection CSRF : Requête invalide' }, { status: 403 } ); } try { const rawBody = await request.json(); const email = rawBody.email?.toLowerCase().trim(); const password = rawBody.password; if (!email || !password) { return NextResponse.json( { error: 'Email et mot de passe requis' }, { status: 400 } ); } // Find user const user = await prisma.user.findUnique({ where: { email } }); if (!user) { return NextResponse.json( { error: 'Identifiants invalides' }, { status: 401 } ); } // Check password const isPasswordValid = await bcrypt.compare(password, user.password); if (!isPasswordValid) { return NextResponse.json( { error: 'Identifiants invalides' }, { status: 401 } ); } // Check if email is verified if (!user.emailVerified) { // En environnement local/développement, on valide automatiquement l'email pour fluidifier les tests if (process.env.NODE_ENV !== 'production') { await prisma.user.update({ where: { id: user.id }, data: { emailVerified: true } }); user.emailVerified = true; } else { return NextResponse.json( { error: 'Veuillez vérifier votre adresse email avant de vous connecter.' }, { status: 403 } ); } } // Check if account is marked for deletion if (user.deletedAt) { return NextResponse.json( { error: 'Votre compte est désactivé. Veuillez le réactiver via le lien envoyé par email ou contacter le support.' }, { status: 403 } ); } // Sign and set HttpOnly session cookie const token = await signUserToken({ userId: user.id, email: user.email, role: user.role, }); await setUserSessionCookie(token); // Return only safe user fields (never leak password, resetToken, verificationToken) const safeUser = { id: user.id, name: user.name, email: user.email, role: user.role, avatar: user.avatar, bio: user.bio, location: user.location, phone: user.phone, countryId: user.countryId, isSuspended: user.isSuspended, suspensionReason: user.suspensionReason, emailVerified: user.emailVerified, createdAt: user.createdAt, updatedAt: user.updatedAt, }; return NextResponse.json( { message: 'Connexion réussie', user: safeUser }, { status: 200 } ); } catch (error) { console.error('Login error:', error); return NextResponse.json( { error: 'Une erreur est survenue lors de la connexion' }, { status: 500 } ); } }