Ajout de 47 features Gherkin (~650 scénarios) pour couvrir 100% des règles métier : - Authentification (5) : validation mot de passe, tentatives connexion, multi-device, 2FA, récupération - Audio-guides (12) : détection mode, création, navigation piéton/voiture, ETA, gestion points, progression - Navigation (5) : notifications minimalistes, décompte 5s, stationnement, historique, basculement auto - Création contenu (3) : image auto, restrictions modification, suppression - Radio live (2) : enregistrement auto, interdictions modération - Droits auteur (6) : fair use 30s, détection musique, signalements, sanctions, appels - Modération (9) : badges Bronze/Argent/Or, score fiabilité, utilisateur confiance, audit, anti-abus - Premium (2) : webhooks Mangopay, tarification multi-canal - Profil/Partage/Recherche (5) : badge vérifié, stats arrondies, partage premium, filtres avancés, carte Tous les scénarios incluent edge cases, métriques de performance et conformité RGPD. Couverture fonctionnelle MVP maintenant complète.
188 lines
11 KiB
Gherkin
188 lines
11 KiB
Gherkin
# language: fr
|
|
|
|
@api @authentication @security @mvp
|
|
Fonctionnalité: Récupération et réinitialisation avancée du mot de passe
|
|
|
|
En tant qu'utilisateur ayant oublié son mot de passe
|
|
Je veux pouvoir récupérer l'accès à mon compte de manière sécurisée
|
|
Afin de reprendre l'utilisation de l'application
|
|
|
|
Contexte:
|
|
Étant donné que le système de récupération est configuré avec:
|
|
| Paramètre | Valeur |
|
|
| Durée de validité du lien de reset | 1 heure |
|
|
| Nombre max de demandes par heure | 3 |
|
|
| Nombre max de demandes par jour | 10 |
|
|
| Longueur du token de reset | 64 chars |
|
|
| Délai de cooldown entre demandes | 5 minutes |
|
|
|
|
Scénario: Demande de réinitialisation de mot de passe
|
|
Étant donné un utilisateur "alice@roadwave.fr" qui a oublié son mot de passe
|
|
Quand l'utilisateur clique sur "Mot de passe oublié ?" sur l'écran de connexion
|
|
Et saisit son adresse email "alice@roadwave.fr"
|
|
Alors un email de réinitialisation est envoyé avec:
|
|
| Élément | Contenu |
|
|
| Sujet | Réinitialisation de votre mot de passe RoadWave |
|
|
| Lien sécurisé | https://roadwave.fr/reset?token=abc123... |
|
|
| Durée de validité | Ce lien expire dans 1 heure |
|
|
| Warning sécurité | Si vous n'êtes pas à l'origine de cette demande... |
|
|
Et un événement "PASSWORD_RESET_REQUESTED" est enregistré
|
|
Et la métrique "auth.password_reset.requested" est incrémentée
|
|
Et un message s'affiche: "Si cette adresse est enregistrée, vous recevrez un email de réinitialisation"
|
|
|
|
Scénario: Protection contre l'énumération d'adresses email
|
|
Étant donné une adresse email "inexistant@roadwave.fr" non enregistrée
|
|
Quand un utilisateur demande la réinitialisation pour cette adresse
|
|
Alors le même message de confirmation s'affiche: "Si cette adresse est enregistrée, vous recevrez un email"
|
|
Et aucun email n'est envoyé
|
|
Et le temps de réponse est identique à une demande valide (800-1200ms)
|
|
Et un événement "PASSWORD_RESET_UNKNOWN_EMAIL" est enregistré
|
|
Et la métrique "auth.password_reset.unknown_email" est incrémentée
|
|
Et les logs n'exposent pas l'information de l'existence ou non de l'email
|
|
|
|
Scénario: Limitation du nombre de demandes de réinitialisation
|
|
Étant donné un utilisateur "bob@roadwave.fr"
|
|
Et il a déjà effectué 3 demandes de réinitialisation dans la dernière heure
|
|
Quand l'utilisateur effectue une 4ème demande
|
|
Alors la demande est refusée avec le message: "Trop de demandes de réinitialisation. Veuillez attendre 1 heure."
|
|
Et aucun email n'est envoyé
|
|
Et un événement "PASSWORD_RESET_RATE_LIMITED" est enregistré
|
|
Et la métrique "auth.password_reset.rate_limited" est incrémentée
|
|
|
|
Scénario: Utilisation du lien de réinitialisation valide
|
|
Étant donné un utilisateur "charlie@roadwave.fr" ayant demandé la réinitialisation
|
|
Et il a reçu un email avec un token valide il y a 30 minutes
|
|
Quand l'utilisateur clique sur le lien dans l'email
|
|
Alors il est redirigé vers la page de réinitialisation
|
|
Et le formulaire de nouveau mot de passe s'affiche
|
|
Et le token est validé côté serveur
|
|
Et un événement "PASSWORD_RESET_TOKEN_ACCESSED" est enregistré
|
|
Et la session est sécurisée avec CSRF protection
|
|
|
|
Scénario: Définition du nouveau mot de passe avec validation
|
|
Étant donné un utilisateur "david@roadwave.fr" sur la page de réinitialisation
|
|
Et il a un token valide
|
|
Quand l'utilisateur saisit un nouveau mot de passe "SecurePass2026!"
|
|
Et confirme le mot de passe
|
|
Alors le mot de passe est validé selon les règles de sécurité
|
|
Et le mot de passe est hashé avec bcrypt (cost: 12)
|
|
Et le mot de passe est enregistré dans la base de données
|
|
Et toutes les sessions actives sont révoquées
|
|
Et tous les tokens d'accès sont invalidés
|
|
Et un événement "PASSWORD_RESET_COMPLETED" est enregistré
|
|
Et un email de confirmation est envoyé: "Votre mot de passe a été modifié avec succès"
|
|
Et la métrique "auth.password_reset.completed" est incrémentée
|
|
Et l'utilisateur est redirigé vers la page de connexion
|
|
|
|
Scénario: Tentative d'utilisation d'un token expiré
|
|
Étant donné un utilisateur "eve@roadwave.fr" ayant demandé la réinitialisation
|
|
Et il a reçu un email avec un token valide il y a 2 heures
|
|
Quand l'utilisateur clique sur le lien expiré
|
|
Alors un message d'erreur s'affiche: "Ce lien de réinitialisation a expiré. Veuillez faire une nouvelle demande."
|
|
Et un bouton "Demander un nouveau lien" est affiché
|
|
Et un événement "PASSWORD_RESET_TOKEN_EXPIRED" est enregistré
|
|
Et la métrique "auth.password_reset.token_expired" est incrémentée
|
|
|
|
Scénario: Tentative d'utilisation d'un token déjà utilisé
|
|
Étant donné un utilisateur "frank@roadwave.fr" ayant réinitialisé son mot de passe
|
|
Et le token a déjà été utilisé il y a 10 minutes
|
|
Quand l'utilisateur tente de réutiliser le même lien
|
|
Alors un message d'erreur s'affiche: "Ce lien a déjà été utilisé. Si vous avez besoin de réinitialiser à nouveau, faites une nouvelle demande."
|
|
Et un événement "PASSWORD_RESET_TOKEN_REUSED" est enregistré avec niveau "MEDIUM"
|
|
Et un email d'alerte est envoyé: "Tentative de réutilisation d'un ancien lien de réinitialisation"
|
|
Et la métrique "auth.password_reset.token_reused" est incrémentée
|
|
|
|
Scénario: Détection de tentative d'attaque par force brute sur les tokens
|
|
Étant donné un attaquant qui tente de deviner des tokens de réinitialisation
|
|
Quand 10 tokens invalides sont testés depuis la même IP en 5 minutes
|
|
Alors l'IP est bloquée temporairement pour 1 heure
|
|
Et tous les tokens valides pour cette IP sont invalidés
|
|
Et un événement "PASSWORD_RESET_BRUTE_FORCE_DETECTED" est enregistré avec niveau "CRITICAL"
|
|
Et l'équipe de sécurité est alertée via webhook
|
|
Et la métrique "security.password_reset.brute_force" est incrémentée
|
|
|
|
Scénario: Réinitialisation avec validation 2FA pour comptes sensibles
|
|
Étant donné un utilisateur "grace@roadwave.fr" avec 2FA activé
|
|
Et il a demandé la réinitialisation de son mot de passe
|
|
Quand l'utilisateur clique sur le lien de réinitialisation
|
|
Alors une étape supplémentaire de vérification 2FA s'affiche
|
|
Et l'utilisateur doit saisir un code TOTP ou un code de récupération
|
|
Et après validation 2FA, le formulaire de nouveau mot de passe s'affiche
|
|
Et un événement "PASSWORD_RESET_2FA_VALIDATED" est enregistré
|
|
Et la métrique "auth.password_reset.with_2fa" est incrémentée
|
|
|
|
Scénario: Notification de sécurité sur tous les appareils
|
|
Étant donné un utilisateur "henry@roadwave.fr" connecté sur 3 appareils
|
|
Quand l'utilisateur réinitialise son mot de passe
|
|
Alors une notification push est envoyée sur tous les appareils:
|
|
| Message |
|
|
| Votre mot de passe a été modifié |
|
|
| Si ce n'est pas vous, contactez immédiatement le support |
|
|
Et un email est envoyé avec détails:
|
|
| Détail | Valeur |
|
|
| Date et heure | 2026-02-03 14:32:18 |
|
|
| Adresse IP | 1.2.3.4 |
|
|
| Localisation | Paris, France |
|
|
| Appareil | iPhone 14 Pro |
|
|
| Navigateur | Safari 17.2 |
|
|
Et un lien "Ce n'était pas moi" permet de bloquer le compte immédiatement
|
|
|
|
Scénario: Historique des modifications de mot de passe
|
|
Étant donné un utilisateur "iris@roadwave.fr"
|
|
Quand l'utilisateur accède à "Mon compte > Sécurité > Historique"
|
|
Alors l'utilisateur voit l'historique des modifications:
|
|
| Date | Action | IP | Appareil | Localisation |
|
|
| 2026-02-03 14:32 | Réinitialisation mot de passe | 1.2.3.4 | iPhone 14 | Paris, FR |
|
|
| 2026-01-15 10:20 | Changement mot de passe | 5.6.7.8 | MacBook Pro | Lyon, FR |
|
|
| 2025-12-01 08:15 | Création du compte | 9.10.11.12| iPad Air | Marseille, FR |
|
|
Et les événements sont conservés pendant 90 jours minimum
|
|
Et les logs sont conformes RGPD
|
|
|
|
Scénario: Réinitialisation impossible pour compte bloqué ou suspendu
|
|
Étant donné un utilisateur "jack@roadwave.fr" dont le compte est suspendu
|
|
Quand l'utilisateur demande la réinitialisation de son mot de passe
|
|
Alors un message s'affiche: "Votre compte est actuellement suspendu. Veuillez contacter le support."
|
|
Et aucun email de réinitialisation n'est envoyé
|
|
Et un événement "PASSWORD_RESET_ACCOUNT_SUSPENDED" est enregistré
|
|
Et un lien vers le support est fourni
|
|
Et la métrique "auth.password_reset.blocked_account" est incrémentée
|
|
|
|
Scénario: Vérification de l'unicité du nouveau mot de passe
|
|
Étant donné un utilisateur "kate@roadwave.fr" sur la page de réinitialisation
|
|
Quand l'utilisateur tente de définir le même mot de passe que l'ancien
|
|
Alors une erreur s'affiche: "Veuillez choisir un mot de passe différent de l'ancien"
|
|
Et le mot de passe n'est pas enregistré
|
|
Et un événement "PASSWORD_RESET_SAME_PASSWORD" est enregistré
|
|
Et la métrique "auth.password_reset.same_password" est incrémentée
|
|
|
|
Scénario: Vérification contre les mots de passe compromis
|
|
Étant donné un utilisateur "luke@roadwave.fr" sur la page de réinitialisation
|
|
Quand l'utilisateur tente de définir un mot de passe "Password123!"
|
|
Et ce mot de passe figure dans la base de données Have I Been Pwned
|
|
Alors une erreur s'affiche: "Ce mot de passe est connu et a été compromis. Veuillez en choisir un autre."
|
|
Et le mot de passe n'est pas enregistré
|
|
Et un événement "PASSWORD_RESET_COMPROMISED_PASSWORD" est enregistré
|
|
Et la métrique "auth.password_reset.compromised_blocked" est incrémentée
|
|
|
|
Scénario: Cooldown entre demandes successives de réinitialisation
|
|
Étant donné un utilisateur "mary@roadwave.fr"
|
|
Et il a fait une demande de réinitialisation il y a 2 minutes
|
|
Quand l'utilisateur fait une nouvelle demande de réinitialisation
|
|
Alors la demande est refusée avec le message: "Veuillez attendre 5 minutes entre chaque demande"
|
|
Et un compteur affiche "Vous pourrez faire une nouvelle demande dans 3 minutes"
|
|
Et un événement "PASSWORD_RESET_COOLDOWN" est enregistré
|
|
Et la métrique "auth.password_reset.cooldown_hit" est incrémentée
|
|
|
|
Scénario: Métriques de sécurité pour la réinitialisation de mot de passe
|
|
Étant donné que le système traite 1000 demandes de réinitialisation par jour
|
|
Quand les métriques de sécurité sont collectées
|
|
Alors les indicateurs suivants sont disponibles:
|
|
| Métrique | Valeur cible |
|
|
| Taux de complétion des réinitialisations | > 75% |
|
|
| Taux de tokens expirés avant utilisation | < 20% |
|
|
| Temps moyen de complétion | < 5 min |
|
|
| Taux de détection de mots de passe compromis | > 5% |
|
|
| Nombre de tentatives de brute force bloquées | Visible |
|
|
Et les métriques sont exportées vers le système de monitoring
|
|
Et des alertes sont déclenchées si anomalies détectées
|