A better-auth plugin for email & phone normalization and additional validation, blocking over 55,000 temporary email domains.
Email normalization: foo+temp@gmail.com
-> foo@gmail.com
Phone normalization: +1 (555) 123-1234
-> +15551231234
Validation: throwaway@mailinator.com
-> Blocked
npm i better-auth-harmony
// auth.ts
import { betterAuth } from 'better-auth';
import { emailHarmony } from 'better-auth-harmony';
export const auth = betterAuth({
// ... other config options
plugins: [emailHarmony()]
});
npx @better-auth/cli migrate
or
npx @better-auth/cli generate
See the Schema section to add the fields manually.
allowNormalizedSignin
(default=false) - Allow logging in with any version of the unnormalized email address. For example, a user who signed up with the emailjohndoe@googlemail.com
may also log in withjohn.doe@gmail.com
. Makes 1 extra database query for every login attempt.validator
- Custom function to validate email. By default uses validator.js and Mailchecker.normalizer
- Custom function to normalize the email address. By default usesvalidator.js/normalizeEmail()
.
The emailHarmony
plugin requires an additional field in the user table:
Field Name | Type | Optional | Unique | Description |
---|---|---|---|---|
normalizedEmail | string | True | True | User's email address after normalization |
The normalizedEmail
field being unique prevents users from signing up with throwaway variations of
the same email address.
Note
Unlike emailHarmony
, phone number normalization intercepts and modifies the user's
phoneNumber
, permitting only normalized numbers in the backend.
npm i better-auth-harmony
// auth.ts
import { betterAuth } from 'better-auth';
import { phoneNumber } from 'better-auth/plugins';
import { phoneHarmony } from 'better-auth-harmony';
export const auth = betterAuth({
// ... other config options
plugins: [phoneNumber(), phoneHarmony()]
});
See the better-auth
phoneNumber
plugin documentation for
information on configuring the phoneNumber()
, including validation.
defaultCountry
- Default country for numbers written in non-international form (without a+
sign).defaultCallingCode
- Default calling code for numbers written in non-international form (without a+
sign). Useful for parsing non-geographic codes such as+800
numbers.extract
(default=true) - Defines the "strictness" of parsing a phone number. By default, it will attempt to extract the phone number from any input string, such as"My phone number is (213) 373-4253"
.acceptRawInputOnError
(default=false) - If the normalizer throws, for example because it is unable to parse the phone number, use the original input. For example, the phone number"+12"
will be saved as-is to the database.normalizer
- Custom function to normalize phone number. Default usesparsePhoneNumberWithError
fromlibphonenumber-js/max
. Can be used to infer the country through the Request object, for example using IP address geolocation.