feat: make authentication optional — no tokens = no auth
Lint & Test / test (push) Successful in 10s

When no api_tokens are configured (the new default), all endpoints
are accessible without authentication. The frontend detects this
via /api/health's auth_required field and skips the login form.

- Backend: auth.py skips verification when api_tokens is empty
- Frontend: shared getAuthHeaders()/hasCredentials() helpers replace
  scattered token logic across all JS modules
- Health endpoint exposes auth_required for frontend discovery
- config.example.yaml ships with tokens commented out
- CLI --show-token and startup log reflect disabled state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-23 13:59:55 +03:00
parent f80f6e9299
commit 4d1bb78c83
14 changed files with 175 additions and 190 deletions
+6 -7
View File
@@ -1,7 +1,6 @@
"""Configuration management for the media server."""
import os
import secrets
from pathlib import Path
from typing import Optional
@@ -62,10 +61,10 @@ class Settings(BaseSettings):
host: str = Field(default="0.0.0.0", description="Server bind address")
port: int = Field(default=8765, description="Server port")
# Authentication
# Authentication (empty = auth disabled, anyone can access the API)
api_tokens: dict[str, str] = Field(
default_factory=lambda: {"default": secrets.token_urlsafe(32)},
description="Named API tokens for access control (label: token pairs)",
default_factory=dict,
description="Named API tokens for access control (label: token pairs). Empty = no auth.",
)
# Media controller settings
@@ -188,9 +187,9 @@ def generate_default_config(path: Optional[Path] = None) -> Path:
config = {
"host": "0.0.0.0",
"port": 8765,
"api_tokens": {
"default": secrets.token_urlsafe(32),
},
# "api_tokens": {
# "default": "your-secret-token-here",
# },
"poll_interval": 1.0,
"log_level": "INFO",
# Audio device to control (use GET /api/audio/devices to list available devices)