Skip to content

fix(auth): prevent duplicate identity email collisions during OAuth a…#2597

Open
Aqeedkalburgi wants to merge 1 commit into
supabase:masterfrom
Aqeedkalburgi:fix/apple-relay-email-conflict
Open

fix(auth): prevent duplicate identity email collisions during OAuth a…#2597
Aqeedkalburgi wants to merge 1 commit into
supabase:masterfrom
Aqeedkalburgi:fix/apple-relay-email-conflict

Conversation

@Aqeedkalburgi

Copy link
Copy Markdown

What kind of change does this PR introduce?

Bug fix

What is the current behavior?

When an existing OAuth identity (e.g. Apple Sign In with a private relay email *@privaterelay.appleid.com) receives a new primary email (e.g. user@gmail.com) on a subsequent login, the system attempts to update the identity's email metadata.

If another user already owns that primary email address, this update creates duplicate email mappings in auth.identities across different users. Future login attempts then fail with:
500: Multiple accounts with the same email address detected

Fixes #43895

What is the new behavior?

Before updating an existing identity's email metadata, the system checks whether the incoming email would collide with another user account (using models.IsDuplicatedEmail).

If a collision is detected, the update is prevented, and the existing identity email metadata (e.g. the private relay email) is safely preserved. This prevents duplicate identity mappings while allowing standard account-linking when no collision exists.

Additional context

Safety & Security

  • No Automatic Account Merging: Avoids account takeover risks by keeping the accounts isolated.
  • Provider-Agnostic: The fix is implemented in the generic OAuth identity handler (createAccountFromExternalIdentity), ensuring security for all OAuth flows.
  • Backward Compatibility: No schema changes or API contract updates.

Regression Tests Added

Integration tests are added to internal/api/external_apple_test.go:

  • TestAppleRelayNoConflict: Verifies email update when no duplicate user exists.
  • TestAppleRelayEmailConflict: Verifies collision prevention and database consistency when a duplicate user exists with the primary email.
  • TestAppleRepeatedLogins: Verifies idempotence over repeated login flows.
  • TestGoogleAndAppleCoexistence: Assures Google and Apple identities coexist harmoniously without collisions.

@Aqeedkalburgi Aqeedkalburgi requested a review from a team as a code owner June 25, 2026 21:07

@Aqeedkalburgi Aqeedkalburgi left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This conditional preserves the existing identity email only when updating it would create a duplicate mapping with another user account.

By retaining the current value in identityData["email"] when IsDuplicatedEmail detects a conflict, the change prevents inconsistent auth.identities state and avoids the Multiple accounts with the same email address detected error without performing any automatic account merging.

If no duplicate is found, the existing email synchronization behavior remains unchanged.

@Aqeedkalburgi Aqeedkalburgi left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking the time to review this PR.

This change addresses an edge case where updating an existing OAuth identity's email metadata could create duplicate mappings across different users, resulting in Multiple accounts with the same email address detected errors during account resolution.

The implementation performs a duplicate-email check before updating identity metadata. If applying the new email would create a collision with another user, the existing identity email is preserved; otherwise, the normal synchronization behavior is unchanged.

I've also added integration tests covering both collision and non-collision scenarios, repeated logins, identity-linking behavior, and coexistence across multiple authentication providers to help prevent regressions.

I'm happy to make further changes or discuss alternative approaches if the maintainers think a different design would better fit the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants