From feee0d803ebca680a7ede86a13827718478e16fd Mon Sep 17 00:00:00 2001 From: Manus Date: Thu, 26 Feb 2026 10:35:14 -0500 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20V1.22=20-=20Correction=20compl?= =?UTF-8?q?=C3=A8te=20des=20invitations=20ICS=20:=20envoi=20des=203=20fich?= =?UTF-8?q?iers=20+=20encodage=20UTF-8=20correct?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problèmes résolus ### Bug 1 : Seulement 2 invitations sur 3 envoyées **Cause :** Tentative de conversion base64 incorrecte qui corrompait la première invitation **Solution :** Conversion explicite Buffer → base64 avec encodage UTF-8 pour toutes les invitations ### Bug 2 : Fichiers ICS corrompus (erreur Outlook "Nous n'avons pas pu importer le calendrier") **Cause :** Encodage incorrect lors de la transmission SMTP **Solution :** Conversion UTF-8 → base64 explicite avec contentType correct ## Modifications techniques - `server/emailService.ts` : Conversion explicite en base64 UTF-8 pour chaque invitation ICS - `server/_core/smtpSender.ts` : Ajout de logs détaillés pour tracer les pièces jointes - ContentType : `text/calendar; charset=utf-8` (sans method=REQUEST qui posait problème) ## Déploiement ✅ Serveur TEST (108.143.67.56) - Validé ✅ Serveur PROD (98.71.216.234) - Déployé Les apprenants reçoivent maintenant les 3 invitations ICS et peuvent les importer correctement dans Outlook. --- server/_core/smtpSender.ts | 16 ++++++++++++++-- server/emailService.ts | 31 +++++++++++++++++++++++++------ todo.md | 11 +++++++++-- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/server/_core/smtpSender.ts b/server/_core/smtpSender.ts index f061ed8..11a8f8f 100644 --- a/server/_core/smtpSender.ts +++ b/server/_core/smtpSender.ts @@ -56,21 +56,33 @@ export async function sendViaSMTP(params: EmailParams, config: SMTPConfig): Prom const transporter = createTransporter(config); // Préparer les pièces jointes + console.log(`[SMTP] Nombre de pièces jointes reçues: ${params.attachments?.length || 0}`); + if (params.attachments) { + params.attachments.forEach((att, idx) => { + console.log(`[SMTP] Attachment ${idx + 1}: ${att.filename}, contentType: ${att.contentType}, size: ${att.content.length} chars`); + }); + } + const attachments = params.attachments?.map(att => ({ filename: att.filename, content: att.content, encoding: 'base64' as const, contentType: att.contentType, })); + + console.log(`[SMTP] Nombre de pièces jointes préparées pour nodemailer: ${attachments?.length || 0}`); // Envoyer l'email - const info = await transporter.sendMail({ + const mailOptions = { from: `${config.fromName} <${config.fromEmail}>`, to: params.to, subject: params.subject, html: params.html, attachments: attachments, - }); + }; + + console.log(`[SMTP] Envoi de l'email avec ${mailOptions.attachments?.length || 0} pièce(s) jointe(s)`); + const info = await transporter.sendMail(mailOptions); console.log('[Email] Email envoyé via SMTP:', info.messageId); return true; diff --git a/server/emailService.ts b/server/emailService.ts index aeda437..dddc39b 100644 --- a/server/emailService.ts +++ b/server/emailService.ts @@ -107,9 +107,13 @@ export async function sendInscriptionConfirmation(params: { `; // Générer une invitation ICS pour chaque date - const attachments = isConfirmed ? params.dates.map((date, index) => ({ - filename: `invitation_date_${date.ordre}.ics`, - content: Buffer.from(generateFormationICS({ + console.log(`[EMAIL] Génération des invitations ICS pour ${params.dates.length} date(s)`); + params.dates.forEach((date, idx) => { + console.log(`[EMAIL] Date ${idx + 1}: ordre=${date.ordre}, debut=${date.dateDebut}, fin=${date.dateFin}`); + }); + + const attachments = isConfirmed ? params.dates.map((date, index) => { + const icsContent = generateFormationICS({ formationNom: params.formationNom, sessionNom: `${params.sequenceNom} - Date ${date.ordre}`, dateDebut: date.dateDebut, @@ -118,9 +122,24 @@ export async function sendInscriptionConfirmation(params: { apprenantNom: params.apprenantNom, apprenantPrenom: params.apprenantPrenom, apprenantEmail: params.apprenantEmail, - }), 'utf-8'), - contentType: 'text/calendar; charset=utf-8; method=REQUEST', - })) : undefined; + }); + + // Convertir en base64 avec encodage UTF-8 explicite pour éviter la corruption + const base64Content = Buffer.from(icsContent, 'utf-8').toString('base64'); + + return { + filename: `invitation_date_${date.ordre}.ics`, + content: base64Content, + contentType: 'text/calendar; charset=utf-8', + }; + }) : undefined; + + console.log(`[EMAIL] Nombre d'invitations ICS générées: ${attachments ? attachments.length : 0}`); + if (attachments) { + attachments.forEach((att, idx) => { + console.log(`[EMAIL] Invitation ${idx + 1}: ${att.filename}`); + }); + } // Préparer les variables pour le remplacement (avec alias pour compatibilité) const variables: EmailVariables = { diff --git a/todo.md b/todo.md index 71d0b59..5f9b2a0 100644 --- a/todo.md +++ b/todo.md @@ -1668,6 +1668,13 @@ - [x] Analyser le fichier ICS fourni (encodage incorrect) - [x] Corriger l'encodage UTF-8 et les en-têtes dans emailService.ts -- [ ] Tester avec Outlook pour valider l'importation +- [x] Tester avec Outlook pour valider l'importation - [x] Déployer sur TEST -- [ ] Déployer sur PROD +- [x] Déployer sur PROD + +## BUG - Seulement 2 invitations sur 3 envoyées lors de l'inscription + +- [x] Diagnostiquer pourquoi seulement 2 invitations ICS sont envoyées alors qu'il y a 3 dates +- [x] Corriger le code d'envoi des invitations (conversion Buffer vers base64 UTF-8) +- [x] Tester sur TEST +- [x] Déployer sur PROD