4 Commits
Author SHA1 Message Date
Christian ManivongandClaude Opus 5.5 369f66afdc feat(screenshots): cropped shots, sizes for the site, a site check
- shots.py crops to a region (clip) or to what one or more elements cover
  (element, pad), per-shot viewport; capture.py writes the published sizes to
  src/data/screenshots.json so the page reserves the right space.
- anonymize.py no longer empties secrets that netOrk compares with each other
  (Wi-Fi keys on an SSID against the key read from the access point). Emptying
  them invented passphrase "drift" that never existed; a keyed hash keeps equal
  equal, reverses nothing, and its key lives for one run.
- scripts/check/site.py checks the built site in both languages at four widths:
  sideways overflow, one h1, images with alt and size, console errors, requests
  to other origins, links to unknown routes, old-URL redirects, language
  detection, and word counts against the budgets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:24:49 +02:00
Christian ManivongandClaude Opus 5.5 011f816fc9 feat: replace UI mockups with real netOrk screenshots
The homepage showed seven hand-built JSX imitations of the netOrk UI. They
are gone; every image is now a screenshot of netOrk v0.28.0 itself, taken
from an anonymized copy of a production database (scripts/demo) with
scripts/screenshots/capture.py and published as WebP (~630 KB for all eight).

- Hero: the device inventory. Walkthrough: device detail, VLANs, the Security
  tab, the vulnerability triage queue (replacing the config-diff row), the
  dashboard and service checks (new row 6). NIS2: the audit log, filtered to
  what people did.
- Copy follows the images: row 3 describes the security assessment, row 4 the
  triage queue; row 2 no longer claims corrections are always automatic;
  18 widgets. Alt texts in both languages.
- Also fixed on the homepage: the NIS2 teaser for Art. 21 (2e) and the
  container list of a deployment (three worker pools, plus Flower, registry,
  APT cache and the Signal gateway).
- Demo tooling hardened on the real dump: secrets inside JSON (Wi-Fi keys),
  reverse DNS zones, glued identifiers, tens of thousands of CrowdSec
  addresses, a schema newer than the release (anonymize, then downgrade),
  MFA-enforcing roles, and click steps for view filters.
- DESIGN.md: real screenshots only. PAGES.md: the six rows as they are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 08:24:51 +02:00
Christian ManivongandClaude Opus 5.5 38834100d1 feat(screenshots): real netOrk screenshots from an anonymized demo copy
The site has shown hand-built JSX mockups of the UI so far. This adds the
tooling to replace them with screenshots of the real application:

- scripts/demo/up.sh restores a pg_dump of a production database into a
  local Postgres and starts netOrk (a pinned release, default v0.28.0) with
  only the API and the UI: no worker, no beat, no Redis, a random encryption
  key. Nothing polls and nothing can reach a device.
- scripts/demo/anonymize.py rewrites every text, JSON and address column of
  every table: domains to example.demo, private IPv4 per /16 with the host
  part kept, public addresses into the documentation ranges, MACs with the
  vendor prefix kept, e-mail addresses and configured names. Secrets are
  emptied by column name, one admin "netork" is left. It refuses non-local
  databases and ends with a leak report. The real-to-demo name map lives
  outside the repo.
- scripts/screenshots/capture.py drives headless Chromium through a
  declarative list of pages, logs in to the demo copy by itself, and aborts
  every non-GET API request, so taking screenshots cannot change anything.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 07:33:18 +02:00
Christian ManivongandClaude Opus 5 c40fa97cd1 feat(ci): publish to Gitea's registry, and stop deploying to a random host
CI / TypeScript — type-check (pull_request) Successful in 10s
CI / Publish — build & push image (pull_request) Skipped
CI / TypeScript — type-check (push) Successful in 9m48s
CI / Publish — build & push image (push) Skipped
The image moves off registry.netork.io. That registry is plain registry:2 with
htpasswd auth, which knows nothing about repositories: every account that can log
in reads and writes everything on it, including the accounts issued to customer
instances. Verified -- a customer server's credentials list the whole catalogue.
It keeps the images those instances are meant to pull; the marketing site is not
one of them. Gitea scopes packages to their owning account, and no customer has
one. netOrk #172.

Login uses a REGISTRY_TOKEN secret (a Gitea token with write:package). The token
Actions injects per run does not work here -- the package registry rejects it
with a bare "unauthorized", which is a confusing way to spend an afternoon.

The deploy job is removed rather than migrated, because it had quietly stopped
being correct. It ran `docker run` against whatever runner picked the job up,
which worked while exactly one runner existed. There are now several --
netork-runner-12 on .12, netork-runner-13 on .13, plus the original
netork-runner -- and none of them is on 10.7.224.11, where this site runs and
where the proxy-net it attaches to lives. The next push would have started a
second website container on the wrong host and reported success while netork.io
went on serving the old one. Nothing had failed yet; the last deploy was
2026-07-17, back when the pool was one runner.

scripts/deploy.sh replaces it: it names the target, pulls before it removes
anything, compares the running container's image id against what was pulled, and
finishes by checking that netork.io actually answers 200.

Push-to-deploy can come back by registering a runner on .11 with a label of its
own and pinning `runs-on:` to it, or by giving CI an ssh key. Both decide where a
credential lives, so neither was decided here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 23:41:10 +02:00