screentinker/server
screentinker 326da8a730
Show the player on the player, and the diagnostics when something is wrong (#290)
The box is now both server and player, so its screen has to be one or the
other at any moment. Three states, and the transitions are the point:

  installing / down / failed  diagnostics, so the fault is visible
  up, but no account yet      diagnostics plus the address to create one
  up, and an account exists   the player, full screen

A fresh install has nothing to play and nobody to play it for, so it stays on
the configuration screen until someone has signed up. Hiding that address
would leave the device unsetuppable: it has no keyboard.

⚠️ THE PLAYER IS AN IFRAME LAYER, NOT A NAVIGATION. Setting location.href
would replace the document and take the poller with it - and that poller is
the only thing able to notice the server failing later. As a layer, the
diagnostics are one style change away from being back on screen, which is
exactly what should happen when a server that has been playing for weeks
throws at 3am. A test asserts location.href is never assigned, so this cannot
be quietly simplified back.

Whether an account exists is asked by the wrapper, not the page:
/api/auth/config is public, but the page is loaded from file:// - origin
"null" - and the server sets no CORS headers on its own API, while this
process is already talking to it. The answer is three-valued. null means the
probe has not replied yet and is deliberately NOT treated as false: guessing
would flip a fresh box to an empty player and take the sign-up address off
the screen while someone was reading it.

Verified against a real server rather than by inspection - install, sign up,
watch it flip:

  BEFORE signup : needsSetup=null   -> diagnostics
  POST /api/auth/register -> HTTP 201
  AFTER  signup : needsSetup=false  -> player


Claude-Session: https://claude.ai/code/session_014kfhrUPit5MCqxeTQyqr56

Co-authored-by: Dan Walters <dan.walters@bytetinker.net>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 16:23:23 -05:00
..
config fix(logging): gate CF-Connecting-IP on a Cloudflare peer, not any trusted proxy 2026-07-26 10:23:04 -05:00
db Run the ScreenTinker server on the player it serves (#288) 2026-08-18 15:16:09 -05:00
lib Stop database snapshots losing their permissions (#289) 2026-08-18 15:24:39 -05:00
middleware Merge branch 'fix/recovery-grants' into release/auth-campaign 2026-07-26 16:22:59 -05:00
player Run the ScreenTinker server on the player it serves (#288) 2026-08-18 15:16:09 -05:00
routes Run the ScreenTinker server on the player it serves (#288) 2026-08-18 15:16:09 -05:00
scripts Drop sharp: pure-JS image ops on a worker thread (#263) 2026-08-13 11:40:13 -05:00
services #240: stop the morning wave buying itself a blocking checkpoint 2026-08-06 20:22:21 -05:00
test Show the player on the player, and the diagnostics when something is wrong (#290) 2026-08-18 16:23:23 -05:00
ws Run the ScreenTinker server on the player it serves (#288) 2026-08-18 15:16:09 -05:00
.gitignore feat(email): Microsoft Graph send + alert spam protection + preferences UI 2026-05-12 18:16:40 -05:00
config.js SSO: prove domain ownership by DNS, and fix what the second review found 2026-08-10 19:23:46 -05:00
node_modules Merge Japanese localisation (#283) (#285) 2026-08-18 09:23:28 -05:00
package-lock.json Stop shipping a licence we would rather not have to explain (#281) 2026-08-14 14:50:18 -05:00
package.json Stop shipping a licence we would rather not have to explain (#281) 2026-08-14 14:50:18 -05:00
server.js Run the ScreenTinker server on the player it serves (#288) 2026-08-18 15:16:09 -05:00
smoke-ui.js Keep the smoke test out of npm test, and update the lockfile 2026-07-28 20:34:34 -05:00
version.js chore(version): single-source VERSION, env-configurable data paths, bump tooling 2026-06-10 12:56:03 -05:00