Bloque A de la fase SaaS:
- Recuperación por email: código de un solo uso (solo su SHA-256 en BD),
caducidad 30 min, emitir uno nuevo invalida los anteriores, respuesta
idéntica exista o no la cuenta (anti-enumeración) y email asíncrono;
restablecer cierra todas las sesiones de la familia. MailService cae a
modo log sin SMTP configurado.
- LoginAttemptService: 5 fallos -> bloqueo con backoff exponencial (429 +
Retry-After) en login, PIN del panel y solicitudes de reset, comprobado
ANTES de evaluar credenciales.
- Registro exige aceptar la política de privacidad (privacy_accepted_at).
- Borrado definitivo de cuenta (RGPD) con confirmación por contraseña.
- CORS por configuración; seeder demo fail-safe (matchIfMissing=false,
activado explícito en el compose local); application-prod.yml.
- Liquibase 005 con rollback. 44 tests verdes incl. migración en Postgres.