From 10d3272ddd9104ffcdec3131aee3c7e88ceecf21 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Wed, 13 May 2026 10:14:32 +0200 Subject: [PATCH] fix(auth+users): production-discovered bugs from live deploy on gk2 (ref #120) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usersctl: parents[3] indexing crashed when run from /usr/sbin/usersctl (production has only 2 parents). Wrapped path resolution in try/except so the script still works in-tree AND when installed. main.py: nginx strips /api/v1/auth/ prefix before forwarding to the auth socket, so the canonical external URL /api/v1/auth/login was being routed to FastAPI's /login — but _login_router was mounted under /auth, producing 404. Now mounted under BOTH '' (canonical) and /auth (legacy doubled-URL compat). Tests still pass under the /auth prefix. Live verified on https://admin.gk2.secubox.in: - empty password -> setup_token (200) - wrong password -> 401 "Aucun mot de passe local" - unknown user -> 401 "Identifiants incorrects" (same body, no enum) Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/secubox-auth/api/main.py | 4 ++++ packages/secubox-users/sbin/usersctl | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/secubox-auth/api/main.py b/packages/secubox-auth/api/main.py index 7f6ff9d4..ab3b4200 100644 --- a/packages/secubox-auth/api/main.py +++ b/packages/secubox-auth/api/main.py @@ -333,6 +333,10 @@ async def _set_password(req: _SetPasswordIn, request: _Request): # Mount v2 router FIRST so its /login overrides the legacy auth_router /login. # FastAPI uses the first matching route, so _login_router must come before auth_router. +# Mounted under both prefixes: "" for the canonical URL (/api/v1/auth/login after nginx +# strips the /api/v1/auth/ prefix) and "/auth" for the legacy doubled URL +# (/api/v1/auth/auth/login), so existing frontend code keeps working during the cutover. +app.include_router(_login_router, prefix="") app.include_router(_login_router, prefix="/auth") app.include_router(auth_router, prefix="/auth") router = APIRouter() diff --git a/packages/secubox-users/sbin/usersctl b/packages/secubox-users/sbin/usersctl index 5c7484f6..1eba5c0e 100755 --- a/packages/secubox-users/sbin/usersctl +++ b/packages/secubox-users/sbin/usersctl @@ -24,9 +24,20 @@ import sys from pathlib import Path # Ensure the engine import resolves whether we're installed (/usr/lib/...) or in-tree. +# In production, /usr/sbin/usersctl has only 2 parents; in-tree, parents[3] is the repo root. sys.path.insert(0, "/usr/lib/secubox/users") -sys.path.insert(0, str(Path(__file__).resolve().parents[1])) -sys.path.insert(0, str(Path(__file__).resolve().parents[3] / "common")) +_here = Path(__file__).resolve() +try: + sys.path.insert(0, str(_here.parents[1])) +except IndexError: + pass +try: + _common = _here.parents[3] / "common" + if _common.exists(): + sys.path.insert(0, str(_common)) +except IndexError: + pass +# Production: secubox_core installed as a site-package, importable directly. from api import engine, password_policy, totp, migrate_v1_to_v2 # noqa: E402