email_assessor 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28e8db711b1571f9f105f0e341b8798bf557edcdd21bfa9af93b97a2fc6e7989
4
- data.tar.gz: 697a161767368eed35a1cf12eaca2fc9c129b6e27f4ab48a4bd07362597a678c
3
+ metadata.gz: 8cb395329e3cd39283e977bf23e76aace70bf54f8a4e735fb853452e9e2cd6a9
4
+ data.tar.gz: b5584869b5c06e03a9be43827685a59b69a1d3b0f516b3670649557097ddc642
5
5
  SHA512:
6
- metadata.gz: ac12ac0944a707a72b3d7f507b016c0d4dad6cd3cd924c1f229178e8dd806cff1e2bdf4eca887566c2271c15ea4a9210f02b2f6e24e26d768c85e47e73104fdb
7
- data.tar.gz: fd148a7343b485d42f320c0e7fcc2265a636f2973faacf3e928d5315c39e8b909c970809c6ebd07b3d929484a2239b33be3c7b2bb38ef0aeb0bd3648e2288db4
6
+ metadata.gz: 22b2a38efbcb45ced0186a9a00a159747aa6c7d66c21c942b02d7862014f99e2a5b3c985d91cab0377ceee2fa91bfbf404e683bfb7b503ad57da4c4fc1bdeadf
7
+ data.tar.gz: 38fc56dd35d5c2dbc31f95cd491398ed102bdc494e6674c5e552e775ba57c538f750c5ae5823ba36ca89d2031b3cffd295fc552047e8793d8ca82a2394f6ec68
@@ -111,11 +111,23 @@ module EmailAssessor
111
111
  end
112
112
 
113
113
  def disposable?
114
- valid? && EmailAssessor.domain_is_disposable?(address.domain)
114
+ domain_in_file?(EmailAssessor::DISPOSABLE_DOMAINS_FILE_NAME)
115
115
  end
116
116
 
117
117
  def blacklisted?
118
- valid? && EmailAssessor.domain_is_blacklisted?(address.domain)
118
+ domain_in_file?(EmailAssessor::BLACKLISTED_DOMAINS_FILE_NAME)
119
+ end
120
+
121
+ def educational?
122
+ domain_in_file?(EmailAssessor::EDUCATIONAL_DOMAINS_FILE_NAME)
123
+ end
124
+
125
+ def fastpass?
126
+ domain_in_file?(EmailAssessor::FASTPASS_DOMAINS_FILE_NAME)
127
+ end
128
+
129
+ def domain_in_file?(filename)
130
+ valid? && EmailAssessor.domain_in_file?(address.domain, filename)
119
131
  end
120
132
 
121
133
  def valid_mx?
@@ -5,31 +5,74 @@ require "active_model/validations"
5
5
 
6
6
  class EmailValidator < ActiveModel::EachValidator
7
7
  def default_options
8
- { regex: true, disposable: false, mx: false }
8
+ { regex: true, disposable: false, mx: false, fastpass: true }
9
9
  end
10
10
 
11
11
  def validate_each(record, attribute, value)
12
12
  return unless value.present?
13
- options = default_options.merge(self.options)
13
+
14
+ options = default_options.merge!(self.options)
14
15
 
15
16
  address = EmailAssessor::Address.new(value)
16
17
 
17
18
  error(record, attribute) && return unless address.valid?
18
19
 
20
+ # Skip all domain blocklist checks for fastpass domains.
21
+ # The goal is to skip needless validation for common "good" domains such as Gmail, Yahoo, and Outlook.
22
+ # The fastpass domain list is configurable via vendor/fastpass_domains.txt
23
+ validate_domain(record, attribute, address, options) unless options[:fastpass] && address.fastpass?
24
+
25
+ # Exit early if validate_domain found a validation error
26
+ return if record.errors.key?(attribute)
27
+
28
+ if options[:mx]
29
+ error(record, attribute, error_type(:mx, options)) && return unless address.valid_mx?
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def error(record, attribute, type = options[:message] || :invalid)
36
+ record.errors.add(attribute, type)
37
+ end
38
+
39
+ def error_type(validator, options)
40
+ option_value = options[validator]
41
+
42
+ if option_value.is_a?(String) || option_value.is_a?(Symbol)
43
+ return option_value
44
+ end
45
+
46
+ options[:message] || :invalid
47
+ end
48
+
49
+ def validate_domain(record, attribute, address, options)
19
50
  if options[:disposable]
20
- error(record, attribute) && return if address.disposable?
51
+ error(record, attribute, error_type(:disposable, options)) && return if address.disposable?
21
52
  end
22
53
 
23
54
  if options[:blacklist]
24
- error(record, attribute) && return if address.blacklisted?
55
+ error(record, attribute, error_type(:blacklist, options)) && return if address.blacklisted?
25
56
  end
26
57
 
27
- if options[:mx]
28
- error(record, attribute) && return unless address.valid_mx?
58
+ if options[:educational]
59
+ error(record, attribute, error_type(:educational, options)) && return if address.educational?
29
60
  end
30
- end
31
61
 
32
- def error(record, attribute)
33
- record.errors.add(attribute, options[:message] || :invalid)
62
+ # if options[:domain_not_in]
63
+ # matched_blocklist = options[:domain_not_in].select do |entry|
64
+ # unless entry.key?(:blocklist)
65
+ # fail "domain_not_in entries must be in format { blocklist: \"filename\"[, message: symbol|string] }"
66
+ # end
67
+
68
+ # next unless address.domain_in_blocklist?(entry[:blocklist])
69
+
70
+ # error(record, attribute, entry[:message])
71
+
72
+ # true
73
+ # end
74
+
75
+ # return if matched_blocklist
76
+ # end
34
77
  end
35
78
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module EmailAssessor
3
- VERSION = "0.7.1"
3
+ VERSION = "0.8.0"
4
4
  end
@@ -3,6 +3,8 @@ require "email_assessor/email_validator"
3
3
 
4
4
  module EmailAssessor
5
5
  DISPOSABLE_DOMAINS_FILE_NAME = File.expand_path("../../vendor/disposable_domains.txt", __FILE__)
6
+ FASTPASS_DOMAINS_FILE_NAME = File.expand_path("../../vendor/fastpass_domains.txt", __FILE__)
7
+ EDUCATIONAL_DOMAINS_FILE_NAME = File.expand_path("../../vendor/educational_domains.txt", __FILE__)
6
8
  BLACKLISTED_DOMAINS_FILE_NAME = File.expand_path("vendor/blacklisted_domains.txt")
7
9
 
8
10
  def self.domain_is_disposable?(domain)
@@ -17,10 +17,15 @@ class TestUserDisallowBlacklisted < TestModel
17
17
  validates :email, email: { blacklist: true }
18
18
  end
19
19
 
20
+ class TestUserDisallowEducational < TestModel
21
+ validates :email, email: { educational: :no_educational }
22
+ end
23
+
20
24
  describe EmailAssessor do
21
25
  let(:plain_user) { TestUser.new(email: "") }
22
26
  let(:disposable_user) { TestUserDisallowDisposable.new(email: "foo@gmail.com") }
23
27
  let(:blacklist_user) { TestUserDisallowBlacklisted.new(email: "foo@gmail.com") }
28
+ let(:educational_user) { TestUserDisallowEducational.new(email: "foo@gmail.com") }
24
29
  let(:mx_user) { TestUserMX.new(email: "foo@gmail.com") }
25
30
 
26
31
  let(:blacklisted_domains_file_name) { described_class::BLACKLISTED_DOMAINS_FILE_NAME }
@@ -29,6 +34,9 @@ describe EmailAssessor do
29
34
  let(:disposable_domains_file_name) { described_class::DISPOSABLE_DOMAINS_FILE_NAME }
30
35
  let(:disposable_domain) { File.open(disposable_domains_file_name, &:readline).chomp }
31
36
 
37
+ let(:educational_domains_file_name) { described_class::EDUCATIONAL_DOMAINS_FILE_NAME }
38
+ let(:educational_domain) { File.open(educational_domains_file_name, &:readline).chomp }
39
+
32
40
  describe "basic validation" do
33
41
  subject(:user) { plain_user }
34
42
 
@@ -161,6 +169,31 @@ describe EmailAssessor do
161
169
  end
162
170
  end
163
171
 
172
+ describe "educational domains" do
173
+ subject(:user) { educational_user }
174
+
175
+ it "is valid when email domain is not in the educational blocklist" do
176
+ is_expected.to be_valid
177
+ end
178
+
179
+ it "is invalid when email domain is in the educational blocklist" do
180
+ user.email = "foo@#{educational_domain}"
181
+ is_expected.to be_invalid
182
+ end
183
+
184
+ it "is invalid when email is in the educational blocklist regardless of case" do
185
+ user.email = "foo@#{educational_domain.upcase}"
186
+ is_expected.to be_invalid
187
+ end
188
+
189
+ it "is invalid when email domain is in the educational blocklist regardless of subdomain" do
190
+ user.email = "foo@abc123.#{educational_domain}"
191
+ is_expected.to be_invalid
192
+ expect(user.errors.added?(:email, :no_educational)).to be_truthy
193
+ end
194
+ end
195
+
196
+
164
197
  describe "mx lookup" do
165
198
  subject(:user) { mx_user }
166
199
 
@@ -0,0 +1,169 @@
1
+ edu
2
+ education
3
+ school
4
+ edu.my
5
+ edu.ph
6
+ edu.au
7
+ edu.vn
8
+ edu.ar
9
+ edu.sv
10
+ edu.mx
11
+ edu.eg
12
+ edu.sg
13
+ edu.co
14
+ edu.jm
15
+ edu.it
16
+ edu.hk
17
+ edu.bd
18
+ edu.tr
19
+ edu.om
20
+ edu.mn
21
+ edu.np
22
+ edu.pk
23
+ edu.ge
24
+ edu.kh
25
+ edu.br
26
+ edu.tw
27
+ edu.in
28
+ edu.do
29
+ edu.kw
30
+ edu.iq
31
+ edu.ee
32
+ edu.pa
33
+ edu.lb
34
+ edu.gh
35
+ edu.gt
36
+ edu.sa
37
+ edu.ec
38
+ edu.pe
39
+ edu.ng
40
+ edu.gr
41
+ edu.pl
42
+ edu.lc
43
+ edu.rs
44
+ edu.cu
45
+ ecsrd.ca
46
+ lbpearson.ca
47
+ egusd.net
48
+ mytusd.org
49
+ rcsd121.org
50
+ nisdtx.org
51
+ fusdk12.net
52
+ stocktonusd.org
53
+ ggusd.net
54
+ ausd.net
55
+ ousd.org
56
+ mytusd.org
57
+ rialtousd.org
58
+ usd250.org
59
+ cusd200.org
60
+ lausd.net
61
+ cusdstudent.com
62
+ sgusd.net
63
+ sjusd.org
64
+ losbanosusd.net
65
+ arusd.org
66
+ cusdk12.org
67
+ dvusd.org
68
+ conejousd.net
69
+ busdk12.com
70
+ lbusd.org
71
+ vusd.us
72
+ cvusd.us
73
+ scusd.net
74
+ twinriversusd.org
75
+ wcusd.net
76
+ lusd.net
77
+ sfusd.edu
78
+ pusd.org
79
+ mbusdapps.org
80
+ lvjusd.org
81
+ etusd.org
82
+ hemetusd.org
83
+ myabcusd.org
84
+ lodiusd.org
85
+ pusd.org
86
+ gusd.org
87
+ uusd.net
88
+ cmsdk12.org
89
+ dpsk12.net
90
+ hdcsk12.org
91
+ wilsonk12tn.us
92
+ herricksk12.org
93
+ gcssk12.net
94
+ bostonk12.org
95
+ rpsk12.org
96
+ muhlsdk12.net
97
+ lpsk12.org
98
+ warrenk12nc.org
99
+ washk12.org
100
+ middletownk12.org
101
+ astoriak12.org
102
+ fusdk12.net
103
+ aurorak12.org
104
+ ycdsbk12.ca
105
+ bentonvillek12.org
106
+ soledadk12.org
107
+ theacademyk12.org
108
+ grinnell-k12.org
109
+ maderak12.org
110
+ boazk12.org
111
+ ccsk12.net
112
+ npsk12.net
113
+ msdk12.org
114
+ dcsk12.org
115
+ nrpsk12.org
116
+ psk12.net
117
+ ilsonk12tn.us
118
+ erricksk12.org
119
+ cssk12.net
120
+ ostonk12.org
121
+ psk12.org
122
+ uhlsdk12.net
123
+ arrenk12nc.org
124
+ gcpsk12.org
125
+ dcsdk12.org
126
+ ashk12.org
127
+ romeok12.org
128
+ storiak12.org
129
+ usdk12.net
130
+ iddletownk12.org
131
+ urorak12.org
132
+ cdsbk12.ca
133
+ novik12.org
134
+ entonvillek12.org
135
+ ghctk12.com
136
+ oledadk12.org
137
+ heacademyk12.org
138
+ rinnell-k12.org
139
+ busdk12.com
140
+ aderak12.org
141
+ oazk12.org
142
+ cusdk12.org
143
+ csk12.net
144
+ k12.nc.us
145
+ k12.ca.us
146
+ k12.or.us
147
+ k12.oh.us
148
+ k12.va.us
149
+ k12.in.us
150
+ k12.ga.us
151
+ k12.mi.us
152
+ k12.al.us
153
+ k12.wi.us
154
+ k12.de.us
155
+ k12.ar.us
156
+ k12.ny.us
157
+ k12.nj.us
158
+ k12.sc.us
159
+ k12.mn.us
160
+ k12.ma.us
161
+ k12.mo.us
162
+ k12.md.us
163
+ k12.tr
164
+ k12.hi.us
165
+ k12.ct.us
166
+ k12.ia.us
167
+ k12.ms.us
168
+ k12.ok.us
169
+ k12.il.us
@@ -0,0 +1,35 @@
1
+ gmail.com
2
+ live.co.uk
3
+ hotmail.com
4
+ web.de
5
+ yahoo.de
6
+ yahoo.com
7
+ outlook.com
8
+ yahoo.co.uk
9
+ hotmail.fr
10
+ seznam.cz
11
+ citromail.hu
12
+ live.com
13
+ o2.pl
14
+ yahoo.ca
15
+ gmx.at
16
+ icloud.com
17
+ outlook.fr
18
+ hotmail.co.uk
19
+ yahoo.com.ph
20
+ ymail.com
21
+ hotmail.it
22
+ mail.ru
23
+ protonmail.com
24
+ live.fr
25
+ hotmail.ca
26
+ me.com
27
+ yahoo.co.id
28
+ gmx.de
29
+ wp.pl
30
+ live.nl
31
+ googlemail.com
32
+ live.de
33
+ mail.com
34
+ outlook.de
35
+ yandex.com
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: email_assessor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Wolfe Millard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-19 00:00:00.000000000 Z
11
+ date: 2022-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -105,6 +105,8 @@ files:
105
105
  - spec/spec_helper.rb
106
106
  - vendor/blacklisted_domains.txt
107
107
  - vendor/disposable_domains.txt
108
+ - vendor/educational_domains.txt
109
+ - vendor/fastpass_domains.txt
108
110
  homepage: https://github.com/wolfemm/email_assessor
109
111
  licenses:
110
112
  - MIT
@@ -124,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
126
  - !ruby/object:Gem::Version
125
127
  version: '0'
126
128
  requirements: []
127
- rubygems_version: 3.2.22
129
+ rubygems_version: 3.1.6
128
130
  signing_key:
129
131
  specification_version: 4
130
132
  summary: Advanced ActiveModel email validation