[PR #8651] fix(email-otp): normalize email casing and whitespace across all endpoints #25021

Open
opened 2026-04-15 22:41:38 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/8651
Author: @Prakash21singh
Created: 3/17/2026
Status: 🔄 Open

Base: mainHead: fix/email-normalization


📝 Commits (3)

  • 59d9d30 fix(email-otp): normalize email with trim().toLowerCase() across all endpoints
  • 750c125 chore: fix line endings
  • 98f7f01 fix(email-otp): normalize email casing and whitespace at call sites

📊 Changes

3 files changed (+61 additions, -14 deletions)

View changed files

📝 packages/better-auth/src/plugins/email-otp/email-otp.test.ts (+47 -0)
📝 packages/better-auth/src/plugins/email-otp/index.ts (+1 -1)
📝 packages/better-auth/src/plugins/email-otp/routes.ts (+13 -13)

📄 Description

Fixes #8561

Problem

The email-otp plugin had inconsistent email normalization across its endpoints.
Some endpoints normalized ctx.body.email to lowercase before building the OTP
identifier and querying the user, while others used the raw input as-is.

This caused OTP verification failures when emails were submitted with different
casing or accidental whitespace between steps (e.g. requesting a password reset
with User@Example.com and resetting with user@example.com).

Changes

utils.ts

  • toOTPIdentifier() now applies .trim().toLowerCase() internally as a
    defensive guarantee — identifiers are always consistent regardless of caller

routes.ts

  • All endpoints now normalize email at the top of the handler with
    .trim().toLowerCase() before any downstream use (findUserByEmail,
    sendVerificationOTP, toOTPIdentifier, etc.)
  • Previously missing normalization in:
    • requestPasswordResetEmailOTP
    • forgetPasswordEmailOTP (deprecated)
    • resetPasswordEmailOTP
  • Previously missing .trim() in all other endpoints

Tests

Added tests to cover the newly fixed scenarios:

  • should reset password with mixed case email
  • should reset password with email containing spaces
  • should sign-in with email containing spaces

Summary by cubic

Normalize email casing and whitespace across all email-otp endpoints and call sites to prevent OTP mismatches during sign-in, verification, password reset, and email change; fixes #8561.

  • Bug Fixes

    • Apply .trim().toLowerCase() to email in all route handlers (body and query) and inside toOTPIdentifier(); also normalize response.user.email before OTP generation
    • Fill missing normalization in password reset endpoints; also normalize newEmail and session email in change-email flows
    • Add tests for mixed-case and spaced emails in sign-in and password reset flows
  • Refactors

    • Normalize line endings in modified files

Written for commit 98f7f01db5. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/8651 **Author:** [@Prakash21singh](https://github.com/Prakash21singh) **Created:** 3/17/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/email-normalization` --- ### 📝 Commits (3) - [`59d9d30`](https://github.com/better-auth/better-auth/commit/59d9d30e4df378502911607feabd485e0c588df0) fix(email-otp): normalize email with trim().toLowerCase() across all endpoints - [`750c125`](https://github.com/better-auth/better-auth/commit/750c12539c8707abbf0e9e63ac31672796f941b6) chore: fix line endings - [`98f7f01`](https://github.com/better-auth/better-auth/commit/98f7f01db500cb9594ad06557d40efb36aed88ad) fix(email-otp): normalize email casing and whitespace at call sites ### 📊 Changes **3 files changed** (+61 additions, -14 deletions) <details> <summary>View changed files</summary> 📝 `packages/better-auth/src/plugins/email-otp/email-otp.test.ts` (+47 -0) 📝 `packages/better-auth/src/plugins/email-otp/index.ts` (+1 -1) 📝 `packages/better-auth/src/plugins/email-otp/routes.ts` (+13 -13) </details> ### 📄 Description Fixes #8561 ## Problem The email-otp plugin had inconsistent email normalization across its endpoints. Some endpoints normalized `ctx.body.email` to lowercase before building the OTP identifier and querying the user, while others used the raw input as-is. This caused OTP verification failures when emails were submitted with different casing or accidental whitespace between steps (e.g. requesting a password reset with `User@Example.com` and resetting with `user@example.com`). ## Changes ### `utils.ts` - `toOTPIdentifier()` now applies `.trim().toLowerCase()` internally as a defensive guarantee — identifiers are always consistent regardless of caller ### `routes.ts` - All endpoints now normalize `email` at the top of the handler with `.trim().toLowerCase()` before any downstream use (`findUserByEmail`, `sendVerificationOTP`, `toOTPIdentifier`, etc.) - Previously missing normalization in: - `requestPasswordResetEmailOTP` - `forgetPasswordEmailOTP` (deprecated) - `resetPasswordEmailOTP` - Previously missing `.trim()` in all other endpoints ## Tests Added tests to cover the newly fixed scenarios: - `should reset password with mixed case email` - `should reset password with email containing spaces` - `should sign-in with email containing spaces` <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Normalize email casing and whitespace across all `email-otp` endpoints and call sites to prevent OTP mismatches during sign-in, verification, password reset, and email change; fixes #8561. - **Bug Fixes** - Apply `.trim().toLowerCase()` to `email` in all route handlers (body and query) and inside `toOTPIdentifier()`; also normalize `response.user.email` before OTP generation - Fill missing normalization in password reset endpoints; also normalize `newEmail` and session `email` in change-email flows - Add tests for mixed-case and spaced emails in sign-in and password reset flows - **Refactors** - Normalize line endings in modified files <sup>Written for commit 98f7f01db500cb9594ad06557d40efb36aed88ad. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-15 22:41:38 -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#25021