Authentication — Implementation¶
How It Works¶
db/auth.pyprovides: bcrypt password check,UserSessioncreation,UserSessionvalidation/deletionapi/auth.pyexposes:POST /auth/login— validates credentials, createsUserSessionrow, setsmp_sessionhttponly cookie (30-day TTL)GET /auth/me— validates session token from cookiePOST /auth/logout— deletesUserSessionrow, clears cookie- React
AuthGuardinApp.tsxcallsGET /auth/meon every load; redirects to/loginif session missing or expired
Session Lifecycle¶
- Login → create
UserSessionrow + setmp_sessioncookie - Page load →
AuthGuardvalidates/auth/me→ session row checked for expiry - Expired sessions deleted on first access
- Logout → delete session row + clear cookie
Gotchas¶
- Cookie is
httponly; samesite=lax— not accessible from JavaScript; always sent with same-origin requests - New accounts:
is_active=Falseuntil admin approves; login returns 403 with "Account pending approval" - Session token:
secrets.token_urlsafe(32)— 43-character URL-safe base64 string - Cascade delete: deleting a
Userrow deletes all theirUserSessionrows andPortfolioSnapshotrows
Creating Users (CLI)¶
Use scripts/create_user.py for initial admin account setup (interactive, not via the API).