Opt-in username/password login — profiles become real accounts. This is the data layer: a per-profile login password, kept SEPARATE from the quick-switch PIN (different security purpose; a 4-digit PIN must not become the password guarding a public instance). - Additive migration: profiles.password_hash column (idempotent, metadata-flagged). - set_profile_password / verify_profile_password / profile_has_password / get_profile_by_name (the login username = profile name, unique + case-insensitive). - Security default: a profile with NO password is NOT loginable (verify returns False) — unlike the PIN where "no PIN = always valid". You can't authenticate to an account with no credential. Tests: migration adds the column; set/verify; no-password-never-loginable; clearing; name lookup; and password is fully independent of the PIN. 6 tests pass. Next: the login endpoint + require_login gate (increment 2). |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| music_database.py | ||
| personalized_schema.py | ||