feat(auth): email+password registration with two-gate activation (5a backend)

Add email+password auth alongside Google: argon2id hashing; users gains
password_hash/email_verified/is_active and google_sub becomes nullable (migration
0022); a single-use, hashed auth_tokens table for email verification + password
reset. Registration creates a pending (inactive, unverified) account + an access
request; sign-in needs verified email AND admin approval. Anti-enumeration: uniform
register/login/reset responses (a correct-password owner still gets a specific
pending reason). allow_registration flag (DB-tunable). Admin users-list + role
endpoint (guards: not self, not demo, not the last admin); approving access (or a
manual whitelist add) now activates the matching pending account. current_user
rejects deactivated accounts. Verified end-to-end via curl + DB.
This commit is contained in:
npeter83 2026-06-19 14:03:11 +02:00
parent 4fc7e1e7df
commit 7efd4f4867
9 changed files with 398 additions and 6 deletions

View file

@ -45,6 +45,10 @@ class Settings(BaseSettings):
allowed_emails: str = ""
admin_emails: str = ""
# Whether anyone may submit an email+password registration (still gated by email
# verification + admin approval before they can sign in). Admin-tunable via the DB.
allow_registration: bool = True
# Origin of a separately served frontend dev server (enables CORS). Empty in production.
frontend_origin: str = ""