ValidEmail2

repository·main·Indexed 20 days ago

https://github.com/micke/valid_email2

A Ruby gem for robust email validation that leverages the mail gem instead of complex regular expressions. It provides features such as MX record verification, disposable email detection, and support for allow/deny lists. It can be used as an ActiveModel validator or via the ValidEmail2::Address class for standalone logic.

Tokens
3.4K
Snippets
14
Records
15
Agent score
73%

What's inside valid_email2

  1. Use ValidEmail2 with ActiveModel

    main

    You can use ValidEmail2 as a validator in your ActiveRecord or ActiveModel classes using the 'valid_email_2/email' key.

    Note: This gem allows empty emails to pass. If you require an email to be present, you must also use presence: true.

    Common Validation Options

    OptionDescription
    mx: trueValidates that the domain has an MX or A record.
    strict_mx: trueStrictly validates that the domain has an MX record.
    disposable: trueValidates that the domain is not a disposable email provider (checks domain and MX server).
    disposable_domain: trueValidates that the domain is not a disposable email provider (checks domain only).
    disposable_with_allow_list: trueValidates against disposable providers but allows domains listed in config/allow_listed_email_domains.yml.
    disposable_domain_with_allow_list: trueValidates against disposable domains only (no MX check) but allows domains in config/allow_listed_email_domains.yml.
    deny_list: trueValidates that the domain is not in config/deny_listed_email_domains.yml.
    disallow_subaddressing: trueValidates that the email is not subaddressed (RFC5233).
    disallow_dotted: trueValidates that the email does not contain a dot before the @ symbol.
    multiple: trueAllows multiple email addresses separated by commas.
    message: "string"Sets a custom error message.

    DNS Configuration

    For validations requiring DNS resolution (mx, strict_mx), you can configure:

    • dns_timeout: Integer seconds (defaults to 5). Example: { strict_mx: true, dns_timeout: 10 }.
    • dns_nameserver: An array of IP addresses. Example: { mx: true, dns_nameserver: ['8.8.8.8', '8.8.4.4'] }.
    class User < ActiveRecord::Base
      # Basic validation
      validates :email, presence: true, 'valid_email_2/email': true
    
      # Advanced validation example
      validates :email, 'valid_email_2/email': { 
        mx: true, 
        disposable: true, 
        disallow_subaddressing: true 
      }
    end
  2. Configure Allow and Deny Lists

    main

    ValidEmail2 uses YAML files to manage allow-listed and deny-listed domains. These files should be located in the config/ directory.

    config/deny_listed_email_domains.yml

    - denied1.example.com
    - denied2.example.com

    config/allow_listed_email_domains.yml (Follow the same format as the deny list.)

    # config/deny_listed_email_domains.yml
    - denied1.example.com
    - denied2.example.com
  3. Stubbing DNS validations in Test Environments

    main

    Because mx and strict_mx validations require an internet connection to perform DNS lookups, your test suite may fail or run slowly in offline environments. It is recommended to stub these methods in your spec_helper.rb using RSpec.

    # spec_helper.rb
    config.before(:each) do
      allow_any_instance_of(ValidEmail2::Address).to receive_messages(
        valid_mx?: true,
        valid_strict_mx?: true,
        mx_server_is_in?: false
      )
    end
  4. Configure permitted multibyte characters

    main

    By default, ValidEmail2 may not permit all multibyte characters. You can explicitly set the allowed regex for multibyte characters on the ValidEmail2::Address class.

    ValidEmail2::Address.permitted_multibyte_characters_regex = /[ÆæØøÅåÄäÖöÞþÐð]/
  5. Use ValidEmail2 without ActiveModel

    main

    You can use the ValidEmail2::Address class directly for standalone email validation logic.

    address = ValidEmail2::Address.new("lisinge@gmail.com")
    address.valid?           # => true
    address.disposable?      # => false
    address.valid_mx?        # => true
    address.valid_strict_mx? # => true
    address.subaddressed?    # => false
  6. Configure prohibited domain characters and multibyte regex

    main

    You can customize the validation logic for ValidEmail2::Address by overriding the class-level regex settings.

    • ValidEmail2::Address.prohibited_domain_characters_regex = /regex/: Defines which characters are forbidden in the domain part. The default is /[+!_\/\s'#]/`.
    • ValidEmail2::Address.permitted_multibyte_characters_regex = /regex/: Defines which non-ASCII characters are allowed. If an address contains multibyte characters not matching this regex, valid? will return false.
    # Example: Allow specific multibyte characters
    ValidEmail2::Address.permitted_multibyte_characters_regex = /[\u{4e00}-\u{9fff}]/
    
    # Example: Change prohibited characters
    ValidEmail2::Address.prohibited_domain_characters_regex = /[#]/ 
  7. Configure domain lists via YAML or TXT files

    main

    ValidEmail2 uses specific file paths for its domain lists. You can manage your validation logic by creating or modifying these files in your project structure:

    1. Deny List: Create config/deny_listed_email_domains.yml containing a YAML list of domains.
    2. Allow List: Create config/allow_listed_email_domains.yml containing a YAML list of domains.
    3. Disposable Emails: The library uses config/disposable_email_domains.txt (a plain text file with one domain per line) to identify disposable email providers.
  8. Use EmailValidator with ActiveModel

    main

    The ValidEmail2::EmailValidator is an ActiveModel::EachValidator designed for use in Rails or any Ruby application using ActiveModel. You can apply it to model attributes to validate email addresses against various criteria like MX records, disposable domains, and subaddressing.

    To use it, add email: true (or with specific options) to your model's validation block.

    class User
      include ActiveModel::Model
      attr_accessor :email
    
      validates :email, email: { disposable: true }
    end
  9. Access email domain lists in ValidEmail2

    main

    The ValidEmail2 module provides access to three primary domain lists used for validation. These lists are loaded from configuration files and are returned as Set objects to ensure high performance during lookups.

    • disposable_emails: Returns a Set of disposable email domains loaded from config/disposable_email_domains.txt.
    • deny_list: Returns a Set of denied email domains loaded from config/deny_listed_email_domains.yml. If the file does not exist, it returns an empty Set.
    • allow_list: Returns a Set of allowed email domains loaded from config/allow_listed_email_domains.yml. If the file does not exist, it returns an empty Set.
    # Accessing the lists
    disposable = ValidEmail2.disposable_emails
    deny = ValidEmail2.deny_list
    allow = ValidEmail2.allow_list
    
    # Example lookup
    if ValidEmail2.deny_list.include?("example.com")
      puts "Domain is denied"
    end
  10. Lookup MX and A records using ValidEmail2::Dns

    main

    The ValidEmail2::Dns client provides methods to retrieve DNS resource records for a given domain. These are used to validate if a domain is configured to receive email.

    • mx_servers(domain): Returns the MX (Mail Exchange) records for the domain.
    • a_servers(domain): Returns the A (Address) records for the domain.
    dns_client = ValidEmail2::Dns.new
    
    # Get MX records
    mx_records = dns_client.mx_servers('example.com')
    
    # Get A records
    a_records = dns_client.a_servers('example.com')
  11. Manage the DNS lookup cache

    main

    The ValidEmail2::Dns class maintains a class-level cache (CACHE) of DNS lookups to avoid redundant network calls. You can manually manage this cache using the following class methods:

    • ValidEmail2::Dns.clear_cache: Removes all entries from the cache.
    • ValidEmail2::Dns.prune_cache: Removes the oldest entries from the cache to bring the size down to MAX_CACHE_SIZE (1,000 entries).
    # Clear all cached DNS results
    ValidEmail2::Dns.clear_cache
    
    # Manually prune the cache to free up space
    ValidEmail2::Dns.prune_cache