From fece771dd0a66cc5371092d13a0035fcd3c05b1f Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Wed, 10 Jun 2026 22:46:15 -0700 Subject: [PATCH] Security UI: show saved login password / recovery question state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After saving a password or recovery question, a refresh made the section look unset (passwords are never echoed back to the browser), so it seemed like you had to redo it. Now the saved state is reflected: - "✓ A login password is set" appears when the admin has a password; the field becomes "Enter a new password to change it". - "✓ Recovery question saved: " appears, the saved question is pre- selected (preset or custom), and the answer field becomes "Enter a new answer to change it". - Shown both on load (applyLoginSavedState from /api/profiles, which now includes recovery_question — not secret, already shown on the sign-in screen) and immediately after saving. 64 integrity tests pass. --- database/music_database.py | 2 ++ webui/index.html | 2 ++ webui/static/init.js | 51 ++++++++++++++++++++++++++++++++++++-- webui/static/settings.js | 2 ++ webui/static/style.css | 6 +++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/database/music_database.py b/database/music_database.py index 1a2bca8b..9c196d25 100644 --- a/database/music_database.py +++ b/database/music_database.py @@ -5248,6 +5248,7 @@ class MusicDatabase: 'has_pin': row['pin_hash'] is not None, 'has_password': row['password_hash'] is not None if 'password_hash' in columns else False, 'has_recovery': row['recovery_answer_hash'] is not None if 'recovery_answer_hash' in columns else False, + 'recovery_question': row['recovery_question'] if 'recovery_question' in columns else None, 'home_page': row['home_page'] if 'home_page' in columns else None, 'allowed_pages': json.loads(ap_raw) if ap_raw else None, 'can_download': bool(row['can_download']) if 'can_download' in columns else True, @@ -5280,6 +5281,7 @@ class MusicDatabase: 'has_pin': row['pin_hash'] is not None, 'has_password': row['password_hash'] is not None if 'password_hash' in columns else False, 'has_recovery': row['recovery_answer_hash'] is not None if 'recovery_answer_hash' in columns else False, + 'recovery_question': row['recovery_question'] if 'recovery_question' in columns else None, 'home_page': row['home_page'] if 'home_page' in columns else None, 'allowed_pages': json.loads(ap_raw) if ap_raw else None, 'can_download': bool(row['can_download']) if 'can_download' in columns else True, diff --git a/webui/index.html b/webui/index.html index 0859b928..256a8ad3 100644 --- a/webui/index.html +++ b/webui/index.html @@ -6040,6 +6040,7 @@
+ @@ -6051,6 +6052,7 @@
So you can reset a forgotten password by answering it on the sign-in screen.
+