2.4 KiB
Email Validation Strategy
We use EctoCommons.EmailValidator with both :html_input and :pow checks, defined centrally in Mv.Constants.email_validator_checks/0.
Checks Used
:html_input- Pragmatic validation matching browser<input type="email">behavior:pow- Stricter validation following email spec, supports internationalization (Unicode)
Rationale
Using both checks ensures:
- Compatibility with common email providers (
:html_input) - Matches what users expect from web forms - Compliance with email standards (
:pow) - Follows RFC 5322 and related specifications - Support for international email addresses (
:pow) - Allows Unicode characters in email addresses
This dual approach provides a balance between user experience (accepting common email formats) and technical correctness (validating against email standards).
Usage
The checks are used consistently across all email validation points:
Mv.Membership.Import.MemberCSV.validate_row/3- CSV import validationMv.Membership.Membervalidations - Member resource validationMv.Accounts.Uservalidations - User resource validation
All three locations use Mv.Constants.email_validator_checks() to ensure consistency.
Implementation Details
CSV Import Validation
The CSV import uses a schemaless changeset for email validation:
changeset =
{%{}, %{email: :string}}
|> Ecto.Changeset.cast(%{email: Map.get(member_attrs, :email)}, [:email])
|> Ecto.Changeset.update_change(:email, &String.trim/1)
|> Ecto.Changeset.validate_required([:email])
|> EctoCommons.EmailValidator.validate_email(:email, checks: Mv.Constants.email_validator_checks())
This approach:
- Trims whitespace before validation
- Validates email is required
- Validates email format using the centralized checks
- Provides consistent error messages via Gettext
Resource Validations
Both Member and User resources use similar schemaless changesets within their Ash validations, ensuring consistent validation behavior across the application.
Changing the Validation Strategy
To change the email validation checks, update the @email_validator_checks constant in Mv.Constants. This will automatically apply to all validation points.
Note: Changing the validation strategy may affect existing data. Consider:
- Whether existing emails will still be valid
- Migration strategy for invalid emails
- User communication if validation becomes stricter