feat: add auth subsystem with WebAuthn passkeys support

New modules: lib/auth, lib/auth_users, lib/db, lib/db_sqlite, lib/password,
lib/webauthn, daemon/handlers/auth, scripts/bootstrap_auth, tests/test_auth

Frontend: webui/api/auth, hoover/components/auth, pages/login, passkeys, users

Updates: daemon/iface and server, lib/common and nginx, pyproject.toml deps,
install script, server.py, app.js, and websocket/api clients
This commit is contained in:
2026-07-24 01:21:39 +00:00
parent 04417cf05c
commit 56b200d233
28 changed files with 4900 additions and 82 deletions
+1 -26
View File
@@ -14,7 +14,7 @@ from typing import Any
from jinja2 import Environment, FileSystemLoader
from lib.acme import find_cert_dir
from lib.common import ensure_dirs, load_json, save_json
from lib.common import _hash_password, ensure_dirs, load_json, save_json
logger = logging.getLogger(__name__)
@@ -50,10 +50,6 @@ DEFAULT_SSL: dict[str, Any] = {
WEBUI_BACKEND: dict[str, Any] = {
"label": "Vacuum Wall WebUI",
"builtin": True,
"auth": {
"user": "admin",
"htpasswd": str(HTPASSWD_FILE),
},
"paths": {
"/": {
"backend": {"host": "127.0.0.1", "port": 9090, "proto": "http"},
@@ -120,13 +116,6 @@ def _ensure_webui_backend(raw: dict[str, Any]) -> None:
return
backends["webui"] = deepcopy(WEBUI_BACKEND)
backends["webui"]["_migrated"] = True
# Harvest auth from legacy path-level auth if present
for dom in raw.get("domains", {}).values():
paths = dom.get("paths", {})
root = paths.get("/", {})
if root.get("auth"):
backends["webui"]["auth"] = root["auth"]
break
def _migrate_mgmt_domains(raw: dict[str, Any]) -> None:
@@ -577,20 +566,6 @@ def write_htpasswd(user: str, password: str) -> None:
os.replace(tmp, HTPASSWD_FILE)
def _hash_password(password: str) -> str:
"""Hash *password* using SHA-256 crypt (``$5$`` format) via passlib.
Args:
password: Plain-text password to hash.
Returns:
The hashed password string suitable for ``.htpasswd`` (e.g. ``$5$rounds=…$…``).
"""
from passlib.hash import sha256_crypt
return sha256_crypt.hash(password)
__all__ = [
"WEBUI_BACKEND",
"_ensure_webui_backend",