62 lines
2.4 KiB
Markdown
62 lines
2.4 KiB
Markdown
# 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 validation
|
|
- `Mv.Membership.Member` validations - Member resource validation
|
|
- `Mv.Accounts.User` validations - 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:
|
|
|
|
```elixir
|
|
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
|
|
|