[PR #8731] fix(username): enforce username uniqueness in updateUser #16423

Closed
opened 2026-04-13 10:31:04 -05:00 by GiteaMirror · 0 comments
Owner

Original Pull Request: https://github.com/better-auth/better-auth/pull/8731

State: closed
Merged: Yes


closes #8689

updateUser didn't actually enforce username uniqueness, so users could set usernames already taken by others.

the before hook had a uniqueness check but it was dead code because ctx.context.session is always null in before hooks.

fixed by resolving the session via getSessionFromCtx() instead. also normalized the username before the db lookup to match what isUsernameAvailable does, which prevents case-different duplicates from slipping through.

also fixed an existing test that was passing for the wrong reason. it used "duplicate-username" which has a hyphen that fails the validator, so it was testing format validation, not uniqueness.


Summary by cubic

Enforces username uniqueness across sign-up and update with case-insensitive checks and correct session handling. Conflicts now return 400 and only allow the current user to keep their own username.

  • Bug Fixes
    • Use getSessionFromCtx() in /update-user to verify the requester before allowing a duplicate.
    • Normalize the username once before the DB lookup to prevent case-only duplicates and avoid double-normalization.
    • Block duplicates on /sign-up/email and /update-user with 400; update tests to use valid duplicate usernames and add a case-variant check.

Written for commit 583fa27053. Summary will update on new commits.

**Original Pull Request:** https://github.com/better-auth/better-auth/pull/8731 **State:** closed **Merged:** Yes --- closes #8689 `updateUser` didn't actually enforce username uniqueness, so users could set usernames already taken by others. the before hook had a uniqueness check but it was dead code because `ctx.context.session` is always `null` in before hooks. fixed by resolving the session via `getSessionFromCtx()` instead. also normalized the username before the db lookup to match what `isUsernameAvailable` does, which prevents case-different duplicates from slipping through. also fixed an existing test that was passing for the wrong reason. it used `"duplicate-username"` which has a hyphen that fails the validator, so it was testing format validation, not uniqueness. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Enforces username uniqueness across sign-up and update with case-insensitive checks and correct session handling. Conflicts now return 400 and only allow the current user to keep their own username. - **Bug Fixes** - Use `getSessionFromCtx()` in `/update-user` to verify the requester before allowing a duplicate. - Normalize the username once before the DB lookup to prevent case-only duplicates and avoid double-normalization. - Block duplicates on `/sign-up/email` and `/update-user` with 400; update tests to use valid duplicate usernames and add a case-variant check. <sup>Written for commit 583fa270530ef6fd6bcda32e919d4fc4de2a64c9. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. -->
GiteaMirror added the pull-request label 2026-04-13 10:31:04 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#16423