Files
formation-manager-itinova/server/_core/smtpSender.ts
Manus Sandbox 40964c8369 Checkpoint: Ajout de la possibilité d'envoyer des emails via SMTP directement (sans Resend) :
**Modifications de la base de données** :
- Ajout des champs SMTP dans la table `emailConfig` : smtpHost, smtpPort, smtpSecure, smtpUser, smtpPassword

**Backend** :
- Installation de `nodemailer` pour l'envoi SMTP
- Création de `server/_core/smtpSender.ts` avec les fonctions d'envoi SMTP et de test de connexion
- Modification de `server/_core/emailSender.ts` pour supporter les deux méthodes (Resend et SMTP)
- Priorité donnée à SMTP si configuré, sinon fallback sur Resend

**Frontend** :
- Mise à jour de `AdminEmailConfig.tsx` pour permettre le choix entre Resend et SMTP
- Ajout d'un sélecteur de méthode d'envoi (Resend API / SMTP Direct)
- Formulaire de configuration SMTP avec :
  * Hôte SMTP (ex: smtp.gmail.com)
  * Port (587, 465, 25)
  * Sécurité (TLS, SSL, None)
  * Identifiants (utilisateur/mot de passe)
  * Email expéditeur

**Compatibilité** :
- Support des principaux fournisseurs SMTP (Gmail, Outlook, serveurs SMTP personnalisés)
- Instructions pour les mots de passe d'application Gmail
- Mode simulation toujours disponible pour les tests
2025-11-28 06:33:25 -05:00

104 lines
2.5 KiB
TypeScript

/**
* Service d'envoi d'emails via SMTP avec nodemailer
*/
import nodemailer from 'nodemailer';
import type { Transporter } from 'nodemailer';
interface EmailParams {
to: string;
subject: string;
html: string;
attachments?: Array<{
filename: string;
content: string;
contentType: string;
}>;
}
interface SMTPConfig {
host: string;
port: number;
secure: 'none' | 'tls' | 'ssl';
user: string;
password: string;
fromEmail: string;
fromName: string;
}
/**
* Crée un transporteur nodemailer à partir de la configuration SMTP
*/
function createTransporter(config: SMTPConfig): Transporter {
const secure = config.secure === 'ssl'; // true pour SSL (port 465), false pour TLS/STARTTLS
return nodemailer.createTransport({
host: config.host,
port: config.port,
secure: secure,
auth: {
user: config.user,
pass: config.password,
},
// Options supplémentaires pour améliorer la compatibilité
tls: {
// Ne pas échouer sur les certificats invalides (à utiliser avec précaution en production)
rejectUnauthorized: false,
},
});
}
/**
* Envoie un email via SMTP
*/
export async function sendViaSMTP(params: EmailParams, config: SMTPConfig): Promise<boolean> {
try {
const transporter = createTransporter(config);
// Préparer les pièces jointes
const attachments = params.attachments?.map(att => ({
filename: att.filename,
content: att.content,
contentType: att.contentType,
}));
// Envoyer l'email
const info = await transporter.sendMail({
from: `${config.fromName} <${config.fromEmail}>`,
to: params.to,
subject: params.subject,
html: params.html,
attachments: attachments,
});
console.log('[Email] Email envoyé via SMTP:', info.messageId);
return true;
} catch (error) {
console.error('[Email] Erreur lors de l\'envoi via SMTP:', error);
return false;
}
}
/**
* Teste la connexion SMTP
*/
export async function testSMTPConnection(config: SMTPConfig): Promise<{ success: boolean; message: string }> {
try {
const transporter = createTransporter(config);
// Vérifier la connexion
await transporter.verify();
return {
success: true,
message: 'Connexion SMTP réussie',
};
} catch (error) {
console.error('[Email] Erreur de connexion SMTP:', error);
return {
success: false,
message: error instanceof Error ? error.message : 'Erreur de connexion SMTP',
};
}
}