espace-paie-odentas/app/api/auto-declaration/generate-token/route.ts
2025-10-12 17:05:46 +02:00

132 lines
No EOL
4.1 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { createSbServiceRole } from '@/lib/supabaseServer';
import crypto from 'crypto';
import { sendUniversalEmailV2 } from '@/lib/emailTemplateService';
export async function POST(request: NextRequest) {
try {
const { salarie_id } = await request.json();
if (!salarie_id) {
return NextResponse.json(
{ error: 'ID du salarié requis' },
{ status: 400 }
);
}
const supabase = createSbServiceRole();
// Récupérer les informations du salarié
const { data: salarie, error: salarieError } = await supabase
.from('salaries')
.select('id, nom, prenom, adresse_mail, code_salarie, civilite, employer_id')
.eq('id', salarie_id)
.single();
if (salarieError || !salarie) {
console.error('Erreur récupération salarié:', salarieError);
return NextResponse.json(
{ error: 'Salarié non trouvé' },
{ status: 404 }
);
}
// Récupérer les informations de l'employeur séparément
let organizationName = 'votre employeur';
if (salarie.employer_id) {
const { data: organization, error: orgError } = await supabase
.from('organizations')
.select('name')
.eq('id', salarie.employer_id)
.single();
console.log('🏢 [TOKEN] Organization query result:', { organization, orgError, employer_id: salarie.employer_id });
if (organization?.name) {
organizationName = organization.name;
console.log('✅ [TOKEN] Organization name found:', organizationName);
} else {
console.log('⚠️ [TOKEN] No organization name found, using default');
}
} else {
console.log('⚠️ [TOKEN] No employer_id found for salarie');
}
if (!salarie.adresse_mail) {
return NextResponse.json(
{ error: 'Email du salarié requis' },
{ status: 400 }
);
}
// Supprimer d'éventuels tokens existants
await supabase
.from('auto_declaration_tokens')
.delete()
.eq('salarie_id', salarie_id);
// Générer un nouveau token sécurisé
const token = crypto.randomBytes(32).toString('hex');
// Créer le token en base avec expiration dans 72h
const expiresAt = new Date();
expiresAt.setHours(expiresAt.getHours() + 72);
const { error: tokenError } = await supabase
.from('auto_declaration_tokens')
.insert({
token,
salarie_id: salarie_id,
expires_at: expiresAt.toISOString(),
used: false
});
if (tokenError) {
console.error('Erreur création token:', tokenError);
return NextResponse.json(
{ error: 'Erreur lors de la génération du token' },
{ status: 500 }
);
}
// Préparer l'URL sécurisée pour l'auto-déclaration
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000';
const autoDeclarationUrl = `${baseUrl}/auto-declaration?token=${token}`;
// Envoyer l'email d'invitation
try {
const emailResult = await sendUniversalEmailV2({
type: 'auto-declaration-invitation',
toEmail: salarie.adresse_mail,
data: {
firstName: salarie.prenom || 'Cher collaborateur',
organizationName: organizationName, // Utilisé à la fois dans le texte ET dans la card
matricule: salarie.code_salarie || 'Non défini',
ctaUrl: autoDeclarationUrl
}
});
return NextResponse.json({
success: true,
message: 'Token généré et invitation envoyée avec succès',
token: token, // Pour debug uniquement, retirer en production
email_sent: true,
messageId: emailResult
});
} catch (emailError) {
console.error('Erreur envoi email invitation:', emailError);
return NextResponse.json(
{ error: 'Token créé mais erreur lors de l\'envoi de l\'email' },
{ status: 207 }
);
}
} catch (error) {
console.error('Erreur génération token:', error);
return NextResponse.json(
{ error: 'Erreur serveur' },
{ status: 500 }
);
}
}