New-login security alerts ("we noticed a new login to your account").
On every login (PhoenixKitWeb.Users.Auth.log_in_user/3), the request's
(ip_address, user_agent_hash) pair is checked against
PhoenixKit.Users.Auth.KnownDevice rows for that user. An unrecognized
pair is a new device: it's persisted, a user.new_login_detected
activity entry is logged, and — when new_login_alert_enabled is on —
an email goes out via
PhoenixKit.Users.Auth.UserNotifier.deliver_new_login_alert/2.
A recognized pair just bumps last_seen_at — no alert, no email.
Sends synchronously (matching every other PhoenixKit auth email — confirmation, password reset, magic link — none of which are queued through Oban): a "new device" login is inherently rare per user (every subsequent login from the same device is silent), so the odd extra round-trip on a first-time login doesn't justify background-job infrastructure this feature would otherwise be the only user of. A send failure is logged and swallowed — it must never block sign-in.
Summary
Functions
Records a login from conn for user, alerting on a new device.
Whether new-login alerts are enabled (setting new_login_alert_enabled,
default false).
Best-effort "City, Country" string for ip_address, or nil.
Functions
@spec check(map(), Plug.Conn.t()) :: :ok
Records a login from conn for user, alerting on a new device.
No-ops entirely (no DB write, no email) when the feature is disabled. Never raises — a failure here must never block sign-in.
@spec enabled?() :: boolean()
Whether new-login alerts are enabled (setting new_login_alert_enabled,
default false).
Best-effort "City, Country" string for ip_address, or nil.
Never raises; a lookup failure (disabled, rate-limited, invalid IP) just means the alert email omits the location line.