Skip to main content

Email Verification

node-auth supports three email-verification enforcement modes:

ModeBehaviour
'none'Email verification is never required (default)
'lazy'User may log in until emailVerificationDeadline is reached, then login is blocked
'strict'Login is blocked immediately if isEmailVerified !== true

Verification flow


Configuration

const auth = new AuthConfigurator({
accessTokenSecret: process.env.ACCESS_TOKEN_SECRET!,
refreshTokenSecret: process.env.REFRESH_TOKEN_SECRET!,

emailVerificationMode: 'lazy', // 'none' | 'lazy' | 'strict'

email: {
siteUrl: 'https://yourapp.com', // used to build the verification link
mailer: { /* … see Mailer guide */ },
// or use the callback override:
// sendVerificationEmail: async (to, token, link) => { … }
},
}, userStore);

Lazy mode: set emailVerificationDeadline

In 'lazy' mode users can log in for a grace period. Set the deadline when creating the user:

onRegister: async (data) => {
const gracePeriodDays = 7;
const deadline = new Date();
deadline.setDate(deadline.getDate() + gracePeriodDays);

return userStore.create({
email: data.email as string,
password: await passwordService.hash(data.password as string),
emailVerificationDeadline: deadline,
});
},

After emailVerificationDeadline, POST /auth/login returns:

{ "error": "Email verification required", "code": "EMAIL_NOT_VERIFIED" }

Implement IUserStore methods

// Required for email verification
async updateEmailVerificationToken(userId, token, expiry) { /* … */ }
async updateEmailVerified(userId, isVerified) { /* … */ }
async findByEmailVerificationToken(token) { /* … */ }

Endpoints

MethodPathAuthDescription
POST/auth/send-verification-emailGenerate token + send verification email
GET/auth/verify-email?token={token}Verify token → mark email as verified

GET /auth/verify-email redirect

When email.siteUrl is configured, the verify endpoint redirects to:

{siteUrl}/email-verified?success=true

or on failure:

{siteUrl}/email-verified?error=INVALID_TOKEN

If siteUrl is not set, it returns a JSON response { "success": true }.