screentinker/frontend
ScreenTinker eb13f716d0 feat(branding): instance-level default white-label branding (#15)
White-label is stored per-workspace (white_labels.workspace_id); unbranded and
new workspaces - and the login page - fell back to hardcoded ScreenTinker. Add a
single platform default that everything inherits beneath the per-workspace layer.

Resolution (lib/branding.js): workspace row -> custom-domain match -> platform
default -> hardcoded ScreenTinker. Row-level override: a workspace with its own
row keeps it (current behavior); only row-less workspaces inherit the default,
so editing the default propagates instantly (no row-copying at creation).

The platform default is a white_labels row with a FIXED id ('platform-default'),
not a "workspace_id IS NULL" sentinel - legacy pre-multitenancy rows can also
have a null workspace_id, which would be ambiguous.

- routes/admin.js: GET/PUT /api/admin/branding (requirePlatformAdmin) to read/
  upsert the single platform-default row; audit-logged.
- server.js: public GET /api/branding (domain match -> platform default ->
  hardcoded) for pre-login/pre-workspace contexts.
- routes/white-label.js: authed GET now falls back to the platform default
  (was hardcoded) for row-less workspaces.
- Frontend: login page resolves + applies branding (logo, name, colors, favicon,
  custom CSS) pre-auth; Admin page gets a "Default branding" form.

Tests: resolver order incl. legacy null-ws safety; admin GET/PUT (single row,
upsert, platform-admin-only 403). Full suite 37/37. Verified end-to-end:
public + authed + login-page all inherit the platform default; per-workspace
override preserved.

Closes #15.
2026-06-08 16:55:22 -05:00
..
assets Landing: replace iframe mock with dashboard screenshot 2026-04-21 19:47:13 -05:00
compare chore(discord): update Discord invite link 2026-05-14 12:26:20 -05:00
css fix(switcher): expose workspace settings for single-workspace users (#19) 2026-06-08 16:39:42 -05:00
guides chore(discord): update Discord invite link 2026-05-14 12:26:20 -05:00
js feat(branding): instance-level default white-label branding (#15) 2026-06-08 16:55:22 -05:00
legal docs(privacy): disclose error and diagnostic telemetry from players 2026-05-15 15:31:21 -05:00
index.html feat(teams): temporarily disable Teams API while feature is redesigned 2026-05-12 13:30:55 -05:00
landing.html fix(landing): replace broken Custom pricing card with enterprise contact form 2026-05-14 13:52:24 -05:00
manifest.json Initial open source release 2026-04-08 12:14:53 -05:00
robots.txt SEO: add meta tags, sitemap, robots.txt, comparison pages, guides, internal linking 2026-04-28 20:54:32 -05:00
sitemap.xml SEO: add meta tags, sitemap, robots.txt, comparison pages, guides, internal linking 2026-04-28 20:54:32 -05:00
sw-admin.js chore(admin-sw): bump cache to v3 to evict stale clients 2026-06-08 10:34:47 -05:00