Browse documentation

Three delivery channels, all driven by settings groups rather than environment variables, so changing one takes effect on the next send.

ChannelServiceSettings group
Emailservices/transporter.service.ts (nodemailer)email.smtp, email.templates
SMSservices/sms.service.ts (Twilio)phone.sms
Pushservices/notification/notification.service.tspush.fcm, push.apns

Email

TransporterService builds a nodemailer transport from the email.smtp group and caches it against a fingerprint — a hash of the resolved config. Change SMTP settings in Studio and the next sendMail rebuilds the transport automatically; nothing restarts.

await transporterService.sendMail({ to, subject, html })
await transporterService.sendTestEmail(to)   // returns { ok: true, ms }

The from address falls back to the SMTP username when from is empty.

The same transport backs sendMail() inside edge functions: configure SMTP once and function code inherits it.

Templates

Auth emails are templated and editable in the email.templates group (apps/server/auth/email-templates.ts):

KindTemplates
OTPverification subject/body, recovery subject/body
Linksmagic-link subject/body, verify-link subject/body

Emails are branded with APP_NAME (default Motherbase), which is also the fallback TOTP issuer when auth.twoFactor.issuer is empty. Set it per project so a client never receives mail under someone else's name.

Each has a frozen default (DEFAULT_AUTH_EMAIL_TEMPLATES, DEFAULT_AUTH_LINK_TEMPLATES) used whenever your override is absent. Templates are interpolated with a fixed variable set and validated by isSafeAuthEmailSubjectTemplate / isSafeAuthEmailBodyTemplate (and the link equivalents) before use — a rejected template falls back to the default rather than sending something malformed.

Note

Passwordless sign-in (magic link, email OTP, password reset) requires working SMTP. Configure it before enabling those methods in Authentication.

SMS

SmsService is provider-agnostic behind an internal SmsProvider interface, with Twilio implemented today. Credentials come from phone.sms and are shared by phone OTP sign-in, MFA second factor, and notifications.

Required config: accountSid, authToken, and either from or messagingServiceSid. Missing any of those raises:

Twilio SMS is not fully configured (accountSid, authToken and from/messagingServiceSid required).

The call is a plain POST to https://api.twilio.com/2010-04-01/Accounts/<sid>/Messages.json with basic auth.

Push

NotificationService is a device registry plus a fan-out that routes by platform:

PlatformProvider
iosAPNs (services/notification/apns.provider.ts)
android, webFCM (services/notification/fcm.provider.ts)
registerDevice(userId, token, platform)   // upsert on token
unregisterDevice(token, userId)
sendToUser(userId, { title, body, data })

Results come back as { token, success, error?, invalid? }. Tokens the provider reports as permanently invalid are deleted from the devices table on the spot, so the registry self-cleans. A disabled provider does not throw — every token gets success: false, error: 'Push provider not configured'.

Provider credentials come from push.fcm / push.apns; the env variables FIREBASE_* and APNS_* seed them (see environment).

Endpoints

MethodPathGuardPurpose
POST/api/devices/session + validatorRegister a push token
DELETE/api/devices/session + validatorUnregister a token
POST/api/notifications/sendsession with role ADMINSend to a user
POST/api/notifications/testsession + validatorTest delivery

Full route table: Admin & HTTP API reference.

  • Auth — the flows that send these emails and SMS codes.
  • Settings reference — every field of email.smtp, email.templates, phone.sms, push.fcm and push.apns.