Adds lucide-react (vrek dec-1vnz5fw, chosen over Heroicons and React
Icons) for the icons goal gol-m8je1wc.
- Camera status badge on each card (iss-scj42jq): Live, Connecting,
Needs login, Not activated, Offline, Session ended. Each is an icon
plus a visible label, derived from existing query state with no
extra device calls. Logic in src/app/camera-status.tsx.
- Action icons (iss-chrdd0v): scan (radar, then spinner), refresh
rate, change or forget login, retry, the camera web page link
(replaces ↗), save, sign in and sign out.
- Warning and error icons (iss-egy082x): unsecured banner, setup
panel, inline errors, session-ended notice, login and setup
headings.
Icons are decorative (aria-hidden), spinners respect reduced motion,
and every accessible name is unchanged (all 403 prior tests pass
untouched). 416 tests, 99.9% line coverage. The vitest threshold
comment now points to principle pri-be2smzk. Refreshes the vrek
export.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>