PD-241 — Synthèse d'implémentation (Étape 6c)
Résumé
L'implémentation de PD-241 (Logout / invalidation session) est complète.
Fichiers créés
| Fichier | Type | Description |
src/modules/auth/dto/logout.dto.ts | DTO | LogoutDto avec refresh_token optionnel |
src/modules/auth/errors/logout.errors.ts | Erreurs | LogoutError, LogoutFailedError, LogoutInternalError |
src/modules/auth/filters/logout-exception.filter.ts | Filter | Transforme exceptions en {error, message} (INV-241-04) |
Fichiers modifiés
| Fichier | Modifications |
src/modules/auth/auth.controller.ts | Ajout endpoint POST /auth/logout avec JwtAuthGuard, LogoutExceptionFilter |
src/modules/auth/auth.service.ts | Ajout méthode logout(userId, refreshToken?) avec atomicité INV-241-03 |
src/modules/auth/mfa/services/keycloak-admin.service.ts | Ajout invalidateSession() et revokeRefreshToken() |
src/modules/auth/auth.service.spec.ts | Ajout tests unitaires logout (5 tests) |
Couverture des invariants
| Invariant | Mécanisme | Test |
| INV-241-01 | JwtAuthGuard sur endpoint | TC-ERR-01 |
| INV-241-02 | invalidateSession() | TC-NOM-01 |
| INV-241-03 | revokeRefreshToken() + atomicité | TC-NOM-02, atomicity test |
| INV-241-04 | LogoutExceptionFilter | TC-ERR-03 |
| INV-241-05 | LogoutFailedError (502) | TC-ERR-02 |
| INV-241-06 | N/A (hors périmètre) | N/A |
Tests ajoutés
Tests unitaires (auth.service.spec.ts)
- TC-NOM-01: Logout nominale sans refresh token
- TC-NOM-02: Logout avec refresh token
- TC-ERR-02: Erreur Keycloak (LogoutFailedError)
- INV-241-03 atomicity: Échec revocation = échec logout
- Wrap unexpected errors: LogoutInternalError
Résultats de validation
| Vérification | Statut |
| TypeScript compilation | ✅ Pas d'erreur |
| ESLint | ✅ Pas d'erreur |
| Tests auth (778 tests) | ✅ Tous passent |
Architecture
Client
│
▼
POST /auth/logout
│ Header: Authorization: Bearer <JWT>
│ Body: { refresh_token?: "<token>" }
│
▼
┌─────────────────────────────────────┐
│ JwtAuthGuard │
│ - Valide JWT │
│ - Throw UnauthorizedException si KO │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ AuthController.logout() │
│ - @UseFilters(LogoutExceptionFilter)│
│ - @HttpCode(200) │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ AuthService.logout() │
│ - Appelle invalidateSession() │
│ - Si refreshToken: │
│ - Appelle revokeRefreshToken() │
│ - Atomicité INV-241-03 │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ KeycloakAdminService │
│ - invalidateSession() │
│ DELETE /users/{id}/sessions │
│ - revokeRefreshToken() │
│ POST /users/{id}/logout │
│ - Circuit breaker + retry │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ LogoutExceptionFilter │
│ - Map errors to {error, message} │
│ - UnauthorizedException → 401 │
│ ERR-241-UNAUTHENTICATED │
│ - LogoutFailedError → 502 │
│ ERR-241-LOGOUT-FAILED │
│ - LogoutInternalError → 500 │
│ ERR-241-INTERNAL │
└─────────────────────────────────────┘
Prochaine étape
→ Étape 7 : Acceptabilité (reviews automatisées + reviews LLM)
Généré par Claude Orchestrateur — 2026-02-07