valid_email 0.0.10 → 0.0.11
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 +4 -4
- data/.travis.yml +3 -4
- data/config/valid_email.yml +2 -0
- data/lib/valid_email/email_validator.rb +3 -3
- data/lib/valid_email/validate_email.rb +76 -48
- data/lib/valid_email/version.rb +1 -1
- data/spec/validate_email_spec.rb +65 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42a2f72cc8d27b8f7bfa7cc975a7b06512f6cbac
|
4
|
+
data.tar.gz: 6e6a23102e9b365aa96da9ce632dc8b890f15753
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3918c4f4a86617449a70451e7f914874972dcb7045beead234ddbfac21b69e84e269e21122ba1e2b433bbadc0d362815f6f0e91dbc34eb1c860af7b53164dc10
|
7
|
+
data.tar.gz: 907854ee62fcc7474d225ab1c87b526b1c688c61f58b40c79023bf84e8b61b13a23dd0b692b03df5886affbe7c82e0d18be0241905ef85148bd58d540afdfa97
|
data/.travis.yml
CHANGED
data/config/valid_email.yml
CHANGED
@@ -469,6 +469,7 @@ disposable_email_services:
|
|
469
469
|
- trashmailer.com
|
470
470
|
- trashymail.com
|
471
471
|
- trashymail.net
|
472
|
+
- trbvm.com
|
472
473
|
- trillianpro.com
|
473
474
|
- turual.com
|
474
475
|
- twinmail.de
|
@@ -515,3 +516,4 @@ disposable_email_services:
|
|
515
516
|
- zippymail.info
|
516
517
|
- zoaxe.com
|
517
518
|
- zoemail.org
|
519
|
+
-
|
@@ -11,15 +11,15 @@ class EmailValidator < ActiveModel::EachValidator
|
|
11
11
|
# Check if domain has DNS MX record
|
12
12
|
if r && options[:mx]
|
13
13
|
require 'valid_email/mx_validator'
|
14
|
-
r
|
14
|
+
r = MxValidator.new(:attributes => attributes).validate(record)
|
15
15
|
elsif r && options[:mx_with_fallback]
|
16
16
|
require 'valid_email/mx_with_fallback_validator'
|
17
|
-
r
|
17
|
+
r = MxWithFallbackValidator.new(:attributes => attributes).validate(record)
|
18
18
|
end
|
19
19
|
# Check if domain is disposable
|
20
20
|
if r && options[:ban_disposable_email]
|
21
21
|
require 'valid_email/ban_disposable_email_validator'
|
22
|
-
r
|
22
|
+
r = BanDisposableEmailValidator.new(:attributes => attributes).validate(record)
|
23
23
|
end
|
24
24
|
record.errors.add attribute, (options[:message] || I18n.t(:invalid, :scope => "valid_email.validations.email")) unless r
|
25
25
|
end
|
@@ -1,51 +1,86 @@
|
|
1
1
|
class ValidateEmail
|
2
|
-
|
3
2
|
class << self
|
3
|
+
SPECIAL_CHARS = %w(( ) , : ; < > @ [ ])
|
4
|
+
SPECIAL_ESCAPED_CHARS = %w(\ \\ ")
|
5
|
+
LOCAL_MAX_LEN = 64
|
4
6
|
|
5
7
|
def valid?(value, user_options={})
|
6
|
-
options = { :mx => false, :message => nil }.merge
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
8
|
+
options = { :mx => false, :message => nil }.merge(user_options)
|
9
|
+
|
10
|
+
m = Mail::Address.new(value)
|
11
|
+
# We must check that value contains a domain and that value is an email address
|
12
|
+
return false unless m.domain && m.address == value
|
13
|
+
|
14
|
+
# Check that domain consists of dot-atom-text elements > 1 and does not
|
15
|
+
# contain spaces.
|
16
|
+
#
|
17
|
+
# In mail 2.6.1, domains are invalid per rfc2822 are parsed when they shouldn't
|
18
|
+
# This is to make sure we cover those cases
|
19
|
+
|
20
|
+
return false unless m.domain.match(/^\S+$/)
|
21
|
+
|
22
|
+
domain_dot_elements = m.domain.split(/\./)
|
23
|
+
return false unless domain_dot_elements.size > 1 && domain_dot_elements.all?(&:present?)
|
24
|
+
|
25
|
+
# Ensure that the local segment adheres to adheres to RFC-5322
|
26
|
+
return false unless valid_local?(m.local)
|
27
|
+
|
28
|
+
# Check if domain has DNS MX record
|
29
|
+
if options[:mx]
|
30
|
+
require 'valid_email/mx_validator'
|
31
|
+
return mx_valid?(value)
|
32
|
+
end
|
33
|
+
|
34
|
+
true
|
35
|
+
rescue Mail::Field::ParseError
|
36
|
+
false
|
37
|
+
end
|
38
|
+
|
39
|
+
def valid_local?(local)
|
40
|
+
return false unless local.length <= LOCAL_MAX_LEN
|
41
|
+
# Emails can be validated by segments delineated by '.', referred to as dot atoms.
|
42
|
+
# See http://tools.ietf.org/html/rfc5322#section-3.2.3
|
43
|
+
return local.split('.', -1).all? { |da| valid_dot_atom?(da) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def valid_dot_atom?(dot_atom)
|
47
|
+
# Leading, trailing, and double '.'s aren't allowed
|
48
|
+
return false if dot_atom.empty?
|
49
|
+
# A dot atom can be quoted, which allows use of the SPECIAL_CHARS
|
50
|
+
if dot_atom[0] == '"' || dot_atom[-1] == '"'
|
51
|
+
# A quoted segment must have leading and trailing '"#"'s
|
52
|
+
return false if dot_atom[0] != dot_atom[-1]
|
53
|
+
|
54
|
+
# Excluding the bounding quotes, all of the SPECIAL_ESCAPED_CHARS must have a leading '\'
|
55
|
+
index = dot_atom.length - 2
|
56
|
+
while index > 0
|
57
|
+
if SPECIAL_ESCAPED_CHARS.include? dot_atom[index]
|
58
|
+
return false if index == 1 || dot_atom[index - 1] != '\\'
|
59
|
+
# On an escaped special character, skip an index to ignore the '\' that's doing the escaping
|
60
|
+
index -= 1
|
25
61
|
end
|
62
|
+
index -= 1
|
26
63
|
end
|
27
|
-
|
28
|
-
|
64
|
+
else
|
65
|
+
# If we're not in a quoted dot atom then no special characters are allowed.
|
66
|
+
return false unless ((SPECIAL_CHARS | SPECIAL_ESCAPED_CHARS) & dot_atom.split('')).empty?
|
29
67
|
end
|
30
|
-
|
68
|
+
return true
|
31
69
|
end
|
32
70
|
|
33
71
|
def mx_valid?(value, fallback=false)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
mx.concat dns.getresources(m.domain, Resolv::DNS::Resource::IN::A) if fallback
|
42
|
-
end
|
43
|
-
r = mx.size > 0
|
44
|
-
end
|
45
|
-
rescue Mail::Field::ParseError
|
46
|
-
r = false
|
72
|
+
m = Mail::Address.new(value)
|
73
|
+
return false unless m.domain
|
74
|
+
|
75
|
+
mx = []
|
76
|
+
Resolv::DNS.open do |dns|
|
77
|
+
mx.concat dns.getresources(m.domain, Resolv::DNS::Resource::IN::MX)
|
78
|
+
mx.concat dns.getresources(m.domain, Resolv::DNS::Resource::IN::A) if fallback
|
47
79
|
end
|
48
|
-
|
80
|
+
|
81
|
+
return mx.any?
|
82
|
+
rescue Mail::Field::ParseError
|
83
|
+
false
|
49
84
|
end
|
50
85
|
|
51
86
|
def mx_valid_with_fallback?(value)
|
@@ -53,17 +88,10 @@ class ValidateEmail
|
|
53
88
|
end
|
54
89
|
|
55
90
|
def ban_disposable_email?(value)
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
rescue Mail::Field::ParseError
|
61
|
-
r = false
|
62
|
-
end
|
63
|
-
|
64
|
-
r
|
91
|
+
m = Mail::Address.new(value)
|
92
|
+
m.domain && !BanDisposableEmailValidator.config.include?(m.domain)
|
93
|
+
rescue Mail::Field::ParseError
|
94
|
+
false
|
65
95
|
end
|
66
|
-
|
67
96
|
end
|
68
|
-
|
69
97
|
end
|
data/lib/valid_email/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ValidEmailVersion = "0.0.
|
1
|
+
ValidEmailVersion = "0.0.11"
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ValidateEmail do
|
4
|
+
describe '.valid?' do
|
5
|
+
it 'should return true when passed email has valid format' do
|
6
|
+
ValidateEmail.valid?('user@gmail.com').should be_truthy
|
7
|
+
ValidateEmail.valid?('valid.user@gmail.com').should be_truthy
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should return false when passed email has invalid format' do
|
11
|
+
ValidateEmail.valid?('user@gmail.com.').should be_falsey
|
12
|
+
ValidateEmail.valid?('user.@gmail.com').should be_falsey
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when mx: true option passed' do
|
16
|
+
it 'should return true when mx record exist' do
|
17
|
+
ValidateEmail.valid?('user@gmail.com', mx: true).should be_truthy
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return false when mx record doesn't exist" do
|
21
|
+
ValidateEmail.valid?('user@example.com', mx: true).should be_falsey
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '.valid_local?' do
|
27
|
+
it 'should return false if the local segment is too long' do
|
28
|
+
ValidateEmail.valid_local?(
|
29
|
+
'abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde'
|
30
|
+
).should be_falsey
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should return false if the local segment has an empty dot atom' do
|
34
|
+
ValidateEmail.valid_local?('.user').should be_falsey
|
35
|
+
ValidateEmail.valid_local?('.user.').should be_falsey
|
36
|
+
ValidateEmail.valid_local?('user.').should be_falsey
|
37
|
+
ValidateEmail.valid_local?('us..er').should be_falsey
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should return false if the local segment has a special character in an unquoted dot atom' do
|
41
|
+
ValidateEmail.valid_local?('us@er').should be_falsey
|
42
|
+
ValidateEmail.valid_local?('user.\\.name').should be_falsey
|
43
|
+
ValidateEmail.valid_local?('user."name').should be_falsey
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should return false if the local segment has an unescaped special character in a quoted dot atom' do
|
47
|
+
ValidateEmail.valid_local?('test." test".test').should be_falsey
|
48
|
+
ValidateEmail.valid_local?('test."test\".test').should be_falsey
|
49
|
+
ValidateEmail.valid_local?('test."te"st".test').should be_falsey
|
50
|
+
ValidateEmail.valid_local?('test."\".test').should be_falsey
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should return true if special characters exist but are properly quoted and escaped' do
|
54
|
+
ValidateEmail.valid_local?('"\ test"').should be_truthy
|
55
|
+
ValidateEmail.valid_local?('"\\\\"').should be_truthy
|
56
|
+
ValidateEmail.valid_local?('test."te@st".test').should be_truthy
|
57
|
+
ValidateEmail.valid_local?('test."\\\\\"".test').should be_truthy
|
58
|
+
ValidateEmail.valid_local?('test."blah\"\ \\\\"').should be_truthy
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should return true if all characters are within the set of allowed characters' do
|
62
|
+
ValidateEmail.valid_local?('!#$%&\'*+-/=?^_`{|}~."\\\\\ \"(),:;<>@[]"').should be_truthy
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valid_email
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ramihajamalala Hery
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- spec/email_validator_spec.rb
|
100
100
|
- spec/extensions_validator_spec.rb
|
101
101
|
- spec/spec_helper.rb
|
102
|
+
- spec/validate_email_spec.rb
|
102
103
|
- valid_email.gemspec
|
103
104
|
homepage: http://my.rails-royce.org/2010/07/21/email-validation-in-ruby-on-rails-without-regexp
|
104
105
|
licenses: []
|
@@ -127,3 +128,5 @@ test_files:
|
|
127
128
|
- spec/email_validator_spec.rb
|
128
129
|
- spec/extensions_validator_spec.rb
|
129
130
|
- spec/spec_helper.rb
|
131
|
+
- spec/validate_email_spec.rb
|
132
|
+
has_rdoc:
|