Root cause: HLS content is AES-128 encrypted, but the key endpoint
required mandatory auth (HybridAuthGuard). HLS.js fetches the key
without auth headers, causing a silent 401 and playback failure.
Backend:
- Changed key.controller.ts to use OptionalHybridAuthGuard
- Free content (price <= 0) now serves keys without authentication
- Paid content still requires auth, returns 401 for anon requests
- Added Content entity injection to look up pricing
Frontend:
- Configured HLS.js xhrSetup to attach Bearer token on /key requests
- Uses nostr_token or auth_token from sessionStorage
- Ensures logged-in users can play paid encrypted content
Co-authored-by: Cursor <cursoragent@cursor.com>