new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Better Auth · Authentication · all subjects

email and password/email verification

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

Manually trigger email verification

Call `authClient.sendVerificationEmail({ email: 'user@email.com', callbackURL: '/' })` to manually trigger email verification on the client side.

Email verification configuration

To enable email verification, provide a `sendVerificationEmail` function in the `emailVerification` configuration. This function takes a data object with properties: user (the user object), url (URL containing verification token to send to user), token (verification token), and a request object as second parameter. Avoid awaiting email sending to prevent timing attacks; on serverless platforms use `waitUntil` or similar to ensure delivery.

Email verification flow

On the client side, call the `sendVerificationEmail` function to send a verification link. When the user clicks the link, if the token is valid, they are redirected to the callbackURL. If the token is invalid, they are redirected to callbackURL with error message in query string: ?error=invalid_token.

Require email verification option

Set `emailAndPassword.requireEmailVerification` to `true` to require users to verify their email before they can sign in. When enabled, every sign-in attempt triggers sendVerificationEmail. Signing up with an existing email returns a success response (not an error) to prevent user enumeration. This only works if sendVerificationEmail is implemented.

Handle unverified email sign-in errors

When a user tries to sign in without verifying their email and `requireEmailVerification` is enabled, the sign-in returns a 403 status error. Handle this with: if (ctx.error.status === 403) { alert('Please verify your email address'); }. The error.message property contains the original error message.

onExistingUserSignUp callback

The `onExistingUserSignUp` callback is triggered when someone signs up with an already-registered email, but only when enumeration protection is active (when `requireEmailVerification` is true or `autoSignIn` is false). Use this to notify existing users: void sendEmail({ to: user.email, subject: 'Sign-up attempt with your email', text: 'Someone tried to create an account using your email address...' }).

Email enumeration protection behavior

When `requireEmailVerification` is enabled or `autoSignIn` is false, the sign-up endpoint prevents email enumeration by returning the same 200 response whether the email is already registered or not, following OWASP authentication best practices. This protection is only active when the sign-up response does not include a session token (i.e., when `requireEmailVerification` is true or `autoSignIn` is false). With default configuration, the endpoint still returns a 422 error for existing emails. The /change-email endpoint always returns a success response to avoid revealing whether target email is registered.

customSyntheticUser for email enumeration protection

When using plugins that add fields to the user table (admin, two-factor, phone-number), use the `customSyntheticUser` option to build a complete synthetic user object for email enumeration protection. The callback receives: coreFields (name, email, emailVerified, image, createdAt, updatedAt), additionalFields (user.additionalFields with defaults applied), and id (generated user ID). Assemble them in database schema order: core fields → plugin fields → additional fields → id.

changeEmail requires emailVerification handler for verified users

`changeEmail` no longer silently returns `{ status: true }` when the flow cannot complete: if `emailVerification.sendVerificationEmail` is missing for a verified user, the request now fails with a 400 error. `callbackURL` values are URL-encoded, so callbacks with their own query string survive the round trip through verify-email links.

callbackURL URL-encoded in verify-email links

`callbackURL` is now URL-encoded in verify-email links sent during OAuth account linking and username sign-in. Values containing an ampersand (e.g., `/welcome?ref=oauth&plan=pro`) are no longer truncated at the first `&`.

Email casing corrected across one-tap, email-otp, and email-verification

Incorrect email casing across one-tap, email-otp, and email-verification flows was corrected.

Give your agent this brain