feat: multi-user authentication (dual mode) #4

Merged
Pakobbix merged 1 commits from feat/multi-user-auth into main 2026-09-02 13:47:27 +00:00
Collaborator

Adds optional login protection for the web UI/API, intended for shared machines (e.g. an AI server).

Dual mode

  • No users configured → API and web UI are open, exactly as before.
  • ≥1 user configured → every /api/* and /ws/* endpoint requires a valid session; the web UI shows a sign-in screen first.

Switches instantly when the first user is added / last user removed (no restart).

Security

  • bcrypt password hashing — stored as $2b$ hashes in /etc/nvcurve/users.json (mode 0600, root-owned). Plaintext is never persisted; login compares the plaintext against the hash.
  • 24-hour sessions — HttpOnly cookie for browsers, Authorization: Bearer token for CLI/scripts. In-memory, invalidated on server restart.
  • Multi-user — multiple named accounts (no shared-password mode).
  • Brute-force lockout — 10 failed logins from an IP within 5 min → 15-min lockout.
  • Password is always prompted via getpass (never a CLI argument, so it never appears in the process list or sudo logs).

New CLI

sudo nvcurve user add alice      # add a user (prompts for password)
nvcurve user list                # list users
sudo nvcurve user set-password alice
sudo nvcurve user remove alice

New endpoints

GET /api/ping (public), GET /api/auth/status, POST /api/auth/login, POST /api/auth/logout, GET /api/auth/users.

Web UI

Sign-in screen when auth is enabled; status bar shows the signed-in user with a sign-out button; expired sessions (401) re-show the sign-in screen.

Testing

Verified with FastAPI TestClient: no-auth mode, auth-required mode, cookie + Bearer login, wrong-password 401, 24-h expiry, multi-user, logout, invalid-token 401, and the >72-byte-password edge (returns 401, not 500). Frontend builds cleanly (tsc -b + vite).

Notes

  • New dependency: bcrypt.
  • NvCurveClient.ping() now hits the public /api/ping so liveness checks work unauthenticated.
  • Existing HTTP API consumers will get 401 once a user is added (intended dual-mode behavior).
  • Added pyrightconfig.json pointing the LSP at the project .venv.
Adds optional login protection for the web UI/API, intended for shared machines (e.g. an AI server). ## Dual mode - **No users configured** → API and web UI are open, exactly as before. - **≥1 user configured** → every `/api/*` and `/ws/*` endpoint requires a valid session; the web UI shows a sign-in screen first. Switches instantly when the first user is added / last user removed (no restart). ## Security - **bcrypt** password hashing — stored as `$2b$` hashes in `/etc/nvcurve/users.json` (mode `0600`, root-owned). Plaintext is never persisted; login compares the plaintext against the hash. - **24-hour sessions** — HttpOnly cookie for browsers, `Authorization: Bearer` token for CLI/scripts. In-memory, invalidated on server restart. - **Multi-user** — multiple named accounts (no shared-password mode). - **Brute-force lockout** — 10 failed logins from an IP within 5 min → 15-min lockout. - Password is always **prompted** via `getpass` (never a CLI argument, so it never appears in the process list or sudo logs). ## New CLI ```bash sudo nvcurve user add alice # add a user (prompts for password) nvcurve user list # list users sudo nvcurve user set-password alice sudo nvcurve user remove alice ``` ## New endpoints `GET /api/ping` (public), `GET /api/auth/status`, `POST /api/auth/login`, `POST /api/auth/logout`, `GET /api/auth/users`. ## Web UI Sign-in screen when auth is enabled; status bar shows the signed-in user with a sign-out button; expired sessions (401) re-show the sign-in screen. ## Testing Verified with FastAPI `TestClient`: no-auth mode, auth-required mode, cookie + Bearer login, wrong-password 401, 24-h expiry, multi-user, logout, invalid-token 401, and the >72-byte-password edge (returns 401, not 500). Frontend builds cleanly (`tsc -b` + vite). ## Notes - New dependency: `bcrypt`. - `NvCurveClient.ping()` now hits the public `/api/ping` so liveness checks work unauthenticated. - Existing HTTP API consumers will get 401 once a user is added (intended dual-mode behavior). - Added `pyrightconfig.json` pointing the LSP at the project `.venv`.
ARIA added 1 commit 2026-09-02 13:22:01 +00:00
Add optional login protection for the web UI/API, intended for shared
machines (e.g. AI servers). Dual mode: with no users configured the API
and web UI are open (as before); once at least one user exists, every
/api/* and /ws/* endpoint requires a valid session.

- bcrypt password hashing: passwords stored as $2b$ hashes in
  /etc/nvcurve/users.json (0600, root-owned); plaintext never persisted.
- 24-hour sessions: HttpOnly cookie for browsers, Authorization: Bearer
  token for CLI/scripts; in-memory, invalidated on server restart.
- Multi-user: multiple named accounts (no shared-password mode).
- New CLI: nvcurve user add|list|remove|set-password (root for mutating
  ops; password always prompted, never a CLI argument).
- New endpoints: GET /api/ping (public), /api/auth/status|login|logout|users.
- Web UI: sign-in screen when auth is enabled; status bar shows the
  signed-in user with sign-out; expired sessions (401) re-show sign-in.
- Brute-force lockout: 10 failed logins/IP within 5 min -> 15 min lockout.
- New dependency: bcrypt.

Also: LSP config (pyrightconfig.json) pointing at the project .venv, and
small error-handling cleanups in daemon.py/server.py.
Collaborator

Review

✅ No issues found — changes look consistent with the stated intent. Ready to be merged.

## Review ✅ No issues found — changes look consistent with the stated intent. Ready to be merged.
Pakobbix merged commit 3c55263250 into main 2026-09-02 13:47:27 +00:00
Pakobbix deleted branch feat/multi-user-auth 2026-09-02 13:47:27 +00:00
Sign in to join this conversation.