valid_email2 5.1.1 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +8 -2
- data/lib/valid_email2/address.rb +6 -3
- data/lib/valid_email2/email_validator.rb +2 -2
- data/lib/valid_email2/version.rb +1 -1
- data/spec/valid_email2_spec.rb +104 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2972753ce57ed3f1c8b9f4b3a5738956bcd3bd67deed34ae248180c9b01155f
|
4
|
+
data.tar.gz: 7b0ca1ec81052af623267b0703e90e63f4200133f556bc6dbe52663593588399
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ff8f1b5eee02958bbd8337e340f9fc90fc41f0d7ede63a3019a403bcc65c1dc6d6f4f031a386e15f601316d4965a3068d6d023a34dfdcca0410f209e46e51b1
|
7
|
+
data.tar.gz: 7a27bc60a0b7e4522ce28a5bc055b37750a285811b3d2aba8ff0d93addeb70668dcb770c4cf62b28b03486d8bd135bb46f040657028893e8e6aeba083a5ca04f
|
data/CHANGELOG.md
CHANGED
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.
|
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 }
|
data/lib/valid_email2/address.rb
CHANGED
@@ -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
|
|
data/lib/valid_email2/version.rb
CHANGED
data/spec/valid_email2_spec.rb
CHANGED
@@ -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.
|
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:
|
11
|
+
date: 2024-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|