Docker mode with --enable-auth was returning 401 for the homepage
and all static assets. Add /assets/, /favicon.ico, / and SPA
frontend routes (non-API paths without dots) to the auth whitelist.
Verified locally: homepage 200, /signin 200, /api/config 401 without key.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Refactor video player API from filesystem scanning to database-backed:
- Video list queries downloads with status="success" + file existence check
- Add GET /api/v1/videos/:id endpoint for playing specific video by task ID
- Add playerUrl to /api/env response (computed from request host)
- Whitelist player/video paths in auth middleware
- Fix video URL generation to preserve folder structure (relative path)
- Fix player-ui Vite base path and video URL resolution under /player/
- Add openUrl implementation to web platform stubs
- Player-UI supports ?id= query param to auto-play specific video
- Play button now passes task.id instead of filename
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously the frontend hashed passwords with MD5 + a hardcoded salt
before sending to the backend. This exposed the salt in client-side JS
and used an insecure hash algorithm.
Backend changes:
- Setup: accepts plain password, bcrypt hashes it, generates UUID apiKey
- Signin: accepts plain password, bcrypt verifies, returns stored apiKey
- Status: checks passwordHash instead of apiKey
- AppStore: new passwordHash field
- Middleware: add X-API-Key header support (was only reading Authorization)
- CORS: allow X-API-Key header
Frontend changes:
- Signin page: send plain password, receive apiKey from response
- Remove md5/crypto-js dependency and APIKEY_SALT_KEY constant
- api/download-task: auto-inject localPath/deleteSegments from store
(was lost during go-adapter migration, caused EOF errors)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>