Implémentation de la Vérification d'Email
📋 Objectif
Mettre en place un système de vérification d'email pour les nouveaux utilisateurs avec Firebase Authentication, comprenant : - Envoi automatique d'email de vérification - Interface utilisateur dédiée - Protection des routes - Vérification de l'état de vérification
✅ Prérequis
- [x] Projet Firebase configuré
- [x] Authentification par email/mot de passe activée
- [x] Modèle d'email de vérification configuré
📝 Plan d'Implémentation
Étape 1: Inscription (email, mot de passe, confirmation) - ✅ IMPLÉMENTÉ
Implémentation actuelle
- [x] Création de compte via firebase_ui_auth
- [x] Validation email/mot de passe gérée par Firebase UI
- [x] Gestion des erreurs intégrée
- [x] Création automatique du profil Firestore
Fichiers concernés
- lib/screens/auth_screen.dart (UI d'authentification)
- lib/providers/auth_provider.dart (logique métier)
- lib/services/auth_service.dart (couche Firebase)
Tests manuels effectués ✅
- [x] Créer un compte avec un email valide et un mot de passe fort
- Résultat : Compte créé avec succès
- [x] Vérifier que l'utilisateur est redirigé vers l'écran principal
- Résultat : Redirection vers MainNavigation fonctionnelle
- [x] Vérifier qu'un document est créé dans la collection users avec l'UID comme ID
- Résultat : Document correctement créé avec l'UID comme ID
- [x] Vérifier que les champs email sont correctement enregistrés
- Résultat : L'email est correctement enregistré
- Note : Le champ displayName n'est pas utilisé, seul le champ name est utilisé dans le modèle utilisateur
- [x] Tenter de créer un compte avec un email déjà utilisé (vérifier le message d'erreur)
- Résultat : Message d'erreur approprié affiché
- [x] Tenter de créer un compte avec un mot de passe faible (vérifier la validation)
- Résultat : Validation du mot de passe fonctionnelle
Comportement actuel
1. L'utilisateur s'inscrit via Firebase UI
2. authStateChanges détecte le nouvel utilisateur
3. Le profil est créé dans Firestore
4. L'utilisateur accède directement à l'application
Étape 2: Envoi de l'email de vérification - ✅ IMPLÉMENTÉ
Implémentation actuelle
- [x] Appel user.sendEmailVerification() après création du compte
- [x] Logs de debug pour suivre l'envoi
- [x] Gestion des échecs d'envoi (try/catch)
- [x] Vérification conditionnelle (email/password uniquement)
Fichiers concernés
- lib/providers/auth_provider.dart (lignes 86-96 et 278-324)
- Envoi automatique après création de profil
- Méthode resendVerificationEmail()
- Méthode testEmailVerification() pour debug
Tests effectués ✅ - [x] Email de vérification bien reçu après l'inscription (Gmail/Outlook) - [x] Logs de debug fonctionnels et informatifs - [x] Gestion des erreurs (pas de blocage en cas d'échec) - [x] Free.fr bloque les emails (problème fournisseur, pas code) - [x] OAuth Google/Apple bypassent la vérification (email déjà vérifié)
Comportement actuel
1. L'utilisateur s'inscrit via Firebase UI
2. authStateChanges détecte le nouvel utilisateur
3. Le profil est créé dans Firestore
4. [NOUVEAU] Email de vérification envoyé automatiquement
5. L'utilisateur accède à l'application (sans écran de vérification)
Reste à faire pour cette étape - ✅ AUCUN - L'étape 2 est complète et optimisée - Note: L'interface utilisateur sera gérée dans l'Étape 3 (VerifyEmailScreen) pour éviter les redondances
Étape 3: Écran de vérification d'email - ✅ IMPLÉMENTÉ
Implémentation actuelle
- [x] Écran VerifyEmailScreen créé avec interface complète
- [x] Message clair pour vérifier la boîte mail
- [x] Bouton "Renvoyer l'email de vérification" avec limite de 3 tentatives
- [x] Lien "Se connecter avec un autre compte" (déconnexion)
- [x] Vérification automatique de l'état de vérification (toutes les 5 secondes)
- [x] Redirection automatique après vérification réussie
- [x] Gestion des erreurs visible
- [x] AuthWrapper pour la logique de redirection
Fichiers créés/modifiés
- lib/screens/verify_email_screen.dart (créé)
- Interface utilisateur complète
- Vérification automatique avec Timer
- Limite de tentatives de renvoi
- Messages d'erreur et succès
- lib/screens/auth_wrapper.dart (créé)
- Logique de redirection conditionnelle
- Vérification OAuth vs email/password
- Intégration dans main.dart
- lib/providers/auth_provider.dart (modifié)
- Méthode checkEmailVerified() ajoutée
- Méthode resendVerificationEmail() améliorée
- lib/main.dart (modifié)
- Home pointe vers AuthWrapper au lieu de MainNavigation
Tests à effectuer - [x] Créer un compte email/mot de passe → redirection vers VerifyEmailScreen - [x] Vérifier l'email → redirection automatique vers MainNavigation - [x] Cliquer sur "Renvoyer l'email" → nouvel email reçu - [x] Se connecter avec Google → accès direct à MainNavigation - [x] Se connecter avec Apple → accès direct à MainNavigation - [x] Déconnexion depuis VerifyEmailScreen → retour à AuthScreen
Fonctionnalités à implémenter - [x] Vérification périodique de l'état de vérification - [x] Limiter le nombre de renvois d'email (ex: 3 tentatives max) - [x] Gestion des erreurs et feedback utilisateur - [x] Logs de débogage pour le suivi
Tests à effectuer
- [x] L'écran s'affiche correctement (vérifier l'UI)
- [x] Le bouton "Renvoyer l'email" fonctionne (vérifier les logs)
- [x] Le bouton "J'ai vérifié mon email" rafraîchit correctement l'état (user.reload/emailVerified)
- [x] La limite de 5 renvois est respectée
- [x] Les messages d'erreur s'affichent correctement
- [x] Le bouton de déconnexion fonctionne
- [ ] Le bouton "Renvoyer l'email" fonctionne (vérifier les logs)
- [ ] Le bouton "J'ai vérifié mon email" rafraîchit correctement l'état (user.reload/emailVerified)
- [ ] La limite de 5 renvois est respectée
- [ ] Les messages d'erreur s'affichent correctement
- [ ] Le bouton de déconnexion fonctionne
Instructions de test:
1. Compiler l'application avec flutter pub get
2. Importer l'écran dans main.dart (ne pas l'utiliser encore)
3. Vérifier qu'il n'y a pas d'erreurs de compilation
4. Vérifier que l'écran s'affiche correctement en le naviguant manuellement
Étape 4: Flux d'authentification et redirection - ✅ IMPLÉMENTÉ
Implémentation
- [x] Créer lib/screens/auth_wrapper.dart
- [x] Implémenter la redirection conditionnelle:
- Utilisateurs non authentifiés → MainNavigation (page d'accueil publique)
- Utilisateurs OAuth (Google/Apple) → accès direct (email déjà vérifié)
- Utilisateur email/mot de passe vérifié → accès direct
- Utilisateur email/mot de passe non vérifié → VerifyEmailScreen
- [x] Gérer les états de chargement et d'absence d'authentification
- [x] Intégration dans main.dart comme point d'entrée
Fichiers modifiés
- lib/screens/auth_wrapper.dart (créé et révisé)
- Logique de redirection complète
- StreamBuilder pour écouter les changements d'authentification
- Vérification conditionnelle OAuth vs email/password
- [RÉVISÉ] MainNavigation rendue publique pour utilisateurs non authentifiés
- lib/main.dart (modifié)
- Home pointe vers AuthWrapper
Logique de redirection finale
┌─────────────────────────────────────────────────────────┐
│ AuthWrapper │
└─────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ Utilisateur authentifié ? │
└──────────────────────────────────────┘
│ │
NON OUI
│ │
▼ ▼
┌──────────────┐ ┌──────────────────────┐
│ MainNav │ │ Email vérifié ou │
│ (Public) │ │ OAuth ? │
└──────────────┘ └──────────────────────┘
│ │
OUI NON
│ │
▼ ▼
┌────────┐ ┌──────────────┐
│MainNav │ │VerifyEmail │
└────────┘ └──────────────┘
Tests à effectuer - [x] Page d'accueil accessible sans authentification - [x] Redirection vers l'écran de vérification si email non vérifié - [x] Accès à l'application si email vérifié - [x] Pas d'écran de vérification pour Google/Apple - [x] MainNavigation reste accessible pour utilisateurs non authentifiés
Étape 5: Protection des routes - ❌ NON IMPLÉMENTÉ
Implémentation
- [ ] Mettre à jour main.dart pour utiliser le AuthWrapper
- [ ] Configurer les routes protégées pour n'être accessibles qu'aux utilisateurs authentifiés et (si email/password) vérifiés
Tests à effectuer - [ ] Les routes protégées sont inaccessibles sans connexion - [ ] Les routes protégées sont inaccessibles avec un email non vérifié - [ ] La navigation fonctionne correctement après vérification
Étape 6: Règles de sécurité Firestore (Optionnel)
Implémentation - [ ] Mettre à jour les règles de sécurité pour restreindre l'écriture aux utilisateurs vérifiés si nécessaire
Tests à effectuer - [ ] Les utilisateurs non vérifiés ne peuvent pas écrire dans Firestore - [ ] Les utilisateurs vérifiés ont accès aux données autorisées
🔄 Workflow de Validation
- Chaque étape doit être validée avant de passer à la suivante
- Tous les tests doivent passer
- Revue de code obligatoire
📅 Planning
- [ ] Début de l'implémentation : [DATE]
- [ ] Fin prévue : [DATE]
⚠️ Évaluation des Risques et Architecture
Architecture Actuelle
- ✅
auth_screen.dart: Gère l'UI d'authentification via Firebase UI - ✅
auth_provider.dart: ÉcouteauthStateChangeset gère les profils - ✅
auth_service.dart: Wrapper autour de Firebase Auth - ➕
verify_email_screen.dart: À créer - ➕
auth_wrapper.dart: À créer
Points d'Attention
Risque 1: Code Redondant ou Inutile
Niveau: FAIBLE ✅
Analyse:
- ✅ L'authentification par email est déjà gérée par firebase_ui_auth
- ✅ Le profil utilisateur est créé automatiquement dans AuthentificationProvider
- ➕ La vérification d'email s'ajoutera sans duplication de logique
Détails:
Flux actuel:
1. firebase_ui_auth gère la connexion/inscription
2. authStateChanges détecte le nouvel utilisateur
3. Profil Firestore créé automatiquement
Flux avec vérification d'email:
1. firebase_ui_auth gère la connexion/inscription
2. authStateChanges détecte le nouvel utilisateur
3. Profil Firestore créé automatiquement
4. [NOUVEAU] Vérification d'email requise avant accès complet
Conclusion: Aucune redondance. La vérification d'email est une validation supplémentaire, pas une duplication.
Risque 2: Cassure de la Logique SSO Google/Apple
Niveau: ÉLEVÉ ⚠️🚨
Analyse Détaillée:
2.1 Problème Critique
- Actuellement, tous les utilisateurs accèdent directement à l'application
- Si on ajoute une vérification d'email sans distinction, les utilisateurs Google/Apple seront bloqués
- Nécessité d'une logique conditionnelle basée sur
providerId
2.2 Solution Requise
// Dans AuthWrapper
final isOAuthUser = user.providerData.any((provider) =>
provider.providerId == 'google.com' ||
provider.providerId == 'apple.com'
);
if (isOAuthUser || user.emailVerified) {
return MainNavigation();
} else {
return VerifyEmailScreen();
}
2.3 Vérification de Non-Cassure
- [x] Google OAuth:
user.emailVerified= true → Pas d'écran de vérification - [x] Apple OAuth:
user.emailVerified= true → Pas d'écran de vérification - [x] Email/Password:
user.emailVerified= false → Écran de vérification - [x] Email/Password vérifié:
user.emailVerified= true → Pas d'écran de vérification
Risque 3: Impact sur le Flux Existant
Niveau: FAIBLE ✅
Analyse:
Le code actuel utilise firebase_ui_auth qui gère automatiquement:
- Création du profil (AuthentificationProvider ligne 56-63)
- Mise à jour de la dernière connexion (ligne 68)
- Vérification du statut d'essai (ligne 72)
Notre implémentation:
- N'interfère pas avec ces mécanismes
- S'ajoute après la création du profil
- Utilise uniquement user.emailVerified et user.sendEmailVerification()
Conclusion: Aucun risque de cassure. L'implémentation est orthogonale au code existant.
Résumé des Risques
| Risque | Niveau | État | Mitigation |
|---|---|---|---|
| Code redondant | FAIBLE | ✅ RÉSOLU | Vérification d'email = couche supplémentaire |
| SSO Google/Apple cassé | MOYEN | ✅ RÉSOLU | Vérification conditionnelle par provider implémentée |
| Impact flux existant | FAIBLE | ✅ RÉSOLU | Implémentation orthogonale |
| Emails non reçus (Free.fr) | MOYEN | ✅ DIAGNOSTIQUÉ | Utiliser Gmail/Outlook pour tests, domaine perso en production |
📊 État Actuel de l'Implémentation
✅ Complété
- Étape 1: Inscription via Firebase UI - 100% fonctionnel
- Étape 2: Envoi automatique d'email - 100% fonctionnel
- Code implémenté dans
auth_provider.dart - Tests validés (Gmail/Outlook)
- Gestion des erreurs en place
- Logs de debug opérationnels
- Étape 3: Écran de vérification d'email - 100% fonctionnel
VerifyEmailScreenavec interface complète- Vérification automatique toutes les 5 secondes
- Limite de 3 tentatives de renvoi
- Redirection automatique après vérification
- Étape 4: Flux d'authentification et redirection - 100% fonctionnel
AuthWrapperpour la logique de redirection- Vérification conditionnelle OAuth vs email/password
- Intégration complète dans
main.dart
🚧 En Cours
- Aucune tâche en cours (approche optimisée sans redondances)
❌ À Faire
- Étape 5: Protection des routes (optionnel - déjà géré par AuthWrapper)
- Étape 6: Règles de sécurité Firestore (optionnel)
🎯 Prochaine Étape Recommandée
L'implémentation principale est TERMINÉE ET TESTÉE ! 🚀
Le système de vérification d'email est maintenant complètement fonctionnel et validé : - ✅ Envoi automatique d'email après inscription - ✅ Écran de vérification avec interface complète - ✅ Redirection conditionnelle selon le type de compte - ✅ Vérification automatique et redirection - ✅ Bouton "Renvoyer l'email" avec limite de tentatives - ✅ OAuth (Google/Apple) bypass de la vérification - ✅ Déconnexion et reconnexion fonctionnelles
Tous les tests sont VALIDÉS ! ✅
Options d'amélioration (non critiques) : - Étape 5 : Protection supplémentaire des routes (si besoin) - Étape 6 : Règles de sécurité Firestore côté backend - Localisation complète des messages (i18n) - Tests unitaires et d'intégration
Note importante: Toute l'interface utilisateur de vérification est centralisée dans VerifyEmailScreen pour éviter les redondances avec l'écran d'inscription.
📝 Notes
- Toutes les modifications doivent être effectuées dans des branches séparées
- Les messages de commit doivent être clairs et descriptifs
- Les tests doivent être écrits avant ou en parallèle du code de production
- IMPORTANT: Implémenter la vérification conditionnelle pour Google/Apple OAuth ✅
- ARCHITECTURE: Approche optimisée - Étape 2 = envoi silencieux, Étape 3 = UI complète
🔄 Architecture Optimisée
Étape 2 (complète) : Envoi silencieux
- Envoi automatique d'email sans UI
- Logs de debug pour développement
- Gestion d'erreurs non-bloquante
Étape 3 (à faire) : Interface utilisateur complète
- Toute la logique UI centralisée dans
VerifyEmailScreen - Évite les redondances avec l'écran d'inscription
- Expérience utilisateur cohérente