4.3 KiB
4.3 KiB
SPEC — Users, Access Matrix, registration, sessions and security
Date: 2026-09-19
Status: hardened Users + Access Matrix; SMTP configurado e validado (2026-09-19).
Module: backend/app/modules/users · Admin UI /users · /users/access
Design references (not a framework swap)
Patterns adapted from production FastAPI auth libraries (kept in-house RBAC matrix):
- fastapi-fullauth — lockout, hashed reset tokens, email verification/reset, RBAC permissions, anti-enumeration
- AuthWarden — single-use reset tokens, OTP attempt limits, brute-force lockout
- OWASP Authentication / Session / Password-reset cheat sheets
RentCharge keeps its own SQLite models, cookie sessions and permissions-first Access Matrix (module.view.action).
Functional scope (both sides)
A — Self-service (/login, /signup, /reset-password, /account)
- Public registration with strong password + email OTP verification.
- Forgot-password → single-use email token (SHA-256 stored, 1 hour).
- Account profile, email verification, password change with strength meter.
- Forced password change when
must_change_passwordis set.
B — Admin Users + Access Matrix (/users, /users/access)
- Create staff logins with generated strong passwords (not shared starter defaults).
- Edit login (username, nickname, display name, recovery email).
- Set password (modal + strength meter) or email a reset token.
- Require password change on first login / after admin reset.
- Role assignment + full Role × Permission matrix with dirty-state and default-drift highlight.
- Sessions revoke + security activity audit.
Security controls
- Password rules are chosen by Admin under
/users/password-policy(not hard-coded). Presets: PIN 6+ digits · alphanumeric · strong · complex · custom toggles (uppercase / lowercase / digit / special / min length / block nick-email / block common). - Passwords: bcrypt cost 12; validation always follows the saved admin policy.
- Account lockout after 5 consecutive failed logins (15 minutes) + IP/identity rate limits.
- Reset tokens: 256-bit random, stored as SHA-256 only, single-use, invalidate previous tokens.
- Registration OTP: HMAC-SHA256, 10 min, max 5 attempts.
- Sessions: JWT + server-side session id; HttpOnly Secure SameSite=Strict cookie; idle + absolute timeouts.
- Logout / password change / reset / disable revoke sessions.
- Generic public responses to reduce account enumeration.
- Passwords and raw tokens never written to
auth_events.
New / updated API
| Method | Path | Purpose |
|---|---|---|
| GET | /api/auth/password-policy |
Policy hint for UIs |
| POST | /api/auth/password-strength |
Strength score helper |
| POST | /api/users/{id}/send-password-reset |
Admin emails recovery token |
| GET | /api/users/generate-password |
Cryptographically strong starter |
| PUT | /api/users/{id} |
Now accepts username (edit login) |
| POST | /api/users |
must_change_password, send_invite_email |
| POST | /api/users/{id}/set-password |
must_change_password flag |
Database (additive)
users columns:
must_change_passwordfailed_login_countlocked_until
Mail transport (VM500)
Validated 2026-09-19 — OTP verification and password-reset emails delivered.
| Setting | Value |
|---|---|
| Host | mail.myvexx.com |
| Port | 465 (SMTP SSL) |
| User | admin@myvexx.com |
| From | Rent & Charge <admin@myvexx.com> |
| Config | /home/mini/rentcharge/config/rentcharge.env (symlink /etc/rentcharge.env) |
| Also | Postfix on VM500 relays [mail.myvexx.com]:465 with SASL |
App flags: SMTP_SSL=true, SMTP_STARTTLS=false. Credentials stay only in env (never in Git).
E2E checks: POST /api/auth/forgot-password → HTTP 200; inbox received Rent & Charge password reset and Your Rent & Charge verification code.
Verification checklist
- Weak passwords rejected on register / change / admin set
- Generate strong password fills create form
- Edit login updates username + email
- Email reset from Users works when SMTP configured
- Forced change redirects to
/account - Access matrix dirty badge + amber default-drift cells
- Backend tests:
python -m unittest backend.tests.test_auth_users