6.2 KiB
SMTP Configuration – Concept
Status: Draft
Last updated: 2026-03-11
1. Goal
Enable configurable SMTP for sending transactional emails (join confirmation, user confirmation, password reset). Configuration via environment variables and Admin Settings (database), with the same precedence pattern as OIDC and Vereinfacht: ENV overrides Settings. Include a test email action in Settings (button + recipient field) with clear success/error feedback.
2. Scope
- In scope: SMTP server configuration (host, port, credentials, TLS/SSL), test email from Settings UI, warning when SMTP is not configured in production.
- Out of scope: Changing how AshAuthentication or existing senders use the mailer; they keep using
Mv.Mailerandmail_from/0. No separate "form_mail" config – the existing mail_from (MAIL_FROM_NAME, MAIL_FROM_EMAIL) remains the single sender identity for all transactional mails.
3. Configuration Sources
| Source | Priority | Use case |
|---|---|---|
| ENV | 1 | Production, Docker, 12-factor |
| Settings | 2 | Admin UI, dev without ENV |
When an ENV variable is set, the corresponding Settings field is read-only in the UI (with hint "Set by environment").
4. SMTP Parameters
| Parameter | ENV | Settings attribute | Notes |
|---|---|---|---|
| Host | SMTP_HOST |
smtp_host |
e.g. smtp.example.com |
| Port | SMTP_PORT |
smtp_port |
Default 587 (TLS), 465 (SSL), 25 (plain) |
| Username | SMTP_USERNAME |
smtp_username |
Optional if no auth |
| Password | SMTP_PASSWORD |
smtp_password |
Sensitive, not shown when set |
| Password | SMTP_PASSWORD_FILE |
— | Docker/Secrets: path to file with password |
| TLS/SSL | SMTP_SSL or similar |
smtp_ssl |
e.g. tls / ssl / none (default: tls) |
Sender (unchanged): mail_from stays separate (MAIL_FROM_NAME, MAIL_FROM_EMAIL in ENV; no DB fields for from-address).
5. Password from File
Support SMTP_PASSWORD_FILE (path to file containing the password), same pattern as OIDC_CLIENT_SECRET_FILE and TOKEN_SIGNING_SECRET_FILE in runtime.exs. Read once at runtime when building mailer config; ENV SMTP_PASSWORD overrides file if both are set (or define explicit precedence and document it).
6. Behaviour When SMTP Is Not Configured
- Dev/Test: Keep current adapters (
Swoosh.Adapters.Local,Swoosh.Adapters.Test). No change. - Production: If neither ENV nor Settings provide SMTP (e.g. no host):
- Keep using the default adapter (e.g. Local) or a no-op adapter so the app does not crash.
- Show a clear warning in the Settings UI (SMTP section): e.g. "SMTP is not configured. Transactional emails (join confirmation, password reset, etc.) will not be delivered reliably." and optionally list consequences (no join confirmations, no password resets, etc.).
- Log a warning at startup or when sending is attempted if SMTP is not configured in prod.
7. Test Email (Settings UI)
- Location: SMTP / E-Mail section in Global Settings (same page as OIDC, Vereinfacht).
- Elements:
- Input: recipient email address (required for sending).
- Button: "Send test email" (or similar).
- Behaviour: On click, send one simple transactional-style email to the given address (subject and body translatable via Gettext, e.g. "Mila – Test email" / "This is a test."). Use current SMTP config and
mail_from. - Feedback: Show success message or error (e.g. connection refused, auth failed, invalid address). Reuse the same UI pattern as Vereinfacht "Test Integration" (result assign, small result component with success/error states).
- Permission: Reuse existing Settings page authorization (admin); no extra check for the test-email action.
8. Implementation Hints
- Config module: Extend
Mv.Configwithsmtp_*helpers (e.g.smtp_host/0,smtp_port/0, …) usingenv_or_setting/2and, for password, ENV vsSMTP_PASSWORD_FILEvs Settings (sensitive). - runtime.exs: When SMTP is configured (e.g. host present), set
config :mv, Mv.Mailer, adapter: Swoosh.Adapters.SMTP, ...with the merged options. Otherwise leave adapter as in base config (Local in dev, Test in test, and in prod either Local with warning or explicit "not configured" behaviour). - Setting resource: New attributes:
smtp_host,smtp_port,smtp_username,smtp_password(sensitive),smtp_ssl(string or enum). Add to create/updateacceptlists and to seeds if needed. - Migration: Add columns for the new Setting attributes.
- Test email: New function (e.g.
Mv.Mailer.send_test_email(to_email)) returning{:ok, _}or{:error, reason}; call from LiveView event and render result in the SMTP section.
9. Documentation and i18n
- Gettext: Use Gettext for test email subject and body and for all new Settings labels/hints (including the "SMTP not configured" warning).
- Docs: Update
CODE_GUIDELINES.md(e.g. §3.11 Email) and deployment/configuration docs to describe ENV and Settings for SMTP and the test email. Add this feature todocs/feature-roadmap.md(e.g. under Admin Panel & Configuration or Communication).
10. Summary Checklist
- ENV:
SMTP_HOST,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORD,SMTP_PASSWORD_FILE,SMTP_SSL(or equivalent). - Settings: attributes and UI for host, port, username, password, TLS/SSL; ENV-override hints.
- Password from file:
SMTP_PASSWORD_FILEsupported in runtime config. - Mailer: Swoosh SMTP adapter configured from merged ENV + Settings when SMTP is configured.
- Prod warning: clear message in Settings when SMTP is not configured, with consequences.
- Test email: button + recipient field, translatable content, success/error display; existing permission sufficient.
- Gettext for new UI and test email text.
- Feature roadmap and code guidelines updated.