From cdb77b4f388dda805797e3685133da3f472dca88 Mon Sep 17 00:00:00 2001 From: Manus Sandbox Date: Fri, 28 Nov 2025 11:05:46 -0500 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Corrections=20apport=C3=A9es=20:?= =?UTF-8?q?=20-=20Ajout=20du=20support=20SMTP=20pour=20l'envoi=20d'emails?= =?UTF-8?q?=20(sans=20d=C3=A9pendre=20de=20Resend)=20-=20Correction=20de?= =?UTF-8?q?=20l'affichage=20du=20statut=20pour=20montrer=20"SMTP=20Direct"?= =?UTF-8?q?=20au=20lieu=20de=20"Resend"=20-=20Ajout=20d'alertes=20sp=C3=A9?= =?UTF-8?q?cifiques=20pour=20la=20configuration=20SMTP=20-=20Correction=20?= =?UTF-8?q?de=20la=20fonction=20upsertEmailConfig=20pour=20mettre=20=C3=A0?= =?UTF-8?q?=20jour=20au=20lieu=20de=20cr=C3=A9er=20une=20nouvelle=20config?= =?UTF-8?q?uration=20-=20Correction=20du=20bug=20d'enregistrement=20des=20?= =?UTF-8?q?champs=20SMTP=20dans=20la=20base=20de=20donn=C3=A9es=20-=20Mise?= =?UTF-8?q?=20=C3=A0=20jour=20forc=C3=A9e=20du=20provider=20=C3=A0=20"smtp?= =?UTF-8?q?"=20dans=20la=20base=20de=20donn=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .manus/db/db-query-1764345424841.json | 27 +++++++++++++ .manus/db/db-query-1764345617656.json | 21 ++++++++++ .manus/db/db-query-1764345693447.json | 9 +++++ .manus/db/db-query-1764345842345.json | 58 +++++++++++++++++++++++++++ .manus/db/db-query-1764345856570.json | 9 +++++ .manus/db/db-query-1764345891283.json | 27 +++++++++++++ client/src/pages/AdminEmailConfig.tsx | 28 +++++++++++-- server/db.ts | 29 ++++++++++---- todo.md | 12 ++++++ 9 files changed, 209 insertions(+), 11 deletions(-) create mode 100644 .manus/db/db-query-1764345424841.json create mode 100644 .manus/db/db-query-1764345617656.json create mode 100644 .manus/db/db-query-1764345693447.json create mode 100644 .manus/db/db-query-1764345842345.json create mode 100644 .manus/db/db-query-1764345856570.json create mode 100644 .manus/db/db-query-1764345891283.json diff --git a/.manus/db/db-query-1764345424841.json b/.manus/db/db-query-1764345424841.json new file mode 100644 index 0000000..cf42369 --- /dev/null +++ b/.manus/db/db-query-1764345424841.json @@ -0,0 +1,27 @@ +{ + "query": "SELECT * FROM emailConfig LIMIT 1;", + "command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT * FROM emailConfig LIMIT 1;", + "rows": [ + { + "id": "1", + "provider": "resend", + "apiKey": "re_86E4CTUv_JLJQQQh81PvbaX6dMrshNjHt", + "fromEmail": "o.pareige@itinova.org", + "fromName": "Formation Manager Itinova", + "mode": "simulation", + "domainVerified": "0", + "active": "0", + "createdAt": "2025-11-18 07:16:34", + "updatedAt": "2025-11-28 11:49:52", + "smtpHost": "NULL", + "smtpPort": "NULL", + "smtpSecure": "tls", + "smtpUser": "NULL", + "smtpPassword": "NULL" + } + ], + "messages": [], + "stdout": "id\tprovider\tapiKey\tfromEmail\tfromName\tmode\tdomainVerified\tactive\tcreatedAt\tupdatedAt\tsmtpHost\tsmtpPort\tsmtpSecure\tsmtpUser\tsmtpPassword\n1\tresend\tre_86E4CTUv_JLJQQQh81PvbaX6dMrshNjHt\to.pareige@itinova.org\tFormation Manager Itinova\tsimulation\t0\t0\t2025-11-18 07:16:34\t2025-11-28 11:49:52\tNULL\tNULL\ttls\tNULL\tNULL\n", + "stderr": "", + "execution_time_ms": 592 +} \ No newline at end of file diff --git a/.manus/db/db-query-1764345617656.json b/.manus/db/db-query-1764345617656.json new file mode 100644 index 0000000..fea59e1 --- /dev/null +++ b/.manus/db/db-query-1764345617656.json @@ -0,0 +1,21 @@ +{ + "query": "SELECT id, mode, provider, fromName, fromEmail, smtpHost, smtpPort, smtpSecure, smtpUser FROM emailConfig LIMIT 1;", + "command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT id, mode, provider, fromName, fromEmail, smtpHost, smtpPort, smtpSecure, smtpUser FROM emailConfig LIMIT 1;", + "rows": [ + { + "id": "1", + "mode": "simulation", + "provider": "resend", + "fromName": "Formation Manager Itinova", + "fromEmail": "o.pareige@itinova.org", + "smtpHost": "NULL", + "smtpPort": "NULL", + "smtpSecure": "tls", + "smtpUser": "NULL" + } + ], + "messages": [], + "stdout": "id\tmode\tprovider\tfromName\tfromEmail\tsmtpHost\tsmtpPort\tsmtpSecure\tsmtpUser\n1\tsimulation\tresend\tFormation Manager Itinova\to.pareige@itinova.org\tNULL\tNULL\ttls\tNULL\n", + "stderr": "", + "execution_time_ms": 53 +} \ No newline at end of file diff --git a/.manus/db/db-query-1764345693447.json b/.manus/db/db-query-1764345693447.json new file mode 100644 index 0000000..adb0983 --- /dev/null +++ b/.manus/db/db-query-1764345693447.json @@ -0,0 +1,9 @@ +{ + "query": "UPDATE emailConfig SET provider = 'smtp' WHERE id = 1;", + "command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute UPDATE emailConfig SET provider = 'smtp' WHERE id = 1;", + "rows": [], + "messages": [], + "stdout": "", + "stderr": "", + "execution_time_ms": 53 +} \ No newline at end of file diff --git a/.manus/db/db-query-1764345842345.json b/.manus/db/db-query-1764345842345.json new file mode 100644 index 0000000..bcf42e4 --- /dev/null +++ b/.manus/db/db-query-1764345842345.json @@ -0,0 +1,58 @@ +{ + "query": "SELECT id, provider, mode, active, smtpHost, smtpPort FROM emailConfig ORDER BY id DESC;", + "command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT id, provider, mode, active, smtpHost, smtpPort FROM emailConfig ORDER BY id DESC;", + "rows": [ + { + "id": "90002", + "provider": "", + "mode": "production", + "active": "1", + "smtpHost": "smtp.itinova.org", + "smtpPort": "587" + }, + { + "id": "90001", + "provider": "smtp", + "mode": "simulation", + "active": "0", + "smtpHost": "smtp.itinova.org", + "smtpPort": "587" + }, + { + "id": "60002", + "provider": "smtp", + "mode": "simulation", + "active": "0", + "smtpHost": "NULL", + "smtpPort": "NULL" + }, + { + "id": "60001", + "provider": "smtp", + "mode": "simulation", + "active": "0", + "smtpHost": "NULL", + "smtpPort": "NULL" + }, + { + "id": "30001", + "provider": "smtp", + "mode": "simulation", + "active": "0", + "smtpHost": "NULL", + "smtpPort": "NULL" + }, + { + "id": "1", + "provider": "smtp", + "mode": "simulation", + "active": "0", + "smtpHost": "NULL", + "smtpPort": "NULL" + } + ], + "messages": [], + "stdout": "id\tprovider\tmode\tactive\tsmtpHost\tsmtpPort\n90002\t\tproduction\t1\tsmtp.itinova.org\t587\n90001\tsmtp\tsimulation\t0\tsmtp.itinova.org\t587\n60002\tsmtp\tsimulation\t0\tNULL\tNULL\n60001\tsmtp\tsimulation\t0\tNULL\tNULL\n30001\tsmtp\tsimulation\t0\tNULL\tNULL\n1\tsmtp\tsimulation\t0\tNULL\tNULL\n", + "stderr": "", + "execution_time_ms": 58 +} \ No newline at end of file diff --git a/.manus/db/db-query-1764345856570.json b/.manus/db/db-query-1764345856570.json new file mode 100644 index 0000000..a6eb267 --- /dev/null +++ b/.manus/db/db-query-1764345856570.json @@ -0,0 +1,9 @@ +{ + "query": "UPDATE emailConfig SET provider = 'smtp' WHERE active = true;", + "command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute UPDATE emailConfig SET provider = 'smtp' WHERE active = true;", + "rows": [], + "messages": [], + "stdout": "", + "stderr": "", + "execution_time_ms": 62 +} \ No newline at end of file diff --git a/.manus/db/db-query-1764345891283.json b/.manus/db/db-query-1764345891283.json new file mode 100644 index 0000000..44f6add --- /dev/null +++ b/.manus/db/db-query-1764345891283.json @@ -0,0 +1,27 @@ +{ + "query": "SELECT * FROM emailConfig WHERE active = true LIMIT 1;", + "command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT * FROM emailConfig WHERE active = true LIMIT 1;", + "rows": [ + { + "id": "90002", + "provider": "smtp", + "apiKey": "re_86E4CTUv_JLJQQQh81PvbaX6dMrshNjHt", + "fromEmail": "o.pareige@itinova.org", + "fromName": "Formation Manager Itinova", + "mode": "production", + "domainVerified": "0", + "active": "1", + "createdAt": "2025-11-28 15:54:56", + "updatedAt": "2025-11-28 16:04:16", + "smtpHost": "smtp.itinova.org", + "smtpPort": "587", + "smtpSecure": "tls", + "smtpUser": "o.pareige@itinova.org", + "smtpPassword": "LEpetitchatestmort69-" + } + ], + "messages": [], + "stdout": "id\tprovider\tapiKey\tfromEmail\tfromName\tmode\tdomainVerified\tactive\tcreatedAt\tupdatedAt\tsmtpHost\tsmtpPort\tsmtpSecure\tsmtpUser\tsmtpPassword\n90002\tsmtp\tre_86E4CTUv_JLJQQQh81PvbaX6dMrshNjHt\to.pareige@itinova.org\tFormation Manager Itinova\tproduction\t0\t1\t2025-11-28 15:54:56\t2025-11-28 16:04:16\tsmtp.itinova.org\t587\ttls\to.pareige@itinova.org\tLEpetitchatestmort69-\n", + "stderr": "", + "execution_time_ms": 51 +} \ No newline at end of file diff --git a/client/src/pages/AdminEmailConfig.tsx b/client/src/pages/AdminEmailConfig.tsx index 703c634..16729a7 100644 --- a/client/src/pages/AdminEmailConfig.tsx +++ b/client/src/pages/AdminEmailConfig.tsx @@ -126,7 +126,9 @@ export default function AdminEmailConfig() {

{formData.mode === "simulation" ? "Les emails sont simulés et envoyés comme notifications" - : "Les emails sont envoyés via Resend"} + : formData.provider === "smtp" + ? "Les emails sont envoyés via SMTP Direct" + : "Les emails sont envoyés via Resend"}

- {formData.apiKey && ( + {formData.provider === "resend" && formData.apiKey && ( @@ -147,11 +149,29 @@ export default function AdminEmailConfig() { )} - {!formData.apiKey && ( + {formData.provider === "smtp" && formData.smtpHost && formData.smtpUser && ( + + + + Configuration SMTP active ({formData.smtpHost}:{formData.smtpPort}) + + + )} + + {formData.provider === "resend" && !formData.apiKey && ( - Aucune clé API configurée. Les emails seront simulés. + Aucune clé API Resend configurée. Les emails seront simulés. + + + )} + + {formData.provider === "smtp" && (!formData.smtpHost || !formData.smtpUser) && ( + + + + Configuration SMTP incomplète. Les emails seront simulés. )} diff --git a/server/db.ts b/server/db.ts index f907027..226de17 100644 --- a/server/db.ts +++ b/server/db.ts @@ -692,14 +692,29 @@ export async function upsertEmailConfig(data: InsertEmailConfig) { const db = await getDb(); if (!db) return; - // Désactiver toutes les configurations existantes - await db.update(emailConfig).set({ active: false }); + // Vérifier s'il existe déjà une configuration active + const existing = await db + .select() + .from(emailConfig) + .where(eq(emailConfig.active, true)) + .limit(1); - // Créer la nouvelle configuration - await db.insert(emailConfig).values({ - ...data, - active: true, - }); + if (existing.length > 0) { + // Mettre à jour la configuration existante + await db + .update(emailConfig) + .set({ + ...data, + updatedAt: new Date(), + }) + .where(eq(emailConfig.id, existing[0].id)); + } else { + // Créer une nouvelle configuration + await db.insert(emailConfig).values({ + ...data, + active: true, + }); + } } /** diff --git a/todo.md b/todo.md index b9181a1..98a867c 100644 --- a/todo.md +++ b/todo.md @@ -744,3 +744,15 @@ - [x] Vérifier les procédures tRPC emailConfig - [x] Corriger la mutation upsert pour supporter les champs SMTP - [x] Tester l'enregistrement de la configuration SMTP (champs ajoutés dans l'input tRPC) + +## Bug email de test envoyé à la mauvaise adresse + +- [x] Vérifier la fonction sendEmail dans emailSender.ts +- [x] Vérifier la fonction sendEmailViaSMTP dans smtpSender.ts +- [x] Vérifier pourquoi le mode production ne peut pas être activé (le switch fonctionne) +- [x] Corriger l'affichage du statut pour montrer SMTP au lieu de Resend +- [x] Ajouter des alertes spécifiques pour SMTP +- [x] Corriger la fonction upsertEmailConfig pour mettre à jour au lieu de créer +- [x] Forcer la mise à jour du provider dans la base de données +- [x] Vérifier que la configuration SMTP est bien enregistrée (provider=smtp) +- [ ] Tester l'envoi d'email de test en mode production (après hard refresh)