All checks were successful
Deploy to Homelab / deploy (push) Successful in 18s
Single attemptLogin() orchestrates lockout check, bcrypt verify (against real or dummy hash), success/failure logging, and a configurable minimum response-time clamp. Both login routes will share this — no duplication. Adds three logger events for the operator's escalation pipeline: AUTH_LOCKOUT_TRIGGERED, AUTH_LOCKED_ATTEMPT, and AUTH_RATE_LIMITED. fail2ban filters can pick these up to escalate persistent attackers from in-app lockout to IP ban. Constant-time defense: unknown users still pay bcrypt cost (via dummy hash) and the clamp ensures locked-vs-unknown-vs-wrong-password aren't distinguishable by response time. Username is canonicalized (lowercase + trim) before lookup so attackers can't bypass lockout via case variation.