feat(web): minimal shared-password auth gate
The web app had no auth — anyone reaching the host could browse the library, trigger downloads, and read/overwrite the stored credentials in Settings. Adds an opt-in single-shared-password gate: - Next.js middleware redirects unauthenticated page requests to /login and returns 401 for /api/*; static assets are excluded via matcher. - Auth is enabled ONLY when LYRA_PASSWORD is set (unset ⇒ app stays open, so existing deployments are unchanged). Documented in README "Security". - The session cookie is httpOnly and carries HMAC-SHA256(password) keyed by LYRA_SECRET_KEY — unforgeable, and the plaintext password never touches the client. Edge-safe Web Crypto so one lib/auth.ts serves middleware + route. - Cookie is NOT Secure: Lyra serves plain HTTP on the LAN; a Secure cookie would loop. Works behind an HTTPS proxy too. - /login page + form, a Sign out button (shown only when auth is enabled), and chrome (nav + worker-status poll) suppressed on /login. - docker-compose passes LYRA_PASSWORD to web; .env.example documents it. Verified live end-to-end (built + next start): no-cookie page→307 /login, API→401, wrong password→401, correct→200+cookie, authed page/API→200, forged cookie→401, and the auth-disabled (no LYRA_PASSWORD) path stays fully open. web 133 tests green, tsc clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,12 @@ DATABASE_URL=postgresql://lyra:lyra@db:5432/lyra
|
||||
# 32 random bytes, base64. Generate with: openssl rand -base64 32
|
||||
LYRA_SECRET_KEY=MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=
|
||||
|
||||
# Shared password protecting the whole web UI + API. When set, every request must sign in
|
||||
# (one shared password, no per-user accounts). LEAVE UNSET AND THE APP IS OPEN to anyone
|
||||
# who can reach the host — only safe on a trusted LAN or behind a VPN/auth proxy. Strongly
|
||||
# recommended for any exposed deployment. See README "Security".
|
||||
# LYRA_PASSWORD=change-me
|
||||
|
||||
# Host directory for the downloaded music library (bind-mounted into the worker at /music)
|
||||
MUSIC_DIR=./music
|
||||
|
||||
|
||||
Reference in New Issue
Block a user