Verify OTP method for forgot password flow #533

Closed
opened 2026-03-13 07:51:35 -05:00 by GiteaMirror · 6 comments
Owner

Originally created by @jasongerbes on GitHub (Jan 6, 2025).

Is this suited for github?

  • Yes, this is suited for github

The Email OTP plugin currently has a 2-step password reset flow:

1. Send OTP

await authClient.emailOtp.sendVerificationOtp({
    email: "user-email@email.com",
    type: "forget-password"
})

2. Reset Password

await authClient.emailOtp.resetPassword({
    email: "user-email@email.com",
    otp: "123456",
    password: "password"
})

This flow requires the user to enter their new password before the OTP has been verified, rather than providing early feedback if the OTP is invalid or expired.

Describe the solution you'd like

To enable a 3-step password reset flow, I propose adding a verifyOtp() method that can be used to verify an OTP before the new password is entered.

await authClient.emailOtp.verifyOtp({
    email: "user-email@email.com",
    type: "forget-password", // or "sign-in", "email-verification"
    otp: "123456"
})

Suggested behaviour:

  • Rate limited.
  • Returns a 200 response if the OTP is valid.
  • Returns a relevant error (or 200 response?) if the OTP is invalid or expired.
  • Deletes the OTP from the database if it's expired.

Describe alternatives you've considered

As a workaround, the getVerificationOTP() method could be used to manually verify an OTP.

However, this method:

  • Isn't currently documented in the Email OTP docs.
  • Is server-only and not rate limited (should it be?).
  • Doesn't indicate whether a token is expired.

Additional context

No response

Originally created by @jasongerbes on GitHub (Jan 6, 2025). ### Is this suited for github? - [X] Yes, this is suited for github ### Is your feature request related to a problem? Please describe. The Email OTP plugin currently has a 2-step password reset flow: **1. Send OTP** ```ts await authClient.emailOtp.sendVerificationOtp({ email: "user-email@email.com", type: "forget-password" }) ``` **2. Reset Password** ```ts await authClient.emailOtp.resetPassword({ email: "user-email@email.com", otp: "123456", password: "password" }) ``` This flow requires the user to enter their new password before the OTP has been verified, rather than providing early feedback if the OTP is invalid or expired. ### Describe the solution you'd like To enable a 3-step password reset flow, I propose adding a `verifyOtp()` method that can be used to verify an OTP before the new password is entered. ```ts await authClient.emailOtp.verifyOtp({ email: "user-email@email.com", type: "forget-password", // or "sign-in", "email-verification" otp: "123456" }) ``` Suggested behaviour: - Rate limited. - Returns a `200` response if the OTP is valid. - Returns a relevant error (or `200` response?) if the OTP is invalid or expired. - Deletes the OTP from the database if it's expired. ### Describe alternatives you've considered As a workaround, the `getVerificationOTP()` method could be used to manually verify an OTP. However, this method: - Isn't currently documented in the [Email OTP docs](https://www.better-auth.com/docs/plugins/email-otp). - Is server-only and not rate limited (should it be?). - Doesn't indicate whether a token is expired. ### Additional context _No response_
GiteaMirror added the enhancement label 2026-03-13 07:51:35 -05:00
Author
Owner

@YounessHassoune commented on GitHub (Apr 21, 2025):

any updates yet ??

@YounessHassoune commented on GitHub (Apr 21, 2025): any updates yet ??
Author
Owner

@giridhar1610 commented on GitHub (May 4, 2025):

Any updates on when will this be merged?

@giridhar1610 commented on GitHub (May 4, 2025): Any updates on when will this be merged?
Author
Owner

@dosubot[bot] commented on GitHub (Aug 3, 2025):

Hi, @jasongerbes. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You proposed adding a verifyOtp() method to the Email OTP plugin to enable a 3-step password reset flow.
  • This method would allow OTP verification before setting a new password, providing early feedback on OTP validity.
  • It would include rate limiting and handle expired OTPs by deleting them.
  • Currently, the workaround using getVerificationOTP() is undocumented, server-only, and lacks expiration checks.
  • Other users have expressed interest in updates or merging of this feature.

Next Steps:

  • Please let me know if this feature is still relevant to the latest version of better-auth by commenting on this issue.
  • If I don’t hear back within 7 days, I will automatically close this issue.

Thanks for your understanding and contribution!

@dosubot[bot] commented on GitHub (Aug 3, 2025): Hi, @jasongerbes. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You proposed adding a `verifyOtp()` method to the Email OTP plugin to enable a 3-step password reset flow. - This method would allow OTP verification before setting a new password, providing early feedback on OTP validity. - It would include rate limiting and handle expired OTPs by deleting them. - Currently, the workaround using `getVerificationOTP()` is undocumented, server-only, and lacks expiration checks. - Other users have expressed interest in updates or merging of this feature. **Next Steps:** - Please let me know if this feature is still relevant to the latest version of better-auth by commenting on this issue. - If I don’t hear back within 7 days, I will automatically close this issue. Thanks for your understanding and contribution!
Author
Owner

@giridhar1610 commented on GitHub (Aug 3, 2025):

Hey, we still want this future. I'm looking to bump the better-auth version immediately after this feature's inclusion

@giridhar1610 commented on GitHub (Aug 3, 2025): Hey, we still want this future. I'm looking to bump the better-auth version immediately after this feature's inclusion
Author
Owner

@sheridanprakash commented on GitHub (Aug 22, 2025):

Thank you so much for adding this middle step! Reading the docs and was wondering why it could find it just to realize it was added just last week.
Thank you Better-Auth team!

@sheridanprakash commented on GitHub (Aug 22, 2025): Thank you so much for adding this middle step! Reading the docs and was wondering why it could find it just to realize it was added just last week. Thank you Better-Auth team!
Author
Owner

@junwen-k commented on GitHub (Dec 19, 2025):

I’m running into the same limitation as described here, but for the phoneNumber plugin instead of email.

Currently, after calling authClient.phoneNumber.requestPasswordReset(), there doesn’t seem to be any way to manually verify the OTP first. I initially assumed authClient.phoneNumber.verify() could be reused, but it appears that password reset OTPs are scoped differently and can’t be verified through that API.

This means the only supported flow right now is passing { otp, newPassword } together to resetPassword, without an intermediate “OTP verified” step.

For production flows, it would be really useful to support:

  1. Request password reset OTP
  2. Verify OTP independently
  3. Proceed to reset password after verification

This would align the phone number reset flow with more flexible UX patterns and with how verification is handled elsewhere.

@junwen-k commented on GitHub (Dec 19, 2025): I’m running into the same limitation as described here, but for the `phoneNumber` plugin instead of email. Currently, after calling `authClient.phoneNumber.requestPasswordReset()`, there doesn’t seem to be any way to manually verify the OTP first. I initially assumed `authClient.phoneNumber.verify()` could be reused, but it appears that password reset OTPs are scoped differently and can’t be verified through that API. This means the only supported flow right now is passing { otp, newPassword } together to resetPassword, without an intermediate “OTP verified” step. For production flows, it would be really useful to support: 1. Request password reset OTP 1. Verify OTP independently 1. Proceed to reset password after verification This would align the phone number reset flow with more flexible UX patterns and with how verification is handled elsewhere.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#533