truemail 2.2.0 → 2.3.1

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.
@@ -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