Implémentation complète du flux de réinitialisation de mot de passe (Story 1.5): Backend: - Aggregate PasswordResetToken avec TTL 1h, UUID v7, usage unique - Endpoint POST /api/password/forgot avec rate limiting (3/h par email, 10/h par IP) - Endpoint POST /api/password/reset avec validation token - Templates email (demande + confirmation) - Repository Redis avec TTL 2h pour distinguer expiré/invalide Frontend: - Page /mot-de-passe-oublie avec message générique (anti-énumération) - Page /reset-password/[token] avec validation temps réel des critères - Gestion erreurs: token invalide, expiré, déjà utilisé Tests: - 14 tests unitaires PasswordResetToken - 7 tests unitaires RequestPasswordResetHandler - 7 tests unitaires ResetPasswordHandler - Tests E2E Playwright pour le flux complet
87 lines
3.4 KiB
YAML
87 lines
3.4 KiB
YAML
framework:
|
|
cache:
|
|
# Unique name of your app: used to compute stable namespaces for cache keys.
|
|
prefix_seed: classeo/backend
|
|
|
|
pools:
|
|
# Pool dédié aux tokens d'activation (7 jours TTL)
|
|
activation_tokens.cache:
|
|
adapter: cache.adapter.filesystem
|
|
default_lifetime: 604800 # 7 jours
|
|
|
|
# Pool dédié aux utilisateurs (pas de TTL - données persistantes)
|
|
users.cache:
|
|
adapter: cache.adapter.filesystem
|
|
default_lifetime: 0 # Pas d'expiration
|
|
|
|
# Pool dédié aux refresh tokens (7 jours TTL max)
|
|
refresh_tokens.cache:
|
|
adapter: cache.adapter.filesystem
|
|
default_lifetime: 604800 # 7 jours
|
|
|
|
# Pool dédié aux tokens de reset mot de passe (1 heure TTL)
|
|
password_reset_tokens.cache:
|
|
adapter: cache.adapter.filesystem
|
|
default_lifetime: 3600 # 1 heure
|
|
|
|
# Pool dédié au rate limiting (15 min TTL)
|
|
cache.rate_limiter:
|
|
adapter: cache.adapter.filesystem
|
|
default_lifetime: 900 # 15 minutes
|
|
|
|
# Test environment uses Redis to avoid filesystem cache timing issues in E2E tests
|
|
# (CLI creates tokens, FrankenPHP must see them immediately)
|
|
when@test:
|
|
framework:
|
|
cache:
|
|
pools:
|
|
activation_tokens.cache:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 604800
|
|
users.cache:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 0
|
|
refresh_tokens.cache:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 604800
|
|
password_reset_tokens.cache:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 3600
|
|
cache.rate_limiter:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 900
|
|
|
|
when@prod:
|
|
framework:
|
|
cache:
|
|
pools:
|
|
doctrine.system_cache_pool:
|
|
adapter: cache.adapter.system
|
|
doctrine.result_cache_pool:
|
|
adapter: cache.adapter.system
|
|
activation_tokens.cache:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 604800 # 7 jours
|
|
users.cache:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 0 # Pas d'expiration
|
|
refresh_tokens.cache:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 604800 # 7 jours
|
|
password_reset_tokens.cache:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 3600 # 1 heure
|
|
cache.rate_limiter:
|
|
adapter: cache.adapter.redis
|
|
provider: '%env(REDIS_URL)%'
|
|
default_lifetime: 900 # 15 minutes
|