Innebygd innlogging (AUTH_MODE=app) med neon-login og proxy-bypass
Valgfri app-auth ved siden av proxy-modus (default uendret). Signert sesjons-cookie (scrypt-passord, HMAC, ingen avhengigheter), gating av API + WebSocket, og en selvstendig neon-login (public/login.html) for uautentiserte. Trusted bypass: en proxy-identitet (X-Remote-User / Basic Auth) regnes som innlogget uten app-passord (TRUST_PROXY_HEADER, default på), så man kan bootstrappe: logg inn via NPM Basic Auth → sett app-passord i konto-modalen → skru av Basic Auth. Konto-UI for sett/endre passord + logg ut. AUTH_MODE leses per createServer-instans (testbart). 34 integrasjonstester (8 nye for app-auth), alle grønne. README/CLAUDE.md/setup-skript oppdatert. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7287f33e47
commit
f6268440d9
9 changed files with 711 additions and 42 deletions
|
|
@ -29,13 +29,20 @@ npm test
|
|||
|---|---|---|
|
||||
| `PORT` | `3000` | HTTP-port |
|
||||
| `HOST` | `0.0.0.0` | Lytteadresse |
|
||||
| `DATA_DIR` | `./data` | Katalog for tasks.json / activity.json / users.json |
|
||||
| `DISABLE_COOKIE_AUTH` | (av) | Sett til `1` for å skru av selvvalgt navn via cookie — da gjelder kun proxy-headere |
|
||||
| `DATA_DIR` | `./data` | Datakatalog (tasks/activity/users/plans/categories/auth) |
|
||||
| `AUTH_MODE` | `proxy` | `proxy` = stol på proxy-header/Basic Auth. `app` = innebygd innlogging (sesjons-cookie + passord) |
|
||||
| `TRUST_PROXY_HEADER` | `1` | I app-modus: la en proxy-identitet (X-Remote-User / Basic) slippe inn uten app-passord (for bootstrapping). Sett `0` for å slå av |
|
||||
| `SESSION_TTL_DAYS` | `30` | Levetid på app-sesjons-cookien |
|
||||
| `AUTH_SECRET` | (auto) | HMAC-nøkkel for sesjons-cookies. Settes ikke den, genereres og lagres i `data/auth.secret` |
|
||||
| `DISABLE_COOKIE_AUTH` | (av) | Proxy-modus: `1` skrur av selvvalgt navn via cookie — da gjelder kun proxy-headere |
|
||||
|
||||
## Autentisering
|
||||
|
||||
Påloggingslogikk er bevisst holdt utenfor appen. Brukernavn hentes fra,
|
||||
i prioritert rekkefølge:
|
||||
To modi, styrt av `AUTH_MODE`.
|
||||
|
||||
### `proxy` (default) — auth utenfor appen
|
||||
|
||||
Brukernavn hentes, i prioritert rekkefølge:
|
||||
|
||||
1. `X-Remote-User`-header — satt av reverse proxy (oauth2-proxy, Authelia, …)
|
||||
2. `Authorization: Basic` — Basic Auth terminert i proxy, brukernavnet gjenbrukes
|
||||
|
|
@ -44,6 +51,29 @@ i prioritert rekkefølge:
|
|||
|
||||
For team-bruk bak proxy: sett `DISABLE_COOKIE_AUTH=1` så ingen kan velge navn selv.
|
||||
|
||||
### `app` — innebygd innlogging
|
||||
|
||||
Egen neon-login (`/login`) med passord. Sesjon er en signert, langlevd cookie
|
||||
(`SESSION_TTL_DAYS`, default 30) — ingen repeterte Basic Auth-prompts, og virker
|
||||
sømløst med WebSocket. Passord hashes med scrypt (Node-kjerne, ingen
|
||||
avhengigheter), lagret i `data/auth.json`.
|
||||
|
||||
**Trusted bypass / migrering fra Basic Auth:** Når `TRUST_PROXY_HEADER=1`
|
||||
(default) regnes en proxy-identitet (X-Remote-User eller Basic Auth) som
|
||||
innlogget, *selv uten app-passord*. Det gir en trygg overgang:
|
||||
|
||||
1. Behold NPM Access List (Basic Auth) og deploy med `AUTH_MODE=app`.
|
||||
2. Åpne appen (du slipper inn via Basic Auth-bypass), klikk brukernavnet ditt
|
||||
oppe til høyre → **sett et app-passord**. Gjenta for hver kollega.
|
||||
3. Fjern NPM Access List. Nå møtes alle av neon-login og logger inn med passordet.
|
||||
|
||||
> Bypass krever at app-porten kun er nåbar fra proxyen (samme antakelse som
|
||||
> proxy-modus). Vil du være streng, sett `TRUST_PROXY_HEADER=0` etter at alle
|
||||
> har satt passord — da gjelder kun app-sesjoner.
|
||||
|
||||
Oppsett som tjeneste: legg `Environment=AUTH_MODE=app` i systemd-enheten (se
|
||||
under), eller kjør skriptet med `AUTH_MODE=app bash setup-debian13.sh`.
|
||||
|
||||
## Rask installasjon på Debian 13 (LXC/VM)
|
||||
|
||||
```bash
|
||||
|
|
@ -74,11 +104,15 @@ frontend bruker absolutte stier, så sti-prefiks (`proxy.lan/todo/`) fungerer ik
|
|||
- *Block Common Exploits:* valgfritt, fungerer fint sammen med appen
|
||||
2. **SSL-fanen:** *Request a new SSL Certificate* (Let's Encrypt) + *Force SSL*.
|
||||
Frontend bytter selv til `wss:` når siden er https.
|
||||
3. **Auth (valgfritt):** *Access Lists* → lag liste med brukere (Basic Auth) og
|
||||
knytt den til proxy-hosten. NPM/nginx sender `Authorization`-headeren videre,
|
||||
og appen bruker brukernavnet derfra — da får hver kollega riktig attribusjon.
|
||||
Sett i så fall `DISABLE_COOKIE_AUTH=1` på tjenesten. Uten access list velger
|
||||
folk navn selv i UI-et (cookie).
|
||||
3. **Auth — to alternativer:**
|
||||
- *Innebygd app-innlogging (anbefalt — slipper repeterte Basic Auth-prompts):*
|
||||
kjør tjenesten med `AUTH_MODE=app`. Bruk gjerne NPM Access List midlertidig
|
||||
for å bootstrappe (se «app»-seksjonen over), og fjern den når alle har satt
|
||||
passord. Da trenger ikke NPM Access List i det hele tatt.
|
||||
- *Proxy Basic Auth:* *Access Lists* → lag brukere og knytt til proxy-hosten.
|
||||
NPM sender `Authorization`-headeren videre og appen bruker brukernavnet
|
||||
derfra. Sett `DISABLE_COOKIE_AUTH=1`. (Ulempe: nettleseren spør om passord
|
||||
på nytt ved hver ny økt — derav app-innlogging som alternativ.)
|
||||
|
||||
**nginx:**
|
||||
|
||||
|
|
@ -122,7 +156,9 @@ Environment=PORT=3000
|
|||
# container/host: fjern linjen (lytt på alt) og brannmur port 3000 til kun proxyen.
|
||||
Environment=HOST=127.0.0.1
|
||||
Environment=DATA_DIR=/var/lib/netops-todo
|
||||
Environment=DISABLE_COOKIE_AUTH=1
|
||||
# Innebygd innlogging (anbefalt). Bytt til proxy-modus ved å fjerne denne
|
||||
# og evt. sette DISABLE_COOKIE_AUTH=1.
|
||||
Environment=AUTH_MODE=app
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
|
|
@ -166,7 +202,11 @@ optimistisk låsing — send med ved update, få 409 hvis noen andre har lagret.
|
|||
|
||||
| Metode | Endepunkt | Beskrivelse |
|
||||
|---|---|---|
|
||||
| GET | `/api/state` | Bruker, oppgaver, aktivitet, kjente brukere, online, kategorier, dagens plan, planIndex |
|
||||
| GET | `/api/state` | Bruker, auth-status, oppgaver, aktivitet, kjente brukere, online, kategorier, dagens plan, planIndex |
|
||||
| GET | `/api/auth/status` | Auth-modus, innlogget?, bruker, via, har passord |
|
||||
| POST | `/api/auth/login` | App-innlogging `{ user, password }` → sesjons-cookie |
|
||||
| POST | `/api/auth/logout` | Tøm sesjons-cookie |
|
||||
| POST | `/api/auth/password` | Sett/endre eget passord `{ password, current? }` |
|
||||
| POST | `/api/tasks` | Opprett oppgave (`title` påkrevd) |
|
||||
| PUT | `/api/tasks/:id` | Oppdater (delvis OK; send `v` for konfliktsjekk; valgfri `comment` festes som status-kommentar) |
|
||||
| DELETE | `/api/tasks/:id` | Slett |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue