rework email settings for true progressive enhancement
All checks were successful
deploy / deploy (push) Successful in 1m19s
All checks were successful
deploy / deploy (push) Successful in 1m19s
Render all adapter field sections in the form with CSS :has(:checked) controlling visibility. Selecting a provider instantly shows its config fields — no JS, no page reload, no server round-trip needed. - Render all 6 adapter configs with data-adapter attribute - CSS :has(:checked) show/hide rules per adapter in admin stylesheet - Namespace field names per adapter (email[brevo][api_key] etc) - Drop 4 transactional-only providers (Resend, Postmark, Mailgun, MailPace) - Remove noscript "Switch provider" button and controller redirect workaround - Remove configured_adapter hidden input tracking - Hide JS-only test email button for no-JS users via noscript style - LiveView progressively enhances with async save and test email Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -84,8 +84,6 @@ defmodule Berrypod.KeyValidation do
|
||||
@known_prefixes [
|
||||
{"SG.", "SendGrid"},
|
||||
{"xkeysib-", "Brevo"},
|
||||
{"re_", "Resend"},
|
||||
{"key-", "Mailgun"},
|
||||
{"mlsn.", "MailerSend"}
|
||||
]
|
||||
|
||||
@@ -98,56 +96,6 @@ defmodule Berrypod.KeyValidation do
|
||||
end
|
||||
end
|
||||
|
||||
# Postmark: UUID format
|
||||
defp validate_email_format(key, "postmark", "api_key") do
|
||||
uuid_pattern = ~r/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
||||
|
||||
cond do
|
||||
Regex.match?(uuid_pattern, key) ->
|
||||
{:ok, key}
|
||||
|
||||
wrong = wrong_provider_hint(key, "postmark") ->
|
||||
{:error, wrong}
|
||||
|
||||
true ->
|
||||
{:error,
|
||||
"Postmark server tokens are UUIDs (like abc12345-abcd-1234-abcd-123456789abc). Make sure you copy the server token, not the account ID"}
|
||||
end
|
||||
end
|
||||
|
||||
# Resend: re_ prefix
|
||||
defp validate_email_format(key, "resend", "api_key") do
|
||||
cond do
|
||||
String.starts_with?(key, "re_") ->
|
||||
{:ok, key}
|
||||
|
||||
wrong = wrong_provider_hint(key, "resend") ->
|
||||
{:error, wrong}
|
||||
|
||||
true ->
|
||||
{:error,
|
||||
"Resend API keys start with re_ — find yours in your Resend dashboard under API Keys"}
|
||||
end
|
||||
end
|
||||
|
||||
# Mailgun: key- prefix (classic) or long RBAC keys
|
||||
defp validate_email_format(key, "mailgun", "api_key") do
|
||||
cond do
|
||||
String.starts_with?(key, "key-") ->
|
||||
{:ok, key}
|
||||
|
||||
String.length(key) >= 20 ->
|
||||
{:ok, key}
|
||||
|
||||
wrong = wrong_provider_hint(key, "mailgun") ->
|
||||
{:error, wrong}
|
||||
|
||||
true ->
|
||||
{:error,
|
||||
"Mailgun API keys usually start with key- — find yours in Settings → API Security"}
|
||||
end
|
||||
end
|
||||
|
||||
# Brevo: xkeysib- prefix
|
||||
defp validate_email_format(key, "brevo", "api_key") do
|
||||
cond do
|
||||
@@ -210,21 +158,6 @@ defmodule Berrypod.KeyValidation do
|
||||
end
|
||||
end
|
||||
|
||||
# MailPace: server token, no known prefix
|
||||
defp validate_email_format(key, "mailpace", "api_key") do
|
||||
cond do
|
||||
String.length(key) >= 10 ->
|
||||
{:ok, key}
|
||||
|
||||
wrong = wrong_provider_hint(key, "mailpace") ->
|
||||
{:error, wrong}
|
||||
|
||||
true ->
|
||||
{:error,
|
||||
"This looks too short — find your server API token under your domain settings in MailPace"}
|
||||
end
|
||||
end
|
||||
|
||||
# Non-api_key fields (domain, relay, base_url, etc.), basic checks
|
||||
defp validate_email_format(key, _adapter_key, _field_key) do
|
||||
if String.length(key) < 3 do
|
||||
|
||||
@@ -69,64 +69,6 @@ defmodule Berrypod.Mailer.Adapters do
|
||||
%Field{key: "api_key", label: "API key", type: :secret, required: true}
|
||||
]
|
||||
},
|
||||
# ── Transactional only ──
|
||||
%Adapter{
|
||||
key: "resend",
|
||||
name: "Resend",
|
||||
module: Swoosh.Adapters.Resend,
|
||||
description: "Developer-friendly API, simple setup.",
|
||||
tags: ["Transactional", "US"],
|
||||
category: :transactional,
|
||||
free_tier: "3,000 emails/month free",
|
||||
setup_hint: "Paste one API key",
|
||||
url: "https://resend.com",
|
||||
fields: [
|
||||
%Field{key: "api_key", label: "API key", type: :secret, required: true}
|
||||
]
|
||||
},
|
||||
%Adapter{
|
||||
key: "postmark",
|
||||
name: "Postmark",
|
||||
module: Swoosh.Adapters.Postmark,
|
||||
description: "Excellent deliverability tracking.",
|
||||
tags: ["Transactional", "US"],
|
||||
category: :transactional,
|
||||
free_tier: "100 emails/month free",
|
||||
setup_hint: "Paste one API key",
|
||||
url: "https://postmarkapp.com",
|
||||
fields: [
|
||||
%Field{key: "api_key", label: "API key", type: :secret, required: true}
|
||||
]
|
||||
},
|
||||
%Adapter{
|
||||
key: "mailgun",
|
||||
name: "Mailgun",
|
||||
module: Swoosh.Adapters.Mailgun,
|
||||
description: "EU region option available.",
|
||||
tags: ["Transactional", "EU option", "Sweden"],
|
||||
category: :transactional,
|
||||
free_tier: "100 emails/day trial",
|
||||
setup_hint: "API key + domain name",
|
||||
url: "https://www.mailgun.com",
|
||||
fields: [
|
||||
%Field{key: "api_key", label: "API key", type: :secret, required: true},
|
||||
%Field{key: "domain", label: "Domain", type: :string, required: true}
|
||||
]
|
||||
},
|
||||
%Adapter{
|
||||
key: "mailpace",
|
||||
name: "MailPace",
|
||||
module: Swoosh.Adapters.MailPace,
|
||||
description: "Privacy-focused, simple API.",
|
||||
tags: ["Transactional", "UK"],
|
||||
category: :transactional,
|
||||
free_tier: "3,000 emails/month free",
|
||||
setup_hint: "Paste one API key",
|
||||
url: "https://mailpace.com",
|
||||
fields: [
|
||||
%Field{key: "api_key", label: "API key", type: :secret, required: true}
|
||||
]
|
||||
},
|
||||
# ── Advanced ──
|
||||
%Adapter{
|
||||
key: "smtp",
|
||||
|
||||
Reference in New Issue
Block a user