Auth Delivery Hooks
Transactional auth delivery hooks live under:
auth.handlers.email.onSendauth.handlers.sms.onSend
Use them to modify or block verification emails, password reset emails, magic links, email OTP, email change messages, and phone OTP/SMS login messages.
Email Hook
import { defineConfig } from '@edgebase/shared';
export default defineConfig({
email: {
provider: 'resend',
apiKey: process.env.EMAIL_API_KEY!,
from: 'noreply@myapp.com',
},
auth: {
handlers: {
email: {
onSend: async (type, to, subject, html, ctx, locale) => {
if (to.endsWith('@disposable.test')) {
throw new Error('Disposable email addresses are not allowed.');
}
return {
subject,
html: `<div data-locale="${locale ?? 'en'}">${html}</div>`,
};
},
},
},
},
});
Signature
type MailType =
| 'verification'
| 'passwordReset'
| 'magicLink'
| 'emailOtp'
| 'emailChange';
type EmailOnSend = (
type: MailType,
to: string,
subject: string,
html: string,
ctx: { waitUntil(promise: Promise<unknown>): void },
locale?: string,
) => Promise<{ subject?: string; html?: string } | void>
| { subject?: string; html?: string }
| void;
SMS Hook
export default defineConfig({
sms: {
provider: 'twilio',
accountSid: process.env.TWILIO_ACCOUNT_SID!,
authToken: process.env.TWILIO_AUTH_TOKEN!,
from: '+15551234567',
},
auth: {
handlers: {
sms: {
onSend: async (type, to, body) => {
if (type === 'phoneOtp') {
return { body: `[MyApp] ${body}` };
}
},
},
},
},
});
Signature
type SmsType = 'phoneOtp' | 'phoneLink';
type SmsOnSend = (
type: SmsType,
to: string,
body: string,
ctx: { waitUntil(promise: Promise<unknown>): void },
) => Promise<{ body?: string } | void>
| { body?: string }
| void;
Behavior
- Blocking hooks
- Timeout is
5s - Throw to reject delivery
- Return partial overrides to rewrite the outbound message
ctx.waitUntil(...)is available for background side effects