truemail 2.2.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,8 +3,6 @@
3
3
  module Truemail
4
4
  module Validate
5
5
  class Mx < Truemail::Validate::Base
6
- require 'resolv'
7
-
8
6
  ERROR = 'target host(s) not found'
9
7
  NULL_MX_RECORD = 'null_mx_record'
10
8
 
@@ -43,11 +41,11 @@ module Truemail
43
41
  end
44
42
 
45
43
  def mx_records(hostname)
46
- domain_mx_records = Resolv::DNS.new.getresources(hostname, Resolv::DNS::Resource::IN::MX)
44
+ domain_mx_records = Truemail::Dns::Resolver.mx_records(hostname, configuration: configuration)
47
45
  return [Truemail::Validate::Mx::NULL_MX_RECORD] if null_mx?(domain_mx_records)
48
- domain_mx_records.sort_by(&:preference).map do |mx_record|
49
- Resolv.getaddresses(mx_record.exchange.to_s)
50
- end.flatten
46
+ domain_mx_records.sort_by(&:preference).flat_map do |mx_record|
47
+ Truemail::Dns::Resolver.a_records(mx_record.exchange.to_s, configuration: configuration)
48
+ end
51
49
  end
52
50
 
53
51
  def mail_servers_found?
@@ -64,15 +62,15 @@ module Truemail
64
62
  end
65
63
 
66
64
  def a_record(hostname)
67
- Resolv.getaddress(hostname)
65
+ Truemail::Dns::Resolver.a_record(hostname, configuration: configuration)
68
66
  end
69
67
 
70
68
  def hosts_from_cname_records?
71
- cname_records = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::CNAME)
69
+ cname_records = Truemail::Dns::Resolver.cname_records(domain, configuration: configuration)
72
70
  return if cname_records.empty?
73
71
  cname_records.each do |cname_record|
74
72
  host = a_record(cname_record.name.to_s)
75
- hostname = Resolv.getname(host)
73
+ hostname = Truemail::Dns::Resolver.dns_lookup(host, configuration: configuration)
76
74
  found_hosts = mx_records(hostname)
77
75
  fetch_target_hosts(found_hosts.empty? ? [host] : found_hosts)
78
76
  end
@@ -13,20 +13,24 @@ module Truemail
13
13
 
14
14
  attr_reader :configuration, :host, :email, :response
15
15
 
16
- def initialize(configuration:, host:, email:, attempts: nil)
16
+ def initialize(configuration:, host:, email:, attempts: nil, port_open_status: proc { true })
17
17
  @configuration = Truemail::Validate::Smtp::Request::Configuration.new(configuration)
18
18
  @response = Truemail::Validate::Smtp::Response.new
19
19
  @host = host
20
20
  @email = email
21
21
  @attempts = attempts
22
+ @port_open_status = port_open_status
22
23
  end
23
24
 
24
25
  def check_port
25
- Timeout.timeout(configuration.connection_timeout) do
26
- return response.port_opened = !TCPSocket.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).close
27
- end
26
+ response.port_opened = ::Socket.tcp(
27
+ host,
28
+ Truemail::Validate::Smtp::Request::SMTP_PORT,
29
+ connect_timeout: configuration.connection_timeout,
30
+ &port_open_status
31
+ )
28
32
  rescue => error
29
- retry if attempts_exist? && error.is_a?(Timeout::Error)
33
+ retry if attempts_exist? && error.is_a?(::Errno::ETIMEDOUT)
30
34
  response.port_opened = false
31
35
  end
32
36
 
@@ -53,7 +57,7 @@ module Truemail
53
57
  end
54
58
  end
55
59
 
56
- attr_reader :attempts
60
+ attr_reader :attempts, :port_open_status
57
61
 
58
62
  def attempts_exist?
59
63
  return false unless attempts
@@ -61,7 +65,7 @@ module Truemail
61
65
  end
62
66
 
63
67
  def session
64
- Net::SMTP.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).tap do |settings|
68
+ ::Net::SMTP.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).tap do |settings|
65
69
  settings.open_timeout = configuration.connection_timeout
66
70
  settings.read_timeout = configuration.response_timeout
67
71
  end
@@ -5,7 +5,7 @@ module Truemail
5
5
  class Smtp
6
6
  RESPONSE_ATTRS = %i[port_opened connection helo mailfrom rcptto errors].freeze
7
7
 
8
- Response = Struct.new(*RESPONSE_ATTRS, keyword_init: true) do
8
+ Response = ::Struct.new(*RESPONSE_ATTRS, keyword_init: true) do
9
9
  def initialize(errors: {}, **args)
10
10
  super
11
11
  end
@@ -5,13 +5,13 @@ module Truemail
5
5
  RESULT_ATTRS = %i[success email domain mail_servers errors smtp_debug configuration].freeze
6
6
  VALIDATION_TYPES = %i[regex mx smtp].freeze
7
7
 
8
- Result = Struct.new(*RESULT_ATTRS, keyword_init: true) do
8
+ Result = ::Struct.new(*RESULT_ATTRS, keyword_init: true) do
9
9
  def initialize(mail_servers: [], errors: {}, **args)
10
10
  super
11
11
  end
12
12
 
13
13
  def punycode_email
14
- @punycode_email ||= Truemail::PunycodeRepresenter.call(email)
14
+ @punycode_email ||= Truemail::Dns::PunycodeRepresenter.call(email)
15
15
  end
16
16
  alias_method :valid?, :success
17
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- VERSION = '2.2.0'
4
+ VERSION = '2.3.1'
5
5
  end
@@ -15,10 +15,10 @@ module Truemail
15
15
  end
16
16
 
17
17
  def call(&block)
18
- Timeout.timeout(timeout, &block)
19
- rescue Resolv::ResolvError, IPAddr::InvalidAddressError
18
+ ::Timeout.timeout(timeout, &block)
19
+ rescue ::Resolv::ResolvError, ::IPAddr::InvalidAddressError
20
20
  false
21
- rescue Timeout::Error
21
+ rescue ::Timeout::Error
22
22
  retry unless (self.attempts -= 1).zero?
23
23
  false
24
24
  end
data/truemail.gemspec CHANGED
@@ -31,21 +31,23 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ['lib']
33
33
 
34
- spec.add_runtime_dependency 'simpleidn', '~> 0.1.1'
34
+ spec.add_runtime_dependency 'simpleidn', '~> 0.2.1'
35
35
 
36
36
  spec.add_development_dependency 'bundler', '~> 1.16'
37
37
  spec.add_development_dependency 'bundler-audit', '~> 0.7.0.1'
38
- spec.add_development_dependency 'fasterer', '~> 0.8.3'
39
- spec.add_development_dependency 'ffaker', '~> 2.17'
38
+ spec.add_development_dependency 'dns_mock', '~> 1.2'
39
+ spec.add_development_dependency 'faker', '~> 2.16'
40
+ spec.add_development_dependency 'fasterer', '~> 0.9.0'
40
41
  spec.add_development_dependency 'json_matchers', '~> 0.11.1'
41
42
  spec.add_development_dependency 'overcommit', '~> 0.57.0'
42
43
  spec.add_development_dependency 'pry-byebug', '~> 3.9'
43
- spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.1'
44
- spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.2'
44
+ spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.3'
45
+ spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.3'
45
46
  spec.add_development_dependency 'rspec', '~> 3.10'
46
- spec.add_development_dependency 'rubocop', '~> 1.3'
47
- spec.add_development_dependency 'rubocop-performance', '~> 1.8', '>= 1.8.1'
48
- spec.add_development_dependency 'rubocop-rspec', '~> 2.0'
47
+ spec.add_development_dependency 'rubocop', '~> 1.10'
48
+ spec.add_development_dependency 'rubocop-performance', '~> 1.9', '>= 1.9.2'
49
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
49
50
  spec.add_development_dependency 'simplecov', '~> 0.17.1'
50
- spec.add_development_dependency 'truemail-rspec', '~> 0.2.1'
51
+ spec.add_development_dependency 'truemail-rspec', '~> 0.4'
52
+ spec.add_development_dependency 'webmock', '~> 3.12'
51
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: truemail
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladislav Trotsenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-01 00:00:00.000000000 Z
11
+ date: 2021-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simpleidn
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.1
19
+ version: 0.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.1
26
+ version: 0.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -53,33 +53,47 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.7.0.1
55
55
  - !ruby/object:Gem::Dependency
56
- name: fasterer
56
+ name: dns_mock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: faker
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: 0.8.3
75
+ version: '2.16'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: 0.8.3
82
+ version: '2.16'
69
83
  - !ruby/object:Gem::Dependency
70
- name: ffaker
84
+ name: fasterer
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '2.17'
89
+ version: 0.9.0
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '2.17'
96
+ version: 0.9.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: json_matchers
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -131,7 +145,7 @@ dependencies:
131
145
  version: '13.0'
132
146
  - - ">="
133
147
  - !ruby/object:Gem::Version
134
- version: 13.0.1
148
+ version: 13.0.3
135
149
  type: :development
136
150
  prerelease: false
137
151
  version_requirements: !ruby/object:Gem::Requirement
@@ -141,7 +155,7 @@ dependencies:
141
155
  version: '13.0'
142
156
  - - ">="
143
157
  - !ruby/object:Gem::Version
144
- version: 13.0.1
158
+ version: 13.0.3
145
159
  - !ruby/object:Gem::Dependency
146
160
  name: reek
147
161
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +165,7 @@ dependencies:
151
165
  version: '6.0'
152
166
  - - ">="
153
167
  - !ruby/object:Gem::Version
154
- version: 6.0.2
168
+ version: 6.0.3
155
169
  type: :development
156
170
  prerelease: false
157
171
  version_requirements: !ruby/object:Gem::Requirement
@@ -161,7 +175,7 @@ dependencies:
161
175
  version: '6.0'
162
176
  - - ">="
163
177
  - !ruby/object:Gem::Version
164
- version: 6.0.2
178
+ version: 6.0.3
165
179
  - !ruby/object:Gem::Dependency
166
180
  name: rspec
167
181
  requirement: !ruby/object:Gem::Requirement
@@ -182,48 +196,48 @@ dependencies:
182
196
  requirements:
183
197
  - - "~>"
184
198
  - !ruby/object:Gem::Version
185
- version: '1.3'
199
+ version: '1.10'
186
200
  type: :development
187
201
  prerelease: false
188
202
  version_requirements: !ruby/object:Gem::Requirement
189
203
  requirements:
190
204
  - - "~>"
191
205
  - !ruby/object:Gem::Version
192
- version: '1.3'
206
+ version: '1.10'
193
207
  - !ruby/object:Gem::Dependency
194
208
  name: rubocop-performance
195
209
  requirement: !ruby/object:Gem::Requirement
196
210
  requirements:
197
211
  - - "~>"
198
212
  - !ruby/object:Gem::Version
199
- version: '1.8'
213
+ version: '1.9'
200
214
  - - ">="
201
215
  - !ruby/object:Gem::Version
202
- version: 1.8.1
216
+ version: 1.9.2
203
217
  type: :development
204
218
  prerelease: false
205
219
  version_requirements: !ruby/object:Gem::Requirement
206
220
  requirements:
207
221
  - - "~>"
208
222
  - !ruby/object:Gem::Version
209
- version: '1.8'
223
+ version: '1.9'
210
224
  - - ">="
211
225
  - !ruby/object:Gem::Version
212
- version: 1.8.1
226
+ version: 1.9.2
213
227
  - !ruby/object:Gem::Dependency
214
228
  name: rubocop-rspec
215
229
  requirement: !ruby/object:Gem::Requirement
216
230
  requirements:
217
231
  - - "~>"
218
232
  - !ruby/object:Gem::Version
219
- version: '2.0'
233
+ version: '2.2'
220
234
  type: :development
221
235
  prerelease: false
222
236
  version_requirements: !ruby/object:Gem::Requirement
223
237
  requirements:
224
238
  - - "~>"
225
239
  - !ruby/object:Gem::Version
226
- version: '2.0'
240
+ version: '2.2'
227
241
  - !ruby/object:Gem::Dependency
228
242
  name: simplecov
229
243
  requirement: !ruby/object:Gem::Requirement
@@ -244,14 +258,28 @@ dependencies:
244
258
  requirements:
245
259
  - - "~>"
246
260
  - !ruby/object:Gem::Version
247
- version: 0.2.1
261
+ version: '0.4'
248
262
  type: :development
249
263
  prerelease: false
250
264
  version_requirements: !ruby/object:Gem::Requirement
251
265
  requirements:
252
266
  - - "~>"
253
267
  - !ruby/object:Gem::Version
254
- version: 0.2.1
268
+ version: '0.4'
269
+ - !ruby/object:Gem::Dependency
270
+ name: webmock
271
+ requirement: !ruby/object:Gem::Requirement
272
+ requirements:
273
+ - - "~>"
274
+ - !ruby/object:Gem::Version
275
+ version: '3.12'
276
+ type: :development
277
+ prerelease: false
278
+ version_requirements: !ruby/object:Gem::Requirement
279
+ requirements:
280
+ - - "~>"
281
+ - !ruby/object:Gem::Version
282
+ version: '3.12'
255
283
  description: Configurable framework agnostic plain Ruby email validator. Verify email
256
284
  via Regex, DNS and SMTP.
257
285
  email:
@@ -293,6 +321,9 @@ files:
293
321
  - lib/truemail/auditor.rb
294
322
  - lib/truemail/configuration.rb
295
323
  - lib/truemail/core.rb
324
+ - lib/truemail/dns/punycode_representer.rb
325
+ - lib/truemail/dns/resolver.rb
326
+ - lib/truemail/dns/worker.rb
296
327
  - lib/truemail/executor.rb
297
328
  - lib/truemail/log/event.rb
298
329
  - lib/truemail/log/serializer/auditor_json.rb