Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: hallelujah/valid_email
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: KMK-ONLINE/valid_email
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 20 commits
  • 6 files changed
  • 11 contributors

Commits on Jun 17, 2015

  1. Add domains that abuse sign up

    sayap committed Jun 17, 2015
    Copy the full SHA
    9fb8e99 View commit details

Commits on Nov 17, 2015

  1. Copy the full SHA
    b6f6c94 View commit details
  2. Copy the full SHA
    e8d7abd View commit details
  3. Copy the full SHA
    fe1957f View commit details
  4. Copy the full SHA
    5cb48e9 View commit details

Commits on Nov 20, 2015

  1. Copy the full SHA
    135e5bc View commit details

Commits on Apr 8, 2016

  1. add a configurable timeout for DNS resolution

    Kurniawan and Tommy Sullivan committed Apr 8, 2016
    Copy the full SHA
    12eeb9a View commit details

Commits on Apr 11, 2016

  1. give the timeout a configurable return value

    enable timeout configuration from outside this gem
    Kurniawan and Tommy Sullivan committed Apr 11, 2016
    Copy the full SHA
    d8e88b1 View commit details
  2. Merge branch 'timeout'

    Kurniawan and Tommy Sullivan committed Apr 11, 2016
    Copy the full SHA
    112998a View commit details

Commits on Nov 29, 2016

  1. Fix return true, but empty exchange name e.g yaho.com domain

    Kurniawan and Sukoreno Mukti Widodo committed Nov 29, 2016
    Copy the full SHA
    4756872 View commit details

Commits on Nov 30, 2016

  1. Add timeout params

    Kurniawan and Sukoreno Mukti Widodo committed Nov 30, 2016
    Copy the full SHA
    2520f05 View commit details
  2. add dns_timeout_return_value params

    Kurniawan and Sukoreno Mukti Widodo committed Nov 30, 2016
    Copy the full SHA
    b70c034 View commit details

Commits on Apr 3, 2017

  1. add kampungseleb.com to blacklist domain

    Sukoreno Mukti Widodo and Wilianto Indrawan committed Apr 3, 2017
    Copy the full SHA
    430d542 View commit details

Commits on Apr 7, 2017

  1. remove kampungseleb.com turn out this is a partner

    Sukoreno Mukti Widodo and Wilianto Indrawan committed Apr 7, 2017
    Copy the full SHA
    69e2fa3 View commit details

Commits on Oct 20, 2017

  1. add more disposable email and fix deprecated test

    Sukoreno Mukti Widodo committed Oct 20, 2017
    Copy the full SHA
    89f3921 View commit details

Commits on Nov 3, 2017

  1. [#152510275] Add spam email list

    Ahmad Ibrahim and Wisnu Alamsyah committed Nov 3, 2017
    Copy the full SHA
    d95767f View commit details

Commits on Nov 6, 2017

  1. [#152510275] Fix spam email list

    Wisnu Alamsyah and Yohan committed Nov 6, 2017
    Copy the full SHA
    6be1283 View commit details

Commits on Nov 7, 2017

  1. [#152510275] Adjust validate email algorithm and add new filter

    Wisnu Alamsyah and Yohan committed Nov 7, 2017
    Copy the full SHA
    f51a528 View commit details

Commits on Dec 18, 2018

  1. [Finished #162335650] Block email from specific domain to reduce spam…

    … video
    Muhammad Arifino Setyawan and Septhianto Diga Chandra authored and sukorenomw committed Dec 18, 2018
    Copy the full SHA
    5a388bf View commit details

Commits on Jan 24, 2019

  1. [#163246767] Remove gemspec version lock to allow vidio rails upgrade…

    … to 5.2
    Charles Isnanto and Meirza Heyder committed Jan 24, 2019
    Copy the full SHA
    4002395 View commit details
Showing with 16,109 additions and 30 deletions.
  1. +15,895 −19 config/valid_email.yml
  2. +31 −2 lib/valid_email.rb
  3. +35 −7 lib/valid_email/validate_email.rb
  4. +1 −0 spec/email_validator_spec.rb
  5. +145 −0 spec/validate_email_spec.rb
  6. +2 −2 valid_email.gemspec
15,914 changes: 15,895 additions & 19 deletions config/valid_email.yml

Large diffs are not rendered by default.

33 changes: 31 additions & 2 deletions lib/valid_email.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
require 'valid_email/all'
I18n.load_path += Dir.glob(File.expand_path('../../config/locales/**/*',__FILE__))

class ValidEmail
def self.config= options
@@config = options
end

def self.disposable_email_services
@@config['disposable_email_services'] || []
end

def self.dns_timeout= value
@@config['dns_timeout'] = value
end

def self.dns_timeout
@@config['dns_timeout'] || 0.5
end

def self.dns_timeout_return_value= value
@@config['dns_timeout_return_value'] = value
end

def self.dns_timeout_return_value
@@config['dns_timeout_return_value'] || true
end
end

# Load list of disposable email domains
config = File.expand_path('../../config/valid_email.yml',__FILE__)
BanDisposableEmailValidator.config= YAML.load_file(config)['disposable_email_services'] rescue []
config_yaml = File.expand_path('../../config/valid_email.yml',__FILE__)
ValidEmail.config = YAML.load_file(config_yaml)

BanDisposableEmailValidator.config= ValidEmail.disposable_email_services
42 changes: 35 additions & 7 deletions lib/valid_email/validate_email.rb
Original file line number Diff line number Diff line change
@@ -86,23 +86,41 @@ def valid_dot_atom?(dot_atom)
return true
end

def mx_valid?(value, fallback=false)
def mx_valid?(value, user_options={})
options = {
:fallback => false,
:timeout => ValidEmail.dns_timeout,
:dns_timeout_return_value => ValidEmail.dns_timeout_return_value,
}.merge(user_options)

m = Mail::Address.new(value)
return false unless m.domain

mx = []
Resolv::DNS.open do |dns|
mx.concat dns.getresources(m.domain, Resolv::DNS::Resource::IN::MX)
mx.concat dns.getresources(m.domain, Resolv::DNS::Resource::IN::A) if fallback
dns = Resolv::DNS.new
begin
Timeout.timeout(options[:timeout]) do
mx.concat dns.getresources(m.domain, Resolv::DNS::Resource::IN::MX)
mx.concat dns.getresources(m.domain, Resolv::DNS::Resource::IN::A) if options[:fallback]
end
rescue Timeout::Error
dns.close
return options[:dns_timeout_return_value]
end

dns.close
if options[:fallback] && (mx.first.respond_to?(:address))
return true
end

return mx.any?
return mx.any? && (mx.first.exchange.length > 0)

rescue Mail::Field::ParseError
false
end

def mx_valid_with_fallback?(value)
mx_valid?(value, true)
mx_valid?(value, {fallback: true})
end

def domain_valid?(value)
@@ -114,9 +132,19 @@ def domain_valid?(value)

def ban_disposable_email?(value)
m = Mail::Address.new(value)
m.domain && !BanDisposableEmailValidator.config.include?(m.domain)
m.domain && matched_disposable_domain(m.domain).empty?
rescue Mail::Field::ParseError
false
end

def matched_disposable_domain(domain)
BanDisposableEmailValidator.config.select do |e|
if e.size > 2
e == domain
else
Regexp.new("#{ e }$").match(domain)
end
end
end
end
end
1 change: 1 addition & 0 deletions spec/email_validator_spec.rb
Original file line number Diff line number Diff line change
@@ -166,6 +166,7 @@
it "fails when email domain has no MX record" do
subject.email = 'john@subdomain.rubyonrails.org'
expect(subject.valid?).to be_falsey

expect(subject.errors[:email]).to eq errors
end

145 changes: 145 additions & 0 deletions spec/validate_email_spec.rb
Original file line number Diff line number Diff line change
@@ -117,4 +117,149 @@
expect(ValidateEmail.valid_local?('!#$%&\'*+-/=?^_`{|}~."\\\\\ \"(),:;<>@[]"')).to be_truthy
end
end

describe '.mx_valid?' do
let(:dns) { double(Resolv::DNS) }
let(:dns_resource) { double(Resolv::DNS::Resource::IN::MX) }
let(:dns_resource_a) { double(Resolv::DNS::Resource::IN::A) }
let(:exchange) { double(Resolv::DNS::Name) }

before do
expect(Resolv::DNS).to receive(:new).and_return(dns)
expect(dns).to receive(:close)
end

it "returns true when MX is true and it doesn't timeout" do
expect(dns).to receive(:getresources).and_return [dns_resource]

expect(dns_resource).to receive(:exchange).and_return exchange
expect(exchange).to receive(:length).and_return(1)

expect(ValidateEmail.mx_valid?('aloha@kmkonline.co.id')).to be_truthy
end

it "returns false when MX is false and it doesn't timeout" do
expect(dns).to receive(:getresources).and_return []
expect(ValidateEmail.mx_valid?('aloha@ga-ada-mx.com')).to be_falsey
end

it "returns config.default when times out" do
expect(Timeout).to receive(:timeout).and_raise(Timeout::Error)
expect(ValidateEmail.mx_valid?('aloha@ga-ada-mx.com')).to eq(ValidEmail.dns_timeout_return_value)
end

it "returns false when domain doest have mx server" do
expect(dns).to receive(:getresources).and_return [dns_resource]

expect(dns_resource).to receive(:exchange).and_return exchange
expect(exchange).to receive(:length).and_return(0)

expect(ValidateEmail.mx_valid?('aloha@yaho.com')).to be_falsey
end

context "timeout params" do
it "can accept timeout params to overide timeout config" do
timeout = 10
expect(Timeout).to receive(:timeout).with(timeout)

ValidateEmail.mx_valid?('aloha@yaho.com', {timeout: timeout})
end

it "using default timeout config when params timeout not set" do
expect(ValidEmail).to receive(:dns_timeout).and_return(2)
expect(Timeout).to receive(:timeout).with(2)

ValidateEmail.mx_valid?('aloha@yaho.com')
end
end

context "fallback params" do
it "doesnt check A record when fallback params not set" do
expect(dns).to receive(:getresources).with('yaho.com', Resolv::DNS::Resource::IN::MX).and_return [dns_resource]
expect(dns_resource).to receive(:exchange).and_return exchange
expect(exchange).to receive(:length).and_return(1)

expect(dns).not_to receive(:getresources).with('yaho.com', Resolv::DNS::Resource::IN::A)

ValidateEmail.mx_valid?('aloha@yaho.com')
end

it "can accept fallback params to check A record" do
expect(dns).to receive(:getresources).with('yaho.com', Resolv::DNS::Resource::IN::MX).and_return [dns_resource]
expect(dns_resource).to receive(:exchange).and_return exchange
expect(exchange).to receive(:length).and_return(1)

expect(dns).to receive(:getresources).with('yaho.com', Resolv::DNS::Resource::IN::A).and_return [dns_resource_a]

ValidateEmail.mx_valid?('aloha@yaho.com', {fallback: true})
end
end

context "dns_timeout_return_value params" do
before do
expect(Timeout).to receive(:timeout).and_raise(Timeout::Error)
end

it "overide config dns_timeout_return_value when params dns_timeout_return_value present" do
allow(ValidEmail).to receive(:dns_timeout_return_value).and_return(true)
expect(ValidateEmail.mx_valid?('aloha@kmklabs.com', {dns_timeout_return_value: false})).to be_falsey
end

it "use config dns_timeout_return_value when params dns_timeout_return_value not present" do
allow(ValidEmail).to receive(:dns_timeout_return_value).and_return(true)
expect(ValidateEmail.mx_valid?('aloha@kmklabs.com')).to be_truthy
end
end
end

describe ".ban_disposable_email?" do
context "domain is empty" do
it "returns false" do
expect(ValidateEmail.ban_disposable_email?("name@")).to eq false
end
end

context "domain is not empty" do
context "domain exists in disposable dictionary" do
it "returns false" do
expect(ValidateEmail.ban_disposable_email?("name@mailnator.com")).to eq false
end
end

context "domain doesn't exist in disposable dictionary" do
it "returns true" do
expect(ValidateEmail.ban_disposable_email?("name@domain-does-not-exists-in-dictionary.com")).to eq true
end
end
end
end

describe ".matched_disposable_domain" do
context "domain doesn't exists" do
it "returns empty array" do
domains = ValidateEmail.matched_disposable_domain("domain-does-not-exists-in-dictionary.com")
expect(domains).to be_empty
end
end

context "top level domain exists" do
it "returns array of matched TLD" do
domains = ValidateEmail.matched_disposable_domain("effing-spammer-that-is-not-in-the-dictionary.tk")
expect(domains).to include "tk"
end

it "does not return domain name that has the blacklisted TLD in the name" do
domains = ValidateEmail.matched_disposable_domain("playground-tk-sd-smp-sma-kuliah.com")
expect(domains).to be_empty
end
end

context "top level domain name exists" do
it "returns array of matched domain" do
domains = ValidateEmail.matched_disposable_domain("mailinator.com")
expect(domains).to include "mailinator.com"
end
end
end

end
4 changes: 2 additions & 2 deletions valid_email.gemspec
Original file line number Diff line number Diff line change
@@ -20,8 +20,8 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]

# specify any dependencies here; for example:
s.add_development_dependency "rspec", "~> 2.99"
s.add_development_dependency "rspec"
s.add_development_dependency "rake"
s.add_runtime_dependency "mail", "~> 2.6.1"
s.add_runtime_dependency "mail"
s.add_runtime_dependency "activemodel"
end