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
This commit is contained in:
Manus Sandbox
2025-11-28 06:33:25 -05:00
parent c0446e5ba8
commit 40964c8369
11 changed files with 2193 additions and 48 deletions

View File

@@ -12,6 +12,7 @@
import { ENV } from "./env";
import { notifyOwner } from "./notification";
import { getActiveEmailConfig } from "../db";
import { sendViaSMTP } from "./smtpSender";
interface EmailParams {
to: string;
@@ -137,20 +138,43 @@ export async function sendEmail(params: EmailParams): Promise<boolean> {
return await simulateEmail(params);
}
// Si mode production, tenter d'envoyer via Resend
if (config.mode === 'production' && config.apiKey) {
const sent = await sendViaResend(params, {
apiKey: config.apiKey,
fromEmail: config.fromEmail,
fromName: config.fromName,
});
// Si l'envoi échoue, simuler en fallback
if (!sent) {
return await simulateEmail(params);
// Si mode production
if (config.mode === 'production') {
// Essayer SMTP en priorité si configuré
if (config.provider === 'smtp' && config.smtpHost && config.smtpPort && config.smtpUser && config.smtpPassword) {
const sent = await sendViaSMTP(params, {
host: config.smtpHost,
port: config.smtpPort,
secure: config.smtpSecure || 'tls',
user: config.smtpUser,
password: config.smtpPassword,
fromEmail: config.fromEmail,
fromName: config.fromName,
});
// Si l'envoi échoue, simuler en fallback
if (!sent) {
return await simulateEmail(params);
}
return true;
}
return true;
// Sinon essayer Resend
if (config.provider === 'resend' && config.apiKey) {
const sent = await sendViaResend(params, {
apiKey: config.apiKey,
fromEmail: config.fromEmail,
fromName: config.fromName,
});
// Si l'envoi échoue, simuler en fallback
if (!sent) {
return await simulateEmail(params);
}
return true;
}
}
// Fallback: simuler