Completes securing the web front end (vrek gol-wqf95dq, iss-r5vrjx7).
- /login: Server Action with a generic error, same-site-only redirect
back to ?next=, and throttling of failed logins (10 per address and
100 overall per 15 min). The header shows "Signed in as" with
Sign out (iss-nj9wmwp).
- First run with no admin: instrumentation prints a one-time setup
code, shared with the app through globalThis. /setup requires it,
and 5 wrong codes rotate it. "Skip for now" runs unsecured for the
browser session behind a red warning banner on every page
(iss-9nxdndr).
- src/proxy.ts: optimistic redirects to /login or /setup, 401 for
the API, and the 12 h sliding session refresh. requirePageAccess()
and apiAccessDenied() re-check in the page and all 6 route handlers
(iss-76d5wrb).
- An expired session now shows "Your session has ended" instead of
the camera-login form.
- README documents in-app setup, skipping and signing in.
Verified with unit tests (383, 99.9% line coverage), end to end
against `next start`, and manually in a browser by the user.
Refreshes the vrek export.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Discovers ONVIF cameras (Hikvision/Annke) over WS-Discovery, keeps a
server-side registry and an encrypted credential store, and serves
info, snapshot and credentials routes for each camera.
The home page is now a Server Component that lists known cameras from
the registry on load, without a scan (vrek iss-a0hz0py). The snapshot
refresh rate lives in the URL (?refresh=), and a scan refreshes the
server-rendered list.
Route input is validated with zod (iss-rjqy3hy), and /api/discover no
longer returns raw error messages (iss-dbwgww8). Adds
@tanstack/react-query and zod as dependencies, with a QueryClient
provider in the root layout.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>