fix(auth): prevent duplicate identity email collisions during OAuth a…#2597
fix(auth): prevent duplicate identity email collisions during OAuth a…#2597Aqeedkalburgi wants to merge 1 commit into
Conversation
…ccount resolution
Aqeedkalburgi
left a comment
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
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.
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.identitiesacross different users. Future login attempts then fail with:500: Multiple accounts with the same email address detectedFixes #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
createAccountFromExternalIdentity), ensuring security for all OAuth flows.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.