Add canStream user permission to control streaming access

Adds a per-user "Can Stream" permission mirroring the existing "Can Download"
pattern. Server admins can now disable streaming for specific users, encouraging
local downloads instead. Addresses #2572.

Changes:
- User model: stream permission in mapping, defaults, and getter
- ApiKey model: stream permission in defaults
- Controller: 403 enforcement on playback session creation endpoints
- Frontend: permission toggle in admin UI, play button gated by canStream,
  download button shown when streaming disabled, message when neither allowed
- Tests: 11 Mocha tests (model + controller), 1 Cypress test (card UI)
- Localization: English strings for toggle label and fallback message

The getter uses !== false (rather than !!) so existing users without the
stream key in their permissions JSON default to allowed on upgrade.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
zriddle 2026-04-02 14:12:08 -06:00
parent 64cbf59609
commit 464b720d9e
11 changed files with 236 additions and 1 deletions

View file

@ -512,6 +512,7 @@
"LabelPermissionsCreateEreader": "Can Create Ereader",
"LabelPermissionsDelete": "Can Delete",
"LabelPermissionsDownload": "Can Download",
"LabelPermissionsStream": "Can Stream",
"LabelPermissionsUpdate": "Can Update",
"LabelPermissionsUpload": "Can Upload",
"LabelPersonalYearReview": "Your Year in Review ({0})",
@ -851,6 +852,7 @@
"MessageNoFoldersAvailable": "No Folders Available",
"MessageNoGenres": "No Genres",
"MessageNoIssues": "No Issues",
"MessageNoStreamOrDownloadAccess": "Contact your server admin for access",
"MessageNoItems": "No Items",
"MessageNoItemsFound": "No items found",
"MessageNoListeningSessions": "No Listening Sessions",