valid_email2 3.6.1 → 4.0.2

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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal:true
2
+
1
3
  require "valid_email2"
2
4
  require "resolv"
3
5
  require "mail"
@@ -7,8 +9,8 @@ module ValidEmail2
7
9
  attr_accessor :address
8
10
 
9
11
  PROHIBITED_DOMAIN_CHARACTERS_REGEX = /[+!_\/\s'`]/
10
- DEFAULT_RECIPIENT_DELIMITER = '+'.freeze
11
- DOT_DELIMITER = '.'.freeze
12
+ DEFAULT_RECIPIENT_DELIMITER = '+'
13
+ DOT_DELIMITER = '.'
12
14
 
13
15
  def self.prohibited_domain_characters_regex
14
16
  @prohibited_domain_characters_regex ||= PROHIBITED_DOMAIN_CHARACTERS_REGEX
@@ -18,9 +20,10 @@ module ValidEmail2
18
20
  @prohibited_domain_characters_regex = val
19
21
  end
20
22
 
21
- def initialize(address)
23
+ def initialize(address, dns_timeout = 5)
22
24
  @parse_error = false
23
25
  @raw_address = address
26
+ @dns_timeout = dns_timeout
24
27
 
25
28
  begin
26
29
  @address = Mail::Address.new(address)
@@ -35,23 +38,27 @@ module ValidEmail2
35
38
  return @valid unless @valid.nil?
36
39
  return false if @parse_error
37
40
 
38
- @valid = begin
39
- if address.domain && address.address == @raw_address
40
- domain = address.domain
41
-
42
- domain !~ self.class.prohibited_domain_characters_regex &&
43
- domain.include?('.') &&
44
- !domain.include?('..') &&
45
- !domain.start_with?('.') &&
46
- !domain.start_with?('-') &&
47
- !domain.include?('-.') &&
48
- !address.local.include?('..') &&
49
- !address.local.end_with?('.') &&
50
- !address.local.start_with?('.')
51
- else
52
- false
53
- end
54
- end
41
+ @valid = address.domain &&
42
+ address.address == @raw_address &&
43
+ valid_domain? &&
44
+ valid_address?
45
+ end
46
+
47
+ def valid_domain?
48
+ domain = address.domain
49
+
50
+ domain !~ self.class.prohibited_domain_characters_regex &&
51
+ domain.include?('.') &&
52
+ !domain.include?('..') &&
53
+ !domain.start_with?('.') &&
54
+ !domain.start_with?('-') &&
55
+ !domain.include?('-.')
56
+ end
57
+
58
+ def valid_address?
59
+ !address.local.include?('..') &&
60
+ !address.local.end_with?('.') &&
61
+ !address.local.start_with?('.')
55
62
  end
56
63
 
57
64
  def dotted?
@@ -103,12 +110,13 @@ module ValidEmail2
103
110
  i = address_domain.index('.')
104
111
  return false unless i
105
112
 
106
- return domain_list.include?(address_domain[(i+1)..-1])
113
+ domain_list.include?(address_domain[(i + 1)..-1])
107
114
  end
108
115
 
109
116
  def mx_server_is_in?(domain_list)
110
117
  mx_servers.any? { |mx_server|
111
118
  return false unless mx_server.respond_to?(:exchange)
119
+
112
120
  mx_server = mx_server.exchange.to_s
113
121
 
114
122
  domain_list.any? { |domain|
@@ -125,12 +133,14 @@ module ValidEmail2
125
133
 
126
134
  def mx_servers
127
135
  @mx_servers ||= Resolv::DNS.open do |dns|
136
+ dns.timeouts = @dns_timeout
128
137
  dns.getresources(address.domain, Resolv::DNS::Resource::IN::MX)
129
138
  end
130
139
  end
131
140
 
132
141
  def mx_or_a_servers
133
142
  @mx_or_a_servers ||= Resolv::DNS.open do |dns|
143
+ dns.timeouts = @dns_timeout
134
144
  (mx_servers.any? && mx_servers) ||
135
145
  dns.getresources(address.domain, Resolv::DNS::Resource::IN::A)
136
146
  end
@@ -5,15 +5,14 @@ require "active_model/validations"
5
5
  module ValidEmail2
6
6
  class EmailValidator < ActiveModel::EachValidator
7
7
  def default_options
8
- { regex: true, disposable: false, mx: false, strict_mx: false, disallow_subaddressing: false, multiple: false }
8
+ { regex: true, disposable: false, mx: false, strict_mx: false, disallow_subaddressing: false, multiple: false, dns_timeout: 5 }
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
- value_spitted = options[:multiple] ? value.split(',').map(&:strip) : [value]
16
- addresses = value_spitted.map { |v| ValidEmail2::Address.new(v) }
15
+ addresses = sanitized_values(value).map { |v| ValidEmail2::Address.new(v, options[:dns_timeout]) }
17
16
 
18
17
  error(record, attribute) && return unless addresses.all?(&:valid?)
19
18
 
@@ -54,6 +53,18 @@ module ValidEmail2
54
53
  end
55
54
  end
56
55
 
56
+ def sanitized_values(input)
57
+ options = default_options.merge(self.options)
58
+
59
+ if options[:multiple]
60
+ email_list = input.is_a?(Array) ? input : input.split(',')
61
+ else
62
+ email_list = [input]
63
+ end
64
+
65
+ email_list.reject(&:empty?).map(&:strip)
66
+ end
67
+
57
68
  def error(record, attribute)
58
69
  record.errors.add(attribute, options[:message] || :invalid)
59
70
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal:true
2
+
1
3
  module ValidEmail2
2
- VERSION = "3.6.1"
4
+ VERSION = "4.0.2"
3
5
  end
@@ -9,6 +9,7 @@ whitelisted_emails = %w(
9
9
  onet.pl poczta.onet.pl fastmail.fm hushmail.com
10
10
  hush.ai hush.com hushmail.me naver.com qq.com example.com
11
11
  yandex.net gmx.com gmx.es webdesignspecialist.com.au vp.com
12
+ onit.com asics.com freemail.hu
12
13
  )
13
14
 
14
15
  existing_emails = File.open("config/disposable_email_domains.txt") { |f| f.read.split("\n") }
@@ -312,6 +312,11 @@ describe ValidEmail2 do
312
312
  expect(user.valid?).to be_truthy
313
313
  end
314
314
 
315
+ it "tests each address from an array" do
316
+ user = TestUserMultiple.new(email: %w[foo@gmail.com bar@gmail.com])
317
+ expect(user.valid?).to be_truthy
318
+ end
319
+
315
320
  context 'when one address is invalid' do
316
321
  it "fails for all" do
317
322
  user = TestUserMultiple.new(email: "foo@gmail.com, bar@123")
data/valid_email2.gemspec CHANGED
@@ -21,9 +21,10 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = ">= 1.9.3"
22
22
 
23
23
  spec.add_development_dependency "bundler", "~> 2.0"
24
- spec.add_development_dependency "rake", "~> 12.3.3"
25
- spec.add_development_dependency "rspec", "~> 3.5.0"
24
+ spec.add_development_dependency "rake", "~> 12.3"
25
+ spec.add_development_dependency "rspec", "~> 3.5"
26
26
  spec.add_development_dependency "rspec-benchmark", "~> 0.6"
27
+ spec.add_development_dependency "net-smtp"
27
28
  spec.add_development_dependency "pry"
28
29
  spec.add_runtime_dependency "mail", "~> 2.5"
29
30
  spec.add_runtime_dependency "activemodel", ">= 3.2"
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: 3.6.1
4
+ version: 4.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Micke Lisinge
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-04 00:00:00.000000000 Z
11
+ date: 2022-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 12.3.3
33
+ version: '12.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 12.3.3
40
+ version: '12.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 3.5.0
47
+ version: '3.5'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 3.5.0
54
+ version: '3.5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec-benchmark
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-smtp
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: pry
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -157,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
171
  - !ruby/object:Gem::Version
158
172
  version: '0'
159
173
  requirements: []
160
- rubygems_version: 3.2.3
174
+ rubygems_version: 3.3.3
161
175
  signing_key:
162
176
  specification_version: 4
163
177
  summary: ActiveModel validation for email. Including MX lookup and disposable email