refactor(docs): réorganiser la documentation selon principes DDD

Réorganise la documentation du projet selon les principes du Domain-Driven Design (DDD) pour améliorer la cohésion, la maintenabilité et l'alignement avec l'architecture modulaire du backend.

**Structure cible:**
```
docs/domains/
├── README.md (Context Map)
├── _shared/ (Core Domain)
├── recommendation/ (Supporting Subdomain)
├── content/ (Supporting Subdomain)
├── moderation/ (Supporting Subdomain)
├── advertising/ (Generic Subdomain)
├── premium/ (Generic Subdomain)
└── monetization/ (Generic Subdomain)
```

**Changements effectués:**

Phase 1: Création de l'arborescence des 7 bounded contexts
Phase 2: Déplacement des règles métier (01-19) vers domains/*/rules/
Phase 3: Déplacement des diagrammes d'entités vers domains/*/entities/
Phase 4: Déplacement des diagrammes flux/états/séquences vers domains/*/
Phase 5: Création des README.md pour chaque domaine
Phase 6: Déplacement des features Gherkin vers domains/*/features/
Phase 7: Création du Context Map (domains/README.md)
Phase 8: Mise à jour de mkdocs.yml pour la nouvelle navigation
Phase 9: Correction automatique des liens internes (script fix-markdown-links.sh)
Phase 10: Nettoyage de l'ancienne structure (regles-metier/, diagrammes/, features/)

**Configuration des tests:**
- Makefile: godog run docs/domains/*/features/
- scripts/generate-bdd-docs.py: features_dir → docs/domains

**Avantages:**
 Cohésion forte: toute la doc d'un domaine au même endroit
 Couplage faible: domaines indépendants, dépendances explicites
 Navigabilité améliorée: README par domaine = entrée claire
 Alignement code/docs: miroir de backend/internal/
 Onboarding facilité: exploration domaine par domaine
 Tests BDD intégrés: features au plus près des règles métier

Voir docs/REFACTOR-DDD.md pour le plan complet.
This commit is contained in:
jpgiannetti
2026-02-07 17:15:02 +01:00
parent 78422bb2c0
commit 5e5fcf4714
227 changed files with 1413 additions and 1967 deletions

View File

@@ -0,0 +1,200 @@
# language: fr
@api @authentication @2fa @security @mvp
Fonctionnalité: Appareils de confiance et authentification à deux facteurs
En tant qu'utilisateur soucieux de la sécurité
Je veux gérer mes appareils de confiance et activer l'authentification à deux facteurs
Afin de protéger mon compte contre les accès non autorisés
Contexte:
Étant donné que le système supporte les méthodes 2FA suivantes:
| Méthode | Disponibilité | Recommandée |
| Application TOTP | Oui | Oui |
| SMS | Oui | Non |
| Email | Oui | Non |
| Clés de sécurité USB | Phase 2 | Oui |
Scénario: Activation de l'authentification à deux facteurs par TOTP
Étant donné un utilisateur "alice@roadwave.fr" sans 2FA activé
Quand l'utilisateur accède à "Mon compte > Sécurité > Authentification à deux facteurs"
Et clique sur "Activer l'authentification à deux facteurs"
Alors le système génère un QR code avec secret TOTP
Et affiche le secret en texte clair pour saisie manuelle
Et affiche les instructions: "Scannez ce QR code avec Google Authenticator, Authy ou Microsoft Authenticator"
Et l'utilisateur scanne le QR code avec son application TOTP
Et saisit le code à 6 chiffres généré par l'application
Alors le 2FA est activé
Et 10 codes de récupération à usage unique sont générés
Et les codes de récupération sont affichés avec avertissement: "Conservez ces codes en lieu sûr"
Et un événement "2FA_ENABLED" est enregistré
Et un email de confirmation est envoyé
Et la métrique "auth.2fa.enabled" est incrémentée
Scénario: Connexion avec 2FA depuis un nouvel appareil
Étant donné un utilisateur "bob@roadwave.fr" avec 2FA activé
Et aucun appareil de confiance enregistré
Quand l'utilisateur se connecte depuis un iPhone avec email/mot de passe corrects
Alors une page de vérification 2FA s'affiche
Et l'utilisateur saisit le code à 6 chiffres de son application TOTP
Et coche l'option "Faire confiance à cet appareil pour 30 jours"
Alors la connexion est réussie
Et l'iPhone est enregistré comme appareil de confiance
Et un token d'appareil de confiance est stocké localement (durée: 30 jours)
Et un événement "2FA_SUCCESS_NEW_TRUSTED_DEVICE" est enregistré
Et un email est envoyé: "Nouvel appareil de confiance ajouté: iPhone"
Et la métrique "auth.2fa.trusted_device.added" est incrémentée
Scénario: Connexion depuis un appareil de confiance existant
Étant donné un utilisateur "charlie@roadwave.fr" avec 2FA activé
Et un iPhone enregistré comme appareil de confiance il y a 10 jours
Quand l'utilisateur se connecte depuis cet iPhone avec email/mot de passe corrects
Alors la connexion est réussie immédiatement sans demander le code 2FA
Et un événement "LOGIN_TRUSTED_DEVICE" est enregistré
Et la date de dernière utilisation de l'appareil de confiance est mise à jour
Et la métrique "auth.2fa.trusted_device.used" est incrémentée
Scénario: Expiration automatique d'un appareil de confiance après 30 jours
Étant donné un utilisateur "david@roadwave.fr" avec 2FA activé
Et un iPad enregistré comme appareil de confiance il y a 31 jours
Quand l'utilisateur se connecte depuis cet iPad avec email/mot de passe corrects
Alors une page de vérification 2FA s'affiche
Et l'utilisateur doit saisir le code TOTP
Et un message s'affiche: "Votre appareil de confiance a expiré après 30 jours. Veuillez vous authentifier à nouveau."
Et l'ancien token d'appareil de confiance est révoqué
Et un événement "TRUSTED_DEVICE_EXPIRED" est enregistré
Et la métrique "auth.2fa.trusted_device.expired" est incrémentée
Scénario: Gestion de la liste des appareils de confiance
Étant donné un utilisateur "eve@roadwave.fr" avec 2FA activé
Et 3 appareils de confiance enregistrés
Quand l'utilisateur accède à "Mon compte > Sécurité > Appareils de confiance"
Alors l'utilisateur voit la liste suivante:
| Appareil | Ajouté le | Dernière utilisation | Expire le | Actions |
| iPhone 14 Pro | 2026-01-15 | Il y a 2 heures | 2026-02-14 | [Révoquer] |
| iPad Air | 2026-01-10 | Il y a 5 jours | 2026-02-09 | [Révoquer] |
| MacBook Pro | 2026-01-05 | Il y a 10 jours | 2026-02-04 | [Révoquer] |
Et un bouton "Révoquer tous les appareils de confiance" est disponible
Et un compteur affiche "3 appareils de confiance actifs"
Scénario: Révocation manuelle d'un appareil de confiance
Étant donné un utilisateur "frank@roadwave.fr" avec 2FA activé
Et un MacBook Pro enregistré comme appareil de confiance
Quand l'utilisateur clique sur "Révoquer" pour le MacBook Pro
Alors l'appareil de confiance est immédiatement révoqué
Et le token d'appareil de confiance est invalidé
Et un événement "TRUSTED_DEVICE_REVOKED_MANUAL" est enregistré
Et un email est envoyé: "Vous avez révoqué l'appareil de confiance: MacBook Pro"
Et lors de la prochaine connexion, le code 2FA sera demandé
Et la métrique "auth.2fa.trusted_device.revoked" est incrémentée
Scénario: Utilisation d'un code de récupération en cas de perte de l'application TOTP
Étant donné un utilisateur "grace@roadwave.fr" avec 2FA activé
Et l'utilisateur a perdu l'accès à son application TOTP
Et il possède ses codes de récupération
Quand l'utilisateur se connecte avec email/mot de passe corrects
Et clique sur "Utiliser un code de récupération"
Et saisit l'un des 10 codes de récupération
Alors la connexion est réussie
Et le code de récupération utilisé est marqué comme consommé
Et il reste 9 codes de récupération disponibles
Et un événement "2FA_RECOVERY_CODE_USED" est enregistré
Et un email d'alerte est envoyé: "Un code de récupération a été utilisé. Il vous reste 9 codes."
Et l'utilisateur est invité à reconfigurer son 2FA
Et la métrique "auth.2fa.recovery_code.used" est incrémentée
Scénario: Régénération des codes de récupération
Étant donné un utilisateur "henry@roadwave.fr" avec 2FA activé
Et 3 codes de récupération ont été utilisés
Quand l'utilisateur accède à "Mon compte > Sécurité > Codes de récupération"
Et clique sur "Régénérer les codes de récupération"
Alors un message d'avertissement s'affiche: "Les anciens codes seront invalidés. Êtes-vous sûr ?"
Et après confirmation, 10 nouveaux codes de récupération sont générés
Et les anciens codes sont invalidés immédiatement
Et les nouveaux codes sont affichés une seule fois
Et un événement "2FA_RECOVERY_CODES_REGENERATED" est enregistré
Et un email est envoyé avec les nouveaux codes (chiffrés)
Et la métrique "auth.2fa.recovery_codes.regenerated" est incrémentée
Scénario: Désactivation du 2FA avec vérification renforcée
Étant donné un utilisateur "iris@roadwave.fr" avec 2FA activé
Quand l'utilisateur accède à "Mon compte > Sécurité > Authentification à deux facteurs"
Et clique sur "Désactiver l'authentification à deux facteurs"
Alors un message d'avertissement s'affiche: "Cela réduira la sécurité de votre compte"
Et l'utilisateur doit saisir son mot de passe actuel
Et l'utilisateur doit saisir un code 2FA valide
Et l'utilisateur doit confirmer par email via un lien sécurisé
Alors le 2FA est désactivé
Et tous les appareils de confiance sont révoqués
Et tous les codes de récupération sont invalidés
Et un événement "2FA_DISABLED" est enregistré
Et un email de confirmation est envoyé
Et la métrique "auth.2fa.disabled" est incrémentée
Scénario: Authentification 2FA par SMS en méthode de secours
Étant donné un utilisateur "jack@roadwave.fr" avec 2FA par TOTP activé
Et l'utilisateur a également configuré un numéro de téléphone de secours
Quand l'utilisateur se connecte et clique sur "Recevoir un code par SMS"
Alors un code à 6 chiffres est envoyé au numéro +33612345678
Et l'utilisateur saisit le code reçu par SMS
Alors la connexion est réussie
Et un événement "2FA_SMS_FALLBACK_USED" est enregistré
Et un email d'alerte est envoyé: "Vous avez utilisé la méthode SMS de secours"
Et la métrique "auth.2fa.sms.used" est incrémentée
Scénario: Limitation des tentatives de codes 2FA
Étant donné un utilisateur "kate@roadwave.fr" avec 2FA activé
Quand l'utilisateur se connecte avec email/mot de passe corrects
Et saisit 5 codes 2FA incorrects consécutivement
Alors le compte est temporairement bloqué pour 15 minutes
Et un message s'affiche: "Trop de tentatives échouées. Veuillez réessayer dans 15 minutes."
Et un email d'alerte est envoyé: "Multiples tentatives échouées de codes 2FA détectées"
Et un événement "2FA_TOO_MANY_ATTEMPTS" est enregistré avec niveau "HIGH"
Et la métrique "auth.2fa.blocked.too_many_attempts" est incrémentée
Scénario: Détection de connexion suspecte malgré 2FA valide
Étant donné un utilisateur "luke@roadwave.fr" avec 2FA activé
Et toutes ses connexions habituelles sont depuis la France
Quand l'utilisateur se connecte avec email/mot de passe corrects depuis la Russie
Et saisit un code 2FA valide
Alors la connexion est réussie mais marquée comme suspecte
Et l'utilisateur reçoit immédiatement un email: "Connexion inhabituelle depuis Russie"
Et une notification push est envoyée sur tous les appareils de confiance
Et l'accès aux fonctionnalités sensibles (paiement, changement de mot de passe) est temporairement bloqué
Et l'utilisateur doit confirmer son identité par email avant accès complet
Et un événement "2FA_SUSPICIOUS_LOCATION" est enregistré avec niveau "HIGH"
Et la métrique "auth.2fa.suspicious_login" est incrémentée
Scénario: Révocation de tous les appareils de confiance en cas de compromission
Étant donné un utilisateur "mary@roadwave.fr" avec 2FA activé
Et 5 appareils de confiance enregistrés
Et l'utilisateur suspecte une compromission de son compte
Quand l'utilisateur clique sur "Révoquer tous les appareils de confiance"
Alors tous les appareils de confiance sont immédiatement révoqués
Et tous les tokens d'appareils de confiance sont invalidés
Et toutes les sessions actives sont fermées (sauf la session actuelle)
Et un événement "ALL_TRUSTED_DEVICES_REVOKED" est enregistré avec niveau "HIGH"
Et un email de confirmation est envoyé
Et l'utilisateur devra saisir un code 2FA à chaque nouvelle connexion
Et la métrique "auth.2fa.trusted_device.bulk_revoked" est incrémentée
Scénario: Métriques de sécurité pour le 2FA
Étant donné que le système gère 50 000 utilisateurs avec 2FA activé
Quand les métriques de sécurité sont collectées
Alors les indicateurs suivants sont disponibles:
| Métrique | Valeur cible |
| Pourcentage d'utilisateurs avec 2FA | > 60% |
| Taux de succès de validation 2FA | > 98% |
| Temps moyen de saisie du code 2FA | < 15s |
| Nombre d'appareils de confiance par user | Moyenne: 2.5 |
| Taux d'utilisation des codes de récup. | < 0.5% |
Et les métriques sont exportées vers le système de monitoring
Et des alertes sont déclenchées si le taux de succès < 95%
Scénario: Badge de sécurité pour utilisateurs avec 2FA activé
Étant donné un utilisateur "nathan@roadwave.fr" avec 2FA activé depuis 30 jours
Quand l'utilisateur consulte son profil public
Alors un badge "Compte sécurisé" s'affiche sur son profil
Et le badge indique: "Cet utilisateur a activé l'authentification à deux facteurs"
Et le badge améliore la visibilité et la crédibilité du créateur de contenu
Et la métrique "profile.badge.2fa_secured" est visible

View File

@@ -0,0 +1,120 @@
# language: fr
Fonctionnalité: Classification des contenus par âge
En tant que plateforme responsable
Je veux classifier les contenus par tranche d'âge
Afin de protéger les mineurs et respecter les obligations légales
Contexte:
Étant donné que l'API RoadWave est disponible
Scénario: Créateur doit classifier son contenu à la publication
Étant donné que je suis un créateur connecté
Quand je crée un nouveau contenu audio
Alors je dois obligatoirement choisir une classification d'âge parmi:
| classification | description |
| Tout public | Contenu adapté à tous les âges |
| 13+ | Contenu mature léger |
| 16+ | Contenu mature |
| 18+ | Contenu adulte |
Scénario: Publication impossible sans classification
Étant donné que je crée un contenu audio
Quand j'essaie de publier sans sélectionner de classification
Alors la publication échoue
Et je vois le message "Vous devez sélectionner une classification d'âge"
Scénario: Utilisateur 13-15 ans voit "Tout public" et "13+"
Étant donné que je suis un utilisateur de 14 ans
Et qu'il existe des contenus avec les classifications suivantes:
| classification | nombre |
| Tout public | 20 |
| 13+ | 15 |
| 16+ | 10 |
| 18+ | 5 |
Quand je demande des recommandations
Alors je vois 35 contenus (Tout public + 13+)
Et les contenus 16+ et 18+ ne sont jamais proposés
Scénario: Utilisateur 16-17 ans voit "Tout public", "13+" et "16+"
Étant donné que je suis un utilisateur de 17 ans
Et qu'il existe des contenus avec les classifications suivantes:
| classification | nombre |
| Tout public | 20 |
| 13+ | 15 |
| 16+ | 10 |
| 18+ | 5 |
Quand je demande des recommandations
Alors je vois 45 contenus (Tout public + 13+ + 16+)
Et les contenus 18+ ne sont pas proposés
Scénario: Utilisateur 18+ voit tous les contenus
Étant donné que je suis un utilisateur de 25 ans
Et qu'il existe des contenus avec toutes les classifications
Quand je demande des recommandations
Alors je vois tous les contenus sans restriction
Et aucun filtre d'âge n'est appliqué
Scénario: Inscription réussie à 13 ans pile - accès limité à "Tout public" et "13+"
Étant donné que je m'inscris avec une date de naissance "2013-01-21"
Alors mon compte est créé avec succès
Et je peux voir les contenus "Tout public" et "13+"
Et les contenus 16+ et 18+ ne sont pas accessibles
Scénario: Modérateur reclassifie un contenu mal catégorisé
Étant donné qu'un contenu est publié avec la classification "Tout public"
Et que ce contenu contient du langage inapproprié détecté en modération
Quand le modérateur reclassifie ce contenu en "16+"
Alors la nouvelle classification est appliquée immédiatement
Et le contenu n'est plus visible pour les utilisateurs de moins de 16 ans
Et le créateur reçoit une notification de reclassification
Scénario: Strike si classification volontairement incorrecte
Étant donné qu'un créateur a publié un contenu "18+" classifié comme "Tout public"
Et que ce contenu a été signalé
Quand le modérateur confirme la mauvaise classification volontaire
Alors le créateur reçoit 1 strike
Et le contenu est reclassifié en "18+"
Et le créateur reçoit une notification explicative
Scénario: Créateur peut voir la distribution d'âge de son audience
Étant donné que je suis un créateur
Et que j'ai publié des contenus avec différentes classifications
Quand je consulte mes statistiques
Alors je vois la répartition des âges de mes auditeurs:
| tranche_age | pourcentage |
| 13-15 ans | 15% |
| 16-17 ans | 20% |
| 18+ ans | 65% |
Scénario: Recherche filtrée par classification d'âge
Étant donné que je suis un utilisateur de 16 ans
Quand je recherche des contenus
Alors les résultats incluent uniquement:
| classification |
| Tout public |
| 13+ |
| 16+ |
Et je ne vois pas les contenus 18+ dans les résultats
Scénario: Notification si tentative d'accès à contenu non autorisé
Étant donné que je suis un utilisateur de 15 ans
Et qu'un contenu "16+" est partagé avec moi via un lien direct
Quand j'essaie d'accéder au contenu
Alors l'accès est refusé
Et je vois le message "Ce contenu est réservé aux utilisateurs de 16 ans et plus"
Scénario: Validation obligatoire des 3 premiers contenus inclut la classification
Étant donné que je suis un nouveau créateur
Et que je publie mon premier contenu classifié "18+"
Quand le modérateur valide mon contenu
Alors il vérifie que la classification "18+" est appropriée
Et peut la modifier si nécessaire avant validation
Scénario: Statistiques de classification dans l'interface créateur
Étant donné que je suis un créateur
Quand je consulte mes contenus publiés
Alors je vois pour chaque contenu:
| information | exemple |
| Classification actuelle | 13+ |
| Nombre de signalements | 2 |
| Reclassifications | Aucune / 1× par modérateur |

View File

@@ -0,0 +1,84 @@
# language: fr
Fonctionnalité: Connexion utilisateur
En tant qu'utilisateur existant
Je veux me connecter à mon compte
Afin d'accéder à mes contenus et paramètres
Contexte:
Étant donné que l'API RoadWave est disponible
Et qu'un utilisateur existe avec:
| email | mot_de_passe |
| user@test.fr | Password123 |
Scénario: Connexion réussie avec identifiants valides
Quand je me connecte avec:
| email | mot_de_passe |
| user@test.fr | Password123 |
Alors je suis connecté avec succès
Et je reçois un access token valide pour 15 minutes
Et je reçois un refresh token valide pour 30 jours
Scénario: Connexion échouée avec email inexistant
Quand je me connecte avec l'email "inexistant@test.fr"
Alors la connexion échoue
Et je vois le message "Email ou mot de passe incorrect"
Scénario: Connexion échouée avec mot de passe incorrect
Quand je me connecte avec:
| email | mot_de_passe |
| user@test.fr | MauvaisPass1 |
Alors la connexion échoue
Et je vois le message "Email ou mot de passe incorrect"
Scénario: Blocage après 5 tentatives échouées
Étant donné que j'ai échoué 4 tentatives de connexion
Quand j'échoue une 5ème tentative de connexion
Alors mon compte est temporairement bloqué
Et je vois le message "Compte bloqué pour 15 minutes après 5 tentatives échouées"
Et je reçois un email de notification de blocage
Scénario: Tentative de connexion pendant le blocage
Étant donné que mon compte est bloqué suite à 5 tentatives échouées
Et que seulement 5 minutes se sont écoulées
Quand j'essaie de me connecter avec les bons identifiants
Alors la connexion échoue
Et je vois le message "Compte bloqué. Réessayez dans 10 minutes"
Scénario: Déblocage automatique après 15 minutes
Étant donné que mon compte est bloqué suite à 5 tentatives échouées
Et que 15 minutes se sont écoulées
Quand je me connecte avec les bons identifiants
Alors je suis connecté avec succès
Et le compteur de tentatives est réinitialisé
Scénario: Reset du compteur après connexion réussie
Étant donné que j'ai échoué 3 tentatives de connexion
Quand je me connecte avec les bons identifiants
Alors je suis connecté avec succès
Et le compteur de tentatives est remis à 0
Scénario: Reset automatique du compteur après 15 minutes sans blocage
Étant donné que j'ai échoué 3 tentatives de connexion
Et que 15 minutes se sont écoulées sans nouvelle tentative
Quand je consulte mon compteur de tentatives
Alors le compteur est réinitialisé à 0
Scénario: Déblocage via lien "Mot de passe oublié"
Étant donné que mon compte est bloqué suite à 5 tentatives échouées
Quand j'utilise la fonction "Mot de passe oublié"
Et que je réinitialise mon mot de passe
Alors le blocage est levé immédiatement
Et je peux me connecter avec le nouveau mot de passe
Scénario: Email de notification lors d'un blocage
Étant donné que j'ai échoué 5 tentatives de connexion
Alors je reçois un email avec:
| sujet | Tentatives de connexion suspectes détectées |
| contenu_contient | Votre compte a été temporairement bloqué |
| lien_mot_de_passe | présent |
Scénario: Connexion multi-device simultanée autorisée
Étant donné que je suis connecté sur un appareil iOS
Quand je me connecte également sur un appareil Android
Alors les deux sessions sont actives simultanément
Et je peux utiliser l'application sur les deux appareils

View File

@@ -0,0 +1,199 @@
# language: fr
Fonctionnalité: Gestion de compte utilisateur
En tant qu'utilisateur connecté
Je veux gérer les paramètres de mon compte
Afin de maintenir la sécurité et l'exactitude de mes informations
Contexte:
Étant donné que l'API RoadWave est disponible
Et que je suis connecté avec:
| email | user@test.fr |
| mot_de_passe | Password123 |
# ==========================================
# Déconnexion
# ==========================================
Scénario: Déconnexion volontaire de l'appareil actuel
Quand je clique sur "Se déconnecter"
Alors ma session est invalidée immédiatement
Et mon refresh token est révoqué
Et je suis redirigé vers l'écran de connexion
Et je dois me reconnecter pour accéder à l'application
Scénario: Déconnexion ne révoque pas les autres appareils
Étant donné que je suis connecté sur mon iPhone et mon iPad
Quand je me déconnecte depuis mon iPhone
Alors la session iPhone est invalidée
Et ma session iPad reste active
Et je peux continuer à utiliser l'application sur iPad
# ==========================================
# Changement de mot de passe
# ==========================================
Scénario: Changement de mot de passe avec ancien mot de passe correct
Quand je change mon mot de passe depuis les paramètres avec:
| ancien_mot_de_passe | Password123 |
| nouveau_mot_de_passe | NewPass456 |
| confirmation | NewPass456 |
Alors mon mot de passe est modifié avec succès
Et je reste connecté sur cet appareil
Et tous les autres appareils sont déconnectés
Et je reçois un email de confirmation de changement
Et je vois le message "Mot de passe modifié avec succès"
Scénario: Changement de mot de passe avec ancien mot de passe incorrect
Quand je change mon mot de passe avec un ancien mot de passe incorrect "WrongPass123"
Alors le changement échoue
Et je vois le message "Ancien mot de passe incorrect"
Et mon mot de passe actuel reste inchangé
Scénario: Changement de mot de passe avec nouveau mot de passe invalide
Quand je change mon mot de passe avec un nouveau mot de passe "faible"
Alors le changement échoue
Et je vois le message "Le mot de passe doit contenir au moins 8 caractères, 1 majuscule et 1 chiffre"
Scénario: Changement de mot de passe avec confirmation non correspondante
Quand je change mon mot de passe avec:
| ancien_mot_de_passe | Password123 |
| nouveau_mot_de_passe | NewPass456 |
| confirmation | DiffPass789 |
Alors le changement échoue
Et je vois le message "Les mots de passe ne correspondent pas"
Scénario: Nouveau mot de passe identique à l'ancien
Quand je change mon mot de passe avec:
| ancien_mot_de_passe | Password123 |
| nouveau_mot_de_passe | Password123 |
| confirmation | Password123 |
Alors le changement échoue
Et je vois le message "Le nouveau mot de passe doit être différent de l'ancien"
Scénario: Notification sur tous les appareils après changement de mot de passe
Étant donné que je suis connecté sur 3 appareils différents
Quand je change mon mot de passe depuis mon iPhone
Alors je reçois une notification push sur mes 2 autres appareils
Et je reçois un email de confirmation avec:
| sujet | Votre mot de passe a été modifié |
| appareil | iPhone 13 - Safari |
| localisation | Paris, France |
| action_urgence | Lien pour sécuriser le compte |
# ==========================================
# Changement d'email
# ==========================================
Scénario: Changement d'email avec vérification
Quand je change mon email pour "nouveau@test.fr"
Alors un email de vérification est envoyé à "nouveau@test.fr"
Et mon ancien email "user@test.fr" reste actif pour la connexion
Et je vois le message "Email de vérification envoyé à nouveau@test.fr"
Et le lien de vérification expire dans 7 jours
Scénario: Validation du changement d'email
Étant donné que j'ai demandé un changement d'email pour "nouveau@test.fr"
Et que j'ai reçu le lien de vérification
Quand je clique sur le lien de vérification dans l'email
Alors mon email est changé pour "nouveau@test.fr"
Et je reçois une notification sur l'ancien email "user@test.fr"
Et je vois le message "Email modifié avec succès"
Et je dois utiliser "nouveau@test.fr" pour me connecter désormais
Scénario: Changement d'email vers un email déjà utilisé
Étant donné qu'un utilisateur existe avec l'email "existant@test.fr"
Quand j'essaie de changer mon email pour "existant@test.fr"
Alors le changement échoue
Et je vois le message "Cet email est déjà utilisé par un autre compte"
Scénario: Changement d'email avec format invalide
Quand j'essaie de changer mon email pour "email.invalide"
Alors le changement échoue
Et je vois le message "Format d'email invalide"
Scénario: Expiration du lien de vérification de changement d'email
Étant donné que j'ai demandé un changement d'email il y a 8 jours
Quand j'essaie d'utiliser le lien de vérification
Alors la vérification échoue
Et je vois le message "Ce lien a expiré"
Et mon email reste inchangé à "user@test.fr"
Et je peux demander un nouveau changement d'email
Scénario: Annulation du changement d'email avant vérification
Étant donné que j'ai demandé un changement d'email pour "nouveau@test.fr"
Et que je n'ai pas encore vérifié le nouveau email
Quand je demande à annuler le changement d'email
Alors la demande de changement est annulée
Et le lien de vérification est invalidé
Et mon email reste "user@test.fr"
Scénario: Limite de changements d'email
Étant donné que j'ai déjà changé mon email 2 fois dans les 30 derniers jours
Quand j'essaie de changer mon email une 3ème fois
Alors le changement échoue
Et je vois le message "Maximum 2 changements d'email par mois"
Scénario: Notification de sécurité sur l'ancien email
Étant donné que j'ai changé mon email de "ancien@test.fr" à "nouveau@test.fr"
Alors je reçois un email sur "ancien@test.fr" avec:
| sujet | Votre adresse email a été modifiée |
| contenu | Votre email de connexion est maintenant nouveau@test.fr |
| date_heure | présente |
| appareil | présent |
| action_urgence | Lien pour annuler si ce n'était pas vous |
# ==========================================
# Changement de pseudo
# ==========================================
Scénario: Changement de pseudo valide
Quand je change mon pseudo pour "nouveau_pseudo"
Alors mon pseudo est modifié avec succès
Et je vois le message "Pseudo modifié avec succès"
Et le nouveau pseudo apparaît sur mon profil
Scénario: Changement de pseudo invalide - trop court
Quand j'essaie de changer mon pseudo pour "ab"
Alors le changement échoue
Et je vois le message "Le pseudo doit contenir entre 3 et 30 caractères"
Scénario: Changement de pseudo invalide - caractères spéciaux
Quand j'essaie de changer mon pseudo pour "user@123"
Alors le changement échoue
Et je vois le message "Le pseudo ne peut contenir que des lettres, chiffres et underscores"
Scénario: Changement de pseudo déjà utilisé
Étant donné qu'un utilisateur existe avec le pseudo "pseudo_existant"
Quand j'essaie de changer mon pseudo pour "pseudo_existant"
Alors le changement échoue
Et je vois le message "Ce pseudo est déjà utilisé"
Scénario: Limite de changements de pseudo
Étant donné que j'ai changé mon pseudo il y a 15 jours
Quand j'essaie de changer mon pseudo à nouveau
Alors le changement échoue
Et je vois le message "Vous ne pouvez changer votre pseudo qu'une fois par mois"
# ==========================================
# Consultation des informations de compte
# ==========================================
Scénario: Consulter les informations de mon compte
Quand je consulte les paramètres de mon compte
Alors je vois les informations suivantes:
| champ | valeur |
| Email | user@test.fr |
| Pseudo | user_test |
| Date création | 15/01/2026 |
| Email vérifié | Oui |
| 2FA activée | Non |
| Abonnement | Gratuit |
Scénario: Historique des changements de sécurité
Quand je consulte l'historique de sécurité de mon compte
Alors je vois la liste des événements suivants:
| événement | date | appareil |
| Changement mot de passe | 01/02/2026 | iPhone 13 |
| Activation 2FA | 25/01/2026 | iPad Pro |
| Changement email | 20/01/2026 | PC Windows |
| Création compte | 15/01/2026 | iPhone 13 |

View File

@@ -0,0 +1,112 @@
# language: fr
Fonctionnalité: Inscription utilisateur
En tant que nouvel utilisateur
Je veux créer un compte avec email et mot de passe
Afin d'accéder à l'application RoadWave
Contexte:
Étant donné que l'API RoadWave est disponible
Et que Zitadel est configuré
Scénario: Inscription réussie avec données valides
Étant donné que l'email "nouveau@example.com" n'existe pas
Quand je m'inscris avec les données suivantes:
| champ | valeur |
| email | nouveau@example.com |
| mot_de_passe | Password123 |
| pseudo | nouveau_user |
| date_naissance | 1995-06-15 |
Alors mon compte est créé avec succès
Et je reçois un email de vérification
Et le lien de vérification expire dans 7 jours
Et je suis redirigé vers l'application
Scénario: Inscription avec email déjà existant
Étant donné qu'un utilisateur existe avec l'email "existant@example.com"
Quand je m'inscris avec l'email "existant@example.com"
Alors l'inscription échoue
Et je vois le message "Cet email est déjà utilisé"
Scénario: Inscription avec mot de passe invalide - trop court
Quand je m'inscris avec un mot de passe de moins de 8 caractères "Pass1"
Alors l'inscription échoue
Et je vois le message "Le mot de passe doit contenir au moins 8 caractères"
Scénario: Inscription avec mot de passe invalide - sans majuscule
Quand je m'inscris avec un mot de passe sans majuscule "password123"
Alors l'inscription échoue
Et je vois le message "Le mot de passe doit contenir au moins une majuscule"
Scénario: Inscription avec mot de passe invalide - sans chiffre
Quand je m'inscris avec un mot de passe sans chiffre "Password"
Alors l'inscription échoue
Et je vois le message "Le mot de passe doit contenir au moins un chiffre"
Scénario: Inscription avec pseudo invalide - trop court
Quand je m'inscris avec un pseudo de 2 caractères "ab"
Alors l'inscription échoue
Et je vois le message "Le pseudo doit contenir entre 3 et 30 caractères"
Scénario: Inscription avec pseudo invalide - caractères spéciaux
Quand je m'inscris avec un pseudo contenant des caractères spéciaux "user@123"
Alors l'inscription échoue
Et je vois le message "Le pseudo ne peut contenir que des lettres, chiffres et underscores"
Scénario: Inscription avec email invalide
Quand je m'inscris avec un email invalide "email.invalide"
Alors l'inscription échoue
Et je vois le message "Format d'email invalide"
Plan du Scénario: Inscription avec âge minimum non respecté
Étant donné la date du jour est "2026-01-21"
Quand je m'inscris avec une date de naissance "<date_naissance>"
Alors l'inscription échoue
Et je vois le message "Vous devez avoir au moins 13 ans pour créer un compte"
Exemples:
| date_naissance | age |
| 2013-01-22 | 12 |
| 2015-06-15 | 10 |
| 2020-01-01 | 6 |
Scénario: Inscription avec âge limite acceptable (13 ans)
Étant donné la date du jour est "2026-01-21"
Quand je m'inscris avec une date de naissance "2013-01-21"
Alors mon compte est créé avec succès
Et je peux accéder aux contenus "Tout public" et "13+"
Scénario: Inscription avec âge supérieur à 18 ans
Étant donné la date du jour est "2026-01-21"
Quand je m'inscris avec une date de naissance "1990-06-15"
Alors mon compte est créé avec succès
Et j'ai accès à tous les contenus sans restriction d'âge
Scénario: Données minimales requises à l'inscription
Quand je m'inscris sans fournir de nom complet
Et sans fournir de photo de profil
Et sans fournir de bio
Alors mon compte est créé avec succès
Et un avatar par défaut est généré
Et les champs optionnels sont vides
Scénario: Renvoyer l'email de vérification
Étant donné que je me suis inscrit avec l'email "nouveau@example.com"
Et que je n'ai pas vérifié mon email
Quand je demande à renvoyer l'email de vérification
Alors un nouvel email de vérification est envoyé
Et le précédent lien est invalidé
Scénario: Limite de renvoi d'email de vérification
Étant donné que je me suis inscrit avec l'email "nouveau@example.com"
Et que j'ai déjà renvoyé l'email de vérification 3 fois aujourd'hui
Quand je demande à renvoyer l'email de vérification une 4ème fois
Alors la demande échoue
Et je vois le message "Vous avez atteint la limite de 3 renvois par jour"
Scénario: Expiration du lien de vérification
Étant donné que je me suis inscrit il y a 8 jours
Et que je n'ai pas vérifié mon email
Quand j'essaie d'utiliser le lien de vérification
Alors la vérification échoue
Et je vois le message "Ce lien a expiré"
Et je peux demander un nouveau lien

View File

@@ -0,0 +1,171 @@
# language: fr
@api @authentication @security @mvp
Fonctionnalité: Limitation des tentatives de connexion
En tant que système de sécurité
Je veux limiter les tentatives de connexion échouées
Afin de protéger les comptes utilisateurs contre les attaques par force brute
Contexte:
Étant donné que le système est configuré avec les limites suivantes:
| Paramètre | Valeur |
| Tentatives max avant blocage | 5 |
| Durée de blocage temporaire | 15 min |
| Tentatives max avant blocage 24h | 10 |
| Durée de blocage prolongé | 24h |
| Fenêtre de temps pour reset | 30 min |
Scénario: Connexion réussie réinitialise le compteur de tentatives
Étant donné un utilisateur "alice@roadwave.fr" avec 3 tentatives échouées
Quand l'utilisateur se connecte avec les bons identifiants
Alors la connexion est réussie
Et le compteur de tentatives échouées est réinitialisé à 0
Et un événement de sécurité "LOGIN_SUCCESS_AFTER_FAILURES" est enregistré
Scénario: Blocage temporaire après 5 tentatives échouées
Étant donné un utilisateur "bob@roadwave.fr" avec 4 tentatives échouées
Quand l'utilisateur tente de se connecter avec un mauvais mot de passe
Alors la connexion échoue avec le code d'erreur "ACCOUNT_TEMPORARILY_LOCKED"
Et le message est "Votre compte est temporairement verrouillé pour 15 minutes suite à de multiples tentatives échouées"
Et un email de notification de sécurité est envoyé à "bob@roadwave.fr"
Et un événement de sécurité "ACCOUNT_LOCKED_TEMP" est enregistré
Et la métrique "security.account_locks.temporary" est incrémentée
Scénario: Tentative de connexion pendant le blocage temporaire
Étant donné un utilisateur "charlie@roadwave.fr" bloqué temporairement
Et il reste 10 minutes avant la fin du blocage
Quand l'utilisateur tente de se connecter avec les bons identifiants
Alors la connexion échoue avec le code d'erreur "ACCOUNT_TEMPORARILY_LOCKED"
Et le message contient "Votre compte reste verrouillé pour 10 minutes"
Et le temps de blocage restant est indiqué en minutes
Et la tentative ne rallonge pas la durée du blocage
Scénario: Connexion autorisée après expiration du blocage temporaire
Étant donné un utilisateur "david@roadwave.fr" bloqué temporairement il y a 16 minutes
Quand l'utilisateur tente de se connecter avec les bons identifiants
Alors la connexion est réussie
Et le compteur de tentatives échouées est réinitialisé à 0
Et le statut de blocage est levé
Et un événement de sécurité "ACCOUNT_UNLOCKED_AUTO" est enregistré
Scénario: Blocage prolongé après 10 tentatives échouées sur 24h
Étant donné un utilisateur "eve@roadwave.fr" avec historique:
| Tentatives échouées | Quand |
| 5 | Il y a 2 heures |
| Blocage 15min levé | Il y a 1h30 |
| 4 | Il y a 30 minutes |
Quand l'utilisateur tente une nouvelle connexion échouée
Alors la connexion échoue avec le code d'erreur "ACCOUNT_LOCKED_24H"
Et le message est "Votre compte est verrouillé pour 24 heures suite à de multiples tentatives suspectes"
Et un email urgent de sécurité est envoyé avec un lien de déblocage sécurisé
Et une notification SMS est envoyée (si configuré)
Et un événement de sécurité "ACCOUNT_LOCKED_24H" est enregistré avec niveau "HIGH"
Et la métrique "security.account_locks.prolonged" est incrémentée
Scénario: Blocage différencié par adresse IP
Étant donné un utilisateur "frank@roadwave.fr" avec 3 tentatives échouées depuis IP "1.2.3.4"
Quand l'utilisateur se connecte avec succès depuis IP "5.6.7.8"
Alors la connexion est réussie
Et le compteur de tentatives échouées pour IP "1.2.3.4" reste à 3
Et le compteur de tentatives échouées pour IP "5.6.7.8" est à 0
Et un événement de sécurité "LOGIN_FROM_NEW_IP" est enregistré
Scénario: Alerte de sécurité sur pattern suspect multi-IP
Étant donné un utilisateur "grace@roadwave.fr"
Quand 5 tentatives échouées sont détectées depuis 5 IP différentes en 10 minutes:
| IP | Tentatives | Timestamp |
| 1.2.3.4 | 2 | Il y a 10 min |
| 5.6.7.8 | 1 | Il y a 8 min |
| 9.10.11.12 | 1 | Il y a 5 min |
| 13.14.15.16| 1 | Il y a 2 min |
Alors le compte est immédiatement bloqué pour 24h
Et un email d'alerte critique "POSSIBLE_CREDENTIAL_STUFFING_ATTACK" est envoyé
Et l'équipe de sécurité est notifiée via webhook
Et toutes les sessions actives sont révoquées
Et la métrique "security.attacks.credential_stuffing.detected" est incrémentée
Scénario: Déblocage manuel par l'utilisateur via email sécurisé
Étant donné un utilisateur "henry@roadwave.fr" bloqué pour 24h
Et il a reçu un email avec un lien de déblocage sécurisé à usage unique
Quand l'utilisateur clique sur le lien dans les 2 heures suivant l'email
Et confirme son identité via un code envoyé par SMS
Alors le compte est débloqué immédiatement
Et l'utilisateur est invité à changer son mot de passe
Et un événement de sécurité "ACCOUNT_UNLOCKED_MANUAL" est enregistré
Et la métrique "security.account_unlocks.user_initiated" est incrémentée
Scénario: Réinitialisation automatique du compteur après période d'inactivité
Étant donné un utilisateur "iris@roadwave.fr" avec 3 tentatives échouées
Et aucune nouvelle tentative depuis 35 minutes
Quand l'utilisateur tente de se connecter avec un mauvais mot de passe
Alors le compteur de tentatives est réinitialisé à 1
Et le message d'erreur est standard sans mention de blocage imminent
Et un événement de sécurité "ATTEMPT_COUNTER_RESET" est enregistré
Scénario: Protection contre les attaques par timing
Étant donné un utilisateur "jack@roadwave.fr"
Quand l'utilisateur effectue 10 tentatives de connexion échouées
Alors chaque réponse HTTP prend entre 800ms et 1200ms (temps constant)
Et les messages d'erreur ne révèlent pas si l'email existe
Et la métrique "security.timing_protection.applied" est incrémentée
Et les logs n'exposent pas de patterns de timing exploitables
Scénario: Escalade des notifications avec tentatives répétées
Étant donné un utilisateur "kate@roadwave.fr" Premium
Quand les événements suivants se produisent:
| Événement | Notification |
| 3 tentatives échouées | Aucune notification |
| 5 tentatives (blocage) | Email standard |
| 10 tentatives (24h) | Email + SMS + notification app|
| Tentative pendant 24h | Email urgent + alerte support |
Alors chaque niveau de notification est proportionnel à la gravité
Et l'utilisateur peut configurer ses préférences de notification
Et la métrique "security.notifications.escalated" est incrémentée
Scénario: Whitelist d'IP pour utilisateurs de confiance
Étant donné un utilisateur "luke@roadwave.fr" avec IP de confiance "1.2.3.4"
Et la whitelist est configurée pour autoriser 10 tentatives au lieu de 5
Quand l'utilisateur effectue 7 tentatives échouées depuis "1.2.3.4"
Alors le compte n'est pas bloqué
Et un avertissement est affiché "3 tentatives restantes avant blocage"
Et un événement de sécurité "TRUSTED_IP_EXTENDED_ATTEMPTS" est enregistré
Scénario: Logs de sécurité détaillés pour audit
Étant donné un utilisateur "mary@roadwave.fr" avec tentatives échouées
Quand un audit de sécurité est effectué
Alors les logs contiennent pour chaque tentative:
| Champ | Exemple |
| Timestamp | 2026-02-03T14:32:18.123Z |
| User ID | uuid-123-456 |
| Email | mary@roadwave.fr |
| IP Address | 1.2.3.4 |
| User Agent | Mozilla/5.0 (iPhone...) |
| Failure Reason | INVALID_PASSWORD |
| Attempts Count | 3 |
| Geolocation | Paris, France |
| Device Fingerprint| hash-abc-def |
Et les logs sont conservés pendant 90 jours minimum
Et les logs sont conformes RGPD (pas de mots de passe en clair)
Scénario: Métriques de performance du système de limitation
Étant donné que le système traite 1000 tentatives de connexion par minute
Quand les métriques de performance sont collectées
Alors les indicateurs suivants sont disponibles:
| Métrique | Valeur cible |
| Temps de vérification du compteur | < 50ms |
| Latence ajoutée par le rate limiting | < 100ms |
| Pourcentage de tentatives bloquées | < 2% |
| Faux positifs (utilisateurs légitimes) | < 0.1% |
| Temps de déblocage automatique | < 1s |
Et les métriques sont exportées vers le système de monitoring
Et des alertes sont déclenchées si les seuils sont dépassés
Scénario: Compatibilité avec authentification multi-facteurs
Étant donné un utilisateur "nathan@roadwave.fr" avec 2FA activé
Et il a 4 tentatives échouées (mot de passe correct mais code 2FA incorrect)
Quand l'utilisateur tente une 5ème connexion avec mot de passe correct et mauvais code 2FA
Alors le compte est bloqué temporairement
Et le message précise "Blocage suite à de multiples erreurs de code 2FA"
Et le compteur 2FA est distinct du compteur de mot de passe
Et un événement de sécurité "2FA_LOCK_TRIGGERED" est enregistré

View File

@@ -0,0 +1,191 @@
# language: fr
@api @authentication @sessions @mvp
Fonctionnalité: Gestion des sessions multi-appareils
En tant qu'utilisateur
Je veux gérer mes sessions actives sur plusieurs appareils
Afin de contrôler l'accès à mon compte et améliorer la sécurité
Contexte:
Étant donné que le système supporte les sessions suivantes:
| Paramètre | Valeur |
| Nombre max de sessions simultanées | 5 |
| Durée de vie d'une session | 30 jours |
| Durée d'inactivité avant expiration | 7 jours |
| Durée du token de refresh | 90 jours |
| Taille max du stockage de session | 10 KB |
Scénario: Création d'une nouvelle session avec empreinte d'appareil
Étant donné un utilisateur "alice@roadwave.fr" non connecté
Quand l'utilisateur se connecte depuis un iPhone 14 Pro avec iOS 17.2
Alors une nouvelle session est créée avec les métadonnées:
| Champ | Valeur |
| Device Type | mobile |
| OS | iOS 17.2 |
| App Version | 1.2.3 |
| Device Model | iPhone 14 Pro |
| Browser | N/A |
| IP Address | 1.2.3.4 |
| Geolocation | Paris, France |
| Created At | 2026-02-03T14:32:18Z |
| Last Activity | 2026-02-03T14:32:18Z |
Et un token JWT avec durée de vie de 30 jours est généré
Et un refresh token avec durée de vie de 90 jours est généré
Et un événement "SESSION_CREATED" est enregistré
Et la métrique "sessions.created" est incrémentée
Scénario: Connexion simultanée sur plusieurs appareils
Étant donné un utilisateur "bob@roadwave.fr" connecté sur:
| Appareil | OS | Dernière activité |
| iPhone 13 | iOS 16.5 | Il y a 5 min |
| iPad Pro | iPadOS 17.1 | Il y a 2 heures |
| MacBook Pro | macOS 14.2 | Il y a 1 jour |
Quand l'utilisateur se connecte depuis un Samsung Galaxy S23
Alors une nouvelle session est créée
Et l'utilisateur a maintenant 4 sessions actives
Et toutes les sessions précédentes restent valides
Et un événement "NEW_DEVICE_LOGIN" est enregistré
Et une notification push est envoyée sur tous les appareils: "Nouvelle connexion depuis Samsung Galaxy S23"
Scénario: Limitation du nombre de sessions simultanées
Étant donné un utilisateur "charlie@roadwave.fr" avec 5 sessions actives
Quand l'utilisateur se connecte depuis un 6ème appareil
Alors la session la plus ancienne est automatiquement révoquée
Et une nouvelle session est créée pour le nouvel appareil
Et l'utilisateur reçoit une notification: "Votre session sur [Ancien Appareil] a été fermée automatiquement"
Et un événement "SESSION_EVICTED_MAX_LIMIT" est enregistré
Et la métrique "sessions.evicted.max_limit" est incrémentée
Scénario: Liste des sessions actives dans les paramètres du compte
Étant donné un utilisateur "david@roadwave.fr" avec 3 sessions actives
Quand l'utilisateur accède à "Mon compte > Sécurité > Appareils connectés"
Alors l'utilisateur voit la liste suivante:
| Appareil | Localisation | Dernière activité | IP | Actions |
| iPhone 14 Pro | Paris, France | Actif maintenant | 1.2.3.4 | [Cet appareil]|
| iPad Air | Lyon, France | Il y a 2 heures | 5.6.7.8 | [Déconnecter] |
| MacBook Pro | Marseille, FR | Il y a 3 jours | 9.10.11.12| [Déconnecter] |
Et la session actuelle est clairement identifiée
Et un bouton "Déconnecter tous les autres appareils" est disponible
Scénario: Révocation manuelle d'une session spécifique
Étant donné un utilisateur "eve@roadwave.fr" avec 4 sessions actives
Et il consulte la liste de ses appareils depuis son iPhone
Quand l'utilisateur clique sur "Déconnecter" pour la session "MacBook Pro"
Alors la session "MacBook Pro" est immédiatement révoquée
Et le token JWT associé est invalidé dans Redis
Et le refresh token est révoqué
Et l'utilisateur sur le MacBook Pro est déconnecté lors de sa prochaine requête
Et un événement "SESSION_REVOKED_MANUAL" est enregistré
Et une notification est envoyée: "Vous avez été déconnecté de votre MacBook Pro"
Scénario: Déconnexion de tous les autres appareils
Étant donné un utilisateur "frank@roadwave.fr" avec 5 sessions actives
Et il suspecte un accès non autorisé
Quand l'utilisateur clique sur "Déconnecter tous les autres appareils" depuis son iPhone
Alors toutes les sessions sauf la session actuelle (iPhone) sont révoquées
Et 4 tokens JWT sont invalidés
Et 4 refresh tokens sont révoqués
Et un événement "SESSIONS_REVOKED_ALL_OTHER" est enregistré
Et une notification est envoyée sur tous les appareils déconnectés
Et un email de confirmation est envoyé: "Vous avez déconnecté tous vos autres appareils"
Et la métrique "sessions.revoked.bulk" est incrémentée
Scénario: Détection de connexion suspecte depuis un nouveau pays
Étant donné un utilisateur "grace@roadwave.fr" avec sessions habituelles en France
Quand l'utilisateur se connecte depuis une IP en Russie
Alors une alerte de sécurité est déclenchée
Et un email est envoyé: "Connexion détectée depuis Russie - Est-ce bien vous ?"
Et une notification push est envoyée sur tous les appareils de confiance
Et la session est créée mais marquée comme "suspecte"
Et un événement "SUSPICIOUS_LOCATION_LOGIN" est enregistré avec niveau "HIGH"
Et l'utilisateur doit confirmer son identité par code SMS avant d'accéder aux fonctionnalités sensibles
Scénario: Expiration automatique d'une session inactive
Étant donné un utilisateur "henry@roadwave.fr" avec une session sur iPad
Et la session n'a pas été utilisée depuis 8 jours
Quand le job de nettoyage des sessions s'exécute
Alors la session iPad est automatiquement révoquée
Et le token JWT est invalidé
Et le refresh token est révoqué
Et un événement "SESSION_EXPIRED_INACTIVITY" est enregistré
Et un email est envoyé: "Votre session sur iPad a expiré suite à 8 jours d'inactivité"
Et la métrique "sessions.expired.inactivity" est incrémentée
Scénario: Rafraîchissement automatique du token avant expiration
Étant donné un utilisateur "iris@roadwave.fr" avec une session active
Et le token JWT expire dans 2 minutes
Quand l'application mobile effectue une requête API
Alors l'API détecte que le token expire bientôt
Et un nouveau token JWT est généré automatiquement
Et le nouveau token est retourné dans le header "X-Refreshed-Token"
Et l'application mobile stocke le nouveau token
Et un événement "TOKEN_REFRESHED" est enregistré
Et la métrique "tokens.refreshed" est incrémentée
Scénario: Révocation de toutes les sessions lors d'un changement de mot de passe
Étant donné un utilisateur "jack@roadwave.fr" avec 4 sessions actives
Quand l'utilisateur change son mot de passe depuis son iPhone
Alors toutes les sessions sauf la session actuelle (iPhone) sont révoquées
Et tous les tokens JWT sont invalidés
Et tous les refresh tokens sont révoqués
Et un événement "SESSIONS_REVOKED_PASSWORD_CHANGE" est enregistré
Et un email est envoyé: "Votre mot de passe a été modifié. Toutes vos autres sessions ont été déconnectées."
Et des notifications push sont envoyées sur tous les appareils déconnectés
Scénario: Persistance de la session avec "Se souvenir de moi"
Étant donné un utilisateur "kate@roadwave.fr" qui se connecte
Quand l'utilisateur coche l'option "Se souvenir de moi"
Alors la durée de vie du token JWT est étendue à 90 jours
Et la durée de vie du refresh token est étendue à 180 jours
Et la session persiste même après fermeture de l'application
Et un cookie sécurisé "remember_token" est stocké (pour web)
Et un événement "LONG_SESSION_CREATED" est enregistré
Et la métrique "sessions.remember_me.enabled" est incrémentée
Scénario: Détection de vol de token et révocation automatique
Étant donné un utilisateur "luke@roadwave.fr" avec une session active
Et le token JWT a été volé et utilisé depuis une IP différente
Quand le système détecte une utilisation simultanée du même token depuis 2 IP différentes
Alors toutes les sessions de l'utilisateur sont immédiatement révoquées
Et tous les tokens sont invalidés
Et un email d'alerte critique est envoyé: "Activité suspecte détectée - Toutes vos sessions ont été fermées"
Et une notification push urgente est envoyée sur tous les appareils
Et l'utilisateur doit réinitialiser son mot de passe avant de se reconnecter
Et un événement "TOKEN_THEFT_DETECTED" est enregistré avec niveau "CRITICAL"
Et l'équipe de sécurité est alertée via webhook
Scénario: Synchronisation des informations de session en temps réel
Étant donné un utilisateur "mary@roadwave.fr" connecté sur 3 appareils
Quand l'utilisateur révoque une session depuis son iPhone
Alors la liste des sessions est mise à jour en temps réel sur tous les appareils via WebSocket
Et l'appareil déconnecté reçoit immédiatement une notification de déconnexion
Et l'UI est rafraîchie automatiquement sur tous les appareils connectés
Et la métrique "sessions.realtime_sync" est incrémentée
Scénario: Métriques de performance de gestion des sessions
Étant donné que le système gère 100 000 sessions actives
Quand les métriques de performance sont collectées
Alors les indicateurs suivants sont respectés:
| Métrique | Valeur cible |
| Temps de création de session | < 50ms |
| Temps de validation de token | < 20ms |
| Temps de révocation de session | < 100ms |
| Latence de synchronisation temps réel | < 500ms |
| Taux de succès du refresh automatique | > 99.9% |
Et les métriques sont exportées vers le système de monitoring
Et des alertes sont déclenchées si les seuils sont dépassés
Scénario: Stockage sécurisé des sessions dans Redis
Étant donné un utilisateur "nathan@roadwave.fr" avec une session active
Quand la session est stockée dans Redis
Alors les données suivantes sont chiffrées:
| Champ | Chiffrement |
| User ID | Hash |
| Refresh Token | AES-256 |
| Device Info | Non |
| IP Address | Hash |
Et la clé Redis a un TTL correspondant à la durée de vie de la session
Et les données sensibles ne sont jamais loggées en clair
Et les accès à Redis sont audités
Et la métrique "sessions.storage.encrypted" est incrémentée

View File

@@ -0,0 +1,107 @@
# language: fr
Fonctionnalité: Récupération de compte
En tant qu'utilisateur ayant oublié son mot de passe
Je veux pouvoir réinitialiser mon mot de passe via email
Afin de récupérer l'accès à mon compte
Contexte:
Étant donné que l'API RoadWave est disponible
Et qu'un utilisateur existe avec l'email "user@test.fr"
Scénario: Demander la réinitialisation du mot de passe
Quand je clique sur "Mot de passe oublié"
Et que je saisis mon email "user@test.fr"
Alors je reçois un email avec un lien de réinitialisation
Et le lien expire dans 1 heure
Et je vois le message "Email de réinitialisation envoyé"
Scénario: Email inexistant lors de la demande de réinitialisation
Quand je demande une réinitialisation pour l'email "inexistant@test.fr"
Alors je vois le même message "Email de réinitialisation envoyé"
Mais aucun email n'est envoyé (sécurité - pas d'énumération d'emails)
Scénario: Réinitialiser le mot de passe avec un lien valide
Étant donné que j'ai demandé une réinitialisation de mot de passe
Et que j'ai reçu le lien de réinitialisation
Quand je clique sur le lien
Et que je saisis un nouveau mot de passe "NouveauPass123"
Et que je confirme le nouveau mot de passe "NouveauPass123"
Alors mon mot de passe est modifié avec succès
Et je suis déconnecté de tous mes appareils sauf celui en cours
Et je reçois un email de confirmation de changement
Scénario: Lien de réinitialisation expiré
Étant donné que j'ai demandé une réinitialisation il y a 2 heures
Quand j'essaie d'utiliser le lien
Alors je vois le message "Ce lien a expiré"
Et je peux demander un nouveau lien
Scénario: Nouveau mot de passe ne respecte pas les règles
Étant donné que j'ai un lien de réinitialisation valide
Quand je saisis un nouveau mot de passe "faible"
Alors la réinitialisation échoue
Et je vois le message "Le mot de passe doit contenir au moins 8 caractères, 1 majuscule et 1 chiffre"
Scénario: Confirmation du mot de passe ne correspond pas
Étant donné que j'ai un lien de réinitialisation valide
Quand je saisis un nouveau mot de passe "NouveauPass123"
Et que je confirme avec un mot de passe différent "AutrePass123"
Alors la réinitialisation échoue
Et je vois le message "Les mots de passe ne correspondent pas"
Scénario: Limite de demandes de réinitialisation
Étant donné que j'ai déjà demandé 3 réinitialisations dans la dernière heure
Quand je demande une 4ème réinitialisation
Alors la demande échoue
Et je vois le message "Maximum 3 demandes par heure. Réessayez plus tard."
Scénario: Compteur de demandes se réinitialise après 1 heure
Étant donné que j'ai demandé 3 réinitialisations
Et que 1 heure s'est écoulée
Quand je demande une nouvelle réinitialisation
Alors la demande réussit
Et je reçois un email avec un nouveau lien
Scénario: Email de notification de changement de mot de passe
Étant donné que je viens de réinitialiser mon mot de passe
Alors je reçois un email de confirmation avec:
| sujet | Votre mot de passe a été modifié |
| contenu_contient | Votre mot de passe a été modifié |
| date_heure | présente |
| appareil | présent |
| localisation | présente |
| action_urgence | Lien si ce n'était pas vous |
Scénario: Notification push si changement depuis appareil non reconnu
Étant donné que je me suis toujours connecté depuis mon iPhone
Et que je réinitialise mon mot de passe depuis un PC Windows
Alors je reçois une notification push sur mon iPhone avec:
| titre | Mot de passe modifié |
| message | Depuis Windows - Paris, France |
| action | Sécuriser le compte si ce n'est pas vous |
Scénario: Déconnexion de tous les appareils après réinitialisation
Étant donné que je suis connecté sur 4 appareils différents
Et que je réinitialise mon mot de passe depuis un navigateur web
Alors les 3 autres appareils sont déconnectés immédiatement
Et seule la session du navigateur web reste active
Et je vois le message "Vous avez été déconnecté des autres appareils par sécurité"
Scénario: Lien de réinitialisation invalide si déjà utilisé
Étant donné que j'ai réinitialisé mon mot de passe avec un lien
Quand j'essaie de réutiliser le même lien
Alors je vois le message "Ce lien a déjà été utilisé"
Et je peux demander un nouveau lien si nécessaire
Scénario: Nouveau lien invalide l'ancien
Étant donné que j'ai demandé une réinitialisation et reçu un lien
Quand je demande une nouvelle réinitialisation
Alors l'ancien lien est invalidé
Et seul le nouveau lien fonctionne
Scénario: Réinitialisation débloque un compte bloqué
Étant donné que mon compte est bloqué après 5 tentatives de connexion
Quand je réinitialise mon mot de passe via email
Alors le blocage est levé immédiatement
Et je peux me connecter avec le nouveau mot de passe
Et le compteur de tentatives est remis à 0

View File

@@ -0,0 +1,187 @@
# 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

View File

@@ -0,0 +1,114 @@
# language: fr
Fonctionnalité: Gestion des sessions et tokens
En tant qu'utilisateur connecté
Je veux que mes sessions soient sécurisées et gérées automatiquement
Afin de maintenir l'accès à l'application sans friction
Contexte:
Étant donné que l'API RoadWave est disponible
Et que je suis connecté avec succès
Scénario: Access token expire après 15 minutes
Étant donné que j'ai reçu un access token
Et que 15 minutes se sont écoulées
Quand je fais une requête API avec cet access token
Alors la requête échoue avec le code 401
Et je vois le message "Token expiré"
Scénario: Refresh automatique du token avec refresh token
Étant donné que mon access token a expiré
Et que mon refresh token est valide
Quand l'application demande un nouveau access token
Alors je reçois un nouvel access token valide pour 15 minutes
Et je reçois un nouveau refresh token (rotation)
Et l'ancien refresh token est invalidé
Scénario: Refresh token expire après 30 jours d'inactivité
Étant donné que je me suis connecté il y a 30 jours
Et que je n'ai pas utilisé l'application depuis
Quand j'essaie d'utiliser mon refresh token
Alors la requête échoue
Et je dois me reconnecter avec email/password
Scénario: Prolongation automatique de la session si l'app est utilisée
Étant donné que je me suis connecté il y a 25 jours
Et que j'utilise l'application régulièrement
Quand je fais une requête API
Alors ma session est automatiquement prolongée
Et mon refresh token reste valide
Scénario: Détection de token replay attack
Étant donné que j'ai rafraîchi mon token
Et que j'ai reçu un nouveau refresh token
Quand j'essaie de réutiliser l'ancien refresh token
Alors la requête échoue
Et je vois le message "Token invalide ou révoqué"
Et toutes mes sessions sont révoquées par sécurité
Scénario: Voir la liste des appareils connectés
Étant donné que je suis connecté sur 3 appareils différents
Quand je consulte la liste de mes appareils connectés
Alors je vois 3 appareils avec les informations suivantes:
| information | exemple |
| OS | iOS 17.1 |
| Navigateur | Safari |
| Dernière connexion | Il y a 2 heures |
| Localisation | Paris, France (IP visible) |
Scénario: Révoquer un appareil spécifique
Étant donné que je suis connecté sur mon iPhone et mon iPad
Quand je révoque la session de mon iPad depuis les paramètres
Alors la session iPad est immédiatement déconnectée
Et ma session iPhone reste active
Scénario: Déconnecter tous les appareils sauf celui en cours
Étant donné que je suis connecté sur 4 appareils
Quand je clique sur "Déconnecter tous les appareils"
Alors les 3 autres appareils sont déconnectés
Et seul l'appareil actuel reste connecté
Scénario: Alerte de connexion depuis nouveau device
Étant donné que je me suis toujours connecté depuis Paris
Quand je me connecte depuis un nouvel appareil à Lyon
Alors je reçois une notification push sur mes autres appareils
Et je reçois un email avec:
| sujet | Nouvelle connexion détectée |
| localisation | Lyon, France |
| appareil | Android 14 - Chrome |
| action | Lien pour révoquer la session |
Scénario: Alerte de connexion suspecte depuis pays différent
Étant donné que je me suis toujours connecté depuis la France
Quand je me connecte depuis un appareil aux États-Unis
Alors je reçois une notification push immédiate
Et je reçois un email d'alerte de sécurité
Et la nouvelle session nécessite une validation 2FA même si désactivée
Scénario: Déconnexion après 30 jours d'inactivité totale
Étant donné que je ne me suis pas connecté depuis 30 jours
Quand j'ouvre l'application
Alors je suis automatiquement déconnecté
Et je dois me reconnecter avec email/password
Et je vois le message "Session expirée après 30 jours d'inactivité"
Scénario: Sessions multiples simultanées autorisées
Étant donné que je suis connecté sur:
| appareil |
| iPhone |
| iPad |
| PC Windows (Web) |
Quand je fais des actions sur les 3 appareils simultanément
Alors toutes les sessions fonctionnent sans conflit
Et chaque appareil maintient sa propre session
Scénario: Validation de JWT via Zitadel
Étant donné que j'ai reçu un access token JWT
Quand l'API RoadWave valide le token
Alors la validation est faite localement avec la clé publique Zitadel
Et aucune requête externe n'est effectuée (performance)
Et le token contient les claims suivants:
| claim | valeur_exemple |
| sub | user-id-123 |
| email | user@test.fr |
| exp | timestamp + 15 minutes |
| iss | zitadel.roadwave.com |

View File

@@ -0,0 +1,132 @@
# language: fr
Fonctionnalité: Authentification à deux facteurs (2FA)
En tant qu'utilisateur soucieux de sécurité
Je veux activer la 2FA sur mon compte
Afin de protéger mon accès même si mon mot de passe est compromis
Contexte:
Étant donné que l'API RoadWave est disponible
Et que je suis connecté à mon compte
Scénario: Activer la 2FA TOTP (Time-based One-Time Password)
Étant donné que la 2FA n'est pas activée sur mon compte
Quand je choisis d'activer la 2FA TOTP
Alors je vois un QR code à scanner
Et je vois le secret partagé en texte clair (backup)
Et je dois entrer un code de vérification depuis mon app authenticator
Quand je saisis un code TOTP valide
Alors la 2FA TOTP est activée avec succès
Et je reçois des codes de backup (10 codes)
Scénario: Connexion avec 2FA TOTP activée
Étant donné que la 2FA TOTP est activée sur mon compte
Quand je me connecte avec email/password
Alors je suis redirigé vers la page de saisie du code 2FA
Quand je saisis un code TOTP valide de mon authenticator
Alors je suis connecté avec succès
Scénario: Connexion échouée avec code TOTP invalide
Étant donné que la 2FA TOTP est activée
Quand je me connecte avec email/password
Et que je saisis un code TOTP invalide "000000"
Alors la connexion échoue
Et je vois le message "Code d'authentification invalide"
Et je peux réessayer
Scénario: Utiliser un code de backup pour 2FA
Étant donné que la 2FA TOTP est activée
Et que j'ai perdu l'accès à mon authenticator
Quand je me connecte avec email/password
Et que je clique sur "Utiliser un code de backup"
Et que je saisis un code de backup valide
Alors je suis connecté avec succès
Et le code de backup utilisé est invalidé
Et il me reste 9 codes de backup
Scénario: Activer la 2FA par email
Étant donné que la 2FA n'est pas activée
Quand je choisis d'activer la 2FA par email
Alors la 2FA email est activée immédiatement
Et je vois le message "2FA email activée. Vous recevrez un code à chaque connexion"
Scénario: Connexion avec 2FA email
Étant donné que la 2FA email est activée
Quand je me connecte avec email/password
Alors je reçois un email avec un code à 6 chiffres
Et le code expire dans 10 minutes
Et je dois saisir ce code pour terminer la connexion
Scénario: Code 2FA email expiré
Étant donné que la 2FA email est activée
Et que je me suis connecté avec email/password
Et que j'ai reçu un code 2FA par email il y a 11 minutes
Quand je saisis ce code
Alors la connexion échoue
Et je vois le message "Code expiré. Demandez un nouveau code."
Scénario: Renvoyer le code 2FA email
Étant donné que la 2FA email est activée
Et que je suis sur la page de saisie du code 2FA
Quand je clique sur "Renvoyer le code"
Alors je reçois un nouveau code par email
Et l'ancien code est invalidé
Scénario: Ajouter un appareil de confiance (skip 2FA pendant 30 jours)
Étant donné que la 2FA TOTP est activée
Quand je me connecte avec email/password et code TOTP
Et que je coche "Ne plus demander sur cet appareil"
Alors je suis connecté avec succès
Et cet appareil est enregistré comme "appareil de confiance"
Quand je me reconnecte dans les 30 jours suivants sur ce même appareil
Alors je ne dois pas saisir de code 2FA
Scénario: Appareil de confiance expire après 30 jours
Étant donné que j'ai enregistré un appareil de confiance il y a 31 jours
Quand je me connecte depuis cet appareil
Alors je dois saisir un code 2FA
Et je vois le message "Appareil de confiance expiré. Veuillez vous authentifier"
Scénario: Voir la liste des appareils de confiance
Étant donné que j'ai enregistré 3 appareils de confiance
Quand je consulte mes paramètres de sécurité
Alors je vois la liste de mes 3 appareils de confiance avec:
| information | exemple |
| Nom | iPhone 13 - Safari |
| Date ajout | 15 janvier 2026 |
| Dernière vue | Il y a 2 heures |
| Expire le | 14 février 2026 |
Scénario: Révoquer un appareil de confiance
Étant donné que j'ai un iPhone enregistré comme appareil de confiance
Quand je révoque cet appareil depuis les paramètres
Alors l'appareil est supprimé de la liste
Quand je me reconnecte depuis cet iPhone
Alors je dois saisir un code 2FA
Scénario: Révoquer tous les appareils de confiance
Étant donné que j'ai 5 appareils de confiance enregistrés
Quand je clique sur "Révoquer tous les appareils de confiance"
Alors tous les appareils sont révoqués
Et je vois le message "Tous les appareils de confiance ont été révoqués"
Scénario: 2FA forcée pour connexion suspecte malgré appareil de confiance
Étant donné que j'ai un appareil de confiance enregistré en France
Et que je me connecte depuis ce même appareil mais avec une IP américaine
Quand je tente de me connecter
Alors la 2FA est requise malgré l'appareil de confiance
Et je vois le message "Connexion suspecte détectée. Authentification requise."
Scénario: Désactiver la 2FA
Étant donné que la 2FA TOTP est activée
Quand je désactive la 2FA depuis mes paramètres
Et que je confirme avec mon mot de passe
Alors la 2FA est désactivée
Et tous les codes de backup sont invalidés
Et tous les appareils de confiance sont révoqués
Scénario: Régénérer les codes de backup
Étant donné que la 2FA est activée
Et que j'ai utilisé 8 codes de backup sur 10
Quand je demande à régénérer les codes de backup
Alors je reçois 10 nouveaux codes
Et tous les anciens codes (utilisés ou non) sont invalidés

View File

@@ -0,0 +1,250 @@
# language: fr
@api @authentication @security @mvp
Fonctionnalité: Validation des règles de mot de passe
En tant que système d'authentification
Je veux valider la complexité des mots de passe
Afin de garantir la sécurité des comptes utilisateurs
Contexte:
Étant donné un utilisateur souhaite créer un compte ou modifier son mot de passe
# ============================================================================
# VALIDATION LONGUEUR MINIMALE (8 CARACTÈRES)
# ============================================================================
Scénario: Mot de passe valide avec 8 caractères minimum
Étant donné l'utilisateur saisit le mot de passe "Azerty123"
Quand le système valide le mot de passe
Alors la validation doit réussir
Et aucune erreur ne doit être affichée
Scénario: Mot de passe trop court (7 caractères)
Étant donné l'utilisateur saisit le mot de passe "Azert12"
Quand le système valide le mot de passe
Alors la validation doit échouer
Et le message d'erreur doit être "Le mot de passe doit contenir au moins 8 caractères"
Et le champ doit être marqué en rouge
Scénario: Mot de passe très court (3 caractères)
Étant donné l'utilisateur saisit le mot de passe "Ab1"
Quand le système valide le mot de passe
Alors la validation doit échouer
Et le message d'erreur doit être "Le mot de passe doit contenir au moins 8 caractères"
# ============================================================================
# VALIDATION MAJUSCULE REQUISE
# ============================================================================
Scénario: Mot de passe valide avec au moins 1 majuscule
Étant donné l'utilisateur saisit le mot de passe "Monpass123"
Quand le système valide le mot de passe
Alors la validation doit réussir
Et le critère "majuscule" doit être validé avec une coche verte
Scénario: Mot de passe sans majuscule
Étant donné l'utilisateur saisit le mot de passe "monpass123"
Quand le système valide le mot de passe
Alors la validation doit échouer
Et le message d'erreur doit être "Le mot de passe doit contenir au moins 1 majuscule"
Scénario: Mot de passe avec plusieurs majuscules
Étant donné l'utilisateur saisit le mot de passe "MonPASSword123"
Quand le système valide le mot de passe
Alors la validation doit réussir
Car au moins 1 majuscule est présente
# ============================================================================
# VALIDATION CHIFFRE REQUIS
# ============================================================================
Scénario: Mot de passe valide avec au moins 1 chiffre
Étant donné l'utilisateur saisit le mot de passe "Monpass1"
Quand le système valide le mot de passe
Alors la validation doit réussir
Et le critère "chiffre" doit être validé avec une coche verte
Scénario: Mot de passe sans chiffre
Étant donné l'utilisateur saisit le mot de passe "Monpassword"
Quand le système valide le mot de passe
Alors la validation doit échouer
Et le message d'erreur doit être "Le mot de passe doit contenir au moins 1 chiffre"
Scénario: Mot de passe avec plusieurs chiffres
Étant donné l'utilisateur saisit le mot de passe "Monpass123456"
Quand le système valide le mot de passe
Alors la validation doit réussir
Car au moins 1 chiffre est présent
# ============================================================================
# VALIDATION COMBINÉE DES 3 CRITÈRES
# ============================================================================
Scénario: Mot de passe valide respectant tous les critères
Étant donné l'utilisateur saisit le mot de passe "SecurePass2024!"
Quand le système valide le mot de passe
Alors la validation doit réussir
Et tous les critères doivent être validés :
| critère | statut |
| longueur | |
| majuscule | |
| chiffre | |
Scénario: Mot de passe échouant sur plusieurs critères
Étant donné l'utilisateur saisit le mot de passe "pass"
Quand le système valide le mot de passe
Alors la validation doit échouer
Et les messages d'erreur suivants doivent être affichés :
| Le mot de passe doit contenir au moins 8 caractères |
| Le mot de passe doit contenir au moins 1 majuscule |
| Le mot de passe doit contenir au moins 1 chiffre |
Scénario: Mot de passe long mais sans majuscule ni chiffre
Étant donné l'utilisateur saisit le mot de passe "monmotdepasse"
Quand le système valide le mot de passe
Alors la validation doit échouer
Et les messages d'erreur suivants doivent être affichés :
| Le mot de passe doit contenir au moins 1 majuscule |
| Le mot de passe doit contenir au moins 1 chiffre |
# ============================================================================
# VALIDATION TEMPS RÉEL (FRONTEND)
# ============================================================================
Scénario: Affichage progressif des critères pendant la saisie
Étant donné l'utilisateur commence à saisir son mot de passe
Quand l'utilisateur tape "m"
Alors les critères suivants doivent être affichés :
| critère | statut |
| longueur | |
| majuscule | |
| chiffre | |
Quand l'utilisateur tape "Mon"
Alors les critères doivent être mis à jour :
| critère | statut |
| longueur | |
| majuscule | |
| chiffre | |
Quand l'utilisateur tape "Monpass1"
Alors les critères doivent être mis à jour :
| critère | statut |
| longueur | |
| majuscule | |
| chiffre | |
Scénario: Feedback visuel temps réel
Étant donné l'utilisateur saisit progressivement son mot de passe
Quand un critère est validé
Alors une coche verte doit apparaître à côté du critère
Et le texte du critère doit passer en vert
Quand un critère n'est pas validé
Alors une croix rouge doit apparaître
Et le texte du critère doit rester en gris ou rouge
# ============================================================================
# VALIDATION BACKEND (SÉCURITÉ)
# ============================================================================
Scénario: Validation backend en plus du frontend
Étant donné l'utilisateur contourne la validation frontend
Et envoie directement le mot de passe "weak" via API
Quand le backend reçoit la requête
Alors la validation backend doit rejeter le mot de passe
Et retourner une erreur HTTP 400 Bad Request
Et le message doit être :
"""
{
"error": "invalid_password",
"details": [
"Le mot de passe doit contenir au moins 8 caractères",
"Le mot de passe doit contenir au moins 1 majuscule",
"Le mot de passe doit contenir au moins 1 chiffre"
]
}
"""
Scénario: Validation backend avec mot de passe valide
Étant donné l'utilisateur envoie le mot de passe "SecurePass123"
Quand le backend valide le mot de passe
Alors la validation backend doit réussir
Et le mot de passe doit être hashé avec bcrypt (coût 12)
Et le hash doit être stocké dans la base de données
# ============================================================================
# CAS LIMITES ET CARACTÈRES SPÉCIAUX
# ============================================================================
Scénario: Mot de passe avec caractères spéciaux (acceptés)
Étant donné l'utilisateur saisit le mot de passe "MonP@ss123!"
Quand le système valide le mot de passe
Alors la validation doit réussir
Car les caractères spéciaux sont autorisés (mais non obligatoires)
Scénario: Mot de passe avec espaces (acceptés)
Étant donné l'utilisateur saisit le mot de passe "Mon Pass 123"
Quand le système valide le mot de passe
Alors la validation doit réussir
Car les espaces sont autorisés
Scénario: Mot de passe avec accents (acceptés)
Étant donné l'utilisateur saisit le mot de passe "MônPàss123"
Quand le système valide le mot de passe
Alors la validation doit réussir
Car les caractères accentués comptent comme des lettres
Scénario: Mot de passe avec émojis (acceptés)
Étant donné l'utilisateur saisit le mot de passe "MonPass123🔒"
Quand le système valide le mot de passe
Alors la validation doit réussir
Car les émojis sont autorisés
Scénario: Mot de passe vide
Étant donné l'utilisateur laisse le champ mot de passe vide
Quand le système valide le mot de passe
Alors la validation doit échouer
Et le message d'erreur doit être "Le mot de passe est requis"
# ============================================================================
# MODIFICATION MOT DE PASSE
# ============================================================================
Scénario: Changement de mot de passe avec validation
Étant donné un utilisateur authentifié veut changer son mot de passe
Et l'utilisateur saisit son ancien mot de passe "OldPass123"
Et l'utilisateur saisit le nouveau mot de passe "NewSecure456"
Quand le système valide le nouveau mot de passe
Alors la validation doit réussir
Et le nouveau mot de passe doit respecter les mêmes règles
Et l'ancien mot de passe doit être vérifié avant le changement
Scénario: Nouveau mot de passe identique à l'ancien (autorisé)
Étant donné un utilisateur veut changer son mot de passe
Et l'utilisateur saisit le nouveau mot de passe identique à l'ancien
Quand le système valide le mot de passe
Alors la validation doit réussir
Car il n'y a pas de règle interdisant la réutilisation
# ============================================================================
# MESSAGES D'AIDE ET UX
# ============================================================================
Scénario: Affichage des règles avant saisie
Étant donné l'utilisateur accède au formulaire d'inscription
Quand le champ mot de passe reçoit le focus
Alors une info-bulle doit s'afficher avec les règles :
"""
Votre mot de passe doit contenir :
Au moins 8 caractères
Au moins 1 majuscule
Au moins 1 chiffre
"""
Scénario: Indicateur de force du mot de passe
Étant donné l'utilisateur saisit progressivement son mot de passe
Quand l'utilisateur tape "Weak1"
Alors l'indicateur de force doit afficher "Faible" en orange
Quand l'utilisateur tape "Medium12"
Alors l'indicateur de force doit afficher "Moyen" en jaune
Quand l'utilisateur tape "VeryStrong123!"
Alors l'indicateur de force doit afficher "Fort" en vert

View File

@@ -0,0 +1,79 @@
# language: fr
Fonctionnalité: Vérification d'email
En tant qu'utilisateur inscrit
Je veux vérifier mon adresse email
Afin d'accéder à toutes les fonctionnalités selon mon rôle
Contexte:
Étant donné que l'API RoadWave est disponible
Scénario: Auditeur avec email non vérifié - lecture illimitée
Étant donné que je suis un auditeur avec email non vérifié
Quand j'essaie d'écouter du contenu
Alors je peux écouter tous les contenus sans limite
Scénario: Auditeur avec email non vérifié - création limitée à 5 contenus
Étant donné que je suis un auditeur avec email non vérifié
Et que j'ai créé 4 contenus
Quand je crée un 5ème contenu
Alors le contenu est créé avec succès
Mais quand j'essaie de créer un 6ème contenu
Alors la création échoue
Et je vois le message "Vérifiez votre email pour créer plus de contenus"
Scénario: Rappel de vérification après le 3ème contenu créé
Étant donné que je suis un auditeur avec email non vérifié
Et que j'ai créé 2 contenus
Quand je crée mon 3ème contenu
Alors le contenu est créé avec succès
Et je vois une notification in-app "Vérifiez votre email pour débloquer la création illimitée"
Scénario: Auditeur vérifie son email
Étant donné que je suis un auditeur avec email non vérifié
Et que j'ai reçu un lien de vérification
Quand je clique sur le lien de vérification dans l'email
Alors mon email est marqué comme vérifié
Et je vois le message "Email vérifié avec succès"
Et toutes les fonctionnalités sont débloquées
Scénario: Créateur doit vérifier son email sous 7 jours pour monétisation
Étant donné que je suis inscrit comme créateur
Et que mon email n'est pas vérifié
Et que je remplis les conditions de monétisation
Quand j'essaie d'accéder au programme de monétisation
Alors l'accès est refusé
Et je vois le message "Vérifiez votre email pour accéder à la monétisation"
Scénario: Créateur ne peut pas publier de contenus illimités sans vérification
Étant donné que je suis un créateur avec email non vérifié
Et que j'ai créé 5 contenus
Quand j'essaie de créer un 6ème contenu
Alors la création échoue
Et je vois le message "Vérifiez votre email pour publier des contenus illimités"
Scénario: Créateur vérifie son email et déboque tout
Étant donné que je suis un créateur avec email non vérifié
Et que j'ai reçu un lien de vérification
Quand je clique sur le lien de vérification
Alors mon email est marqué comme vérifié
Et je peux publier des contenus illimités
Et je peux accéder au programme de monétisation si j'en remplis les conditions
Scénario: KYC impossible sans email vérifié
Étant donné que je suis un créateur avec email non vérifié
Quand j'essaie de compléter le KYC via Mangopay
Alors l'accès au KYC est refusé
Et je vois le message "Vérifiez votre email avant de procéder au KYC"
Scénario: Tentative de vérification avec un lien déjà utilisé
Étant donné que j'ai déjà vérifié mon email avec un lien
Quand j'essaie de réutiliser le même lien de vérification
Alors la vérification échoue
Et je vois le message "Ce lien a déjà été utilisé"
Scénario: Auditeur vérifié peut créer plus de 5 contenus
Étant donné que je suis un auditeur avec email vérifié
Et que j'ai créé 10 contenus
Quand je crée un 11ème contenu
Alors le contenu est créé avec succès
Et il n'y a pas de limite de création