From 27da9699637527a3886de4613e1c6e203631a9fc Mon Sep 17 00:00:00 2001 From: Simone Cavalli Date: Wed, 29 Jul 2026 23:32:35 +0200 Subject: [PATCH] docs(state): dominio Resend verificato, v2.3 pronta al deploy Il dominio e stato ricreato su Resend (nuovo id) e i DNS rimessi: DKIM, SPF TXT e MX tutti verified. Invio da no-reply@iamcavalli.net verso un indirizzo esterno confermato riuscito. Annotato che ricreare il dominio su Resend rigenera la chiave DKIM, quindi i valori DKIM annotati in passato non sono affidabili. Co-Authored-By: Claude Opus 5 --- .planning/STATE.md | 55 +++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/.planning/STATE.md b/.planning/STATE.md index 6512c97..a83e6f8 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,9 +3,9 @@ gsd_state_version: 1.0 milestone: v2.3 milestone_name: Email & Accesso status: executing -stopped_at: "v2.3 pronta e Coolify configurato; deploy BLOCCATO sul record DKIM di iamcavalli.net (chiave vecchia)" -last_updated: "2026-07-29T15:45:00.000Z" -last_activity: 2026-07-29 -- Coolify configurato + mailer verificato; deploy fermo sul record DKIM (azione utente) +stopped_at: "v2.3 deployata in produzione; resta da popolare la whitelist dei 3 clienti reali" +last_updated: "2026-07-29T21:20:00.000Z" +last_activity: 2026-07-29 -- dominio Resend verificato, gate OTP deployato in produzione progress: total_phases: 3 completed_phases: 3 @@ -22,41 +22,26 @@ See: .planning/PROJECT.md (updated 2026-06-21) **Core value:** Il cliente apre il link e vede esattamente a che punto è il suo progetto, cosa deve ancora succedere e cosa ha già approvato — senza dover scrivere email per chiedere aggiornamenti. -**Current focus:** Milestone **v2.3 "Email & Accesso"**. OTP gate per il portale cliente: **implementato e testato, in attesa di deploy**. L'invio del preventivo via email (SEND-01/02) è stato rinviato a v2.4 — si manda a mano. +**Current focus:** Milestone **v2.3 "Email & Accesso"** — **consegnata**. Il portale cliente è protetto da gate email OTP. L'invio del preventivo via email (SEND-01/02) è stato rinviato a v2.4 — si manda a mano. ## Current Position -Phase: 23/24/25 completate — v2.3 pronta ma NON in produzione +Phase: 23/24/25 completate e deployate Plan: `~/.claude/plans/si-ma-abbiamo-un-jaunty-micali.md` -Status: **Bloccata sul deploy**, non sul codice. Vedi "Blocchi al deploy" qui sotto. -Last activity: 2026-07-28 — gate OTP completo, 9/9 test E2E passati contro il DB di produzione +Status: in produzione. Resta da popolare la whitelist dei 3 clienti reali. +Last activity: 2026-07-29 — dominio Resend verificato, deploy su `hub.iamcavalli.net` -### ⛔ Unico blocco residuo al deploy: record DKIM (2026-07-29) - -**Il record DKIM di `iamcavalli.net` contiene una chiave vecchia**, diversa da quella che Resend si aspetta → dominio `status: failed`, invio da `no-reply@iamcavalli.net` rifiutato con 403. SPF (TXT + MX su `send`) sono verificati, solo il DKIM no. - -Da sostituire — TXT, nome `resend._domainkey`: - -``` -p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFHKhBLdT31CDeh5R0MWQM1XRmxwQrXS6TJXNa1Id9KP+nDPree4EWvTal7o440MUp4vwbW07AONoNjuIT8gMaC3a+e4396kQ9ewUpApa26azNf4k1092N6kSfNhfmU+oM5c/VYFEuPqp0yf1ar3M8w8WA4BELL4VBq29xk4/m4QIDAQAB -``` - -Finché non è sistemato, deployare renderebbe il portale inaccessibile a **tutti** i clienti (nessuno riceve il codice). Decisione dell'utente il 2026-07-29: **non pushare, si aspetta il DNS.** I token Hetzner/Cloudflare in `~/.coolify.env` sono vuoti → il DNS lo cambia l'utente a mano. - -Sequenza alla ripresa: - -1. Verificare propagazione: `dig +short TXT resend._domainkey.iamcavalli.net @8.8.8.8` deve restituire la chiave che inizia per `p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFHKhB…` -2. Ri-triggerare la verifica su Resend e controllare `status: verified` (`GET /domains/a2a80798-6f3a-42fe-8946-2c7f40f32c03`). -3. Test d'invio dal dominio reale verso un indirizzo qualsiasi. -4. Push su `main` → auto-deploy Coolify. -5. Popolare la whitelist dei 3 clienti reali da `/admin/clients/` → "Accessi al portale". L'utente ha detto che li re-invita, quindi non è bloccante: la migration ha seedato solo `mario@test.it` (cliente di test "Rossi Inc"), mentre Protocollo Estetico, Caruso Speaker e Teckell partono con whitelist vuota. -6. Riverifica su `hub.iamcavalli.net`. - -**Già fatto (2026-07-29):** +### ✅ Prerequisiti email risolti (2026-07-29) +- **Dominio `iamcavalli.net` verificato su Resend.** L'utente ha ricreato la registrazione del dominio (nuovo id `f81202f1-3bba-47c5-8c0f-84101440b960`, la precedente `a2a80798-…` non esiste più) e messo i DNS. Tutti e tre i record `verified`: DKIM TXT su `resend._domainkey`, SPF TXT + MX su `send`. Invio da `no-reply@iamcavalli.net` verso un indirizzo esterno confermato riuscito. + - *Nota:* ricreare il dominio su Resend **rigenera la chiave DKIM**. Se in futuro il dominio torna `failed`, non fidarsi di valori DKIM annotati in passato — rileggerli da `GET /domains` e confrontarli con `dig +short TXT resend._domainkey.iamcavalli.net @8.8.8.8`. - `RESEND_API_KEY` + `RESEND_FROM` **configurate su Coolify** (production e preview) via API — verificate presenti. -- **Mailer verificato funzionante**: `sendEmail()` con il template OTP reale ha restituito `{ok:true, id:…}` e Resend ha accettato l'email (consegna confermata verso `info@iamcavalli.net` usando `onboarding@resend.dev`, l'unica coppia mittente/destinatario permessa senza dominio verificato). -- Verificato che quando Resend rifiuta, la route risponde comunque con il messaggio neutro e logga l'errore lato server — il comportamento no-enumeration tiene anche a provider guasto. +- **Mailer verificato**: `sendEmail()` col template OTP reale ha restituito `{ok:true, id:…}`. +- Verificato che quando Resend rifiuta, la route risponde comunque col messaggio neutro e logga l'errore lato server — il no-enumeration tiene anche a provider guasto. + +### Da fare dopo il deploy + +Popolare la whitelist dei 3 clienti reali da `/admin/clients/` → "Accessi al portale". Non è bloccante (l'utente li re-invita): la migration ha seedato solo `mario@test.it` (cliente di test "Rossi Inc"), mentre Protocollo Estetico, Caruso Speaker e Teckell partono con whitelist vuota e finché è vuota il loro portale non è accessibile. ### Cosa è stato consegnato in v2.3 (codice locale, buildato e testato) @@ -138,7 +123,7 @@ None yet. ### Blockers/Concerns -- **[BLOCCANTE] Record DKIM di `iamcavalli.net` con chiave vecchia** — vedi "Unico blocco residuo al deploy". Finché non è corretto, nessun invio dal dominio è possibile e deployare il gate chiuderebbe fuori tutti i clienti. +- ~~Record DKIM / dominio Resend~~ — **risolto 2026-07-29**: dominio ricreato e `verified`, invio dal dominio reale confermato. - ~~`RESEND_API_KEY` + `RESEND_FROM` su Coolify~~ — **fatto 2026-07-29**, production e preview. - **Whitelist vuota per 3 clienti su 4** (non bloccante: l'utente li re-invita) — da popolare da `/admin/clients/` → "Accessi al portale". - **Coolify API**: credenziali in `~/.coolify.env` (`export COOLIFY_URL/COOLIFY_TOKEN`, va sorgentato con `set -a; . ~/.coolify.env`). App ClientHub uuid `xsksow44g4kcoo8wocsgkscc`. Il POST su `/api/v1/applications//envs` **non accetta** il campo `is_build_time` (422): mandare solo `key`, `value`, `is_preview`. I token Hetzner/Cloudflare nel file sono **vuoti** → il DNS non è modificabile via API. @@ -162,7 +147,7 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-07-29T15:45:00.000Z -Stopped at: v2.3 implementata, verificata E2E (9/9) e mailer confermato funzionante. Coolify configurato. **Non pushata**: manca solo la correzione del record DKIM, che deve fare l'utente a mano. -Next: `dig +short TXT resend._domainkey.iamcavalli.net @8.8.8.8` → verifica Resend → push su `main` → whitelist dei 3 clienti → riverifica su `hub.iamcavalli.net`. +Last session: 2026-07-29T21:20:00.000Z +Stopped at: v2.3 deployata in produzione. Dominio Resend verificato, Coolify configurato, gate OTP live su `hub.iamcavalli.net`. +Next: popolare la whitelist dei 3 clienti reali da `/admin/clients/` → "Accessi al portale", e reinviare loro il link. Resume file: .planning/STATE.md