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:
parent
62f46de301
commit
8f5e26d2ee
9 changed files with 398 additions and 6 deletions
|
|
@ -92,6 +92,28 @@ def send_admin_new_request(admins: list[str], requester: str) -> bool:
|
|||
return _send(admins, f"Siftlode access request from {requester}", body, reply_to=requester)
|
||||
|
||||
|
||||
def send_verify_email(to: str, link: str) -> bool:
|
||||
body = (
|
||||
"Hi,\n\n"
|
||||
"Confirm your email to finish creating your Siftlode account:\n\n"
|
||||
f"{link}\n\n"
|
||||
"If you didn't sign up, you can ignore this message.\n\n"
|
||||
"— Siftlode"
|
||||
)
|
||||
return _send([to], "Confirm your Siftlode email", body)
|
||||
|
||||
|
||||
def send_password_reset(to: str, link: str) -> bool:
|
||||
body = (
|
||||
"Hi,\n\n"
|
||||
"Use this link to set a new Siftlode password (it expires in an hour):\n\n"
|
||||
f"{link}\n\n"
|
||||
"If you didn't request this, you can ignore this message — your password is unchanged.\n\n"
|
||||
"— Siftlode"
|
||||
)
|
||||
return _send([to], "Reset your Siftlode password", body)
|
||||
|
||||
|
||||
def send_test(to: str) -> bool:
|
||||
body = (
|
||||
"This is a test email from Siftlode.\n\n"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue