Files
afrov2/app/api/auth/login/route.ts

118 lines
3.7 KiB
TypeScript

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 }
);
}
}