valid_email2 5.1.0 → 5.2.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: ca51b0f797d9251b8a850e2d55640ea0c278128f29ebed57b8d1e0d426393b0f
4
- data.tar.gz: e3d180928ccea8db43191a40df53c0b2f8a226452b30fa55e8ed3d4a32c39186
3
+ metadata.gz: c2972753ce57ed3f1c8b9f4b3a5738956bcd3bd67deed34ae248180c9b01155f
4
+ data.tar.gz: 7b0ca1ec81052af623267b0703e90e63f4200133f556bc6dbe52663593588399
5
5
  SHA512:
6
- metadata.gz: b0cdb4311843b16ee38ab13c774c8f9f4e75c6e208f2feca5e143d8abf465bfb29d0e6bf314e0789d18178620bac7c96c17c06fb61c5d4a32b5157ac8a584cf4
7
- data.tar.gz: 3c8fc7f7ae71dcb32f290254678d98f1d15151c60ee15602d82765947faae76466609ac483c910f8ce0a3f403eaaab8126abf001b00311c2556ae58d40bbcb66
6
+ metadata.gz: 1ff8f1b5eee02958bbd8337e340f9fc90fc41f0d7ede63a3019a403bcc65c1dc6d6f4f031a386e15f601316d4965a3068d6d023a34dfdcca0410f209e46e51b1
7
+ data.tar.gz: 7a27bc60a0b7e4522ce28a5bc055b37750a285811b3d2aba8ff0d93addeb70668dcb770c4cf62b28b03486d8bd135bb46f040657028893e8e6aeba083a5ca04f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## Version 5.2.0
2
+ * Allow configuration of DNS nameserver [#230](https://github.com/micke/valid_email2/pull/230)
3
+
4
+ ## Version 5.1.1
5
+ * Remove false positives [#223](https://github.com/micke/valid_email2/issues/223)
6
+
1
7
  ## Version 5.1.0
2
8
  * Allow dynamic validaton error messages [#221](https://github.com/micke/valid_email2/pull/221)
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 }
@@ -8565,7 +8565,6 @@
8565
8565
  8a818.club
8566
8566
  8a9itx.online
8567
8567
  8aj.net
8568
- 8alias.com
8569
8568
  8americain.fr
8570
8569
  8angue9wtjv4dwa9.com
8571
8570
  8avz.net
@@ -8708,7 +8707,6 @@
8708
8707
  8rskf3xpyq.ml
8709
8708
  8rskf3xpyq.tk
8710
8709
  8rygn.com
8711
- 8shield.net
8712
8710
  8t0sznngp6aowxsrj.cf
8713
8711
  8t0sznngp6aowxsrj.ga
8714
8712
  8t0sznngp6aowxsrj.gq
@@ -45553,7 +45551,6 @@ drakeslansdowne.com
45553
45551
  drakor.pro
45554
45552
  drakorfor.me
45555
45553
  draktar.online
45556
- dralias.com
45557
45554
  dralselahi.com
45558
45555
  dram.network
45559
45556
  drama.tw
@@ -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.0"
4
+ VERSION = "5.2.0"
5
5
  end
@@ -13,7 +13,7 @@ whitelisted_emails = %w(
13
13
  zoho.com zoho.in simplelogin.com simplelogin.fr simplelogin.co
14
14
  simplelogin.io aleeas.com slmails.com silomails.com slmail.me
15
15
  passinbox.com passfwd.com passmail.com passmail.net
16
- duck.com mozmail.com
16
+ duck.com mozmail.com dralias.com 8alias.com 8shield.net
17
17
  )
18
18
 
19
19
  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.0
4
+ version: 5.2.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: 2023-10-03 00:00:00.000000000 Z
11
+ date: 2024-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler