soulsync/database
BoulderBadgeDad 613688a9ad Login recovery (DB + backend): security question to reset a forgotten password
Closes the forgot-login-password gap. A per-profile recovery question + answer lets
a locked-out user reset their own password.

- DB: additive recovery_question + recovery_answer_hash columns (idempotent
  migration). set/get-question/verify/has methods; answer is hashed (pbkdf2) and
  matched forgivingly (trim + lowercase + collapse whitespace). No recovery set →
  never verifies.
- Endpoints (allowlisted in the login gate so they work pre-auth):
  GET /api/auth/recovery-question?username= (generic 404 when absent),
  POST /api/auth/recovery-reset {username, answer, new_password} — brute-force
  limited; a correct answer sets the new password + authenticates the session.
  POST /api/profiles/<id>/set-recovery (admin or self) to configure it.

Tests: set/get/verify, forgiving match, hashed-not-plaintext, no-recovery-never-
verifies, full reset flow (wrong answer rejected + password intact; correct answer
resets), unknown-user 404. 25 tests pass. Next: the Settings + login-screen UI.
2026-06-10 22:24:54 -07:00
..
__init__.py basic db structure 2025-08-05 22:43:04 -07:00
music_database.py Login recovery (DB + backend): security question to reset a forgotten password 2026-06-10 22:24:54 -07:00
personalized_schema.py Personalized pipeline: auto-refresh stale snapshots after watchlist scan 2026-05-15 20:53:03 -07:00