Commit graph

5 commits

Author SHA1 Message Date
ScreenTinker 436a3be7f6 Phase 3: playlist publish/draft state with auto-publish from device detail
Schema: add status and published_snapshot columns to playlists table.
Migration snapshots all existing playlists as published (idempotent via schema_migrations).

Devices always receive the published_snapshot, not live playlist_items.
Edits from device-detail/groups auto-publish immediately (display updates instantly).
Edits from playlist detail page go to draft (requires explicit publish).
POST /playlists/:id/publish snapshots and pushes to all devices.
POST /playlists/:id/discard reverts playlist_items from published snapshot.
Content deletion scrubs references from all published snapshots.

Frontend: draft badge in playlist list, prominent yellow banner with publish/discard
buttons on playlist detail and device detail pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 20:52:29 -05:00
ScreenTinker afbe113acf Security audit remediation: auth, IDOR, XSS, hardening
- Device WebSocket authentication: devices get a device_token on
  registration, must present it on reconnect. All WS events require
  prior auth. Timing-safe token comparison.
- IDOR fixes: ownership checks on schedules (device, week), layouts
  (all CRUD, zones, duplicate, device assign), video-walls (content,
  device-config).
- XSS prevention: shared esc() helper in utils.js, fixed 13 innerHTML
  injection points across 9 frontend files.
- OAuth hardening: no longer silently overwrites auth_provider on
  accounts with local passwords (returns 409).
- JWT pinned to HS256 for sign and verify.
- Password policy: change endpoint now requires 8 chars (was 6).
- HSTS header enabled (max-age 1 year, includeSubDomains).
- Stripe webhook rejects unsigned payloads when no secret configured.
- Screenshot size validation (max 2MB base64).
- Rate limiting on exports, imports, content operations.
- Content file serving checks playlist_items instead of old assignments.
- Content ownership verified in device-groups assign-content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 22:48:07 -05:00
ScreenTinker aca1558702 Show auto-generated playlists by default in playlist list
Users need to see migrated playlists immediately. The toggle still
allows hiding them if desired.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 22:17:31 -05:00
ScreenTinker a66feab53e Phase 2: playlists UI shows display count, auto-generated filter toggle
List view: auto-generated playlists hidden by default with toggle checkbox.
Cards show 'auto' badge and display count. Detail view shows display count
in the header.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 22:10:48 -05:00
ScreenTinker bc7e68d680 Add playlists view with list, detail, and item management
List view: playlist cards with name, description, item count.
Detail view: inline-editable name/description, ordered item list
with thumbnails, duration editing, drag-to-reorder, remove.
Add-item modal: content/widget picker with search and tabs.
All user strings escaped via esc() helper for safe innerHTML.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 21:18:43 -05:00