Skip to content

feat(auth)!: emit USER_UPDATED for email and phone change verification#2446

Open
mandarini wants to merge 1 commit into
v3from
feat/auth-user-updated-on
Open

feat(auth)!: emit USER_UPDATED for email and phone change verification#2446
mandarini wants to merge 1 commit into
v3from
feat/auth-user-updated-on

Conversation

@mandarini

@mandarini mandarini commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Description

Aligns auth-js with the auth server's classification of email-change and phone-change verifications as user modifications rather than sign-ins. Subscribers to onAuthStateChange now receive USER_UPDATED for these flows instead of SIGNED_IN.

What changed?

  • All three event-emission sites in GoTrueClient now branch on email_change / phone_change and emit USER_UPDATED:
    • implicit-grant callback in _initialize (the setTimeout block following _getSessionFromURL)
    • _exchangeCodeForSession (PKCE)
    • verifyOtp
  • getCodeChallengeAndMethod signature changed from (storage, key, isPasswordRecovery?: boolean) to (storage, key, flowType?: 'recovery' | 'email_change'). The helper is internal and not re-exported.
  • updateUser({ email }) PKCE branch now tags the stored verifier with email_change so the post-redirect _exchangeCodeForSession step actually reaches the new branch. Without this, the PKCE-side fix would have been dead code (the server's PKCE redirect URL only carries code, not type).
  • The recovery PKCE branch now passes 'recovery' instead of true (semantically identical).
  • JSDoc on verifyOtp and onAuthStateChange documents the new event mapping.
  • New per-package migration note: packages/core/auth-js/migrations/email-phone-change-user-updated-event.md.

Why was this change needed?

The auth server (supabase/auth) records email- and phone-change verifications as UserModifiedAction in the audit log. Both emailChangeVerify and the phone_change branch of smsVerify write that action; neither is treated as a sign-in. Emitting SIGNED_IN on the client diverged from that semantics and produced spurious sign-in events on what is fundamentally a profile mutation. This change brings auth-js in line with the server and prepares parity with the other SDKs (Flutter/Dart, Swift, Kotlin, Python), which previously had to mirror the inaccurate auth-js behavior.

Breaking changes

Behavioral breaking change. No type or signature changes for the public API: both USER_UPDATED and SIGNED_IN are already members of AuthChangeEvent. Consumers running first-login work (analytics, redirects, welcome UI) inside their SIGNED_IN handler and relying on it firing after email or phone change will no longer receive that event for those flows. Migration guidance: handle the post-mutation case in USER_UPDATED instead. Full details in the new per-package migration note.

The internal getCodeChallengeAndMethod helper signature changed, but the helper is not re-exported from the package, so no external caller is affected.

Checklist

  • I have read the Contributing Guidelines
  • My PR title follows the conventional commit format: <type>(<scope>): <description>
  • I have run pnpm nx format to ensure consistent code formatting
  • I have added tests for new functionality (if applicable)
  • I have updated documentation (if applicable)

Additional notes

  • Targets the v3 branch as a breaking change.
  • New tests: parameterized test.each blocks covering verifyOtp (email_change, phone_change, recovery, magiclink) and exchangeCodeForSession (verifier tagged email_change, recovery, untagged). Seven new assertions in total against onAuthStateChange.
  • Cross-SDK parity follow-up: Flutter/Dart, Swift, Kotlin, and Python should adopt the same mapping once this lands.

@mandarini mandarini self-assigned this Jun 12, 2026
@mandarini mandarini marked this pull request as ready for review June 12, 2026 07:18
@mandarini mandarini requested review from a team as code owners June 12, 2026 07:18
@mandarini mandarini added the v3 Planned for v3 label Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v3 Planned for v3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant