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>
77 lines
2.7 KiB
JavaScript
77 lines
2.7 KiB
JavaScript
// ============================================================
|
|
// MVA Global Fret — Page de confirmation post-validation email
|
|
// ============================================================
|
|
// Cette page est la cible du lien dans l'email de validation
|
|
// (envoyé par Resend après soumission du formulaire).
|
|
//
|
|
// URL : https://mva-global-fret.github.io/site-mva-global-fret/confirmation.html?token=XXX
|
|
//
|
|
// Étapes :
|
|
// 1. Lire le token depuis l'URL
|
|
// 2. POST au Worker avec action 'verifyToken'
|
|
// 3. Worker valide le token, envoie le welcome email (avec ref +
|
|
// adresse Paris) via Resend, puis renvoie OK
|
|
// 4. Page affiche "Inscription confirmée !"
|
|
//
|
|
// Si le token est invalide / expiré : affichage d'un message d'erreur
|
|
// avec invitation à contacter le support.
|
|
// ============================================================
|
|
|
|
const WORKER_PROXY_URL = 'https://mva-hubspot-proxy.mvaglobalfret.workers.dev';
|
|
|
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
const token = new URLSearchParams(window.location.search).get('token');
|
|
|
|
if (!token) {
|
|
showError('Lien de confirmation invalide. Veuillez vérifier votre email ou nous contacter.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const res = await fetch(WORKER_PROXY_URL, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ action: 'verifyToken', token }),
|
|
});
|
|
const data = await res.json();
|
|
|
|
if (data.ok) {
|
|
showSuccess(data.reference_client || null);
|
|
} else {
|
|
// Token expiré, déjà utilisé, ou inconnu
|
|
showError(data.error === 'Token invalide ou expiré'
|
|
? 'Ce lien de confirmation a expiré ou a déjà été utilisé.'
|
|
: 'Une erreur est survenue lors de la confirmation.');
|
|
}
|
|
} catch (err) {
|
|
console.warn('[confirmation]', err);
|
|
showError('Impossible de joindre le serveur. Vérifiez votre connexion et réessayez.');
|
|
}
|
|
});
|
|
|
|
function showSuccess(ref) {
|
|
const loading = document.getElementById('cardLoading');
|
|
const success = document.getElementById('cardSuccess');
|
|
if (loading) loading.style.display = 'none';
|
|
if (success) {
|
|
success.style.display = '';
|
|
if (ref) {
|
|
const refDisplay = document.getElementById('refDisplay');
|
|
const refBlock = document.getElementById('refBlock');
|
|
if (refDisplay) refDisplay.textContent = ref;
|
|
if (refBlock) refBlock.style.display = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
function showError(msg) {
|
|
const loading = document.getElementById('cardLoading');
|
|
const error = document.getElementById('cardError');
|
|
if (loading) loading.style.display = 'none';
|
|
if (error) {
|
|
error.style.display = '';
|
|
const desc = error.querySelector('p');
|
|
if (desc && msg) desc.textContent = msg;
|
|
}
|
|
}
|