refactor: unify smtp config logic
This commit is contained in:
parent
e95c1d6254
commit
e8f27690a1
6 changed files with 162 additions and 54 deletions
58
lib/mv/smtp/config_builder.ex
Normal file
58
lib/mv/smtp/config_builder.ex
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
defmodule Mv.Smtp.ConfigBuilder do
|
||||
@moduledoc """
|
||||
Builds Swoosh/gen_smtp SMTP adapter options from connection parameters.
|
||||
|
||||
Single source of truth for TLS/sockopts logic (port 587 vs 465):
|
||||
- Port 587 (STARTTLS): `gen_tcp` is used first; `sockopts` must NOT contain `:verify`.
|
||||
- Port 465 (implicit SSL): initial connection is `ssl:connect`; `sockopts` must contain `:verify`.
|
||||
|
||||
Used by `config/runtime.exs` (boot-time ENV) and `Mv.Mailer.smtp_config/0` (Settings-only).
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Builds the keyword list of Swoosh SMTP adapter options.
|
||||
|
||||
Options (keyword list):
|
||||
- `:host` (required) — relay hostname
|
||||
- `:port` (required) — port number (e.g. 587 or 465)
|
||||
- `:ssl_mode` (required) — `"tls"` or `"ssl"`
|
||||
- `:verify_mode` (required) — `:verify_peer` or `:verify_none`
|
||||
- `:username` (optional)
|
||||
- `:password` (optional)
|
||||
|
||||
Nil values are stripped from the result.
|
||||
"""
|
||||
@spec build_opts(keyword()) :: keyword()
|
||||
def build_opts(opts) do
|
||||
host = Keyword.fetch!(opts, :host)
|
||||
port = Keyword.fetch!(opts, :port)
|
||||
username = Keyword.get(opts, :username)
|
||||
password = Keyword.get(opts, :password)
|
||||
ssl_mode = Keyword.fetch!(opts, :ssl_mode)
|
||||
verify_mode = Keyword.fetch!(opts, :verify_mode)
|
||||
|
||||
base_opts = [
|
||||
adapter: Swoosh.Adapters.SMTP,
|
||||
relay: host,
|
||||
port: port,
|
||||
username: username,
|
||||
password: password,
|
||||
ssl: ssl_mode == "ssl",
|
||||
tls: if(ssl_mode == "tls", do: :always, else: :never),
|
||||
auth: :always,
|
||||
# tls_options: used for STARTTLS (587). For 465, gen_smtp uses sockopts for initial ssl:connect.
|
||||
tls_options: [verify: verify_mode]
|
||||
]
|
||||
|
||||
# Port 465: initial connection is ssl:connect; pass verify in sockopts.
|
||||
# Port 587: initial connection is gen_tcp; sockopts must NOT contain verify (gen_tcp rejects it).
|
||||
opts =
|
||||
if ssl_mode == "ssl" do
|
||||
Keyword.put(base_opts, :sockopts, verify: verify_mode)
|
||||
else
|
||||
base_opts
|
||||
end
|
||||
|
||||
Enum.reject(opts, fn {_k, v} -> is_nil(v) end)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue