gate magic link login on verified email delivery
All checks were successful
deploy / deploy (push) Successful in 1m2s

The login page now only shows the magic link form when a test email has
been sent successfully, not just when an adapter is configured. Saving
email settings or disconnecting clears the flag so the admin must
re-verify after config changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-21 22:25:27 +00:00
parent b0607621f3
commit 3dca9ad9d0
4 changed files with 71 additions and 2 deletions

View File

@@ -15,6 +15,27 @@ defmodule Berrypod.Mailer do
adapter != nil and adapter != Swoosh.Adapters.Local
end
@doc """
Returns whether email delivery has been verified via a successful test email.
This is the flag the login page uses to decide whether to show the magic link
form. A configured adapter alone isn't enough — the admin must have sent a
test email that succeeded.
"""
def email_verified? do
email_configured?() and Settings.get_setting("email_verified", false) == true
end
@doc "Marks email delivery as verified (called after a successful test email)."
def mark_email_verified do
Settings.put_setting("email_verified", true, "boolean")
end
@doc "Clears the email verified flag (called when config changes)."
def clear_email_verified do
Settings.delete_setting("email_verified")
end
@doc """
Returns true if email is configured via environment variables (SMTP_HOST).

View File

@@ -94,6 +94,8 @@ defmodule BerrypodWeb.Admin.EmailSettings do
Settings.delete_setting(key)
end
Mailer.clear_email_verified()
# Reset to Local adapter
Application.put_env(:berrypod, Mailer, adapter: Swoosh.Adapters.Local)
@@ -113,6 +115,8 @@ defmodule BerrypodWeb.Admin.EmailSettings do
case Mailer.send_test_email(user.email, socket.assigns.from_address) do
{:ok, _} ->
Mailer.mark_email_verified()
{:noreply,
socket
|> assign(:sending_test, false)
@@ -174,6 +178,9 @@ defmodule BerrypodWeb.Admin.EmailSettings do
Settings.put_setting("email_from_address", from_address)
end
# Config changed — require re-verification
Mailer.clear_email_verified()
# Apply config immediately
Mailer.load_config()

View File

@@ -117,7 +117,7 @@ defmodule BerrypodWeb.Auth.Login do
form: form,
trigger_submit: false,
registration_open: !Accounts.has_admin?(),
email_configured: Mailer.email_configured?()
email_configured: Mailer.email_verified?()
)}
end