diff --git a/config/runtime.exs b/config/runtime.exs index 9d8bf67..7034cd0 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -22,6 +22,13 @@ int_env = fn name, default -> end end +bool_env = fn name, default -> + case System.get_env(name) do + nil -> default + value -> value in ~w(true 1) + end +end + non_prod? = config_env() != :prod api_default_request_size_cap = if non_prod?, do: 2_000_000, else: 1_000_000 @@ -168,11 +175,41 @@ if config_env() == :prod do # pool_count: 4, socket_options: maybe_ipv6 - config :acai, Acai.Mailer, - adapter: Swoosh.Adapters.Mailgun, - api_key: System.get_env("MAILGUN_API_KEY"), - domain: System.get_env("MAILGUN_DOMAIN"), - base_url: System.get_env("MAILGUN_BASE_URL") + if smtp_host = System.get_env("SMTP_HOST") do + smtp_ssl = bool_env.("SMTP_SSL", false) + + smtp_cacerts = + CAStore.file_path() + |> File.read!() + |> :public_key.pem_decode() + |> Enum.map(fn {_, der, _} -> der end) + + smtp_tls_opts = [ + versions: [:"tlsv1.2", :"tlsv1.3"], + verify: :verify_peer, + cacerts: smtp_cacerts, + depth: 99, + server_name_indication: String.to_charlist(smtp_host) + ] + + config :acai, Acai.Mailer, + adapter: Swoosh.Adapters.SMTP, + relay: smtp_host, + port: int_env.("SMTP_PORT", 587), + username: System.get_env("SMTP_USERNAME"), + password: System.get_env("SMTP_PASSWORD"), + ssl: smtp_ssl, + tls: if(smtp_ssl, do: :never, else: :always), + auth: :always, + tls_options: smtp_tls_opts, + sockopts: smtp_tls_opts + else + config :acai, Acai.Mailer, + adapter: Swoosh.Adapters.Mailgun, + api_key: System.get_env("MAILGUN_API_KEY"), + domain: System.get_env("MAILGUN_DOMAIN"), + base_url: System.get_env("MAILGUN_BASE_URL") + end # See https://hexdocs.pm/swoosh/Swoosh.html#module-installation for details. config :swoosh, :api_client, Swoosh.ApiClient.Req diff --git a/infra/.env.example b/infra/.env.example index 7ac44b7..14d372b 100644 --- a/infra/.env.example +++ b/infra/.env.example @@ -15,12 +15,21 @@ # devcontainer | devrelease | prod CADDYFILE=devcontainer -### Mailgun (for sending emails) +### Email transport (choose one of the two options below) + +# Option A: Mailgun MAILGUN_DOMAIN=mail.example.com # sender key for the above domain MAILGUN_API_KEY=inject_with_secret_manager MAILGUN_BASE_URL=https://api.eu.mailgun.net/v3 +# Option B: Custom SMTP (takes priority over Mailgun when SMTP_HOST is set) +# SMTP_HOST=smtp.example.com +# SMTP_PORT=587 +# SMTP_USERNAME=user@example.com +# SMTP_PASSWORD=inject_with_secret_manager +# SMTP_SSL=false # set to true for implicit TLS / SMTPS (port 465); false = STARTTLS (port 587) + ### Email sender configuration (for white-labeling) # Display name in "From" field (defaults to your app name) MAIL_FROM_NAME=My App diff --git a/mix.exs b/mix.exs index 942f836..7349ade 100644 --- a/mix.exs +++ b/mix.exs @@ -42,10 +42,12 @@ defmodule Acai.MixProject do [ {:argon2_elixir, "~> 4.0"}, {:bandit, "~> 1.10.4"}, + {:castore, ">= 0.0.0"}, {:dns_cluster, "~> 0.2.0"}, {:ecto_psql_extras, "~> 0.8"}, {:ecto_sql, "~> 3.13"}, {:esbuild, "~> 0.10", runtime: Mix.env() == :dev}, + {:gen_smtp, "~> 1.0"}, {:gettext, "~> 1.0"}, {:heroicons, github: "tailwindlabs/heroicons",