valid_email2 5.1.1 → 5.2.1

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: 925627af7072ddf7e2f82482253520d9bef1111e605317106afbf84b951c5a57
4
- data.tar.gz: 7eb5251aa7f5cf9e2bcd24c63f23fb45ea6770581d8e1ceebf00933f64f24498
3
+ metadata.gz: 57071297cdef5b2a46ca31b127b601458a6a072aa99f051effc120d8adba3206
4
+ data.tar.gz: 3d3d64f311440deaec02775e03378d6c73c49a2df05d7cb646053d80810f6edc
5
5
  SHA512:
6
- metadata.gz: 3f02e361ed0c985a4f770a09222fef9179de6a9f01995ac84c57ae6b9a843172afaf80116d01dc1ad9a9b5959dfcc6a089ce5b2ea2d6340701308b8e3b8a9817
7
- data.tar.gz: f05c620994e0aaf353dfc4227cc317d20d2bd9be59e1b85ba4ab70db5d0cf0522ed939dab7fff625ad5701c710da33f037ba37e44123d9f1989b14b3faa64980
6
+ metadata.gz: fa072ecdf03263aa77b3f474f0bac7046db97d1c5ed3aa731a994f7f3a7c71bc1ae433feedd5b2cae0e3fe3ac7869f6b4b3335580e5068de98c874e129b177cb
7
+ data.tar.gz: 82d3b5add7b081e6db4813445c5d46f3123de7f604893039855d91f0f42cfd6a5704854b28f0e990ff94d222110763febfa24f949cccba37e0be764bec79e710
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## Version 5.2.1
2
+ * Remov false positive [#231](https://github.com/micke/valid_email2/pull/231)
3
+
4
+ ## Version 5.2.0
5
+ * Allow configuration of DNS nameserver [#230](https://github.com/micke/valid_email2/pull/230)
6
+
1
7
  ## Version 5.1.1
2
8
  * Remove false positives [#223](https://github.com/micke/valid_email2/issues/223)
3
9
 
data/README.md CHANGED
@@ -51,12 +51,18 @@ To validate strictly that the domain has an MX record:
51
51
  ```ruby
52
52
  validates :email, 'valid_email_2/email': { strict_mx: true }
53
53
  ```
54
- `strict_mx` and `mx` both default to a 5 second timeout for DNS lookups. To
55
- override this timeout, specify a `dns_timeout` option:
54
+ `strict_mx` and `mx` both default to a 5 second timeout for DNS lookups.
55
+ To override this timeout, specify a `dns_timeout` option:
56
56
  ```ruby
57
57
  validates :email, 'valid_email_2/email': { strict_mx: true, dns_timeout: 10 }
58
58
  ```
59
59
 
60
+ Any checks that require DNS resolution will use the default `Resolv::DNS` nameservers for DNS lookups.
61
+ To override these, specify a `dns_nameserver` option:
62
+ ```ruby
63
+ validates :email, 'valid_email_2/email': { mx: true, dns_nameserver: ['8.8.8.8', '8.8.4.4'] }
64
+ ```
65
+
60
66
  To validate that the domain is not a disposable email (checks domain and MX server):
61
67
  ```ruby
62
68
  validates :email, 'valid_email_2/email': { disposable: true }
@@ -89730,7 +89730,6 @@ mailinator8.com
89730
89730
  mailinator9.com
89731
89731
  mailinatorzz.mooo.com
89732
89732
  mailinatr.com
89733
- mailinblack.com
89734
89733
  mailinbox.cf
89735
89734
  mailinbox.co
89736
89735
  mailinbox.ga
@@ -20,11 +20,14 @@ module ValidEmail2
20
20
  @prohibited_domain_characters_regex = val
21
21
  end
22
22
 
23
- def initialize(address, dns_timeout = 5)
23
+ def initialize(address, dns_timeout = 5, dns_nameserver = nil)
24
24
  @parse_error = false
25
25
  @raw_address = address
26
26
  @dns_timeout = dns_timeout
27
27
 
28
+ @resolv_config = Resolv::DNS::Config.default_config_hash
29
+ @resolv_config[:nameserver] = dns_nameserver if dns_nameserver
30
+
28
31
  begin
29
32
  @address = Mail::Address.new(address)
30
33
  rescue Mail::Field::ParseError
@@ -134,7 +137,7 @@ module ValidEmail2
134
137
  end
135
138
 
136
139
  def mx_servers
137
- @mx_servers ||= Resolv::DNS.open do |dns|
140
+ @mx_servers ||= Resolv::DNS.open(@resolv_config) do |dns|
138
141
  dns.timeouts = @dns_timeout
139
142
  dns.getresources(address.domain, Resolv::DNS::Resource::IN::MX)
140
143
  end
@@ -145,7 +148,7 @@ module ValidEmail2
145
148
  end
146
149
 
147
150
  def mx_or_a_servers
148
- @mx_or_a_servers ||= Resolv::DNS.open do |dns|
151
+ @mx_or_a_servers ||= Resolv::DNS.open(@resolv_config) do |dns|
149
152
  dns.timeouts = @dns_timeout
150
153
  (mx_servers.any? && mx_servers) ||
151
154
  dns.getresources(address.domain, Resolv::DNS::Resource::IN::A)
@@ -5,14 +5,14 @@ require "active_model/validations"
5
5
  module ValidEmail2
6
6
  class EmailValidator < ActiveModel::EachValidator
7
7
  def default_options
8
- { disposable: false, mx: false, strict_mx: false, disallow_subaddressing: false, multiple: false, dns_timeout: 5 }
8
+ { disposable: false, mx: false, strict_mx: false, disallow_subaddressing: false, multiple: false, dns_timeout: 5, dns_nameserver: nil }
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
- addresses = sanitized_values(value).map { |v| ValidEmail2::Address.new(v, options[:dns_timeout]) }
15
+ addresses = sanitized_values(value).map { |v| ValidEmail2::Address.new(v, options[:dns_timeout], options[:dns_nameserver]) }
16
16
 
17
17
  error(record, attribute) && return unless addresses.all?(&:valid?)
18
18
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal:true
2
2
 
3
3
  module ValidEmail2
4
- VERSION = "5.1.1"
4
+ VERSION = "5.2.1"
5
5
  end
@@ -14,6 +14,7 @@ whitelisted_emails = %w(
14
14
  simplelogin.io aleeas.com slmails.com silomails.com slmail.me
15
15
  passinbox.com passfwd.com passmail.com passmail.net
16
16
  duck.com mozmail.com dralias.com 8alias.com 8shield.net
17
+ mailinblack.com
17
18
  )
18
19
 
19
20
  existing_emails = File.open("config/disposable_email_domains.txt") { |f| f.read.split("\n") }
@@ -23,6 +23,22 @@ class TestUserStrictMX < TestModel
23
23
  validates :email, 'valid_email_2/email': { strict_mx: true }
24
24
  end
25
25
 
26
+ class TestUserMXDnsTimeout < TestModel
27
+ validates :email, 'valid_email_2/email': { mx: true, dns_timeout: 10 }
28
+ end
29
+
30
+ class TestUserMXDnsFailingTimeout < TestModel
31
+ validates :email, 'valid_email_2/email': { mx: true, dns_timeout: Float::MIN }
32
+ end
33
+
34
+ class TestUserMXDnsNameserver < TestModel
35
+ validates :email, 'valid_email_2/email': { mx: true, dns_nameserver: ['8.8.8.8', '8.8.4.4'] }
36
+ end
37
+
38
+ class TestUserMXDnsFailingNameserver < TestModel
39
+ validates :email, 'valid_email_2/email': { mx: true, dns_timeout: 0.1, dns_nameserver: '1.0.0.0' }
40
+ end
41
+
26
42
  class TestUserDisallowDisposable < TestModel
27
43
  validates :email, 'valid_email_2/email': { disposable: true }
28
44
  end
@@ -292,6 +308,94 @@ describe ValidEmail2 do
292
308
  end
293
309
  end
294
310
 
311
+ describe "with mx validation and dns not hitting timeout" do
312
+ it "is valid if mx records are found" do
313
+ user = TestUserMXDnsTimeout.new(email: "foo@gmail.com")
314
+ expect(user.valid?).to be_truthy
315
+ end
316
+
317
+ it "is valid if A records are found" do
318
+ user = TestUserMXDnsTimeout.new(email: "foo@ghs.google.com")
319
+ expect(user.valid?).to be_truthy
320
+ end
321
+
322
+ it "is invalid if no mx records are found" do
323
+ user = TestUserMXDnsTimeout.new(email: "foo@subdomain.gmail.com")
324
+ expect(user.valid?).to be_falsey
325
+ end
326
+
327
+ it "is invalid if a null mx is found" do
328
+ user = TestUserMXDnsTimeout.new(email: "foo@gmail.de")
329
+ expect(user.valid?).to be_falsey
330
+ end
331
+ end
332
+
333
+ describe "with mx validation and dns hitting timeout" do
334
+ it "is never valid even if mx records exist" do
335
+ user = TestUserMXDnsFailingTimeout.new(email: "foo@gmail.com")
336
+ expect(user.valid?).to be_falsey
337
+ end
338
+
339
+ it "is never valid even A records exist" do
340
+ user = TestUserMXDnsFailingTimeout.new(email: "foo@ghs.google.com")
341
+ expect(user.valid?).to be_falsey
342
+ end
343
+
344
+ it "is invalid if no mx records exist" do
345
+ user = TestUserMXDnsFailingTimeout.new(email: "foo@subdomain.gmail.com")
346
+ expect(user.valid?).to be_falsey
347
+ end
348
+
349
+ it "is invalid if a null mx exists" do
350
+ user = TestUserMXDnsFailingTimeout.new(email: "foo@gmail.de")
351
+ expect(user.valid?).to be_falsey
352
+ end
353
+ end
354
+
355
+ describe "with mx validation and dns nameserver" do
356
+ it "is valid if mx records are found" do
357
+ user = TestUserMXDnsNameserver.new(email: "foo@gmail.com")
358
+ expect(user.valid?).to be_truthy
359
+ end
360
+
361
+ it "is valid if A records are found" do
362
+ user = TestUserMXDnsNameserver.new(email: "foo@ghs.google.com")
363
+ expect(user.valid?).to be_truthy
364
+ end
365
+
366
+ it "is invalid if no mx records are found" do
367
+ user = TestUserMXDnsNameserver.new(email: "foo@subdomain.gmail.com")
368
+ expect(user.valid?).to be_falsey
369
+ end
370
+
371
+ it "is invalid if a null mx is found" do
372
+ user = TestUserMXDnsNameserver.new(email: "foo@gmail.de")
373
+ expect(user.valid?).to be_falsey
374
+ end
375
+ end
376
+
377
+ describe "with mx validation and failing dns nameserver" do
378
+ it "is never valid even if mx records exist" do
379
+ user = TestUserMXDnsFailingNameserver.new(email: "foo@gmail.com")
380
+ expect(user.valid?).to be_falsey
381
+ end
382
+
383
+ it "is never valid even A records exist" do
384
+ user = TestUserMXDnsFailingNameserver.new(email: "foo@ghs.google.com")
385
+ expect(user.valid?).to be_falsey
386
+ end
387
+
388
+ it "is invalid if no mx records exist" do
389
+ user = TestUserMXDnsFailingNameserver.new(email: "foo@subdomain.gmail.com")
390
+ expect(user.valid?).to be_falsey
391
+ end
392
+
393
+ it "is invalid if a null mx exists" do
394
+ user = TestUserMXDnsFailingNameserver.new(email: "foo@gmail.de")
395
+ expect(user.valid?).to be_falsey
396
+ end
397
+ end
398
+
295
399
  describe "with dotted validation" do
296
400
  it "is valid when address does not contain dots" do
297
401
  user = TestUserDotted.new(email: "johndoe@gmail.com")
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: 5.1.1
4
+ version: 5.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Micke Lisinge
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-26 00:00:00.000000000 Z
11
+ date: 2024-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler