fix(auth): Google adoption revokes the password of a never-activated account
Without SMTP, registration marks the address verified with no proof, and an ADMIN_EMAILS / ALLOWED_EMAILS address gets no invite row to gate it. So a stranger who registered such an address (or a sibling spelling) before its owner kept their own password when the owner's first Google sign-in adopted the row, activated it and made it admin, and could then sign in with it. The adoption now treats a never-activated row like an unverified one: the password goes, password_revoked_at is stamped and the session epoch bumped. An account already let in keeps its password. The helper is renamed to say what it now judges (revoke_untrusted_preset_password). test_google_callback.py drives the callback's account-matching branches through the real route, none of which a test ran before: the squat (red on the old rule), adoption by mailbox, the sub-collision and unverified-address refusals, the refused sign-in recorded in Google's locale, and the link flow's conflict, mismatch and attach answers.
This commit is contained in:
@@ -151,7 +151,7 @@ def _activate_user_by_email(db: Session, email: str) -> None:
|
||||
attacker can always register last — and it handed anonymous callers a write onto a real
|
||||
account's credential. The owner's recourse is password-reset, which proves the mailbox, rewrites
|
||||
the hash and bumps the session epoch. The residual is logged as SEC-16. The revoke also stays on
|
||||
the Google-adoption path (auth.revoke_preset_password_if_unverified), where ownership is
|
||||
the Google-adoption path (auth.revoke_untrusted_preset_password), where ownership is
|
||||
actually attested."""
|
||||
# Canonical, with the literal spelling preferred when both exist: approving
|
||||
# `npeter83.temu@gmail.com` must activate the account that registered as `npeter83temu@gmail.com`,
|
||||
|
||||
Reference in New Issue
Block a user