namespace email settings keys per adapter
All checks were successful
deploy / deploy (push) Successful in 57s

Settings keys like api_key were shared across providers, so switching
from e.g. Postmark to SendGrid showed the old API key. Now each
adapter gets its own namespaced key (email_postmark_api_key, etc.)
so credentials persist independently and switching back pre-fills
previously saved values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-21 19:57:23 +00:00
parent 366a1e6a48
commit 194fec8240
6 changed files with 72 additions and 34 deletions

View File

@@ -30,6 +30,26 @@ defmodule BerrypodWeb.Admin.EmailSettings do
|> assign(:form, to_form(%{}, as: :email))}
end
defp load_adapter_values(adapter_key) do
case Adapters.get(adapter_key) do
nil ->
%{}
adapter_info ->
for field <- adapter_info.fields, into: %{} do
settings_key = Adapters.settings_key(adapter_key, field.key)
value =
case field.type do
:secret -> Settings.secret_hint(settings_key)
_ -> Settings.get_setting(settings_key)
end
{field.key, value}
end
end
end
defp provider_options do
Enum.map(Adapters.all(), fn adapter ->
%{
@@ -44,7 +64,8 @@ defmodule BerrypodWeb.Admin.EmailSettings do
@impl true
def handle_event("change_adapter", %{"email" => %{"adapter" => key}}, socket) do
{:noreply, assign(socket, :adapter_key, key)}
values = load_adapter_values(key)
{:noreply, socket |> assign(:adapter_key, key) |> assign(:current_values, values)}
end
def handle_event("save", %{"email" => params}, socket) do
@@ -113,8 +134,9 @@ defmodule BerrypodWeb.Admin.EmailSettings do
|> Enum.filter(fn field ->
val = params[field.key]
empty = is_nil(val) or val == ""
settings_key = Adapters.settings_key(adapter_info.key, field.key)
# Secret fields can be left blank to keep existing value
empty and not (field.type == :secret and Settings.get_secret("email_#{field.key}") != nil)
empty and not (field.type == :secret and Settings.get_secret(settings_key) != nil)
end)
if missing != [] do
@@ -124,17 +146,10 @@ defmodule BerrypodWeb.Admin.EmailSettings do
# Save adapter type
Settings.put_setting("email_adapter", adapter_info.key)
# Clear fields from other adapters
current_keys = MapSet.new(Enum.map(adapter_info.fields, &"email_#{&1.key}"))
for key <- Adapters.all_field_keys(), key not in current_keys do
Settings.delete_setting(key)
end
# Save current adapter fields (blank secrets keep existing value)
for field <- adapter_info.fields do
value = params[field.key]
settings_key = "email_#{field.key}"
settings_key = Adapters.settings_key(adapter_info.key, field.key)
cond do
value && value != "" ->