valid_email 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|