NextMyDay/internal/core/server
Claus Lohmar 6d421b61fd feat(setup): gate first run with a printed setup code and a first-run page
The real topology is an LXC container (11020) behind Proxmox + Zoraxy, so
the SSH tunnel is impractical: it lands on the container gateway, not
loopback. D-025 is re-revised and D-044 adds the general gate.

- core/setup: a Gate (gate.go) holding the 128-bit setup code (generated at
  first run, or pinned by config `setup_code`) plus a signed unlock cookie
  (`myday_setup`) that carries a keyed one-way FINGERPRINT of the code, never
  the code itself. The code is single-use (retired on the first success) and
  the comparison ignores case/separators.
- The unlock action (`POST /setup?do=setup&action=unlock`) is CSRF-protected
  (A15), rate-limited (the /setup A3 class) and audited; a wrong or absent
  code gets the same generic 403 page.
- The door (server.Deps.SetupGate): in setup mode the wizard is served to
  EITHER the direct tunnel (gate a) OR an unlocked request (gate b); `GET /`
  and an un-unlocked `GET /setup` render a friendly first-run page with the
  code form — never a bare 404 — and every other route stays 404.
- cmd/myday prints an unmistakable startup banner: setup mode, the wizard
  URL, the code, where to read it (journalctl / pct exec 11020) and the
  restart that adopts the persisted secrets.
- httpx.Signer.Fingerprint backs the unlock cookie; config gains `setup_code`.

Tests cover the boilerplate at `/` and `/setup` (200, not 404), the unlock
(code → wizard; wrong/absent → generic, 429 under the limit), single-use, the
CSRF requirement, access-log redaction, and that a non-/setup route is still
404. Gate green (build · vet · test -race); live-smoked against the binary.
2026-10-15 06:33:13 +00:00
..
authflow.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
enroll_login_test.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
handlers.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
recoveryflow.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
registry.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
requestcontext.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
roles.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
roles_test.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
server.go feat(setup): gate first run with a printed setup code and a first-run page 2026-10-15 06:33:13 +00:00
server_test.go feat(setup): gate first run with a printed setup code and a first-run page 2026-10-15 06:33:13 +00:00
setup_code_test.go feat(setup): gate first run with a printed setup code and a first-run page 2026-10-15 06:33:13 +00:00
setup_wizard_test.go feat(setup): gate first run with a printed setup code and a first-run page 2026-10-15 06:33:13 +00:00
setupflow.go feat(setup): gate first run with a printed setup code and a first-run page 2026-10-15 06:33:13 +00:00
spec006_passkey_nudge_test.go fix(security): gate /setup per request and pin the setup module 2026-10-14 11:30:13 +00:00
spec007_recovery_test.go feat(server): gate /setup by the direct tunnel and trust the proxy scheme 2026-10-15 05:40:36 +00:00
spec008_modules_test.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
spec009_web_pwa_test.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00
static.go feat(core): add the store, identity plumbing and the door (SPEC-003/004) 2026-10-14 10:53:51 +00:00