Docs · Emails

Email pipeline

Every email has a template at app/email_defaults/<name>.body.html and <name>.subject.txt. The admin can override either of them in /admin/settings#templates. Placeholders are substituted via render_email_template().

Available emails

EmailTriggerTemplateGates
loginSuccessful login (incl. social)loginusers.notifySessions = 1
loginCodeEmail passwordless: send 6-digit codeloginCodealways (rate-limited separately)
reset"Forgot my PIN" → reset linkresetalways
monthlyDay 1 of the month (cron)monthlynotifyMonthly=1 + plan_feature(monthly_summary_email) + ≥1 prior scan
breachAlertAfter a manual scan with new compromised passwordsbreachAlertnotifyBreaches=1 + plan_feature(basic OR realtime)
breachDigestDaily cron, if HIBP published new breachesbreachDigestnotifyBreaches=1 + plan_feature(basic OR realtime)
emergency_inviteAdmin designates an emergency contactemergency_invite
emergency_requestContact requests accessemergency_requestSent to the vault owner
emergency_grantedWait period elapsed without denial → contact receives the encrypted recovery codeemergency_grantedSent to the contact
emergency_deniedOwner denies the request manuallyemergency_deniedSent to the contact

All emails are wrapped in a shared HTML layout (wrap_email_html()) that adapts to light/dark via CSS media queries.

Email i18n

Every send_*_email() function wraps its body in with_lang($recipient_lang, callable). This temporarily swaps $config['LANG_CODE'] so the template is rendered in the recipient's preferred language, regardless of which language the originating request happens to be in.

Subjects and bodies are also listed in translatable_settings_list(), so when the admin saves a template, translate_now() auto-translates it to every installed language. See i18n & auto-translation for the full pipeline.

Sending method

Configured in /admin/settings#email:

The sender address and display name are set globally. A "Send test" button delivers a synthetic email to the admin to verify the config.

Defense in depth: gates at send time

Every email gate is rechecked at the moment of sending. Even if the user has a toggle ON, the sender re-evaluates plan_feature() — an email the plan no longer allows is never delivered. This protects against the "I downgraded but the toggle stayed on" race.

FortPass · © 2026 Medel Platforms · medel.es