From 20afb0e5655308a045ecb1c8d54b2fa059b37ce6 Mon Sep 17 00:00:00 2001 From: "n.siegfried" Date: Thu, 25 Jun 2026 16:55:54 -0500 Subject: [PATCH] Add secure username/password login portal Gate the suite behind a self-contained login (no external IdP): - User model with bcrypt-hashed passwords; admin/user roles - /api/auth endpoints: login, logout, me, change-password, and admin-only user management (list/create/delete/reset/enable) - Stateless JWT session in an HttpOnly, SameSite=Lax, auto-Secure cookie; middleware refuses every /api data route without a session - login.html + auth-guard.js: login page and per-page guard with a top-right "name / Admin / Sign out" pill - Admin Console now gated on admin role (passphrase gate removed) with a User administration card - manage_users.py CLI to bootstrap the first admin - Rebuilt help.js into a searchable, multi-topic help center - Local-dev convenience: app serves html/ so the site + API share one origin under uvicorn (inactive in the prod container) - Docs/env: AUTH_SECRET_KEY, requirements (bcrypt, PyJWT), README Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 3 + docker-compose.yml | 3 + html/admin.html | 53 +++- html/admin.js | 160 +++++++++--- html/auth-guard.js | 90 +++++++ html/help.js | 484 +++++++++++++++++++++++++++++++---- html/index.html | 1 + html/login.html | 103 ++++++++ html/login.js | 59 +++++ html/work-package-suite.html | 1 + html/wp-creation-index.html | 1 + server/.env.example | 10 + server/README.md | 75 +++++- server/app.py | 168 +++++++++++- server/auth.py | 186 ++++++++++++++ server/manage_users.py | 144 +++++++++++ server/models.py | 26 ++ server/requirements.txt | 2 + 18 files changed, 1470 insertions(+), 99 deletions(-) create mode 100644 html/auth-guard.js create mode 100644 html/login.html create mode 100644 html/login.js create mode 100644 server/auth.py create mode 100644 server/manage_users.py diff --git a/.gitignore b/.gitignore index 0c5f277..7ddb774 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ wpsuite.db # Runtime directories (created by containers) logs/ + +# Local server logs +*.log diff --git a/docker-compose.yml b/docker-compose.yml index a5f0070..0d436ea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,6 +27,9 @@ services: POSTGRES_HOST: db # Optional full-URL override (must be URL-encoded if used). DATABASE_URL: ${DATABASE_URL:-} + # Signs login session cookies. MUST be set (see server/.env.example). + AUTH_SECRET_KEY: ${AUTH_SECRET_KEY} + AUTH_SESSION_HOURS: ${AUTH_SESSION_HOURS:-12} restart: unless-stopped depends_on: db: diff --git a/html/admin.html b/html/admin.html index ca8698d..9294b4f 100644 --- a/html/admin.html +++ b/html/admin.html @@ -4,6 +4,7 @@ Admin Console β€” Work Package Suite + - -
-
-

πŸ”’ Admin Console

-

Enter the admin passphrase to continue.

- -
- + + @@ -62,11 +73,9 @@