new·Earn with mozg — 20% of every monthSend somebody here and take a fifth of every plan payment they make, for as long as they keep paying — not a bounty on the first invoice. Your handle is the link, the window is thirty days, and the commission lands on your balance the second they pay. Free to join: if you have signed in, you already have the link. mozg.sh/earnall news →
mozg.beta
Sign in

Better Auth · Plugins · all subjects

email otp plugin

27 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Email OTP plugin for one-time password authentication

Better Auth includes an Email OTP plugin that provides email-based one-time password authentication.

Email OTP plugin installation

To install the email OTP plugin, import emailOTP from 'better-auth/plugins' and add it to the plugins array in the betterAuth config. The plugin requires implementation of the sendVerificationOTP() method that handles three types: 'sign-in', 'email-verification', and 'forget-password'.

Email OTP client plugin installation

To add the client plugin for email OTP, import emailOTPClient from 'better-auth/client/plugins' and add it to the plugins array in createAuthClient().

sendVerificationOTP endpoint

POST /email-otp/send-verification-otp sends an OTP to a user's email. Parameters: email (string, required), type (required, one of 'email-verification', 'sign-in', or 'forget-password').

signIn.emailOtp endpoint

POST /sign-in/email-otp signs in a user with OTP. Parameters: email (string, required), otp (string, required), name (string, optional, display name used only for first-time registration), image (string, optional, profile image URL used only for first-time registration).

Email OTP sign-in auto-registration behavior

If a user is not registered when signing in with OTP, they will be automatically registered. Configured additional fields are also accepted for new users.

Email OTP sign-in with pre-existing unverified account

When a sign-in OTP confirms a pre-existing account whose email was never verified, any existing password on that account is removed and its sessions are revoked. The user is signed in through the OTP and can set a new password through password reset. This keeps email ownership as the source of truth for the account.

verifyEmail endpoint for email OTP

POST /email-otp/verify-email completes email verification with OTP. Parameters: email (string, required), otp (string, required).

resetPassword endpoint for email OTP

POST /email-otp/reset-password resets the user's password with OTP. Parameters: email (string, required), otp (string, required), password (string, required, the new password).

Change email feature for email OTP

The changeEmail feature is disabled by default. To enable it, set changeEmail.enabled to true in the plugin options. By default, when a user requests to change their email, an OTP is sent to the new email address. The email is only updated after the user verifies the new email.

changeEmail endpoint for email OTP

POST /email-otp/change-email requires a session and changes the user's email address. Parameters: newEmail (string, required), otp (string, required, the OTP sent to the new email).

Email OTP verify current email option

To require users to confirm email change with an OTP sent to their current email before sending an OTP to the new email, set changeEmail.verifyCurrentEmail to true in the plugin options. Before requesting the email change, use sendVerificationOtp() with type 'email-verification' on the current email address.

Override default email verification with email OTP

To override the default email verification to use email OTP instead of verification links, set overrideDefaultEmailVerification to true in the plugin options. Users will verify their email using an OTP rather than clicking a link.

Email OTP configuration options

Configuration options for emailOTP plugin: sendVerificationOTP (function, required, sends OTP to email with properties email, otp, type), otpLength (number, default 6), expiresIn (number in seconds, default 300), sendVerificationOnSignUp (boolean, default false), disableSignUp (boolean, default false), generateOTP (function, generates OTP, defaults to random 6-digit number), allowedAttempts (number, default 3, max attempts before OTP becomes invalid), resendStrategy (string, default 'rotate', controls behavior when new OTP requested while existing one valid), storeOTP (string or object, default 'plain', controls OTP transformation before storage), changeEmail (object with enabled and verifyCurrentEmail properties), overrideDefaultEmailVerification (boolean, default false).

Email OTP otpLength configuration

The otpLength configuration option sets the length of the OTP. It defaults to 6.

Email OTP expiresIn configuration

The expiresIn configuration option sets the expiry time of the OTP in seconds. It defaults to 300 seconds.

Email OTP sendVerificationOnSignUp configuration

The sendVerificationOnSignUp configuration option is a boolean that determines whether to send the OTP when a user signs up. It defaults to false.

Email OTP disableSignUp configuration

The disableSignUp configuration option is a boolean that determines whether to prevent automatic sign-up when the user is not registered. It defaults to false.

Email OTP generateOTP configuration

The generateOTP configuration option is a function that generates the OTP. It defaults to a random 6-digit number.

Email OTP allowedAttempts configuration

The allowedAttempts configuration option sets the maximum number of attempts allowed for verifying an OTP. It defaults to 3. After exceeding this limit, the OTP becomes invalid and the user needs to request a new one. When exceeded, methods verifyOTP, signIn.emailOtp, verifyEmail, and resetPassword return an error with code TOO_MANY_ATTEMPTS.

Email OTP resendStrategy configuration

The resendStrategy configuration option controls what happens when a user requests a new OTP while an existing one is still valid. It defaults to 'rotate'. Options are: 'rotate' (always generates a new OTP, default), 'reuse' (resends the same OTP and extends its expiry, prevents multiple valid codes when emails are delayed, only works when OTP is recoverable as plain, encrypted, or custom encrypt/decrypt, falls back to 'rotate' when OTP is hashed, generates fresh OTP if allowed attempts exhausted instead of reusing exhausted one).

Email OTP storeOTP configuration

The storeOTP configuration option specifies the method used to transform the OTP before storage. It defaults to 'plain' text. Options are: 'encrypted', 'hashed', 'plain'. Alternatively, pass a custom object with encrypt/decrypt functions or a hash function. This affects only the stored OTP value, not the OTP sent to the user. The storage backend is controlled by the global verification config.

Email OTP custom encryptor example

To use a custom encryptor for storing OTP, pass storeOTP as an object with encrypt and decrypt async functions: emailOTP({ storeOTP: { encrypt: async (otp) => { return myCustomEncryptor(otp); }, decrypt: async (otp) => { return myCustomDecryptor(otp); } } })

Email OTP custom hasher example

To use a custom hasher for storing OTP, pass storeOTP as an object with hash async function: emailOTP({ storeOTP: { hash: async (otp) => { return myCustomHasher(otp); } } })

Email OTP sendVerificationOTP timing attack warning

It is recommended to not await the email sending in sendVerificationOTP to avoid timing attacks. On serverless platforms, use waitUntil or similar to ensure the email is sent.

Email OTP plugin purpose

The Email OTP plugin allows users to sign in, verify their email, or reset their password using a one-time password (OTP) sent to their email address.

Email OTP sendVerificationOTP function signature

The sendVerificationOTP function receives an object with properties: email (the user's email address), otp (the OTP to send), type (the type of OTP, one of 'sign-in', 'email-verification', or 'forget-password').

Give your agent this brain