94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import prisma from '@/lib/prisma';
|
|
import bcrypt from 'bcryptjs';
|
|
|
|
import { verifyCsrfToken, verifyOrigin } from '@/lib/csrf';
|
|
|
|
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 }
|
|
);
|
|
}
|
|
|
|
// Omit password from response
|
|
const { password: _, ...userWithoutPassword } = user;
|
|
|
|
return NextResponse.json(
|
|
{ message: 'Connexion réussie', user: userWithoutPassword },
|
|
{ status: 200 }
|
|
);
|
|
|
|
} catch (error) {
|
|
console.error('Login error:', error);
|
|
return NextResponse.json(
|
|
{ error: 'Une erreur est survenue lors de la connexion' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|