[PR #7772] [CLOSED] feat(email-otp): add persistOTP option to resend existing OTP #7545

Closed
opened 2026-03-13 13:41:01 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/7772
Author: @bytaesu
Created: 2/3/2026
Status: Closed

Base: canaryHead: 2026-02-03/feat/email-otp-persist-otp


📝 Commits (7)

  • 640c6c2 feat(email-otp): add persistOTP option to resend existing OTP
  • 8eef69b docs: add persistOTP option guide
  • 4020af9 fix: format
  • 14e4ed7 fix: cspell
  • 32d80ed fix: delete verification in persistOTP path when user not found
  • 5b61701 test: undefined check
  • 726bf13 Merge branch 'canary' into 2026-02-03/feat/email-otp-persist-otp

📊 Changes

5 files changed (+385 additions, -8 deletions)

View changed files

📝 docs/content/docs/plugins/email-otp.mdx (+12 -0)
📝 packages/better-auth/src/plugins/email-otp/email-otp.test.ts (+280 -0)
📝 packages/better-auth/src/plugins/email-otp/otp-token.ts (+23 -0)
📝 packages/better-auth/src/plugins/email-otp/routes.ts (+62 -8)
📝 packages/better-auth/src/plugins/email-otp/types.ts (+8 -0)

📄 Description

I chose this approach because it felt more reliable than sending multiple OTPs and validating them all together. It addresses the same case where a user requests multiple OTPs while emails are delayed.


Summary by cubic

Add a persistOTP option to email-otp to resend the same OTP and extend its expiry instead of generating new codes. Addresses #1568 by preventing multiple valid codes when emails are delayed.

  • New Features

    • persistOTP (default false): reuses the existing unexpired OTP and extends its expiry; otherwise generates a new one.
    • Works when the OTP is recoverable (plain/encrypted/custom decrypt); falls back when hashed/custom-hashed.
    • Added retrieveOTP helper, route logic, docs, and tests.
    • Deletes existing verification when the user doesn’t exist in the persistOTP path.
  • Migration

    • Opt-in only; no breaking changes.
    • Ignored when storeOTP is "hashed" or uses a custom hasher.

Written for commit 726bf13b85. 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/7772 **Author:** [@bytaesu](https://github.com/bytaesu) **Created:** 2/3/2026 **Status:** ❌ Closed **Base:** `canary` ← **Head:** `2026-02-03/feat/email-otp-persist-otp` --- ### 📝 Commits (7) - [`640c6c2`](https://github.com/better-auth/better-auth/commit/640c6c2dce11a31e4f67257ee701a777ad683d0e) feat(email-otp): add persistOTP option to resend existing OTP - [`8eef69b`](https://github.com/better-auth/better-auth/commit/8eef69b52372279f2ae65e9ff2eea61a73e41d44) docs: add persistOTP option guide - [`4020af9`](https://github.com/better-auth/better-auth/commit/4020af9d128a29f47bd3e144ca7aff10d9ffc2a4) fix: format - [`14e4ed7`](https://github.com/better-auth/better-auth/commit/14e4ed7ebbff51309e31e3b62d59d2a9c95b98ba) fix: cspell - [`32d80ed`](https://github.com/better-auth/better-auth/commit/32d80eded2b4ebf2796884266ec810a37555c153) fix: delete verification in persistOTP path when user not found - [`5b61701`](https://github.com/better-auth/better-auth/commit/5b617013bb0ac3155495f35602aaf89f3ee89c9f) test: undefined check - [`726bf13`](https://github.com/better-auth/better-auth/commit/726bf13b85463ec96906c0746fa7856928f8a75c) Merge branch 'canary' into 2026-02-03/feat/email-otp-persist-otp ### 📊 Changes **5 files changed** (+385 additions, -8 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/plugins/email-otp.mdx` (+12 -0) 📝 `packages/better-auth/src/plugins/email-otp/email-otp.test.ts` (+280 -0) 📝 `packages/better-auth/src/plugins/email-otp/otp-token.ts` (+23 -0) 📝 `packages/better-auth/src/plugins/email-otp/routes.ts` (+62 -8) 📝 `packages/better-auth/src/plugins/email-otp/types.ts` (+8 -0) </details> ### 📄 Description I chose this approach because it felt more reliable than sending multiple OTPs and validating them all together. It addresses the same case where a user requests multiple OTPs while emails are delayed. - Closes #1568 <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Add a persistOTP option to email-otp to resend the same OTP and extend its expiry instead of generating new codes. Addresses #1568 by preventing multiple valid codes when emails are delayed. - **New Features** - persistOTP (default false): reuses the existing unexpired OTP and extends its expiry; otherwise generates a new one. - Works when the OTP is recoverable (plain/encrypted/custom decrypt); falls back when hashed/custom-hashed. - Added retrieveOTP helper, route logic, docs, and tests. - Deletes existing verification when the user doesn’t exist in the persistOTP path. - **Migration** - Opt-in only; no breaking changes. - Ignored when storeOTP is "hashed" or uses a custom hasher. <sup>Written for commit 726bf13b85463ec96906c0746fa7856928f8a75c. 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-03-13 13:41:01 -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#7545