Aller au contenu

Auth Module Implementation - Notes techniques

Contexte

Implémentation de l'authentification JWT pour le projet gest-recettes-depenses selon le pattern DDD strict du GUIDE_ARCHITECTURE_DDD.md.

Architecture implémentée

Layers

  • Domain : AuthExceptions, AuthDTO, auth.schemas (constantes)
  • Application : ILoginUseCase/IRegisterUseCase interfaces avec DonnesXxx/ResultatXxx/ CodeErreurXxx
  • Infrastructure : AuthService (JWT+bcrypt), ServiceValidationAuth (Zod), AuthModule (DI)
  • Interface-Adapters : Handlers (extends BaseActionHandler), Controllers, Routes

Problèmes rencontrés

1. Accès au mot de passe haché (RÉSOLU)

Le LoginUseCase doit comparer le mot de passe en clair avec le hash. L'IUtilisateurRepository ne fournit pas le hash dans le DTO (pas de champ motDePasse).

Solution implémentée : Méthode obtenirMotDePasseParEmail(email: string) ajoutée dans l'interface et l'implémentation Prisma :

// IUtilisateurRepository.ts
obtenirMotDePasseParEmail(email: string): Promise<string | null>;

// UtilisateurRepositoryPrisma.ts
async obtenirMotDePasseParEmail(email: string): Promise<string | null> {
  const result = await this.prisma.utilisateur.findUnique({
    where: { email },
    select: { motDePasse: true }
  });
  return result?.motDePasse || null;
}

Cette solution respecte le pattern DDD : le UseCase n'a accès qu'aux interfaces, jamais aux implémentations concrètes.

2. Type expiresIn pour jsonwebtoken

// ❌ Erreur TS2769
return sign(payload, secret, { expiresIn: string });

// ✅ Solution
const options: SignOptions = { expiresIn: this.jwtExpiresIn as any };
return sign(payload, this.jwtSecret, options);

3. Convention d'imports

Tous les imports utilisent le path alias @/ configuré dans tsconfig.json.

Points forts du pattern DDD

Aspect Bonne pratique
Exceptions extends ErreurMetier, union types pour codes
DTOs versObjetPlainPublic() pour HTTP, jamais versObjetPlain()
UseCase 5 étapes: validation → logique → audit → résultat → erreur
DI Ordre strict: repos → services → usecases → controllers
Handlers Extends BaseActionHandler, 3 méthodes publiques max

Recommandations architecturelles

  1. Extraire AuthMiddleware dans shared/infrastructure/middleware/ (actuellement inline dans server.ts)
  2. ~~Ajouter méthode repository pour récupérer le hash mot de passe~~ ✅ TERMINÉ
  3. Implémenter 2FA avec otplib (déjà dans package.json, champ deuxFacteursActive existant)
  4. Rate limiting spécifique pour /auth/login et /auth/register (déjà configuré via rateLimit: 'auth')

Fichiers créés

Modules/Auth/
├── domain/exceptions/AuthExceptions.ts
├── domain/schemas/auth.schemas.ts
├── domain/types/AuthDTO.ts
├── application/interfaces/ILoginUseCase.ts
├── application/interfaces/IRegisterUseCase.ts
├── application/usecases/LoginUseCase.ts
├── application/usecases/RegisterUseCase.ts
├── infrastructure/di/AuthModule.ts
├── infrastructure/services/AuthService.ts
├── infrastructure/schemas/zod/login.schemas.ts
├── infrastructure/schemas/zod/register.schemas.ts
├── infrastructure/services/validation/ServiceValidationAuth.ts
├── interface-adapters/controllers/AuthModuleController.ts
├── interface-adapters/controllers/LoginController.ts
├── interface-adapters/controllers/RegisterController.ts
├── interface-adapters/handlers/LoginHandler.ts
├── interface-adapters/handlers/RegisterHandler.ts
├── interface-adapters/routes/auth.module.routes.ts
└── index.ts

Liens liés

📝 Implémentation Audit (2026-05-31)

Modèle Prisma ajouté :

model AuditLog {
  id            String   @id @default(uuid())
  utilisateurId String
  action        String   @db.VarChar(100)
  ressource     String   @db.VarChar(100)
  ressourceId   String?
  details       String?  @db.Text
  resultat      String?  @db.VarChar(10)
  adresseIP     String?  @db.VarChar(45)
  userAgent     String?  @db.VarChar(500)
  dateCreation  DateTime @default(now())
  @@index([utilisateurId])
  @@index([action])
  @@index([dateCreation])
  @@map("audit_logs")
}

Fichiers créés : - shared/domain/interfaces/repositories/IAuditLogRepository.ts (existait déjà) - shared/infrastructure/repositories/prisma/AuditLogRepositoryPrisma.ts

Intégration : - AuthModule.ts → injecte AuditLogRepositoryPrisma - LoginUseCase.ts → utilise auditLogRepository.creer() pour journaliser - RegisterUseCase.ts → utilise auditLogRepository.creer() pour journaliser

⚠️ À faire : Exécuter npx prisma generate pour régénérer le client avec le modèle AuditLog.