Skip to content

[pull] master from Ehco1996:master#313

Merged
pull[bot] merged 1 commit into
Kiterepo:masterfrom
Ehco1996:master
May 2, 2026
Merged

[pull] master from Ehco1996:master#313
pull[bot] merged 1 commit into
Kiterepo:masterfrom
Ehco1996:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 2, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

* web: cookie sessions + bearer-header machine auth, drop dual gate

Replace the KeyAuth(?token=) + BasicAuth dual middleware with a single
auth path: cookie session for browsers, Authorization: Bearer (or the
X-Ehco-Token header) for non-browser callers.

Why:
- ?token= leaks creds into URLs, server access logs, browser history,
  and screenshots.
- Authorization: Basic can't be set by JS on WebSocket upgrades, so
  /ws/logs was dead under BasicAuth-only deployments. Cookies ride
  WS upgrades natively, killing the ticket workaround we'd been
  about to bolt on.
- Native BasicAuth dialog can't be dismissed from JS — already
  replaced with a custom middleware in 52a5276; this commit finishes
  the job by removing both middlewares entirely.

Config:
- Add Config.DashboardPass and Config.ApiToken as the new structured
  fields. Keep WebToken / WebAuthPass / WebAuthUser as legacy
  compatibility aliases that Adjust() folds onto the new fields when
  the new ones are empty. This lets a node pick up a config served
  by an old mizhiwu (still emitting web_auth_pass / web_token)
  without code changes on either side.
- GetMetricURL() drops creds from the URL entirely; the local pullers
  (metric_reader, bandwidth_recorder) now attach Authorization:
  Bearer <ApiToken> as a header. Plumbed via cmgr.Config.ApiToken
  and the NewUserPool / NewBandwidthRecorder / NewReader signatures.

Auth flow:
- POST /api/v1/auth/login takes {password}, validates against
  cfg.DashboardPass, issues a 7d sliding-TTL session, sets
  ehco_sid=<sid>; HttpOnly; SameSite=Strict; Path=/; Secure
  (Secure is conditional on the request being TLS — most ehco
  deployments are plain HTTP on tailnet today).
- POST /api/v1/auth/logout revokes server-side and clears the cookie.
- GET /api/v1/auth/info reports {auth_required, authenticated} so
  the SPA can boot directly to the dashboard when a cookie is
  already valid.
- Sessions are an in-memory map (sid → expiry); restarts force a
  re-login, which is acceptable at this fleet size and saves us a
  persistence layer.

Tests cover: auth-disabled passthrough, anonymous reject, cookie
session accept, bearer-header accept, X-Ehco-Token accept, wrong
bearer reject, /auth/info public probe, sliding TTL, session revoke,
and legacy field folding in Config.Adjust.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* webui: cookie-based auth, drop ?token= and Basic header

The dashboard now relies on the server's session cookie set by
POST /api/v1/auth/login. The browser owns auth state via the cookie;
the SPA stops trying to attach Authorization headers or rewrite URLs
on every fetch.

- store/auth.ts: state machine simplifies to {auth_required,
  authenticated} from /auth/info. signIn POSTs the password,
  signOut POSTs /auth/logout. No more sessionStorage of creds —
  the cookie is the only source of truth.
- api/client.ts: drop withAuth + cookie-via-creds rewriting; use
  credentials: "same-origin" so the browser sends the cookie.
- LoginGate.tsx: collapses to a single password field. The old
  token / basic dual UI no longer maps to anything on the server.
- Layout.tsx: authConfigured() now keys off auth_required.
- Settings.tsx: surfaces "session (cookie / bearer)" instead of
  the basic+token combinatoric.
- types.ts: name dashboard_pass / api_token explicitly so the
  EhcoConfig catch-all doesn't hide them.

WS auth comes free: /ws/logs upgrade requests carry the cookie
natively, killing the JS-can't-set-Authorization-on-WS problem
that had us about to bolt on a ticket store.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* config: drop legacy WebToken / WebAuth* fields and Adjust folding

mizhiwu now emits dashboard_pass / api_token natively (no more
web_auth_pass / web_token mirror keys), so the legacy compat shim
in Config and Adjust() is dead weight. Remove the three legacy
struct fields and the folding step.

The CLI flag --web_token / EHCO_WEB_TOKEN is replaced by
--dashboard_pass / --api_token (env EHCO_DASHBOARD_PASS,
EHCO_API_TOKEN), matching the new structured naming. The single
"web token" concept that conflated browser auth with machine auth
is gone — they're separate fields with different consumers.

Drop TestLegacyConfigFolding accordingly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@pull pull Bot locked and limited conversation to collaborators May 2, 2026
@pull pull Bot added the ⤵️ pull label May 2, 2026
@pull pull Bot merged commit 3d597b3 into Kiterepo:master May 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant