valid_email2 3.2.5 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +19 -2
- data/config/disposable_email_domains.txt +7 -2
- data/lib/valid_email2.rb +28 -16
- data/lib/valid_email2/address.rb +33 -17
- data/lib/valid_email2/email_validator.rb +19 -10
- data/lib/valid_email2/version.rb +1 -1
- data/pull_mailchecker_emails.rb +1 -1
- data/spec/benchmark_spec.rb +18 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/valid_email2_spec.rb +81 -5
- data/valid_email2.gemspec +1 -0
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6543e0ca764df6ed5698a864b232260e456a0fc3b8e3f82918122e21cdca0c3
|
4
|
+
data.tar.gz: 989805e58182e1b4ab18b9a16a80a9507465f840bea19840abebe841d628dfa9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59813d38f00f9c75cbaae7d944f47d50f9e0239f740c468e8718c51345af324f46411e13b2796c5881769a62127345529be92ae374d07082d07e06610e50b62a
|
7
|
+
data.tar.gz: 131d25e900327ff67b0cd80e17ecc0de83462394d8094cafbed93780ec9b4d472b8e1b95591dc8c894fc8c4f47a8a5a60d31d7fa3c6733210f1b429ca79ff72c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
## Version 3.6.0
|
2
|
+
* Add strict_mx validation https://github.com/micke/valid_email2/pull/173
|
3
|
+
|
4
|
+
## Version 3.5.0
|
5
|
+
* Disallow emails starting with a dot https://github.com/micke/valid_email2/pull/170
|
6
|
+
* Add option to whitelist domains from MX check https://github.com/micke/valid_email2/pull/167
|
7
|
+
* Remove false positives
|
8
|
+
|
9
|
+
## Version 3.4.0
|
10
|
+
* Disallow consecutive dots https://github.com/micke/valid_email2/pull/163
|
11
|
+
* Add andyes.net https://github.com/micke/valid_email2/pull/162
|
12
|
+
|
13
|
+
## Version 3.3.1
|
14
|
+
* Fix some performance regressions (https://github.com/micke/valid_email2/pull/150)
|
15
|
+
|
16
|
+
## Version 3.3.0
|
17
|
+
* Allow multiple addresses separated by comma (https://github.com/micke/valid_email2/pull/156)
|
18
|
+
* Make prohibited_domain_characters_regex changeable (https://github.com/micke/valid_email2/pull/157)
|
19
|
+
|
1
20
|
## Version 3.2.5
|
2
21
|
* Remove false positives
|
3
22
|
* Pull new domains
|
data/README.md
CHANGED
@@ -43,10 +43,14 @@ class User < ActiveRecord::Base
|
|
43
43
|
end
|
44
44
|
```
|
45
45
|
|
46
|
-
To validate that the domain has
|
46
|
+
To validate that the domain has an MX record or A record:
|
47
47
|
```ruby
|
48
48
|
validates :email, 'valid_email_2/email': { mx: true }
|
49
49
|
```
|
50
|
+
To validate strictly that the domain has an MX record:
|
51
|
+
```ruby
|
52
|
+
validates :email, 'valid_email_2/email': { strict_mx: true }
|
53
|
+
```
|
50
54
|
|
51
55
|
To validate that the domain is not a disposable email (checks domain and MX server):
|
52
56
|
```ruby
|
@@ -58,11 +62,17 @@ To validate that the domain is not a disposable email (checks domain only, does
|
|
58
62
|
validates :email, 'valid_email_2/email': { disposable_domain: true }
|
59
63
|
```
|
60
64
|
|
61
|
-
To validate that the domain is not a disposable email or a disposable email but whitelisted (under config/whitelisted_email_domains.yml):
|
65
|
+
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):
|
62
66
|
```ruby
|
63
67
|
validates :email, 'valid_email_2/email': { disposable_with_whitelist: true }
|
64
68
|
```
|
65
69
|
|
70
|
+
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):
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
validates :email, 'valid_email_2/email': { disposable_domain_with_whitelist: true }
|
74
|
+
```
|
75
|
+
|
66
76
|
To validate that the domain is not blacklisted (under config/blacklisted_email_domains.yml):
|
67
77
|
```ruby
|
68
78
|
validates :email, 'valid_email_2/email': { blacklist: true }
|
@@ -83,6 +93,11 @@ To validate create your own custom message:
|
|
83
93
|
validates :email, 'valid_email_2/email': { message: "is not a valid email" }
|
84
94
|
```
|
85
95
|
|
96
|
+
To allow multiple addresses separated by comma:
|
97
|
+
```ruby
|
98
|
+
validates :email, 'valid_email_2/email': { multiple: true }
|
99
|
+
```
|
100
|
+
|
86
101
|
All together:
|
87
102
|
```ruby
|
88
103
|
validates :email, 'valid_email_2/email': { mx: true, disposable: true, disallow_subaddressing: true}
|
@@ -98,6 +113,7 @@ address = ValidEmail2::Address.new("lisinge@gmail.com")
|
|
98
113
|
address.valid? => true
|
99
114
|
address.disposable? => false
|
100
115
|
address.valid_mx? => true
|
116
|
+
address.valid_strict_mx? => true
|
101
117
|
address.subaddressed? => false
|
102
118
|
```
|
103
119
|
|
@@ -109,6 +125,7 @@ Do so by adding this in your `spec_helper`:
|
|
109
125
|
```ruby
|
110
126
|
config.before(:each) do
|
111
127
|
allow_any_instance_of(ValidEmail2::Address).to receive(:valid_mx?).and_return(true)
|
128
|
+
allow_any_instance_of(ValidEmail2::Address).to receive(:valid_strict_mx?).and_return(true)
|
112
129
|
end
|
113
130
|
```
|
114
131
|
|
@@ -3398,6 +3398,7 @@ androidsapps.co
|
|
3398
3398
|
androidworld.tw
|
3399
3399
|
andthen.us
|
3400
3400
|
andy1mail.host
|
3401
|
+
andyes.net
|
3401
3402
|
andynugraha.net
|
3402
3403
|
andyyxc45.biz
|
3403
3404
|
aneaproducciones.com
|
@@ -4173,6 +4174,7 @@ avuimkgtbgccejft901.ml
|
|
4173
4174
|
avuimkgtbgccejft901.tk
|
4174
4175
|
avumail.com
|
4175
4176
|
avvmail.com
|
4177
|
+
avxrja.com
|
4176
4178
|
aw.kikwet.com
|
4177
4179
|
awahal0vk1o7gbyzf0.cf
|
4178
4180
|
awahal0vk1o7gbyzf0.ga
|
@@ -12788,6 +12790,7 @@ gmailllll.ga
|
|
12788
12790
|
gmaills.eu
|
12789
12791
|
gmailmail.ga
|
12790
12792
|
gmailmarina.com
|
12793
|
+
gmailnator.com
|
12791
12794
|
gmailner.com
|
12792
12795
|
gmailnew.com
|
12793
12796
|
gmailom.co
|
@@ -12938,6 +12941,7 @@ golivejasmin.com
|
|
12938
12941
|
gomail.in
|
12939
12942
|
gomail.pgojual.com
|
12940
12943
|
gomailbox.info
|
12944
|
+
gomaild.com
|
12941
12945
|
gomaile.com
|
12942
12946
|
gomailstar.xyz
|
12943
12947
|
gomessage.ml
|
@@ -18053,6 +18057,7 @@ louboutinshoessalejp.com
|
|
18053
18057
|
louboutinshoesstoresjp.com
|
18054
18058
|
louboutinshoesus.com
|
18055
18059
|
louder1.bid
|
18060
|
+
loufad.com
|
18056
18061
|
louis-vuitton-onlinestore.com
|
18057
18062
|
louis-vuitton-outlet.com
|
18058
18063
|
louis-vuitton-outletenter.com
|
@@ -31026,7 +31031,6 @@ voyagebirmanie.net
|
|
31026
31031
|
voyancegratuite10min.com
|
31027
31032
|
voyeurseite.info
|
31028
31033
|
vozmivtop.ru
|
31029
|
-
vp.com
|
31030
31034
|
vp.ycare.de
|
31031
31035
|
vpanel.ru
|
31032
31036
|
vpc608a0.pl
|
@@ -31423,7 +31427,6 @@ webcontact-france.eu
|
|
31423
31427
|
webcool.club
|
31424
31428
|
webdesign-guide.info
|
31425
31429
|
webdesign-romania.net
|
31426
|
-
webdesignspecialist.com.au
|
31427
31430
|
webdesigrsbio.gr
|
31428
31431
|
webdespro.ru
|
31429
31432
|
webdev-pro.ru
|
@@ -32328,6 +32331,7 @@ xdvsagsdg4we.ga
|
|
32328
32331
|
xe2g.com
|
32329
32332
|
xeames.net
|
32330
32333
|
xeb9xwp7.tk
|
32334
|
+
xedmi.com
|
32331
32335
|
xemaps.com
|
32332
32336
|
xemne.com
|
32333
32337
|
xenacareholdings.com
|
@@ -32378,6 +32382,7 @@ xhkss.net
|
|
32378
32382
|
xijjfjoo.turystyka.pl
|
32379
32383
|
xilopro.com
|
32380
32384
|
xilor.com
|
32385
|
+
ximtyl.com
|
32381
32386
|
xinbo.info
|
32382
32387
|
xinbox.info
|
32383
32388
|
xinfi.com.pl
|
data/lib/valid_email2.rb
CHANGED
@@ -7,23 +7,35 @@ module ValidEmail2
|
|
7
7
|
WHITELIST_FILE = "config/whitelisted_email_domains.yml"
|
8
8
|
DISPOSABLE_FILE = File.expand_path('../config/disposable_email_domains.txt', __dir__)
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
class << self
|
11
|
+
def disposable_emails
|
12
|
+
@disposable_emails ||= load_file(DISPOSABLE_FILE)
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
def blacklist
|
16
|
+
@blacklist ||= load_if_exists(BLACKLIST_FILE)
|
17
|
+
end
|
18
|
+
|
19
|
+
def whitelist
|
20
|
+
@whitelist ||= load_if_exists(WHITELIST_FILE)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def load_if_exists(path)
|
26
|
+
File.exist?(path) ? load_file(path) : Set.new
|
27
|
+
end
|
21
28
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
29
|
+
def load_file(path)
|
30
|
+
# This method MUST return a Set, otherwise the
|
31
|
+
# performance will suffer!
|
32
|
+
if path.end_with?(".yml")
|
33
|
+
Set.new(YAML.load_file(path))
|
34
|
+
else
|
35
|
+
File.open(path, "r").each_line.each_with_object(Set.new) do |domain, set|
|
36
|
+
set << domain.tap(&:chomp!)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
28
40
|
end
|
29
41
|
end
|
data/lib/valid_email2/address.rb
CHANGED
@@ -10,6 +10,14 @@ module ValidEmail2
|
|
10
10
|
DEFAULT_RECIPIENT_DELIMITER = '+'.freeze
|
11
11
|
DOT_DELIMITER = '.'.freeze
|
12
12
|
|
13
|
+
def self.prohibited_domain_characters_regex
|
14
|
+
@prohibited_domain_characters_regex ||= PROHIBITED_DOMAIN_CHARACTERS_REGEX
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.prohibited_domain_characters_regex=(val)
|
18
|
+
@prohibited_domain_characters_regex = val
|
19
|
+
end
|
20
|
+
|
13
21
|
def initialize(address)
|
14
22
|
@parse_error = false
|
15
23
|
@raw_address = address
|
@@ -24,25 +32,22 @@ module ValidEmail2
|
|
24
32
|
end
|
25
33
|
|
26
34
|
def valid?
|
27
|
-
@valid
|
28
|
-
|
35
|
+
return @valid unless @valid.nil?
|
36
|
+
return false if @parse_error
|
29
37
|
|
38
|
+
@valid = begin
|
30
39
|
if address.domain && address.address == @raw_address
|
31
40
|
domain = address.domain
|
32
41
|
|
33
|
-
domain !~
|
34
|
-
|
35
|
-
domain
|
36
|
-
|
37
|
-
domain
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
# Domain name may not end with a dash
|
43
|
-
domain !~ /-\./ &&
|
44
|
-
# Address may not contain a dot directly before @
|
45
|
-
address.address !~ /\.@/
|
42
|
+
domain !~ self.class.prohibited_domain_characters_regex &&
|
43
|
+
domain.include?('.') &&
|
44
|
+
!domain.include?('..') &&
|
45
|
+
!domain.start_with?('.') &&
|
46
|
+
!domain.start_with?('-') &&
|
47
|
+
!domain.include?('-.') &&
|
48
|
+
!address.local.include?('..') &&
|
49
|
+
!address.local.end_with?('.') &&
|
50
|
+
!address.local.start_with?('.')
|
46
51
|
else
|
47
52
|
false
|
48
53
|
end
|
@@ -62,7 +67,7 @@ module ValidEmail2
|
|
62
67
|
end
|
63
68
|
|
64
69
|
def disposable_domain?
|
65
|
-
|
70
|
+
domain_is_in?(ValidEmail2.disposable_emails)
|
66
71
|
end
|
67
72
|
|
68
73
|
def disposable_mx_server?
|
@@ -80,6 +85,12 @@ module ValidEmail2
|
|
80
85
|
def valid_mx?
|
81
86
|
return false unless valid?
|
82
87
|
|
88
|
+
mx_or_a_servers.any?
|
89
|
+
end
|
90
|
+
|
91
|
+
def valid_strict_mx?
|
92
|
+
return false unless valid?
|
93
|
+
|
83
94
|
mx_servers.any?
|
84
95
|
end
|
85
96
|
|
@@ -114,7 +125,12 @@ module ValidEmail2
|
|
114
125
|
|
115
126
|
def mx_servers
|
116
127
|
@mx_servers ||= Resolv::DNS.open do |dns|
|
117
|
-
|
128
|
+
dns.getresources(address.domain, Resolv::DNS::Resource::IN::MX)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def mx_or_a_servers
|
133
|
+
@mx_or_a_servers ||= Resolv::DNS.open do |dns|
|
118
134
|
(mx_servers.any? && mx_servers) ||
|
119
135
|
dns.getresources(address.domain, Resolv::DNS::Resource::IN::A)
|
120
136
|
end
|
@@ -5,43 +5,52 @@ require "active_model/validations"
|
|
5
5
|
module ValidEmail2
|
6
6
|
class EmailValidator < ActiveModel::EachValidator
|
7
7
|
def default_options
|
8
|
-
{ regex: true, disposable: false, mx: false, disallow_subaddressing: false }
|
8
|
+
{ regex: true, disposable: false, mx: false, strict_mx: false, disallow_subaddressing: false, multiple: false }
|
9
9
|
end
|
10
10
|
|
11
11
|
def validate_each(record, attribute, value)
|
12
12
|
return unless value.present?
|
13
13
|
options = default_options.merge(self.options)
|
14
14
|
|
15
|
-
|
15
|
+
value_spitted = options[:multiple] ? value.split(',').map(&:strip) : [value]
|
16
|
+
addresses = value_spitted.map { |v| ValidEmail2::Address.new(v) }
|
16
17
|
|
17
|
-
error(record, attribute) && return unless
|
18
|
+
error(record, attribute) && return unless addresses.all?(&:valid?)
|
18
19
|
|
19
20
|
if options[:disallow_dotted]
|
20
|
-
error(record, attribute) && return if
|
21
|
+
error(record, attribute) && return if addresses.any?(&:dotted?)
|
21
22
|
end
|
22
23
|
|
23
24
|
if options[:disallow_subaddressing]
|
24
|
-
error(record, attribute) && return if
|
25
|
+
error(record, attribute) && return if addresses.any?(&:subaddressed?)
|
25
26
|
end
|
26
27
|
|
27
28
|
if options[:disposable]
|
28
|
-
error(record, attribute) && return if
|
29
|
+
error(record, attribute) && return if addresses.any?(&:disposable?)
|
29
30
|
end
|
30
31
|
|
31
32
|
if options[:disposable_domain]
|
32
|
-
error(record, attribute) && return if
|
33
|
+
error(record, attribute) && return if addresses.any?(&:disposable_domain?)
|
33
34
|
end
|
34
35
|
|
35
36
|
if options[:disposable_with_whitelist]
|
36
|
-
error(record, attribute) && return if address.disposable? && !address.whitelisted?
|
37
|
+
error(record, attribute) && return if addresses.any? { |address| address.disposable? && !address.whitelisted? }
|
38
|
+
end
|
39
|
+
|
40
|
+
if options[:disposable_domain_with_whitelist]
|
41
|
+
error(record, attribute) && return if addresses.any? { |address| address.disposable_domain? && !address.whitelisted? }
|
37
42
|
end
|
38
43
|
|
39
44
|
if options[:blacklist]
|
40
|
-
error(record, attribute) && return if
|
45
|
+
error(record, attribute) && return if addresses.any?(&:blacklisted?)
|
41
46
|
end
|
42
47
|
|
43
48
|
if options[:mx]
|
44
|
-
error(record, attribute) && return unless
|
49
|
+
error(record, attribute) && return unless addresses.all?(&:valid_mx?)
|
50
|
+
end
|
51
|
+
|
52
|
+
if options[:strict_mx]
|
53
|
+
error(record, attribute) && return unless addresses.all?(&:valid_strict_mx?)
|
45
54
|
end
|
46
55
|
end
|
47
56
|
|
data/lib/valid_email2/version.rb
CHANGED
data/pull_mailchecker_emails.rb
CHANGED
@@ -8,7 +8,7 @@ require "net/http"
|
|
8
8
|
whitelisted_emails = %w(
|
9
9
|
onet.pl poczta.onet.pl fastmail.fm hushmail.com
|
10
10
|
hush.ai hush.com hushmail.me naver.com qq.com example.com
|
11
|
-
yandex.net gmx.com gmx.es
|
11
|
+
yandex.net gmx.com gmx.es webdesignspecialist.com.au vp.com
|
12
12
|
)
|
13
13
|
|
14
14
|
existing_emails = File.open("config/disposable_email_domains.txt") { |f| f.read.split("\n") }
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe "Performance testing" do
|
6
|
+
let(:disposable_domain) { ValidEmail2.disposable_emails.first }
|
7
|
+
|
8
|
+
it "has acceptable lookup performance" do
|
9
|
+
address = ValidEmail2::Address.new("test@example.com")
|
10
|
+
|
11
|
+
# preload list and check size
|
12
|
+
expect(ValidEmail2.disposable_emails).to be_a(Set)
|
13
|
+
expect(ValidEmail2.disposable_emails.count).to be > 30000
|
14
|
+
|
15
|
+
# check lookup timing
|
16
|
+
expect { address.disposable_domain? }.to perform_under(0.0001).sample(10).times
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
$:.unshift File.expand_path("../lib",__FILE__)
|
2
2
|
require "valid_email2"
|
3
3
|
|
4
|
+
# Include and configure benchmark
|
5
|
+
require 'rspec-benchmark'
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.include RSpec::Benchmark::Matchers
|
8
|
+
end
|
9
|
+
RSpec::Benchmark.configure do |config|
|
10
|
+
config.disable_gc = true
|
11
|
+
end
|
12
|
+
|
4
13
|
class TestModel
|
5
14
|
include ActiveModel::Validations
|
6
15
|
|
data/spec/valid_email2_spec.rb
CHANGED
@@ -19,6 +19,10 @@ class TestUserMX < TestModel
|
|
19
19
|
validates :email, 'valid_email_2/email': { mx: true }
|
20
20
|
end
|
21
21
|
|
22
|
+
class TestUserStrictMX < TestModel
|
23
|
+
validates :email, 'valid_email_2/email': { strict_mx: true }
|
24
|
+
end
|
25
|
+
|
22
26
|
class TestUserDisallowDisposable < TestModel
|
23
27
|
validates :email, 'valid_email_2/email': { disposable: true }
|
24
28
|
end
|
@@ -31,6 +35,10 @@ class TestUserDisallowDisposableWithWhitelist < TestModel
|
|
31
35
|
validates :email, 'valid_email_2/email': { disposable_with_whitelist: true }
|
32
36
|
end
|
33
37
|
|
38
|
+
class TestUserDisallowDisposableDomainWithWhitelist < TestModel
|
39
|
+
validates :email, 'valid_email_2/email': { disposable_domain_with_whitelist: true }
|
40
|
+
end
|
41
|
+
|
34
42
|
class TestUserDisallowBlacklisted < TestModel
|
35
43
|
validates :email, 'valid_email_2/email': { blacklist: true }
|
36
44
|
end
|
@@ -39,6 +47,10 @@ class TestUserMessage < TestModel
|
|
39
47
|
validates :email, 'valid_email_2/email': { message: "custom message" }
|
40
48
|
end
|
41
49
|
|
50
|
+
class TestUserMultiple < TestModel
|
51
|
+
validates :email, 'valid_email_2/email': { multiple: true }
|
52
|
+
end
|
53
|
+
|
42
54
|
describe ValidEmail2 do
|
43
55
|
|
44
56
|
let(:disposable_domain) { ValidEmail2.disposable_emails.first }
|
@@ -83,13 +95,23 @@ describe ValidEmail2 do
|
|
83
95
|
expect(user.valid?).to be_falsey
|
84
96
|
end
|
85
97
|
|
86
|
-
it "is invalid if the
|
87
|
-
user = TestUser.new(email: "foo
|
88
|
-
expect(user.valid?).to
|
98
|
+
it "is invalid if the address contains consecutive dots" do
|
99
|
+
user = TestUser.new(email: "foo..bar@gmail.com")
|
100
|
+
expect(user.valid?).to be_falsey
|
101
|
+
end
|
102
|
+
|
103
|
+
it "is invalid if the address starts with a dot" do
|
104
|
+
user = TestUser.new(email: ".foo@bar.com")
|
105
|
+
expect(user.valid?).to be_falsey
|
89
106
|
end
|
90
107
|
|
91
|
-
it "is invalid if the
|
92
|
-
user = TestUser.new(email: "foo.@
|
108
|
+
it "is invalid if the local part of the address ends with a dot" do
|
109
|
+
user = TestUser.new(email: "foo.@bar.com")
|
110
|
+
expect(user.valid?).to be_falsey
|
111
|
+
end
|
112
|
+
|
113
|
+
it "is invalid if the email contains emoticons" do
|
114
|
+
user = TestUser.new(email: "foo🙈@gmail.com")
|
93
115
|
expect(user.valid?).to be_falsy
|
94
116
|
end
|
95
117
|
|
@@ -166,8 +188,18 @@ describe ValidEmail2 do
|
|
166
188
|
let(:whitelist_domain) { disposable_domain }
|
167
189
|
let(:whitelist_file_path) { "config/whitelisted_email_domains.yml" }
|
168
190
|
|
191
|
+
# Some of the specs below need to explictly set the whitelist var or it
|
192
|
+
# may be cached to an empty set
|
193
|
+
def set_whitelist
|
194
|
+
ValidEmail2.instance_variable_set(
|
195
|
+
:@whitelist,
|
196
|
+
ValidEmail2.send(:load_if_exists, ValidEmail2::WHITELIST_FILE)
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
169
200
|
after do
|
170
201
|
FileUtils.rm(whitelist_file_path, force: true)
|
202
|
+
set_whitelist
|
171
203
|
end
|
172
204
|
|
173
205
|
it "is invalid if the domain is disposable and not in the whitelist" do
|
@@ -177,9 +209,22 @@ describe ValidEmail2 do
|
|
177
209
|
|
178
210
|
it "is valid if the domain is disposable but in the whitelist" do
|
179
211
|
File.open(whitelist_file_path, "w") { |f| f.write [whitelist_domain].to_yaml }
|
212
|
+
set_whitelist
|
180
213
|
user = TestUserDisallowDisposableWithWhitelist.new(email: "foo@#{whitelist_domain}")
|
214
|
+
expect(user.valid?).to be_truthy
|
215
|
+
end
|
216
|
+
|
217
|
+
it "is invalid if the domain is a disposable_domain and not in the whitelist" do
|
218
|
+
user = TestUserDisallowDisposableDomainWithWhitelist.new(email: "foo@#{whitelist_domain}")
|
181
219
|
expect(user.valid?).to be_falsey
|
182
220
|
end
|
221
|
+
|
222
|
+
it "is valid if the domain is a disposable_domain but in the whitelist" do
|
223
|
+
File.open(whitelist_file_path, "w") { |f| f.write [whitelist_domain].to_yaml }
|
224
|
+
set_whitelist
|
225
|
+
user = TestUserDisallowDisposableDomainWithWhitelist.new(email: "foo@#{whitelist_domain}")
|
226
|
+
expect(user.valid?).to be_truthy
|
227
|
+
end
|
183
228
|
end
|
184
229
|
end
|
185
230
|
|
@@ -212,6 +257,23 @@ describe ValidEmail2 do
|
|
212
257
|
end
|
213
258
|
end
|
214
259
|
|
260
|
+
describe "with strict mx validation" do
|
261
|
+
it "is valid if mx records are found" do
|
262
|
+
user = TestUserStrictMX.new(email: "foo@gmail.com")
|
263
|
+
expect(user.valid?).to be_truthy
|
264
|
+
end
|
265
|
+
|
266
|
+
it "is invalid if A records are found but no mx records are found" do
|
267
|
+
user = TestUserStrictMX.new(email: "foo@ghs.google.com")
|
268
|
+
expect(user.valid?).to be_falsey
|
269
|
+
end
|
270
|
+
|
271
|
+
it "is invalid if no mx records are found" do
|
272
|
+
user = TestUserStrictMX.new(email: "foo@subdomain.gmail.com")
|
273
|
+
expect(user.valid?).to be_falsey
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
215
277
|
describe "with dotted validation" do
|
216
278
|
it "is valid when address does not contain dots" do
|
217
279
|
user = TestUserDotted.new(email: "johndoe@gmail.com")
|
@@ -244,6 +306,20 @@ describe ValidEmail2 do
|
|
244
306
|
end
|
245
307
|
end
|
246
308
|
|
309
|
+
describe "with multiple addresses" do
|
310
|
+
it "tests each address for it's own" do
|
311
|
+
user = TestUserMultiple.new(email: "foo@gmail.com, bar@gmail.com")
|
312
|
+
expect(user.valid?).to be_truthy
|
313
|
+
end
|
314
|
+
|
315
|
+
context 'when one address is invalid' do
|
316
|
+
it "fails for all" do
|
317
|
+
user = TestUserMultiple.new(email: "foo@gmail.com, bar@123")
|
318
|
+
expect(user.valid?).to be_falsey
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
247
323
|
describe "#dotted?" do
|
248
324
|
it "is true when address local part contains a dot delimiter ('.')" do
|
249
325
|
email = ValidEmail2::Address.new("john.doe@gmail.com")
|
data/valid_email2.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 2.0"
|
24
24
|
spec.add_development_dependency "rake", "~> 12.3.3"
|
25
25
|
spec.add_development_dependency "rspec", "~> 3.5.0"
|
26
|
+
spec.add_development_dependency "rspec-benchmark", "~> 0.6"
|
26
27
|
spec.add_development_dependency "pry"
|
27
28
|
spec.add_runtime_dependency "mail", "~> 2.5"
|
28
29
|
spec.add_runtime_dependency "activemodel", ">= 3.2"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valid_email2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micke Lisinge
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 3.5.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-benchmark
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.6'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: pry
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,6 +134,7 @@ files:
|
|
120
134
|
- lib/valid_email2/email_validator.rb
|
121
135
|
- lib/valid_email2/version.rb
|
122
136
|
- pull_mailchecker_emails.rb
|
137
|
+
- spec/benchmark_spec.rb
|
123
138
|
- spec/spec_helper.rb
|
124
139
|
- spec/valid_email2_spec.rb
|
125
140
|
- valid_email2.gemspec
|
@@ -142,11 +157,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
157
|
- !ruby/object:Gem::Version
|
143
158
|
version: '0'
|
144
159
|
requirements: []
|
145
|
-
rubygems_version: 3.1.
|
160
|
+
rubygems_version: 3.1.4
|
146
161
|
signing_key:
|
147
162
|
specification_version: 4
|
148
163
|
summary: ActiveModel validation for email. Including MX lookup and disposable email
|
149
164
|
blacklist
|
150
165
|
test_files:
|
166
|
+
- spec/benchmark_spec.rb
|
151
167
|
- spec/spec_helper.rb
|
152
168
|
- spec/valid_email2_spec.rb
|