View Source EctoCommons.EmailValidator (Ecto Commons v0.3.6)

Validates emails.

Options

There are various :checks depending on the strictness of the validation you require. Indeed, perfect email validation does not exist (see StackOverflow questions about it):

  • :html_input: Checks if the email follows the regular expression used by browsers for their type="email" input fields. This is the default as it corresponds to most use-cases. It is quite strict without being too narrow. It does not support unicode emails though. If you need better internationalization, please use the :pow check as it is more flexible with international emails. Defaults to enabled.

  • :burner: Checks if the email given is a burner email provider (uses the Burnex lib under the hood, so make sure to add it to your dependencies). When enabled, will reject temporary email providers. Defaults to disabled.

  • :check_mx_record: Checks if the email domain exists in the DNS system (can be a bit slow).

  • :pow: Checks the email using the pow logic. Defaults to disabled. The rules are the following:

    • Split into local-part and domain at last @ occurrence
    • Local-part should;
      • be at most 64 octets
      • separate quoted and unquoted content with a single dot
      • only have letters, digits, and the following characters outside quoted content:
          !#$%&'*+-/=?^_`{|}~.
      • not have any consecutive dots outside quoted content
    • Domain should;
      • be at most 255 octets
      • only have letters, digits, hyphen, and dots

    Unicode characters are permitted in both local-part and domain.

    The implementation is based on RFC 3696. IP addresses are not allowed as per the RFC 3696 specification: "The domain name can also be replaced by an IP address in square brackets, but that form is strongly discouraged except for testing and troubleshooting purposes.".

    You're invited to compare the tests to see the difference between the :html_input check and the :pow check. :pow is better suited for i18n and is more correct in regards to the email specification but will allow valid emails many systems don't manage correctly. :html_input is more basic but should be OK for most common use-cases.

Example:

iex> types = %{email: :string}
iex> params = %{email: "valid.email@example.com"}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> validate_email(:email)
#Ecto.Changeset<action: nil, changes: %{email: "valid.email@example.com"}, errors: [], data: %{}, valid?: true>

iex> types = %{email: :string}
iex> params = %{email: "@invalid_email"}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> validate_email(:email)
#Ecto.Changeset<action: nil, changes: %{email: "@invalid_email"}, errors: [email: {"is not a valid email", [validation: :email]}], data: %{}, valid?: false>

iex> types = %{email: :string}
iex> params = %{email: "uses_a_forbidden_provider@yopmail.net"}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> validate_email(:email, checks: [:html_input, :burner])
#Ecto.Changeset<action: nil, changes: %{email: "uses_a_forbidden_provider@yopmail.net"}, errors: [email: {"uses a forbidden provider", [validation: :email]}], data: %{}, valid?: false>

iex> types = %{email: :string}
iex> params = %{email: "uses_a_forbidden_provider@yopmail.net"}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> validate_email(:email, checks: [:html_input, :pow])
#Ecto.Changeset<action: nil, changes: %{email: "uses_a_forbidden_provider@yopmail.net"}, errors: [], data: %{}, valid?: true>

Summary

Functions

Link to this function

validate_email(changeset, field, opts \\ [])

View Source