<commit_before>require "email_domain_inclusion/version"

# A custom validator that checks that the email's domain is included in the specified domains
# Usage: validates :email, email_domain: {allowed_domains: ->() { AllowedEmailDomains.pluck(:domain) } }
# +allowed_domains+ can be an array of strings, or a Proc that returns an array of strings
class EmailDomainInclusionValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    allow_subdomains = options[:allow_subdomains]
    unless valid_full_domain?(value) || (allow_subdomains && valid_subdomain?(value))
      record.errors[attribute] << options[:message] || "domain_not_in_list"
    end
  end

  private
  def valid_subdomain?(value)
    domain = domain_from_email(value)
    allowed_domains.any? { |allowed_domain| domain.end_with? ".#{allowed_domain}" }
  end

  def valid_full_domain?(value)
    domain = domain_from_email(value)
    allowed_domains.include?(domain)
  end

  def allowed_domains
    domains = options[:allowed_domains]
    domains = domains.call if domains.respond_to?(:call)
    domains
  end

  def domain_from_email(email)
    Mail::Address.new(email).try(:domain).try(:downcase)
  rescue Mail::Field::ParseError
    nil
  end
end<commit_msg>Added a fix for nil domain.<commit_after>require "email_domain_inclusion/version"

# A custom validator that checks that the email's domain is included in the specified domains
# Usage: validates :email, email_domain: {allowed_domains: ->() { AllowedEmailDomains.pluck(:domain) } }
# +allowed_domains+ can be an array of strings, or a Proc that returns an array of strings
class EmailDomainInclusionValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    allow_subdomains = options[:allow_subdomains]
    unless valid_full_domain?(value) || (allow_subdomains && valid_subdomain?(value))
      record.errors[attribute] << options[:message] || "domain_not_in_list"
    end
  end

  private
  def valid_subdomain?(value)
    domain = domain_from_email(value)
    return false unless domain
    allowed_domains.any? { |allowed_domain| domain.end_with? ".#{allowed_domain}" }
  end

  def valid_full_domain?(value)
    domain = domain_from_email(value)
    return false unless domain
    allowed_domains.include?(domain)
  end

  def allowed_domains
    domains = options[:allowed_domains]
    domains = domains.call if domains.respond_to?(:call)
    domains
  end

  def domain_from_email(email)
    Mail::Address.new(email).try(:domain).try(:downcase)
  rescue Mail::Field::ParseError
    nil
  end
end
{'fraction_non_alphanumeric': 0.09698608964451313, 'fraction_numerical': 0.0, 'mean_word_length': 4.979214780600462, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1757032', 'n_tokens_mistral': 784, 'n_tokens_neox': 765, 'n_words': 194}