Commit Graph

5 Commits

Author SHA1 Message Date
daaecb7452 Fix the published package: compile the CLI, bundle onvif (0.1.1)
Installing 0.1.0 failed twice, both my mistakes.

- Node refuses to strip types under node_modules, so shipping .ts for the
  CLI could never work from an installed package. tsconfig.cli.json now
  compiles those modules to dist/ as ES modules, and the helper scripts
  are plain .mjs.
- serverExternalPackages made Turbopack emit require("onvif-<hash>"),
  a name that resolves nowhere, because onvif comes from a git URL.
  Bundling it fixes that; checked from an installed tarball, where
  /api/discover answered 200 and a real camera's info and snapshot came
  back through the packaged server.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 19:21:53 -05:00
30b1f36e1b Ship a standalone build and an onvif-dashboard start command
- next.config.ts builds standalone output with image optimization off,
  and scripts/bundle-standalone.mjs puts the static files beside the
  server, then drops what tracing swept in but the app never runs (the
  MediaMTX binary and sharp's platform binaries, 79 MB). The build is
  27 MB and npm pack is 4.9 MB.
- The CLI gained start, which runs that server from any directory with
  the remembered data folder and stored key in its environment, and
  admin, so the messages in the UI can name a command that exists.
- Messages that said "npm run …" now say "onvif-dashboard …".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 19:09:13 -05:00
5824db8ea9 Add MediaMTX video bridge: pinned installer and supervised localhost process
- npm run video:install downloads the pinned MediaMTX v1.21.0 for this
  platform, verifies its SHA-256 against checksums committed in
  src/lib/mediamtx-install.ts, and installs it into gitignored bin/.
- On server start, instrumentation launches MediaMTX with a generated
  owner-only config: API and WebRTC signaling on 127.0.0.1, only the ICE
  port (UDP 8189) on the LAN, a hashed per-boot API password, no
  anonymous users, unused protocols off. Restarts on crash with backoff,
  stops with the server; VIDEO_BRIDGE=off skips it.
- Camera streams are added to MediaMTX at runtime, on demand, with the
  stored login; nothing with a password is written to disk or echoed.
- rtspSourceWithLogin() reads a profile's RTSP URI over ONVIF.
- Export vrek log (live video goal, decisions, codec finding).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 15:33:55 -05:00
462141aa35 Add admin login foundations: scrypt admin file, CLI, sessions
Groundwork for securing the web front end (vrek gol-wqf95dq). The app
does not enforce login yet.

- src/lib/admin-file.ts: the admin file at ADMIN_AUTH_FILE (default
  .data/admin.json). scrypt hashing (N=2^16, random salt, bounded
  parameters, constant-time compare), zod-validated reads where a
  malformed file is an error, and atomic 0600 writes that won't
  replace an existing admin without overwrite. Plain Node, so the
  CLI can share it (iss-mffqscg).
- src/lib/admin-auth.ts: server-only app layer; failed logins always
  cost one hash.
- scripts/create-admin.mts + `npm run admin:create`: create or reset
  the admin outside the app, interactive (hidden, confirmed) or piped
  (iss-7xmka20). The README documents it, a no-npm Node one-liner,
  the file format, and password reset.
- src/lib/session-token.ts and session.ts: stateless HMAC-signed
  session cookie, keyed from the password hash so a password change
  ends every session, with a 12 h sliding window (iss-e27nb70,
  dec-f0xar8r).

281 tests, 99.8% line coverage. Refreshes the vrek export.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 09:46:40 -05:00
f39d16a8c0 Add ONVIF camera app with a server-rendered camera dashboard
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>
2026-09-19 08:40:32 -05:00