Skip to content

Email-uniqueness check runs after SaveChangesAsync, so a duplicate email still persists other account changes #2657

Description

@hahn-kev-bot

Problem

In UserMutations.UpdateUser (backend/LexBoxApi/GraphQL/UserMutations.cs), mutations are persisted before the email uniqueness check runs, so a duplicate email leaves other changes committed.

The current order is:

  1. Apply Name, Locale, and (for self-updates) OptedOutOfAnalytics to the tracked User.
  2. await dbContext.SaveChangesAsync(); — all changes are committed here (line ~235).
  3. Only after saving, if the email changed, check dbContext.Users.AnyAsync(u => u.Email == input.Email) and throw UniqueValueException("Email") if it's taken (line ~237-240).

Because the SaveChangesAsync at step 2 has already persisted the analytics preference (and name/locale), a UniqueValueException thrown at step 3 does not roll those changes back. The caller sees an error implying nothing was saved, but OptedOutOfAnalytics (and other fields) were in fact changed.

Expected behavior

A UniqueValueException (duplicate email) should leave the account entirely unchanged — neither the email update nor the analytics preference (nor name/locale) should be persisted.

Suggested fix

Either:

  • Reorder validation: perform the email-uniqueness query before SaveChangesAsync, so nothing is persisted when validation fails; or
  • Make it transactional: wrap the mutations + validation so a UniqueValueException rolls back all changes atomically.

Location

backend/LexBoxApi/GraphQL/UserMutations.cs, UpdateUser (self-update flow, around the SaveChangesAsync call near line 235 and the email check at lines 237-240).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    📦 Lexboxissues related to any server side code, fw-headless included

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions