mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-19 11:24:57 -05:00
feat(email-otp): add resendStrategy option to reuse existing OTP (#8560)
This commit is contained in:
@@ -411,6 +411,26 @@ export const auth = betterAuth({
|
||||
|
||||
When the maximum attempts are exceeded, the `verifyOTP`, `signIn.emailOtp`, `verifyEmail`, and `resetPassword` methods will return an error with code `TOO_MANY_ATTEMPTS`.
|
||||
|
||||
- `resendStrategy`: Controls what happens when a user requests a new OTP while an existing one is still valid. Defaults to `"rotate"`.
|
||||
- `"rotate"`: Always generates a new OTP (default behavior).
|
||||
- `"reuse"`: Resends the same OTP and extends its expiry. This prevents multiple valid codes from existing simultaneously when emails are delayed. Only works when the OTP is recoverable (`plain`, `encrypted`, or custom encrypt/decrypt). Falls back to `"rotate"` when the OTP is hashed. If the allowed attempts have been exhausted, a fresh OTP is generated instead of reusing the exhausted one.
|
||||
|
||||
```ts title="auth.ts"
|
||||
import { betterAuth } from "better-auth"
|
||||
import { emailOTP } from "better-auth/plugins"
|
||||
|
||||
export const auth = betterAuth({
|
||||
plugins: [
|
||||
emailOTP({
|
||||
resendStrategy: "reuse", // [!code highlight]
|
||||
async sendVerificationOTP({ email, otp, type }) {
|
||||
// send the OTP
|
||||
},
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
- `storeOTP`: The method used to transform the OTP before it is stored by Better Auth's verification layer, whether `encrypted`, `hashed` or `plain` text. Default is `plain` text.
|
||||
|
||||
<Callout>
|
||||
|
||||
Reference in New Issue
Block a user