PhoenixKit.Integrations.Validators (phoenix_kit v1.7.206)

Copy Markdown View Source

Real connection checks for providers that cannot be validated with a simple authenticated HTTP GET.

PhoenixKit.Integrations falls through to :ok for any provider that declares no validation. For the e-mail providers that meant "Test Connection" verified nothing: the connection was stamped "connected" without a single byte leaving the box, so an operator who pasted a wrong key or a bad SMTP password saw a green check and then a failing send.

A check that always says yes is worse than no check — but so is one that says no when the configuration is fine. These validators are therefore careful in both directions:

  • a relay that authenticates by IP and offers no AUTH verb passes (the credentials are simply unused — sending works, so the check is green);
  • SES credentials scoped to ses:SendEmail only — the least-privilege policy AWS itself recommends — pass, even though they cannot read the send quota.

Every check runs through PhoenixKit.Integrations.Probe, which bounds it with a hard deadline and isolates it from the caller — the libraries underneath bound neither themselves nor their crashes, and both call sites are LiveView callbacks.

Summary

Functions

Validates AWS SES credentials against the SES API itself.

Validates a Brevo API key against the account endpoint, and reports the remaining credits.

Validates an SMTP relay by opening a real session and authenticating.

Functions

aws_ses(data)

@spec aws_ses(map()) :: :ok | {:ok, String.t()} | {:error, String.t()}

Validates AWS SES credentials against the SES API itself.

Asks SES for the account's send quota — the cheapest call that proves the credentials are real. Built as a raw ExAws.Operation.Query, so it needs no ex_aws_ses dependency.

The endpoint host is passed explicitly rather than left to ExAws, whose region resolution is a hard-coded prefix allowlist (~r/^(us|eu|af|ap|sa|ca|me)-.../) that silently yields no host at all for newer regions such as il-central-1 — while the send path (Swoosh.Adapters.AmazonSES) simply interpolates the region and works. Validate and send must resolve the same endpoint.

brevo_api(data)

@spec brevo_api(map()) :: :ok | {:ok, String.t()} | {:error, String.t()}

Validates a Brevo API key against the account endpoint, and reports the remaining credits.

Brevo authenticates with a bare api-key header (no Bearer prefix), and GET /v3/account doubles as the cheapest authenticated call and the only one that tells the operator anything beyond "the key works" — the plan's remaining send credits, which is exactly what silently runs out mid-campaign.

smtp(data)

@spec smtp(map()) :: :ok | {:ok, String.t()} | {:error, String.t()}

Validates an SMTP relay by opening a real session and authenticating.

The connection options come from PhoenixKit.Mailer.SmtpTransport.config/1, so the check exercises exactly the transport a real send uses — one source of truth, no drift between "tested" and "sent".

auth: :always is deliberate: with gen_smtp's default the AUTH exchange is attempted but its failure is tolerated, so a wrong password would still open a session and the check would pass. A relay that advertises no AUTH verb at all is a different case, and is treated as a pass — see the module doc.