Commit graph

4 commits

Author SHA1 Message Date
ScreenTinker 0a9a749475 Make help tips reachable, and explain the pages that had none
An audit of every view turned up two problems with the in-product help.

The tips only appeared on :hover. On a tablet or a phone there is no hover, so
the entire explanation layer was invisible to touch users — a large share of
the people administering signage — and unreachable from a keyboard. Tapping a
marker now opens it, Escape or a tap elsewhere closes it, and the marker is
focusable so Tab reaches it and a screen reader announces it. Bound once at the
document level and applied by observing the DOM, because views render from
about twenty call sites and modals appear later still; hooking each one would
have left the next new route silently unreachable again.

Four views had no tip at all. Playlists is the important one: a playlist is the
concept the reported confusion was actually about, and the page said nothing
about what one is or how it reaches a screen. Activity and Settings now have
one too. Help does not, because it is the help.

The schedule tip described a product that no longer exists — it said to click
Add Schedule, predating the drag, resize and right-click gestures. Rewritten.

All four are translated into every active locale rather than left to fall back
to English, since a tip falling back is a non-English user being handed an
English paragraph at the moment they are confused. hi.js stays deliberately
empty per the note in that file. Tests now check that every tip is translated
everywhere, and that a tip marker never names a string that does not exist.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-07-28 19:37:49 -05:00
ScreenTinker 6d6f901ef4 i18n batch 6: wire teams + activity + help (~62 keys)
- teams.js: list, detail with members + shared devices, invite/role
  controls, all toasts
- activity.js: page chrome, action verb/noun mapping translated through
  t() so the audit log reads naturally in each language
- help.js: page chrome translated; guides and FAQ body content kept
  in English with a comment explaining why (machine-translated docs
  read worse than English source)
- 1008 keys total, parity 100% across en/es/fr/de/pt

All 16 dashboard views now use t(). index.html modal, player overlay,
and Android resources still pending.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 20:16:21 -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 1594a9d4a4 Initial open source release
ScreenTinker - open source digital signage management software.
MIT License, all features included, no license gates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 12:14:53 -05:00