diff --git a/README.md b/README.md index ffb59f4..f63dfb7 100644 --- a/README.md +++ b/README.md @@ -58,11 +58,17 @@ To validate that the domain is not a disposable email (checks domain only, does validates :email, 'valid_email_2/email': { disposable_domain: true } ``` -To validate that the domain is not a disposable email or a disposable email but whitelisted (under config/whitelisted_email_domains.yml): +To validate that the domain is not a disposable email or a disposable email (checks domain and MX server) but whitelisted (under config/whitelisted_email_domains.yml): ```ruby validates :email, 'valid_email_2/email': { disposable_with_whitelist: true } ``` +To validate that the domain is not a disposable email or a disposable email (checks domain only, does not check MX server) but whitelisted (under config/whitelisted_email_domains.yml): + +```ruby +validates :email, 'valid_email_2/email': { disposable_domain_with_whitelist: true } +``` + To validate that the domain is not blacklisted (under config/blacklisted_email_domains.yml): ```ruby validates :email, 'valid_email_2/email': { blacklist: true } diff --git a/lib/valid_email2/email_validator.rb b/lib/valid_email2/email_validator.rb index f71c42f..4253e73 100644 --- a/lib/valid_email2/email_validator.rb +++ b/lib/valid_email2/email_validator.rb @@ -37,6 +37,10 @@ def validate_each(record, attribute, value) error(record, attribute) && return if addresses.any? { |address| address.disposable? && !address.whitelisted? } end + if options[:disposable_domain_with_whitelist] + error(record, attribute) && return if addresses.any? { |address| address.disposable_domain? && !address.whitelisted? } + end + if options[:blacklist] error(record, attribute) && return if addresses.any?(&:blacklisted?) end diff --git a/spec/valid_email2_spec.rb b/spec/valid_email2_spec.rb index de92920..60295ed 100644 --- a/spec/valid_email2_spec.rb +++ b/spec/valid_email2_spec.rb @@ -31,6 +31,10 @@ class TestUserDisallowDisposableWithWhitelist < TestModel validates :email, 'valid_email_2/email': { disposable_with_whitelist: true } end +class TestUserDisallowDisposableDomainWithWhitelist < TestModel + validates :email, 'valid_email_2/email': { disposable_domain_with_whitelist: true } +end + class TestUserDisallowBlacklisted < TestModel validates :email, 'valid_email_2/email': { blacklist: true } end @@ -180,8 +184,18 @@ class TestUserMultiple < TestModel let(:whitelist_domain) { disposable_domain } let(:whitelist_file_path) { "config/whitelisted_email_domains.yml" } + # Some of the specs below need to explictly set the whitelist var or it + # may be cached to an empty set + def set_whitelist + ValidEmail2.instance_variable_set( + :@whitelist, + ValidEmail2.send(:load_if_exists, ValidEmail2::WHITELIST_FILE) + ) + end + after do FileUtils.rm(whitelist_file_path, force: true) + set_whitelist end it "is invalid if the domain is disposable and not in the whitelist" do @@ -191,9 +205,22 @@ class TestUserMultiple < TestModel it "is valid if the domain is disposable but in the whitelist" do File.open(whitelist_file_path, "w") { |f| f.write [whitelist_domain].to_yaml } + set_whitelist user = TestUserDisallowDisposableWithWhitelist.new(email: "foo@#{whitelist_domain}") + expect(user.valid?).to be_truthy + end + + it "is invalid if the domain is a disposable_domain and not in the whitelist" do + user = TestUserDisallowDisposableDomainWithWhitelist.new(email: "foo@#{whitelist_domain}") expect(user.valid?).to be_falsey end + + it "is valid if the domain is a disposable_domain but in the whitelist" do + File.open(whitelist_file_path, "w") { |f| f.write [whitelist_domain].to_yaml } + set_whitelist + user = TestUserDisallowDisposableDomainWithWhitelist.new(email: "foo@#{whitelist_domain}") + expect(user.valid?).to be_truthy + end end end