Email & SMS Providers
Configure how nauth-toolkit sends emails and SMS messages. Pick a provider for each channel and pass it to your auth configuration.
Email Providers
Install the Nodemailer-based email provider:
- npm
- Yarn
- pnpm
- Bun
npm install @nauth-toolkit/email-nodemailer
yarn add @nauth-toolkit/email-nodemailer
pnpm add @nauth-toolkit/email-nodemailer
bun add @nauth-toolkit/email-nodemailer
- SMTP
- AWS SES
- SendGrid
- Custom Provider
import { NodemailerEmailProvider } from '@nauth-toolkit/email-nodemailer';
{
emailProvider: new NodemailerEmailProvider({
transport: {
host: 'smtp.example.com',
port: 587,
secure: false,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
},
defaults: {
from: '"My App" <noreply@example.com>',
},
}),
}
Uses AWS SDK v3 with IAM role discovery. No credentials needed on EC2/ECS/Lambda.
- npm
- Yarn
- pnpm
- Bun
npm install @aws-sdk/client-sesv2
yarn add @aws-sdk/client-sesv2
pnpm add @aws-sdk/client-sesv2
bun add @aws-sdk/client-sesv2
import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2';
import { NodemailerEmailProvider } from '@nauth-toolkit/email-nodemailer';
{
emailProvider: new NodemailerEmailProvider({
transport: {
SES: {
sesClient: new SESv2Client({
region: process.env.AWS_REGION || 'us-east-1',
}),
SendEmailCommand,
},
},
defaults: {
from: '"My App" <noreply@example.com>',
},
}),
}
import { NodemailerEmailProvider } from '@nauth-toolkit/email-nodemailer';
{
emailProvider: new NodemailerEmailProvider({
transport: {
service: 'SendGrid',
auth: {
user: 'apikey',
pass: process.env.SENDGRID_API_KEY,
},
},
defaults: {
from: '"My App" <noreply@example.com>',
},
}),
}
Implement the EmailProvider interface to use any email service:
import { EmailProvider } from '@nauth-toolkit/core';
class MyEmailProvider implements EmailProvider {
async sendVerificationEmail(to: string, code: string, link?: string, expiryMinutes?: number): Promise<void> {
await myService.send({
to,
subject: 'Verify your email',
html: `Code: ${code}${link ? ` | <a href="${link}">Verify</a>` : ''}`,
});
}
async sendMFAEmailCode(to: string, code: string, expiryMinutes?: number): Promise<void> {
await myService.send({ to, subject: 'Your sign-in code', html: `Code: ${code}` });
}
async sendPasswordResetEmail(to: string, _token: string, code: string, link?: string, expiryMinutes?: number): Promise<void> {
await myService.send({ to, subject: 'Reset your password', html: `Code: ${code}` });
}
async sendAdminPasswordResetEmail(to: string, code: string, link?: string, expiryMinutes?: number): Promise<void> {
await myService.send({ to, subject: 'Password reset', html: `Code: ${code}` });
}
async sendWelcomeEmail(to: string, name: string): Promise<void> {
await myService.send({ to, subject: 'Welcome!', html: `Hi ${name}` });
}
// Optional notification methods (implement only the ones you need):
// sendPasswordChangedEmail?, sendLockoutEmail?, sendNewDeviceEmail?,
// sendAccountLockedEmail?, sendSessionsRevokedEmail?, sendMFAFirstEnabledEmail?,
// sendMFAMethodAddedEmail?, sendMFADeviceRemovedEmail?, sendAdaptiveMFARiskAlertEmail?,
// sendAccountDisabledEmail?, sendAccountEnabledEmail?, sendEmailChangedAlertEmail?,
// sendEmailChangedConfirmationEmail?
}
{
emailProvider: new MyEmailProvider(),
}
Console provider (development)
For local development, log emails to the console instead of sending them:
- npm
- Yarn
- pnpm
- Bun
npm install @nauth-toolkit/email-console
yarn add @nauth-toolkit/email-console
pnpm add @nauth-toolkit/email-console
bun add @nauth-toolkit/email-console
import { ConsoleEmailProvider } from '@nauth-toolkit/email-console';
{
emailProvider: new ConsoleEmailProvider(),
}
SMS Providers
- AWS SNS
- Console (Development)
- Custom Provider
- npm
- Yarn
- pnpm
- Bun
npm install @nauth-toolkit/sms-aws-sns
yarn add @nauth-toolkit/sms-aws-sns
pnpm add @nauth-toolkit/sms-aws-sns
bun add @nauth-toolkit/sms-aws-sns
import { AWSSMSProvider } from '@nauth-toolkit/sms-aws-sns';
{
smsProvider: new AWSSMSProvider({
region: 'us-east-1',
originationNumber: process.env.AWS_SMS_ORIGINATION || '+12345678901',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
}),
}
AWS SNS supports two API modes:
| Mode | Config | Description |
|---|---|---|
'sns' (default) | apiMode: 'sns' | Standard SNS Publish API |
'end-user-messaging-sms' | apiMode: 'end-user-messaging-sms' | AWS End User Messaging SMS API (supports configuration sets) |
new AWSSMSProvider({
region: 'us-east-1',
originationNumber: process.env.AWS_SMS_ORIGINATION,
apiMode: 'end-user-messaging-sms',
configurationSetName: 'my-config-set',
})
Logs SMS messages to the console instead of sending them:
- npm
- Yarn
- pnpm
- Bun
npm install @nauth-toolkit/sms-console
yarn add @nauth-toolkit/sms-console
pnpm add @nauth-toolkit/sms-console
bun add @nauth-toolkit/sms-console
import { ConsoleSMSProvider } from '@nauth-toolkit/sms-console';
{
smsProvider: new ConsoleSMSProvider(),
}
Implement the SMSProvider interface to use any SMS service (Twilio, MessageBird, Vonage, etc.):
import { SMSProvider, SMSTemplateEngine, SMSTemplateVariables } from '@nauth-toolkit/core';
class TwilioSMSProvider implements SMSProvider {
private templateEngine?: SMSTemplateEngine;
private globalVariables: SMSTemplateVariables = {};
setTemplateEngine(engine: SMSTemplateEngine): void {
this.templateEngine = engine;
}
setGlobalVariables(variables: SMSTemplateVariables): void {
this.globalVariables = variables;
}
async sendOTP(
phone: string,
code: string,
templateType?: string,
variables?: Record<string, unknown>,
): Promise<void> {
let message: string;
if (this.templateEngine && templateType) {
const allVariables: SMSTemplateVariables = {
...this.globalVariables,
code,
...(variables as SMSTemplateVariables),
};
const template = await this.templateEngine.render(templateType, allVariables);
message = template.content;
} else {
message = `Your verification code is: ${code}`;
}
await twilioClient.messages.create({
to: phone,
from: this.fromNumber,
body: message,
});
}
}
{
smsProvider: new TwilioSMSProvider({
accountSid: process.env.TWILIO_ACCOUNT_SID,
authToken: process.env.TWILIO_AUTH_TOKEN,
fromNumber: '+1234567890',
}),
}
When implementing a custom provider, call this.templateEngine.render() if a template engine is set. This ensures your custom templates and global variables work correctly. Fall back to a hardcoded message if no engine is available.
What's Next
- Email Templates --- Customize email templates and enable security notifications
- SMS Templates --- Customize SMS message wording
- Notifications & Templates --- All template types, variables, and Handlebars syntax reference