Auth-herding: roller, kontoadmin, token-revokering + søkbar planliste + neon

Auth (app-modus):
- Roller admin/standard. Admin oppretter/sletter kontoer, resetter passord,
  endrer roller (konto-modal). Eksisterende brukere → admin ved migrering;
  bootstrap-bruker via proxy-bypass → admin. Siste admin vernet.
- Tilbakekalling via per-bruker epoke i tokenet: passordbytte, admin-reset,
  «Logg ut alle enheter» og sletting dreper alle aktive sesjoner. Token-format
  endret (3- → 4-delt) — alle logges ut én gang ved oppgradering.

Dagsplan: søkbar/velgbar planliste («📋 Planer») avledet fra planIndex —
finn plan på navn/dato/person uten å gjette dato.

GUI: login-neon trukket inn i hovedappen (header/knapper/KPI-kanter), og
login-siden fikk mer tech (HUD-hjørner, glitch-tittel, scanlines).

40 integrasjonstester (6 nye), alle grønne. README + CLAUDE.md oppdatert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jon Vanvik 2026-06-15 14:56:39 +02:00
parent f6268440d9
commit 3f69cd4248
9 changed files with 518 additions and 36 deletions

View file

@ -74,9 +74,18 @@ netops-todo-node/
proxy-innlogget; krever nåværende passord kun når man endrer via en app-sesjon.
- `resolveAuth` brukes både i HTTP-middleware og WS (`server.on('upgrade')` +
`wss.on('connection')`), så samme identitet/gating gjelder begge.
- Sesjon: signert cookie `b64url(user).exp.HMAC` (ingen server-side lager).
- Sesjon: signert cookie `b64url(user).exp.epoch.HMAC` (ingen server-side lager).
Hemmelighet fra `AUTH_SECRET` eller persistert `data/auth.secret`. Cookie er
HttpOnly, SameSite=Lax, Secure når `X-Forwarded-Proto: https`.
- **Roller + tilbakekalling:** hver bruker i auth.json har `role`
(admin/standard) og `epoch`. Tokenet bærer epoken; `verifyToken` avviser hvis
epoken ikke matcher brukerens nåværende (eller kontoen er slettet). `setPassword`,
admin-reset, `bumpEpoch()` («logg ut alle enheter») og sletting tilbakekaller
dermed alle aktive sesjoner. Migrering: eksisterende brukere → admin, epoch=1.
Ny bruker via proxy-bypass → admin (bootstrap). `isAdminReq()` i server.js
regner proxy-bypass uten konto som admin. Siste admin kan ikke slettes/degraderes.
- **Token-format endret** med herdingen (3- → 4-delt), så alle eksisterende
sesjoner blir ugyldige én gang ved oppgradering — brukerne logger inn på nytt.
### WebSocket-protokoll (server → klient)
@ -156,6 +165,11 @@ hardkodede `CATEGORIES`/`CAT_COLORS`.
muterer `state.plan.items` og kaller `savePlan()` (PUT) som reconciler mot
serverens validerte svar. Container-nivå drag-lyttere bindes én gang
(`bindPlanContainer`); per-element bindes ved hver render (`bindPlanDnD`).
- **Søkbar planliste** (`derivePlanList()`) bygges på klienten ved å gruppere
`state.planIndex` på (bruker, dato) — ingen eget endepunkt, holder seg i synk
via `plan`-WS-meldingene. «📋 Planer»-knappen åpner en søkbar dropdown.
- **Neon-aksenter** fra login-siden er trukket inn i hoved-GUI via en liten
blokk i style.css (header-glød, primærknapp, aktiv visning, KPI-kanter).
- **Kommentar-sletting er begrenset til egen bruker** (eneste
autorisasjonsregel i appen — alt annet er åpent for alle innloggede).
- Chart.js fra CDN; frontend degraderer pent (skjuler grafer) uten nett.
@ -193,14 +207,15 @@ strenglengde-klamping, brukernavn-regex `[A-Za-z0-9._@-]{1,64}`), pluss:
## Testing-status
- `npm test`: 34 integrasjonstester (node:test), booter ekte servere på
- `npm test`: 40 integrasjonstester (node:test), booter ekte servere på
tilfeldig port med temp-datakatalog (én i proxy-modus, én i app-modus). Dekker
normalisering, versjonskonflikt, kommentar-autorisasjon, statuskommentar,
dagsplan (CRUD, per-bruker, validering, scrub, dato-fallback, navn, flytt/merge,
deling + tilgang, planIndex per viewer), egendefinerte kategorier, aktivitetslogg,
WS-broadcast (delt vs. privat plan), persistens, cookie-auth, og app-auth
(401-guard, login-side på navigasjon, proxy-bypass, passord-bootstrap, sesjon,
feil passord, TRUST_PROXY_HEADER=0). Alle grønne per 2026-06-15 (Node 25).
(401-guard, login-side, proxy-bypass, passord-bootstrap, sesjon, feil passord,
TRUST_PROXY_HEADER=0, roller/admin-CRUD, epoke-tilbakekalling ved passordbytte/
reset/logout-all, vern av siste admin). Alle grønne per 2026-06-15 (Node 25).
- Manuell røyk-test over HTTP: kategori-opprettelse (auto-id + farge), navngitt
delt plan, annen brukers tilgang (delt 200 / privat 403), flytt med bevart
navn+delingsstatus, og planIndex verifisert.