Aller au contenu

Analyse de conformité — Module Auth

Date : 2026-06-16
Heure : 10:58
Références analysées : - flow_connexion.md — Flow de connexion Caritas - 3_REFERENCE_GESTION_SESSIONS.md — Référence gestion des sessions


Flow connexion (flow_connexion.md)

✅ Conforme — Connexion simple (sans 2FA)

Toutes les étapes clés sont implémentées : vérification utilisateur, bcrypt, verrouillage 5 tentatives/30 min, génération tokens JWT 24h/7j, session en BD, audit LOGIN, retour du profil + tokens.

⚠️ Écarts — Connexion simple

Étape spec Écart Fichier concerné
Vérification email confirmé TODO commenté (EC-3 ligne 208) — le champ emailVerifie n'existe pas encore dans le schéma Prisma ConnexionUseCase.ts L.207-211
Localisation stockée en session IP et UserAgent sont stockés, mais la localisation géographique est absente SessionAuthRepositoryPrisma.ts
Max 5 tentatives 2FA La spec dit 5, mais incrementerTentativesEchouees retourne 0 au 3ème essai échoué — à vérifier dans SessionAuthRepositoryPrisma Verifier2FAUseCase.ts L.259-288

✅ Conforme — 2FA Phase 1 (Connexion initiale)

  • Détection 2FA actif (utilisateur.deuxFacteursActive) ✅
  • Code EMAIL 6 chiffres, stocké en BD, validité 15 min ✅
  • Méthode TOTP → aucun code envoyé ✅
  • Session temporaire créée (10 min) ✅
  • Retour requires2FA: true + méthode 2FA ✅

✅ Conforme — 2FA Phase 2 (Vérification)

  • Validation code EMAIL (existence, non-expiré, non-utilisé) ✅
  • Validation TOTP avec fenêtre ±30 secondes ✅
  • Marquage code comme utilisé après validation ✅
  • Audit 2FA_VERIFIED
  • Génération tokens JWT + session définitive ✅
  • Invalidation session temporaire ✅

⚠️ Écart — Refresh Token

La spec dit "conserver le même refresh token sauf si proche expiration", mais l'implémentation fait une rotation systématique (enableRefreshTokenRotation: true dans RefreshTokenUseCase.ts L.56).
→ C'est plus sécurisé mais ne suit pas la spec à la lettre.

✅ Conforme — Gestion des erreurs

Erreur spec Code implémenté
Email inexistant CREDENTIALS_INVALIDES
Mot de passe incorrect CREDENTIALS_INVALIDES
Compte bloqué COMPTE_VERROUILLE / COMPTE_INACTIF
Code 2FA invalide CODE_INVALIDE
Session 2FA expirée SESSION_EXPIREE
Refresh Token expiré REFRESH_TOKEN_EXPIRE
Session révoquée SESSION_INVALIDE
IP bloquée IP_BLOQUEE

Référence gestion des sessions (3_REFERENCE_GESTION_SESSIONS.md)

✅ Conforme

Aspect Valeur implémentée
Bibliothèque JWT jose (conforme recommandation Opt-A)
Algorithme HS256
Access Token 24h (JWT_ACCESS_EXPIRES)
Refresh Token 7 jours (JWT_REFRESH_EXPIRES)
Issuer caritas-questionnaire-system
Hachage token en BD SHA256 (crypto.createHash('sha256'))
Hachage mot de passe bcryptjs (ServiceHashage.ts)
Rotation tokens au refresh ✅ activée par défaut
Pub/Sub Redis SESSION_CREATED via publishSessionEvent
2FA TOTP otplib via Service2FA.ts
2FA Email Nodemailer via ServiceEmail.ts
Brute-force protection 5 tentatives → 30 min lockout
Payload JWT idUtilisateur, email, role, permissions, sessionId
Endpoints sessions Lister, révoquer une, révoquer toutes ✅

⚠️ Écarts — Référence sessions

Point référence Écart
Flag emailVerifie Recommandé dans la référence, absent du schéma Prisma (même TODO EC-3 que ci-dessus)
Redis blacklist avant BD Le diagramme de la référence met Redis en premier (EXISTS jwt:blacklist:{sessionId}), mais RefreshTokenUseCase interroge la BD en premier. Redis est utilisé uniquement pour les événements Pub/Sub, pas pour la blacklist.

Synthèse

Le module est solide et largement conforme aux deux références.

Points ouverts prioritaires

Priorité Point Action
1 emailVerifie absent du schéma Prisma Ajouter le champ au schéma + migration prisma db push + décommenter la vérification dans ConnexionUseCase.ts L.207-211
2 Limite tentatives 2FA à confirmer Vérifier SessionAuthRepositoryPrisma.incrementerTentativesEchouees — doit bloquer à 5 tentatives et non 3
3 Redis blacklist absente Ajouter vérification jwt:blacklist:{sessionId} dans RefreshTokenUseCase avant la requête BD

Points acceptés (divergences volontaires)

  • Rotation systématique du Refresh Token : plus sécurisé que la spec, aucune action requise.
  • Localisation géographique absente : optionnelle selon la spec, non bloquante.