mitgliederverwaltung/docs/smtp-configuration-concept.md

6.2 KiB
Raw Blame History

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.Mailer and mail_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.Config with smtp_* helpers (e.g. smtp_host/0, smtp_port/0, …) using env_or_setting/2 and, for password, ENV vs SMTP_PASSWORD_FILE vs 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/update accept lists 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 to docs/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_FILE supported 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.