feat: dedicated verify-before-apply email-change flow - #115
felixgateru wants to merge 8 commits into
Conversation
…ability so it matches the migration-seeded database contract Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
…ady hit the undeclared api_endpoint applicability error Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
… verified email-change flow Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
…confirm flow Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
…contracts Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
|
Re-reviewed PR #115 at
CI blocker: An extra blank line before the compatibility-test comment in Validation boundary: this re-review inspected the exact PR commits and confirmed that the email-change implementation is unchanged from the initial review. |
Problem
Fix
POST /auth/email/change/request— real session only (no access token, scoped or unscoped), rejects a session older thanATOM_EMAIL_CHANGE_MAX_SESSION_AGE_SECS(stand-in for step-up reauth), enumeration-resistant, mutates nothing — only mints a single-use tokenPOST /auth/email/change/confirm— unauthenticated (the token, provable only by receipt at the proposed mailbox, is the credential); locks the entity then the canonicalentity_emailsrow, fails safely (without consuming the token) if the email drifted since the request, atomically updates the canonical email + password credential identifier +attributes.emailmirror, invalidates stale tokens, revokes every session, notifies the old address with no secret in itentity.updateevent rather than a new event name (v1 event names are frozen)Security hardening
upsert_oauth_identity's auto-link lookup only locked theentitiesrow, notentity_emails— could commit a link keyed to an email being concurrently moved away, including against the existing admin sync path. Now locks both.Tests
Part of #110 (workstream A).