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:
Jon Vanvik 2026-06-15 14:27:13 +02:00
parent 7287f33e47
commit f6268440d9
9 changed files with 711 additions and 42 deletions

View file

@ -326,6 +326,36 @@
</div>
</div>
<div class="modal-overlay" id="account-modal">
<div class="modal" style="max-width:440px">
<div class="modal-head">
<h2>Konto</h2>
<button class="icon-btn" id="account-close" style="font-size:18px">×</button>
</div>
<div class="modal-warning" id="account-status"></div>
<div class="modal-body" style="grid-template-columns:1fr">
<div class="form-field full" id="account-current-field" style="display:none">
<label>Nåværende passord</label>
<input type="password" id="account-current" autocomplete="current-password">
</div>
<div class="form-field full">
<label id="account-pw-label">Nytt passord</label>
<input type="password" id="account-newpw" autocomplete="new-password" placeholder="minst 6 tegn">
</div>
<div class="form-field full">
<label>Bekreft passord</label>
<input type="password" id="account-newpw2" autocomplete="new-password">
</div>
</div>
<div class="modal-foot">
<button class="danger" id="account-logout">Logg ut</button>
<div style="flex:1"></div>
<button id="account-cancel">Avbryt</button>
<button class="primary" id="account-save">Lagre passord</button>
</div>
</div>
</div>
<div class="toast-stack" id="toast-stack"></div>
<script src="app.js"></script>