### Install better-auth-harmony Source: https://github.com/gekorm/better-auth-harmony/blob/main/README.md Install the plugin package via npm. ```shell npm i better-auth-harmony ``` -------------------------------- ### Documentation Structure Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/DOCUMENTATION.md Illustrates the directory structure of the generated documentation files for better-auth-harmony. ```tree output/ ├── INDEX.md # Start here - complete overview ├── types.md # All type definitions ├── configuration.md # Configuration guide ├── errors.md # Error handling reference ├── exports-reference.md # Import paths and exports └── api-reference/ ├── email-harmony.md # Email plugin API ├── email-matchers.md # Email route matchers ├── phone-harmony.md # Phone plugin API └── phone-matchers.md # Phone route matchers ``` -------------------------------- ### Minimal Setup Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Demonstrates a minimal configuration for Better Auth using both emailHarmony and phoneHarmony plugins, including database and secret configuration. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { emailHarmony, phoneHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ emailHarmony(), phoneNumber(), phoneHarmony() ] }); ``` -------------------------------- ### By-Country Phone Harmony Configuration Examples Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/configuration.md Demonstrates configuring phone number normalization for different regions. Includes examples for US-focused, EU-focused with multiple countries, and UK-specific settings. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; // US-focused export const usAuth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ defaultCountry: 'US', extract: true }) ] }); // EU-focused with multiple countries export const euAuth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ defaultCountry: 'DE', // Fallback to Germany extract: false, // Strict parsing acceptRawInputOnError: false // Reject invalid }) ] }); // UK-specific export const ukAuth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ defaultCountry: 'GB', extract: true }) ] }); ``` -------------------------------- ### signInPhone Matcher Usage Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-matchers.md Example showing how to use the `signInPhone` matcher to specifically target phone number sign-in requests. This matcher applies to the `/sign-in/phone-number` endpoint. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/phone/matchers'; export const auth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ matchers: [matchers.signInPhone] }) ] }); ``` -------------------------------- ### Setup Phone Normalization Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Shows how to set up the phoneHarmony plugin with Better Auth, including specifying a default country. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ defaultCountry: 'US' }) ] }); ``` -------------------------------- ### Common Plugin Setup with Email and Phone Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Configure the Better Auth core with email and phone plugins, specifying options and matchers for each. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { emailHarmony, phoneHarmony } from 'better-auth-harmony'; import * as emailMatchers from 'better-auth-harmony/email/matchers'; import * as phoneMatchers from 'better-auth-harmony/phone/matchers'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ emailHarmony({ allowNormalizedSignin: true, matchers: { validation: [emailMatchers.emailSignUp, emailMatchers.emailSignIn], signIn: [emailMatchers.allEmailSignIn] } }), phoneNumber(), phoneHarmony({ defaultCountry: 'US', matchers: [ phoneMatchers.signInPhone, phoneMatchers.phoneOtp, phoneMatchers.phoneVerify ] }) ] }); ``` -------------------------------- ### Matcher Examples Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/types.md Examples of Matcher functions for defining routing logic based on request paths. `matchSignIn` checks for a specific sign-in path, while `matchAllPhone` checks if the path includes 'phone'. ```typescript const matchSignIn: Matcher = ({ path }) => path === '/sign-in/phone-number'; const matchAllPhone: Matcher = ({ path }) => path?.includes('phone'); ``` -------------------------------- ### phoneOtp Matcher Usage Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-matchers.md Example demonstrating the use of the `phoneOtp` matcher for phone number OTP sending requests. This matcher is relevant for the `/phone-number/send-otp` endpoint. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/phone/matchers'; export const auth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ matchers: [matchers.phoneOtp] }) ] }); ``` -------------------------------- ### Import Plugins for Setup Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Import the necessary plugins for setting up both email and phone normalization features. This includes importing `emailHarmony` and `phoneHarmony` from `better-auth-harmony` and `phoneNumber` from `better-auth/plugins`. ```typescript import { emailHarmony, phoneHarmony } from 'better-auth-harmony'; import { phoneNumber } from 'better-auth/plugins'; ``` -------------------------------- ### allPhone Matcher Usage Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-matchers.md Example demonstrating how to use the `allPhone` matcher to apply phone number normalization to all phone-based authentication flows. This is the default matcher if none are specified. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/phone/matchers'; export const auth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ matchers: [matchers.allPhone] }) ] }); ``` -------------------------------- ### phoneForget Matcher Usage Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-matchers.md Example demonstrating the `phoneForget` matcher, which applies to both current and deprecated phone number password reset request endpoints. It covers `/phone-number/request-password-reset` and `/phone-number/forget-password`. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/phone/matchers'; export const auth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ matchers: [matchers.phoneForget] }) ] }); ``` -------------------------------- ### Phone Reset Matcher Setup Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-matchers.md Example of how to configure Better Auth Harmony to use the phoneReset matcher for completing password reset flows. This matcher is intended for the endpoint where users finalize their password reset. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/phone/matchers'; export const auth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ matchers: [matchers.phoneReset] }) ] }); ``` -------------------------------- ### Default Email Validation Setup Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/errors.md Shows the recommended way to set up email validation using emailHarmony with its default validator. ```typescript emailHarmony({ // Use default validator for most cases validator: validateEmail // (default) }) // For custom logic: // validator: async (email) => { // if (!email.endsWith('@company.com')) return false; // return true; // } ``` -------------------------------- ### Enable Normalized Signin with Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Enables users to log in with any normalized variation of their email. This requires an extra database query per login attempt and a unique 'normalizedEmail' field. ```typescript emailHarmony({ allowNormalizedSignin: true }) ``` -------------------------------- ### Basic Phone Harmony Setup Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-harmony.md Demonstrates the basic integration of the phoneHarmony plugin into Better Auth. It normalizes phone numbers to E.164 format. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ phoneNumber(), phoneHarmony() ] }); // User provides: "+1 (213) 373-4253" // Stored as: "+12133734253" ``` -------------------------------- ### Configure EmailHarmony with emailSignUp Matcher Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md Example of configuring emailHarmony to use the `emailSignUp` matcher for validation. This matcher is specifically for email sign-up requests. ```typescript import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ matchers: { validation: [matchers.emailSignUp] } }) ] }); ``` -------------------------------- ### Import Plugins for Email Only Setup Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Import only the necessary components for email normalization. This includes `emailHarmony` and specific email-related utilities like `validateEmail` and the `EmailHarmonyOptions` type. ```typescript import { emailHarmony } from 'better-auth-harmony'; import { validateEmail, type EmailHarmonyOptions } from 'better-auth-harmony/email'; ``` -------------------------------- ### phoneVerify Matcher Usage Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-matchers.md Example illustrating the `phoneVerify` matcher for OTP verification requests. This matcher targets the `/phone-number/verify` endpoint. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/phone/matchers'; export const auth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ matchers: [matchers.phoneVerify] }) ] }); ``` -------------------------------- ### Configure EmailHarmony with emailSendVerification Matcher Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md Example of configuring emailHarmony to use the `emailSendVerification` matcher. This matcher is for email verification sending requests. ```typescript import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ matchers: { validation: [matchers.emailSendVerification] } }) ] }); ``` -------------------------------- ### Full Email Harmony Configuration Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/configuration.md Demonstrates a comprehensive configuration of email Harmony, including enabling normalized signin, custom validation for corporate emails, a custom normalizer that preserves certain aliases, specific route matchers for validation and signin, and custom database field names. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ emailHarmony({ // Allow users to sign in with variations of their email allowNormalizedSignin: true, // Custom validation: only allow corporate emails validator: async (email) => { if (!email.endsWith('@company.com')) return false; // Could also check against external list, database, etc. return true; }, // Custom normalizer: preserve some aliases normalizer: (email) => { // Custom logic: keep team aliases if (email.includes('+team')) return email; // Otherwise use default normalization const { normalizeEmail } = await import('validator'); return normalizeEmail(email); }, // Only validate during key routes matchers: { validation: [ matchers.emailSignUp, matchers.emailSignIn, matchers.emailForget ], signIn: [ matchers.emailSignUp, matchers.emailSignIn ] }, // Use custom database field names schema: { user: { fields: { normalizedEmail: 'email_normalized' } } } }) ] }); ``` -------------------------------- ### Configure EmailHarmony with emailSignIn Matcher Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md Example of configuring emailHarmony to use the `emailSignIn` matcher for validation. This matcher is specifically for email password-based sign-in requests. ```typescript import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ matchers: { validation: [matchers.emailSignIn] } }) ] }); ``` -------------------------------- ### Configure EmailHarmony with allEmail Matcher Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md Example of configuring the emailHarmony plugin to use the `allEmail` matcher for validation. This matcher applies to all email-related authentication routes. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ matchers: { validation: [matchers.allEmail] } }) ] }); ``` -------------------------------- ### Combined Email Matcher Configuration Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md An example showcasing how to combine multiple email matchers for validation and sign-in routes. This configuration allows for flexible authentication flows, including normalized sign-in. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ allowNormalizedSignin: true, matchers: { // Validate email during signup, signin, and password reset validation: [ matchers.emailSignUp, matchers.emailSignIn, matchers.emailForget ], // Allow normalized signin on all sign-in routes signIn: [ matchers.emailSignIn, matchers.emailOtpVerify, matchers.magicLinkSignIn ] } }) ] }); ``` -------------------------------- ### Accessing Re-exported Types Directly Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Example of importing types like EmailHarmonyOptions directly from the 'better-auth-harmony/email' submodule. ```typescript import type { EmailHarmonyOptions } from 'better-auth-harmony/email'; // Type: EmailHarmonyOptions // Source: src/email/index.ts:22-70 ``` -------------------------------- ### Examples of Invalid Emails Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/errors.md Illustrates common patterns of invalid email addresses, including temporary domains and incorrect formats. ```javascript // Temporary/disposable domains (rejected by Mailchecker) invalidEmails = [ 'user@mailinator.com', 'user@guerrillamail.com', 'user@temp-mail.org', 'user@throwaway.email' // ... 55,000+ more domains ]; // Invalid format (rejected by validator.js) invalidFormats = [ 'not-an-email', '@example.com', 'user@', 'user @example.com', // space in local part 'user@.com' ]; ``` -------------------------------- ### Basic Email Harmony Setup Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-harmony.md This snippet shows the basic configuration for the emailHarmony plugin. It's used to enable email normalization and validation in Better Auth. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, emailAndPassword: { enabled: true, }, plugins: [emailHarmony()] }); ``` -------------------------------- ### Configure EmailHarmony with allEmailSignIn Matcher Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md Example of configuring emailHarmony to use `allEmailSignIn` for sign-in routes, enabling normalized sign-in. This matcher applies to email-related sign-in and verification routes, excluding sign-up. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ allowNormalizedSignin: true, matchers: { signIn: [matchers.allEmailSignIn] } }) ] }); ``` -------------------------------- ### Configure EmailHarmony with emailForget Matcher Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md Example of configuring emailHarmony to use the `emailForget` matcher for validation. This matcher applies to both current and deprecated password reset request routes. ```typescript import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ matchers: { validation: [matchers.emailForget] } }) ] }); ``` -------------------------------- ### Selective Email Normalization Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/configuration.md Configure different validation strategies for email routes like signup and sign-in. This example shows strict validation on signup and allows multiple normalized sign-in flows. ```typescript import { betterAuth } from 'better-better-auth'; import { emailHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ // Different validation strategies per route matchers: { // Strict validation on signup validation: [matchers.emailSignUp], // Allow normalized signin on all signin flows signIn: [ matchers.emailSignIn, matchers.emailOtpVerify, matchers.magicLinkSignIn ] } }) ] }); ``` -------------------------------- ### PhoneHarmonyOptions Configuration Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-harmony.md Example of configuring `PhoneHarmonyOptions` to set default country and calling code, enable lenient parsing, and control error handling for phone number normalization. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony, type PhoneHarmonyOptions } from 'better-auth-harmony/phone'; const options: PhoneHarmonyOptions = { defaultCountry: 'US', defaultCallingCode: '1', extract: true, acceptRawInputOnError: false }; export const auth = betterAuth({ plugins: [phoneNumber(), phoneHarmony(options)] }); ``` -------------------------------- ### Email Harmony with Selective Matcher Configuration Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-harmony.md Customize when email validation and normalization occur by providing specific matchers to emailHarmony. This example limits validation to signup and signin, and normalization to OTP flows. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ emailHarmony({ matchers: { // Only validate during signup and signin validation: [matchers.emailSignUp, matchers.emailSignIn], // Only normalize during email OTP flows signIn: [matchers.emailOtpVerify, matchers.emailOtpReset] } }) ] }); ``` -------------------------------- ### Integrate Email and Phone Harmony Plugins Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Integrate both emailHarmony and phoneHarmony plugins into Better Auth. This setup configures the authentication system to handle both email and phone-based authentication flows. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony, phoneHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ // ... other config plugins: [emailHarmony(), phoneHarmony()] }); ``` -------------------------------- ### Custom Normalizer Usage Example Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-harmony.md Demonstrates how to define and use a custom `NormalizePhoneNumber` function that infers the user's country from request headers. Ensure the `libphonenumber-js/max` module is imported dynamically within the normalizer if not globally available. ```typescript import { phoneHarmony, type NormalizePhoneNumber } from 'better-auth-harmony/phone'; const customNormalizer: NormalizePhoneNumber = async (phoneNumber, request) => { // Custom logic: infer country from request headers const userCountry = request?.headers.get('cf-ipcountry') || 'US'; const { parsePhoneNumberWithError } = await import('libphonenumber-js/max'); const parsed = parsePhoneNumberWithError(phoneNumber, { defaultCountry: userCountry as any }); return parsed.number; }; export const auth = betterAuth({ plugins: [phoneHarmony({ normalizer: customNormalizer })] }); ``` -------------------------------- ### Usage of Main Entry Point Plugins Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Demonstrates how to import and use emailHarmony and phoneHarmony plugins with the main betterAuth function. ```typescript import { emailHarmony, phoneHarmony } from 'better-auth-harmony'; const auth = betterAuth({ plugins: [ emailHarmony(), phoneHarmony() ] }); ``` -------------------------------- ### Import Main Entry Point Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Shows the import path for the main entry point of the better-auth-harmony library. ```typescript // Import path: better-auth-harmony ``` -------------------------------- ### Main Exports Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Shows how to import the main emailHarmony and phoneHarmony plugins, along with their respective matchers modules. ```typescript import { emailHarmony, phoneHarmony } from 'better-auth-harmony'; import * as emailMatchers from 'better-auth-harmony/email/matchers'; import * as phoneMatchers from 'better-auth-harmony/phone/matchers'; ``` -------------------------------- ### Usage of Email Matchers Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Demonstrates importing and using email matchers for configuring the emailHarmony plugin. ```typescript import * as matchers from 'better-auth-harmony/email/matchers'; import { emailSignUp, emailSignIn } from 'better-auth-harmony/email/matchers'; const plugin = emailHarmony({ matchers: { validation: [matchers.emailSignUp, matchers.emailSignIn], signIn: [emailSignUp, emailSignIn] } }); ``` -------------------------------- ### Usage of Phone Module Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Demonstrates importing and using phoneHarmony plugin factory, PhoneHarmonyOptions type, and NormalizePhoneNumber type from the phone module. ```typescript import { phoneHarmony, PhoneHarmonyOptions } from 'better-auth-harmony/phone'; import type { NormalizePhoneNumber } from 'better-auth-harmony/phone'; // Plugin usage const plugin = phoneHarmony({ defaultCountry: 'US' }); // Type usage const normalizer: NormalizePhoneNumber = async (phone) => { // Custom normalization logic return phone; }; const options: PhoneHarmonyOptions = { normalizer }; ``` -------------------------------- ### Migrate Database Source: https://github.com/gekorm/better-auth-harmony/blob/main/README.md Run database migrations or generate schema changes. ```shell npx @better-auth/cli migrate ``` ```shell npx @better-auth/cli generate ``` -------------------------------- ### Email Harmony with Custom Email Validation Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-harmony.md Integrate a custom email validation function into emailHarmony. This example restricts signups to corporate emails ending with '@company.com'. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ emailHarmony({ validator: async (email) => { // Custom validation: only allow corporate emails return email.endsWith('@company.com'); } }) ] }); ``` -------------------------------- ### Usage of Email Module Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Demonstrates importing and using emailHarmony plugin factory, validateEmail function, and UserWithNormalizedEmail type from the email module. ```typescript import { emailHarmony, validateEmail, UserWithNormalizedEmail } from 'better-auth-harmony/email'; import type { EmailHarmonyOptions } from 'better-auth-harmony/email'; // Plugin usage const plugin = emailHarmony({ validator: validateEmail }); // Type usage const user: UserWithNormalizedEmail = { id: '123', email: 'user@example.com', normalizedEmail: 'user@example.com' }; ``` -------------------------------- ### Run CLI with Experimental Module Detection Source: https://github.com/gekorm/better-auth-harmony/blob/main/README.md Execute the CLI with experimental module detection to resolve ESM import errors. ```shell npx --node-options=--experimental-detect-module @better-auth/cli generate ``` -------------------------------- ### Examples of Invalid Phone Numbers Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/errors.md Provides a list of phone number strings that would typically cause parsing errors due to format, length, or country code issues. ```javascript invalidNumbers = [ '+0123456789', // Invalid country code (0) '+12', // Too short '+1234567890123456', // Too long '(555)', // Too short NSN 'not-a-number' // No digits ]; // Country-specific validation // US number must have 10 digits invalidUS = [ '+1555', // Too short for US '+15559', // Too short for US '555-1234' // Incomplete ]; // UK number must have 10 digits (plus country code) invalidUK = [ '+4420', // Too short '+442071' // Too short ]; ``` -------------------------------- ### Package Information Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Displays package metadata including name, version, license, and repository links. ```plaintext Name: better-auth-harmony Version: 1.3.2 License: MIT Repository: https://github.com/gekorm/better-auth-harmony NPM: https://www.npmjs.com/package/better-auth-harmony ``` -------------------------------- ### Configure Email Harmony Schema with Custom Field Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-harmony.md Example of configuring the `EmailHarmonySchema` to map the `normalizedEmail` field to a custom database column name, 'email_normalized'. This allows flexibility in database schema design. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony, type EmailHarmonySchema } from 'better-auth-harmony'; const schema: EmailHarmonySchema = { user: { fields: { normalizedEmail: 'email_normalized' } } }; export const auth = betterAuth({ plugins: [emailHarmony({ schema })] }); ``` -------------------------------- ### Import Email Matchers Module Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Shows the import path for the email matchers module of the better-auth-harmony library. ```typescript // Import path: better-auth-harmony/email/matchers ``` -------------------------------- ### Integrating Environment Variables for Configuration Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/configuration.md Configure better-auth-harmony using environment variables for database URLs, secrets, feature flags, and default countries. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony, phoneHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ // Database database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ emailHarmony({ // Feature flags from env allowNormalizedSignin: process.env.ALLOW_NORMALIZED_SIGNIN === 'true' }), phoneHarmony({ // Default country from env defaultCountry: (process.env.DEFAULT_COUNTRY || 'US') as any }) ] }); ``` -------------------------------- ### Handle Phone Number Parsing Errors Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md This example shows how to catch and handle errors when parsing phone numbers. It specifically targets the 'BAD_REQUEST' error with 'ParseError' details, which occurs if the phone number format is invalid. ```typescript try { await auth.updatePhoneNumber({ phoneNumber: input }); } catch (error) { // APIError with code 'BAD_REQUEST' // Message: ParseError details (e.g., 'TOO_SHORT', 'INVALID_COUNTRY_CODE') // Thrown when phone number parsing fails } ``` -------------------------------- ### Importing Functions and Types in TypeScript Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Demonstrates the correct way to import functions and types from the Better Auth Harmony library. Use 'type' keyword for importing types to enable tree-shaking. ```typescript // Functions (use import without 'type' keyword) import { emailHarmony } from 'better-auth-harmony'; import { validateEmail } from 'better-auth-harmony/email'; // Types (use 'type' keyword for tree-shaking) import type { UserWithNormalizedEmail } from 'better-auth-harmony/email'; import type { PhoneHarmonyOptions } from 'better-auth-harmony/phone'; ``` -------------------------------- ### ESM and CJS Import Compatibility Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Demonstrates how to import functions like emailHarmony using both ES Module (import) and CommonJS (require) syntax. ```typescript // ES Module (modern) import { emailHarmony } from 'better-auth-harmony'; // CommonJS (legacy) const { emailHarmony } = require('better-auth-harmony'); // Submodule ES Module import { validateEmail } from 'better-auth-harmony/email'; // Submodule CommonJS const { validateEmail } = require('better-auth-harmony/email'); ``` -------------------------------- ### Async Validator Example for Email Harmony Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/configuration.md Configures email Harmony with an asynchronous validator that checks email validity against an external validation service via a POST request. This allows for more complex or external validation logic. ```typescript import { betterAuth } from 'better-better-auth'; import { emailHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ plugins: [ emailHarmony({ validator: async (email) => { // Check against external validation service const response = await fetch('https://api.example.com/validate-email', { method: 'POST', body: JSON.stringify({ email }) }); const { valid } = await response.json(); return valid; } }) ] }); ``` -------------------------------- ### Default Entry Point Re-exports Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Illustrates how the main 'better-auth-harmony' module re-exports default exports from its email and phone submodules. ```typescript // src/index.ts export { default as emailHarmony } from './src/email'; export { default as phoneHarmony } from './src/phone'; ``` -------------------------------- ### Import Phone Module Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Shows the import path for the phone module of the better-auth-harmony library. ```typescript // Import path: better-auth-harmony/phone ``` -------------------------------- ### Import Email Module Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Shows the import path for the email module of the better-auth-harmony library. ```typescript // Import path: better-auth-harmony/email ``` -------------------------------- ### Add Auth Generate Script Source: https://github.com/gekorm/better-auth-harmony/blob/main/README.md Add a script to package.json to run the CLI with experimental module detection. ```json { "scripts": { "auth-generate": "NODE_OPTIONS=--experimental-detect-module cli generate" } } ``` -------------------------------- ### Configure better-auth-harmony Source: https://github.com/gekorm/better-auth-harmony/blob/main/README.md Add the emailHarmony plugin to your better-auth configuration. ```typescript // auth.ts import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ // ... other config options plugins: [emailHarmony()] }); ``` -------------------------------- ### Combined Phone Matchers Configuration Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-matchers.md Demonstrates a comprehensive configuration of Better Auth Harmony, integrating multiple phone-related matchers for various authentication steps including sign-in, OTP handling, verification, and password reset. Includes custom OTP sending logic. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; import * as matchers from 'better-auth-harmony/phone/matchers'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ phoneNumber({ sendOTP({ code }) { // Send OTP via SMS } }), phoneHarmony({ defaultCountry: 'US', matchers: [ matchers.signInPhone, matchers.phoneOtp, matchers.phoneVerify, matchers.phoneForget, matchers.phoneReset ] }) ] }); ``` -------------------------------- ### Email Recovery with Automatic Retry and Suggestions Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/errors.md Implement email signup with automatic retry logic for 'Invalid email' errors. It suggests common corrections for typos in email domains or addresses. ```typescript // Automatic retry with suggestion async function signupWithRecovery(email, password) { try { return await auth.signUp.email({ email, password }); } catch (error) { if (error?.message === 'Invalid email') { // Suggest fixing common issues const suggestions = [ { original: 'gmail.com', suggestion: 'gmail.com' }, { original: 'gmai.com', suggestion: 'gmail.com' }, { original: '@domain.cm', suggestion: '@domain.com' } ]; const fixed = suggestions.find(s => email.includes(s.original)); if (fixed) { const corrected = email.replace(fixed.original, fixed.suggestion); return await auth.signUp.email({ email: corrected, password }); } } throw error; } } ``` -------------------------------- ### Import and Use Email Matchers Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Import and utilize pre-made route matchers for various email-related authentication flows. This simplifies routing configuration for email sign-up, sign-in, password reset, and OTP verification. ```typescript import * as matchers from 'better-auth-harmony/email/matchers'; // Broad matchers matchers.allEmail // All 15 email routes matchers.allEmailSignIn // 11 signin/verification routes // Specific matchers matchers.emailSignUp // /sign-up/email matchers.emailSignIn // /sign-in/email matchers.emailForget // /request-password-reset, /forget-password matchers.changeEmail // /change-email // Email OTP matchers matchers.emailOtpVerify // /email-otp/verify-email matchers.emailOtpReset // /email-otp/reset-password matchers.emailOtpForget // /email-otp/request-password-reset // Magic Link matchers matchers.magicLinkSignIn // /sign-in/magic-link ``` -------------------------------- ### Import Email Matchers Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Import email matching utilities from the better-auth-harmony/email/matchers module. These are used for validating and processing email addresses during sign-up or sign-in. ```typescript import * as emailMatchers from 'better-auth-harmony/email/matchers'; import { emailSignUp, emailSignIn } from 'better-auth-harmony/email/matchers'; ``` -------------------------------- ### TypeScript Imports for Email and Phone Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Import necessary functions, types, and matchers for email and phone authentication modules in TypeScript. ```typescript import { emailHarmony, phoneHarmony } from 'better-auth-harmony'; import { validateEmail, type UserWithNormalizedEmail, type EmailHarmonyOptions } from 'better-auth-harmony/email'; import * as emailMatchers from 'better-auth-harmony/email/matchers'; import type { NormalizePhoneNumber, type PhoneHarmonyOptions } from 'better-auth-harmony/phone'; import * as phoneMatchers from 'better-auth-harmony/phone/matchers'; ``` -------------------------------- ### Magic Link Sign-In Matcher Usage Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md Shows the configuration for the magicLinkSignIn matcher, used for authenticating users via magic links. This is typically used with the Better Auth Magic Link plugin. ```typescript import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ matchers: { validation: [matchers.magicLinkSignIn] } }) ] }); ``` -------------------------------- ### Import Phone Matchers Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Import phone matching utilities from the better-auth-harmony/phone/matchers module. These are used for validating and processing phone numbers during sign-in. ```typescript import * as phoneMatchers from 'better-auth-harmony/phone/matchers'; import { signInPhone, phoneOtp } from 'better-auth-harmony/phone/matchers'; ``` -------------------------------- ### Handle Authentication Validation Errors Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Demonstrates how to catch and handle specific errors thrown during authentication, such as invalid email formats or phone parsing failures. ```typescript try { await auth.signUp.email({ email, password }); } catch (error) { if (error?.message === 'Invalid email') { // Handle email validation failure } else if (error?.message?.includes('ParseError')) { // Handle phone parsing failure } } ``` -------------------------------- ### Configure Phone Validation with Options Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/errors.md Configure phone validation with options like default country, allowing loose input, and strict error handling. Use `acceptRawInputOnError: true` to save raw input on error. ```typescript phoneHarmony({ defaultCountry: 'US', // Most users' country extract: true, // Allow loose input acceptRawInputOnError: false // Be strict on errors }) // For accepting invalid: // acceptRawInputOnError: true // Save raw input on error ``` -------------------------------- ### Frontend Email Validation Handling Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/errors.md Demonstrates a frontend approach to validating email formats before sending a request and handling potential server-side validation errors. ```typescript async function onEmailChange(email) { // Pre-validate before sending request if (!isValidEmailFormat(email)) { setError('Invalid email format'); return; } try { await signup(email); } catch (error) { if (error?.message?.includes('Invalid email')) { // Server validation also failed if (email.includes('@gmail.com')) { setError('Gmail addresses not allowed'); } else { setError('This email domain is not accepted'); } } else { setError('An error occurred'); } } } ``` -------------------------------- ### Configure phoneHarmony plugin Source: https://github.com/gekorm/better-auth-harmony/blob/main/README.md Add the phoneHarmony plugin to your better-auth configuration alongside the standard phoneNumber plugin. ```typescript // 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()] }); ``` -------------------------------- ### Phone Number Parsing with acceptRawInputOnError Enabled Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/errors.md Shows how enabling acceptRawInputOnError in phoneHarmony allows the system to fall back to using the raw input when parsing fails. ```typescript const auth = betterAuth({ plugins: [ phoneNumber(), phoneHarmony({ acceptRawInputOnError: true // Fall back to raw input }) ] }); // Behavior changes: // +12 (invalid) → saved as "+12" (unchanged) // (213) 373-4253 → normalized to "+12133734253" // My number is 213 → saved as "My number is 213" (unchanged) ``` -------------------------------- ### Import and Use Phone Matchers Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/INDEX.md Import and utilize pre-made route matchers for phone number authentication flows. This includes matchers for sign-in, OTP sending, verification, and password reset. ```typescript import * as matchers from 'better-auth-harmony/phone/matchers'; // Broad matcher matchers.allPhone // All 6 phone routes // Specific matchers matchers.signInPhone // /sign-in/phone-number matchers.phoneOtp // /phone-number/send-otp matchers.phoneVerify // /phone-number/verify matchers.phoneForget // /phone-number/request-password-reset matchers.phoneReset // /phone-number/reset-password ``` -------------------------------- ### Phone Harmony with Error Handling Fallback Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/phone-harmony.md Shows how to configure the phoneHarmony plugin to accept raw input on normalization errors, preventing exceptions and allowing invalid numbers to be saved as-is. ```typescript import { betterAuth } from 'better-auth'; import { phoneNumber } from 'better-auth/plugins'; import { phoneHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, plugins: [ phoneNumber(), phoneHarmony({ acceptRawInputOnError: true // Save "+12" as-is instead of throwing }) ] }); ``` -------------------------------- ### Change Email Matcher Usage Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-matchers.md Demonstrates how to integrate the changeEmail matcher for handling email address updates. This matcher is specifically designed for routes where users change their email. ```typescript import * as matchers from 'better-auth-harmony/email/matchers'; export const auth = betterAuth({ plugins: [ emailHarmony({ matchers: { validation: [matchers.changeEmail] } }) ] }); ``` -------------------------------- ### Phone Matchers Usage Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Import and use phone-related matchers with the phoneHarmony plugin. Ensure correct import paths for matchers. ```typescript import * as matchers from 'better-auth-harmony/phone/matchers'; import { signInPhone, phoneOtp } from 'better-auth-harmony/phone/matchers'; const plugin = phoneHarmony({ matchers: [matchers.signInPhone, matchers.phoneOtp, phoneOtp] }); ``` -------------------------------- ### User Interface with Normalized Email Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-harmony.md Demonstrates how to use the `UserWithNormalizedEmail` interface when `allowNormalizedSignin` is enabled in the adapter. This interface includes the optional `normalizedEmail` field. ```typescript import { emailHarmony, type UserWithNormalizedEmail } from 'better-auth-harmony'; // When allowNormalizedSignin is enabled, the adapter returns this type const user = await auth.api.adapter.findOne({ model: 'user', where: [{ field: 'normalizedEmail', value: 'john@gmail.com' }] }); if (user?.normalizedEmail) { console.log(`User logged in via normalized email: ${user.normalizedEmail}`); } ``` -------------------------------- ### Phone Module Re-exports Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Details the re-exporting mechanism for the 'better-auth-harmony/phone' module, consolidating exports from its primary index file. ```typescript // src/phone/index.ts export { default } from './index'; // phoneHarmony export { NormalizePhoneNumber, PhoneHarmonyOptions } from './index'; ``` -------------------------------- ### PhoneHarmonyOptions Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/exports-reference.md Interface for configuration options specific to the phone harmony plugin. ```APIDOC ## PhoneHarmonyOptions ### Description Defines the structure for configuration options when initializing the phone harmony plugin. ### Import Path `better-auth-harmony/phone` ### Type Definition ```typescript interface PhoneHarmonyOptions { defaultCountry?: string; normalizer?: NormalizePhoneNumber; // other options... } ``` ``` -------------------------------- ### Email Harmony with Normalized Signin Enabled Source: https://github.com/gekorm/better-auth-harmony/blob/main/_autodocs/api-reference/email-harmony.md Configure emailHarmony to allow users to sign in with any variation of their email address, not just the normalized one. This can increase database load. ```typescript import { betterAuth } from 'better-auth'; import { emailHarmony } from 'better-auth-harmony'; export const auth = betterAuth({ database: process.env.DATABASE_URL, secret: process.env.AUTH_SECRET, emailAndPassword: { enabled: true, }, plugins: [ emailHarmony({ allowNormalizedSignin: true }) ] }); // User signs up with: johndoe+newsletter@gmail.com // Can now login with: johndoe@gmail.com, john.doe@gmail.com, etc. ```