Documentation

Lockout brute-force

Verrouillage progressif des comptes en cas de tentatives échouées.

Au bout de 3 mauvais mots de passe consécutifs, le compte se verrouille pour une durée croissante. Le compteur se reset tout seul après 24h sans nouvelle tentative.

Progression

Définie dans lib/auth-lockout.ts :

export const FAILS_BEFORE_LOCK = 3;
export const LOCKOUT_MINUTES = [10, 20, 30, 45, 60];
Échec n°Verrouillage
1, 2Aucun, juste un compteur qui monte
310 min
420 min
530 min
645 min
7+60 min (cap)

Au-delà du 7e échec, on reste à 60 min — on ne punit pas indéfiniment.

Decay 24h

Si la dernière tentative ratée date de plus de 24h, le compteur repart à zéro. Constante :

const ATTEMPT_DECAY_MS = 24 * 60 * 60 * 1000;

Pas de cron nécessaire — la décrémentation est lazy, calculée à la prochaine tentative de login.

Champs Prisma

Trois colonnes sur User :

failedLoginAttempts Int       @default(0)
lastFailedLoginAt   DateTime?
lockedUntil         DateTime?

API helpers (lib/auth-lockout.ts)

recordFailedAttempt(userId)   // appelé sur mot de passe faux
clearLockout(userId)          // appelé sur login réussi
adminUnlockUser(userId)       // déverrouillage manuel admin
getLockState({...})           // lecture sans mutation

Route publique de status

GET /api/auth/lock-status?email=foo@bar.com retourne l'état actuel du verrouillage. Utilisée par la page de login pour afficher un message "Compte verrouillé pendant X minutes" sans révéler si l'email existe (retourne { locked: false, attempts: 0 } si user inconnu).

Action admin "déverrouiller"

Sur la page /admin/users, l'action Déverrouiller apparaît si lockedUntil > now. Elle appelle adminUnlockUser qui réinitialise les trois champs. Audit loggé via user.unlock.

Allez plus loin

On this page