Authentication & MFA
Login checks password, account status, email verification, and optional two-factor authentication.
Login
app.post("/login", async (req, res) => {
try {
await req.auth.login(req.body.email, req.body.password, req.body.remember);
res.json({ success: true });
} catch (error) {
if (error.name === "SecondFactorRequiredError") {
return res.status(202).json({
requiresTwoFactor: true,
availableMethods: error.availableMethods,
});
}
res.status(401).json({ error: error.message });
}
});
The login method:
- Finds the account by email
- Verifies the password hash
- Checks that the email is verified
- Checks that the account status is
Normal(not banned, locked, etc.) - If 2FA is enabled and the user has verified methods, throws
SecondFactorRequiredError - Otherwise, creates a session and optionally sets a remember-me token
Two-Factor Challenge
When SecondFactorRequiredError is thrown, the user is not logged in yet. The error includes availableMethods describing which mechanisms are available (TOTP, email, SMS). The session holds an awaitingTwoFactor state with an expiry.
Return the available methods to the client so it can show the appropriate UI. Do not return raw OTP codes to the client - send them via your email/SMS service.
Completing 2FA
app.post("/verify-2fa", async (req, res) => {
const { code, method } = req.body;
switch (method) {
case "totp":
await req.auth.twoFactor.verify.totp(code);
break;
case "email":
await req.auth.twoFactor.verify.email(code);
break;
case "sms":
await req.auth.twoFactor.verify.sms(code);
break;
case "backup":
await req.auth.twoFactor.verify.backupCode(code);
break;
case "otp":
await req.auth.twoFactor.verify.otp(code);
break;
}
await req.auth.completeTwoFactorLogin();
res.json({ success: true });
});
verify.otp() is a smart verifier that tries both email and SMS OTP methods automatically.
Remember Me
Login with remember: true creates a persistent token in {prefix}remembers and sets an httpOnly cookie. On future requests, the middleware auto-restores the session from the cookie.
Configure the duration and cookie name in AuthConfig:
Logout
logout()clears the current session and remember tokenlogoutEverywhere()clears all sessions and remember tokenslogoutEverywhereElse()keeps the current session, clears everything else