import { NextRequest, NextResponse } from 'next/server'; import prisma from '@/lib/prisma'; import bcrypt from 'bcryptjs'; import crypto from 'crypto'; 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 { name, email, password } = await request.json(); // Basic validation if (!name || !email || !password) { return NextResponse.json( { error: 'Tous les champs sont obligatoires' }, { status: 400 } ); } if (password.length < 6) { return NextResponse.json( { error: 'Le mot de passe doit contenir au moins 6 caractères' }, { status: 400 } ); } // Check if user already exists const existingUser = await prisma.user.findUnique({ where: { email } }); if (existingUser) { return NextResponse.json( { error: 'Un utilisateur avec cet email existe déjà' }, { status: 400 } ); } // Hash password const hashedPassword = await bcrypt.hash(password, 12); // Generate verification token const verificationToken = crypto.randomBytes(32).toString('hex'); // Create user const user = await prisma.user.create({ data: { name, email, password: hashedPassword, role: 'VISITOR', // Default role verificationToken, emailVerified: false, } }); // Send verification email try { const settings = await prisma.siteSetting.findUnique({ where: { id: 'singleton' } }); const siteName = settings?.siteName || 'Afrohub'; const subject = settings?.verifyEmailSubject || 'Vérification de votre compte - Afrohub'; const verifyUrl = `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/api/auth/verify?token=${verificationToken}`; let html = settings?.verifyEmailTemplate || `

${siteName}

Bonjour ${name},

Merci de vous être inscrit sur ${siteName}. Veuillez vérifier votre adresse email en cliquant sur le bouton ci-dessous :

Vérifier mon compte
`; // Replace placeholders html = html .replace(/{name}/g, name) .replace(/{verifyUrl}/g, verifyUrl) .replace(/{siteName}/g, siteName); const { sendEmail } = await import('@/lib/mail'); await sendEmail({ to: email, subject, html, }); } catch (mailError) { console.error('Failed to send verification email:', mailError); // We don't fail registration if mail fails, but maybe we should? // For now, just log it. } // Omit password from response const { password: _, ...userWithoutPassword } = user; return NextResponse.json( { message: 'Compte créé avec succès', user: userWithoutPassword }, { status: 201 } ); } catch (error) { console.error('Registration error:', error); return NextResponse.json( { error: 'Une erreur est survenue lors de l\'inscription' }, { status: 500 } ); } }