feat(web): optional web login and API tokens, off by default (stacked on #674) (#683)

Optional web login, off by default: a device that sets no password behaves
exactly as before. Set under General > Security; then every page and API
route needs a session login or an API token (Authorization: Bearer).
Loopback, the Wi-Fi setup flow in AP mode, static files, captive-portal
probes and a reduced /api/v3/health stay open. Secrets live in the web_auth
section of config_secrets.json and no API returns them.
scripts/reset_web_password.py turns login off. Stacked on #674.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-09-30 09:09:40 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent ba38a83c2c
commit e3c85cece6
23 changed files with 2310 additions and 26 deletions
+7 -4
View File
@@ -43,11 +43,14 @@ CORE_CONFIG_KEYS = frozenset({
})
#: Top-level keys of ``config_secrets.json`` that belong to the core rather than
#: to a plugin: the GitHub token the Plugin Store reads, and the historical
#: ``youtube`` section. Plugin secrets are namespaced by plugin id, so anything
#: deciding whether a secrets section is a plugin's needs this as well as
#: ``CORE_CONFIG_KEYS``.
#: to a plugin: the GitHub token the Plugin Store reads, the historical
#: ``youtube`` section, and ``web_auth`` (the optional web login's password
#: hash and API-token hashes, web_interface/auth.py) -- which orphan-plugin
#: cleanup would otherwise delete, logging everyone out. Plugin secrets are
#: namespaced by plugin id, so anything deciding whether a secrets section is a
#: plugin's needs this as well as ``CORE_CONFIG_KEYS``.
CORE_SECRETS_KEYS = frozenset({
'github',
'youtube',
'web_auth',
})