[GH-ISSUE #3253] Reset password phone number method can use same code twice #18172

Closed
opened 2026-04-15 16:33:16 -05:00 by GiteaMirror · 8 comments
Owner

Originally created by @irg1008 on GitHub (Jul 3, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3253

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Call requestPasswordReset:

await authClient.phoneNumber.requestPasswordReset({
    phoneNumber: "+1234567890"
})

Then call resetPassword with your code for a successful reset:

const isVerified = await authClient.phoneNumber.resetPassword({
    otp: "123456", // OTP code sent to the user's phone number
    phoneNumber: "+1234567890",
    newPassword: "newPassword"
}) 

Then call again the same function with same parameter and different newPassword.

I would expect the code would be invalidated after use but consequent resets are being accepted.
For me is a problem since I check with my sms provider every successful code check and this crats multiple checks for a code that has already being used.

Also It would be useful to have a callback function for the password reset as we have one with sendOTP

Current vs. Expected behavior

Current: right now the same OTP number can be used for multiple password reset

Expected: OTP code should be deleted or invalidated after successful password reset (as it does after surpassing max tries)

What version of Better Auth are you using?

1.2.10

Provide environment information

- OS: W11
- Using Expo (SDK53/RN79)

Which area(s) are affected? (Select all that apply)

Package

Auth config (if applicable)

...
  hooks: {
    after: phoneOTPMiddleware,
  },
...

I need to use this middleware for reset password callback and there I call my sms provider, this could be moved to a seperate callback to ensure calling sms provider only on successful resets and uses of OTP code

Additional context

No response

Originally created by @irg1008 on GitHub (Jul 3, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3253 ### Is this suited for github? - [ ] Yes, this is suited for github ### To Reproduce Call requestPasswordReset: ```typescript await authClient.phoneNumber.requestPasswordReset({ phoneNumber: "+1234567890" }) ``` Then call resetPassword with your code for a successful reset: ```typescript const isVerified = await authClient.phoneNumber.resetPassword({ otp: "123456", // OTP code sent to the user's phone number phoneNumber: "+1234567890", newPassword: "newPassword" }) ``` Then call again the same function with same parameter and different newPassword. I would expect the code would be invalidated after use but consequent resets are being accepted. For me is a problem since I check with my sms provider every successful code check and this crats multiple checks for a code that has already being used. Also It would be useful to have a callback function for the password reset as we have one with sendOTP ### Current vs. Expected behavior Current: right now the same OTP number can be used for multiple password reset Expected: OTP code should be deleted or invalidated after successful password reset (as it does after surpassing max tries) ### What version of Better Auth are you using? 1.2.10 ### Provide environment information ```bash - OS: W11 - Using Expo (SDK53/RN79) ``` ### Which area(s) are affected? (Select all that apply) Package ### Auth config (if applicable) ```typescript ... hooks: { after: phoneOTPMiddleware, }, ... I need to use this middleware for reset password callback and there I call my sms provider, this could be moved to a seperate callback to ensure calling sms provider only on successful resets and uses of OTP code ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-15 16:33:16 -05:00
Author
Owner

@rebasecase commented on GitHub (Jul 3, 2025):

379b5d872c/packages/better-auth/src/plugins/phone-number/index.ts (L903-L922)

What happens when you set allowedAttempts to 1?

IMO this should be 1 by default?

<!-- gh-comment-id:3032965889 --> @rebasecase commented on GitHub (Jul 3, 2025): https://github.com/better-auth/better-auth/blob/379b5d872c9c05fbfc1740fe34ba3f209814bde0/packages/better-auth/src/plugins/phone-number/index.ts#L903-L922 What happens when you set [allowedAttempts](https://github.com/better-auth/better-auth/blob/379b5d872c9c05fbfc1740fe34ba3f209814bde0/packages/better-auth/src/plugins/phone-number/index.ts#L130) to 1? IMO this should be 1 by default?
Author
Owner

@rikarani commented on GitHub (Jul 3, 2025):

default attempt for OTP code is 3...
so (for now) you need to pass allowedAttempts option in the phoneNumber plugin
Image

https://www.better-auth.com/docs/plugins/phone-number#otp-verification-attempts

<!-- gh-comment-id:3033440756 --> @rikarani commented on GitHub (Jul 3, 2025): default attempt for OTP code is 3... so (for now) you need to pass `allowedAttempts` option in the `phoneNumber` plugin ![Image](https://github.com/user-attachments/assets/1e922bd5-7cdc-4849-bccb-03adcbc6f1f3) https://www.better-auth.com/docs/plugins/phone-number#otp-verification-attempts
Author
Owner

@rebasecase commented on GitHub (Jul 3, 2025):

I don't think this is correct. Verification attempts is, I request an OTP then I have 3 failed attempts until I have to request a new one.

OP wants it so that once the OTP is consumed it can't be used again, which this does not look like it accounts for currently.

<!-- gh-comment-id:3033502254 --> @rebasecase commented on GitHub (Jul 3, 2025): I don't think this is correct. Verification attempts is, I request an OTP then I have 3 failed attempts until I have to request a new one. OP wants it so that once the OTP is consumed it can't be used again, which this does not look like it accounts for currently.
Author
Owner

@irg1008 commented on GitHub (Jul 3, 2025):

I don't think this is correct. Verification attempts is, I request an OTP then I have 3 failed attempts until I have to request a new one.

OP wants it so that once the OTP is consumed it can't be used again, which this does not look like it accounts for currently.

Exactly this yeah, or maybe a success verification or reset callback including the code

<!-- gh-comment-id:3033900001 --> @irg1008 commented on GitHub (Jul 3, 2025): > I don't think this is correct. Verification attempts is, I request an OTP then I have 3 failed attempts until I have to request a new one. > > OP wants it so that once the OTP is consumed it can't be used again, which this does not look like it accounts for currently. Exactly this yeah, or maybe a success verification or reset callback including the code
Author
Owner

@rikarani commented on GitHub (Jul 4, 2025):

I don't think this is correct. Verification attempts is, I request an OTP then I have 3 failed attempts until I have to request a new one.

OP wants it so that once the OTP is consumed it can't be used again, which this does not look like it accounts for currently.

just pass the options

phoneNumber({
    allowedAttempts: 1,
    // other option
})

maybe in future version, the default allowedAttempts change from 3 to 1, so didn't need to pass the options

<!-- gh-comment-id:3036486678 --> @rikarani commented on GitHub (Jul 4, 2025): > I don't think this is correct. Verification attempts is, I request an OTP then I have 3 failed attempts until I have to request a new one. > > OP wants it so that once the OTP is consumed it can't be used again, which this does not look like it accounts for currently. just pass the options ```ts phoneNumber({ allowedAttempts: 1, // other option }) ``` maybe in future version, the default `allowedAttempts` change from 3 to 1, so didn't need to pass the options
Author
Owner

@irg1008 commented on GitHub (Jul 4, 2025):

No that's not what I mean. I mean that after a successful OTP reset code, the code it's not deleted in verification table and so it can be used again and again for further password changes

<!-- gh-comment-id:3036513146 --> @irg1008 commented on GitHub (Jul 4, 2025): No that's not what I mean. I mean that after a successful OTP reset code, the code it's not deleted in verification table and so it can be used again and again for further password changes
Author
Owner

@rebasecase commented on GitHub (Jul 4, 2025):

@rikarani what he's saying is that you can re-use the same valid OTP to reset the phone number as many times as you want

<!-- gh-comment-id:3036696301 --> @rebasecase commented on GitHub (Jul 4, 2025): @rikarani what he's saying is that you can re-use the same valid OTP to reset the phone number as many times as you want
Author
Owner

@irg1008 commented on GitHub (Jul 4, 2025):

Amazing!! Thank you!

<!-- gh-comment-id:3037022247 --> @irg1008 commented on GitHub (Jul 4, 2025): Amazing!! Thank you!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#18172