email_assessor 0.7.1 → 0.8.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 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