Commit Graph

6 Commits

Author SHA1 Message Date
MVA Global Fret
eb5c4f1cee Email verification flow via Resend (Turnstile + click-to-confirm)
Architecture finale :

1. User remplit formulaire + passe Turnstile CAPTCHA → form-handler.js
2. form-handler.js POST au Worker avec action 'requestVerification'
3. Worker valide Turnstile, génère un token UUID, le stocke en KV (TTL 24h)
   avec firstname/email/reference_client, puis envoie un email via Resend
   avec un lien : confirmation.html?token=XXX
4. User reçoit email, clique 'Confirmer mon email'
5. confirmation.html lit le token de l'URL, POST au Worker avec action
   'verifyToken'
6. Worker valide le token, envoie le welcome email via Resend (avec ref +
   adresse Paris depuis env var), marque le token comme utilisé
7. confirmation.html affiche 'Inscription confirmée !'

Ainsi : ref + adresse Paris ne sortent JAMAIS avant validation email,
et les bots sont bloqués à l'étape 1 par Turnstile.

Setup Cloudflare requis (côté user) :
- RESEND_API_KEY  : clé API Resend (re_...)
- RESEND_FROM     : adresse expéditrice ('onboarding@resend.dev' pour test,
                    ou domain vérifié pour prod)
- SITE_URL        : optionnel, défaut https://mva-global-fret.github.io/site-mva-global-fret

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 10:59:26 +02:00
MVA Global Fret
a3a36df811 Anti-spam: add Cloudflare Turnstile (CAPTCHA) on registration form
- contact.html: ajout du widget Turnstile (site key: 0x4AAAAAADKDuc7Rmlb1svIL)
- form-handler.js: blocage de la soumission si pas de token Turnstile valide
- Worker: validation server-side du token via /turnstile/v0/siteverify
  avant chaque appel sendWelcomeNow → bloque les bots qui n'auraient
  pas passé le challenge côté client.

Le secret Turnstile est en env var Cloudflare (TURNSTILE_SECRET).

Limite humain : Turnstile détecte les bots avec très peu d'interaction
côté utilisateur (mode 'Managed', le plus souvent invisible).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 10:47:29 +02:00
MVA Global Fret
313c870ea4 Fix bugs inscription: ref dupliquée + email de bienvenue manquant
Bug 1 — Ref MVA-001 dupliquée :
Le filtre HubSpot 'HAS_PROPERTY' avec value:'' retournait 0 résultats.
Suppression du value:'' → maintenant le worker liste correctement les
contacts avec reference_client et incrémente bien (testé : MVA-004).

Bug 2 — Email post-inscription jamais reçu :
Le double opt-in HubSpot ne se déclenche pas via Forms API sans
subscription consent (impossible à configurer sans nouveaux scopes
Private App). Pivot vers une approche plus simple :
- L'email de bienvenue est désormais envoyé directement après
  soumission du formulaire (pas de DOI HubSpot)
- L'envoi passe par le Cloudflare Worker (action sendWelcomeNow)
  pour que l'adresse Paris reste dans les env vars Cloudflare et
  ne soit JAMAIS dans le JS public
- Worker appelle EmailJS REST avec firstname + reference + paris_address

Cleanup : message de succès reverti à 'Inscription réussie' (FR/EN/MG).

Anti-spam : protection légère via filtre email/téléphone côté formulaire.
La cron-based welcome (post-DOI) reste en place mais sera inerte tant
que aucun contact n'a le statut CONFIRMED côté HubSpot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:52:48 +02:00
MVA Global Fret
0ef9f01fd9 Worker: cron post-confirmation pour envoyer le welcome email après opt-in
Architecture finale (Option A choisie) :

1. User submit form → contact créé en HubSpot avec reference_client
2. HubSpot envoie l'email de double opt-in (sans la ref ni l'adresse Paris)
3. User clique 'Confirmer' → HubSpot met hs_emailconfirmationstatus = CONFIRMED
4. Cron Cloudflare (toutes les 5 min) :
   - Liste les contacts CONFIRMED + créés après le cutoff
   - Filtre via Cloudflare KV (welcomed:<email>) pour idempotence
   - Envoie le welcome email via EmailJS REST API avec :
     • firstname
     • reference_client
     • paris_address (depuis env var PARIS_DEPOT_ADDRESS)
   - Marque envoyé dans KV avec TTL 1 an

Protection :
- L'adresse du dépôt Paris ne quitte JAMAIS Cloudflare/EmailJS
- Elle n'arrive au client que dans le mail de bienvenue post-opt-in
- Bots qui n'ont pas un vrai email ne peuvent pas valider → ne reçoivent rien
- Anti-spam et anti-cartons-vides blindé

Ajout d'une action 'triggerWelcomeQueue' pour debug/manual run.
Doc complète dans cloudflare-worker/DEPLOIEMENT.md (étapes 1 à 6).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:24:26 +02:00
MVA Global Fret
15e98b9c32 feat: numérotation séquentielle MVA-XXX, texte succès corrigé, message email/spam 2026-05-04 16:28:28 +02:00
MVA Global Fret
1970b10089 Sécurise form-handler : retire token côté client, prépare proxy Worker
- Supprime HUBSPOT_SERVICE_KEY du code JS public (évite l'exposition du token)
- Remplace l'appel CORS-bloqué vers api.hubapi.com par un appel au proxy
  Cloudflare Worker (WORKER_PROXY_URL, vide par défaut = sans blocage)
- Ajoute cloudflare-worker/hubspot-proxy.js : code complet du Worker à
  déployer gratuitement depuis dash.cloudflare.com (sans CLI ni Node.js)
- Quand WORKER_PROXY_URL est renseigné, la détection doublon est active :
  un client existant voit son message "déjà inscrit" sans re-soumission

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-04 14:13:17 +02:00