truemail 2.1.0 → 2.3.0
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/.codeclimate.yml +1 -1
- data/.reek.yml +10 -0
- data/.rubocop.yml +54 -0
- data/CHANGELOG.md +96 -1
- data/Gemfile.lock +60 -42
- data/LICENSE.txt +1 -1
- data/README.md +124 -1
- data/lib/truemail.rb +2 -2
- data/lib/truemail/audit/base.rb +0 -1
- data/lib/truemail/audit/dns.rb +1 -1
- data/lib/truemail/audit/ip.rb +1 -1
- data/lib/truemail/audit/ptr.rb +4 -3
- data/lib/truemail/auditor.rb +1 -1
- data/lib/truemail/configuration.rb +41 -32
- data/lib/truemail/core.rb +11 -15
- data/lib/truemail/dns/punycode_representer.rb +16 -0
- data/lib/truemail/dns/resolver.rb +17 -0
- data/lib/truemail/dns/worker.rb +52 -0
- data/lib/truemail/log/serializer/auditor_json.rb +1 -1
- data/lib/truemail/log/serializer/base.rb +3 -1
- data/lib/truemail/log/serializer/validator_base.rb +6 -2
- data/lib/truemail/log/serializer/validator_text.rb +2 -2
- data/lib/truemail/logger.rb +1 -1
- data/lib/truemail/validate/mx.rb +7 -9
- data/lib/truemail/validate/smtp.rb +15 -5
- data/lib/truemail/validate/smtp/request.rb +11 -7
- data/lib/truemail/validate/smtp/response.rb +1 -1
- data/lib/truemail/validator.rb +2 -2
- data/lib/truemail/version.rb +1 -1
- data/lib/truemail/wrapper.rb +3 -3
- data/truemail.gemspec +10 -8
- metadata +73 -24
@@ -24,13 +24,23 @@ module Truemail
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
-
def
|
28
|
-
|
27
|
+
def fail_fast?
|
28
|
+
configuration.smtp_fail_fast
|
29
|
+
end
|
30
|
+
|
31
|
+
def filtered_mail_servers_by_fail_fast_scenario
|
32
|
+
fail_fast? ? mail_servers.first(1) : mail_servers
|
29
33
|
end
|
30
34
|
|
31
35
|
def attempts
|
32
|
-
@attempts ||=
|
33
|
-
|
36
|
+
@attempts ||= begin
|
37
|
+
return {} if fail_fast? || !mail_servers.one?
|
38
|
+
{ attempts: configuration.connection_attempts }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def request
|
43
|
+
smtp_results.last
|
34
44
|
end
|
35
45
|
|
36
46
|
def rcptto_error
|
@@ -38,7 +48,7 @@ module Truemail
|
|
38
48
|
end
|
39
49
|
|
40
50
|
def establish_smtp_connection
|
41
|
-
|
51
|
+
filtered_mail_servers_by_fail_fast_scenario.each do |mail_server|
|
42
52
|
smtp_results << Truemail::Validate::Smtp::Request.new(
|
43
53
|
configuration: configuration, host: mail_server, email: result.punycode_email, **attempts
|
44
54
|
)
|
@@ -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
|
-
|
26
|
-
|
27
|
-
|
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?(
|
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
|
data/lib/truemail/validator.rb
CHANGED
@@ -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
|
data/lib/truemail/version.rb
CHANGED
data/lib/truemail/wrapper.rb
CHANGED
@@ -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.
|
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 'dns_mock', '~> 1.2'
|
39
|
+
spec.add_development_dependency 'faker', '~> 2.15', '>= 2.15.1'
|
38
40
|
spec.add_development_dependency 'fasterer', '~> 0.8.3'
|
39
|
-
spec.add_development_dependency 'ffaker', '~> 2.17'
|
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.
|
44
|
-
spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.
|
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.
|
47
|
-
spec.add_development_dependency 'rubocop-performance', '~> 1.
|
48
|
-
spec.add_development_dependency 'rubocop-rspec', '~> 2.
|
47
|
+
spec.add_development_dependency 'rubocop', '~> 1.9', '>= 1.9.1'
|
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.
|
51
|
+
spec.add_development_dependency 'truemail-rspec', '~> 0.3.3'
|
52
|
+
spec.add_development_dependency 'webmock', '~> 3.11', '>= 3.11.2'
|
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.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladislav Trotsenko
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-05 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.
|
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.
|
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,53 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.7.0.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: dns_mock
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '1.2'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '1.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faker
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.15'
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 2.15.1
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '2.15'
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 2.15.1
|
69
89
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
90
|
+
name: fasterer
|
71
91
|
requirement: !ruby/object:Gem::Requirement
|
72
92
|
requirements:
|
73
93
|
- - "~>"
|
74
94
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
95
|
+
version: 0.8.3
|
76
96
|
type: :development
|
77
97
|
prerelease: false
|
78
98
|
version_requirements: !ruby/object:Gem::Requirement
|
79
99
|
requirements:
|
80
100
|
- - "~>"
|
81
101
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
102
|
+
version: 0.8.3
|
83
103
|
- !ruby/object:Gem::Dependency
|
84
104
|
name: json_matchers
|
85
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,7 +151,7 @@ dependencies:
|
|
131
151
|
version: '13.0'
|
132
152
|
- - ">="
|
133
153
|
- !ruby/object:Gem::Version
|
134
|
-
version: 13.0.
|
154
|
+
version: 13.0.3
|
135
155
|
type: :development
|
136
156
|
prerelease: false
|
137
157
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -141,7 +161,7 @@ dependencies:
|
|
141
161
|
version: '13.0'
|
142
162
|
- - ">="
|
143
163
|
- !ruby/object:Gem::Version
|
144
|
-
version: 13.0.
|
164
|
+
version: 13.0.3
|
145
165
|
- !ruby/object:Gem::Dependency
|
146
166
|
name: reek
|
147
167
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,7 +171,7 @@ dependencies:
|
|
151
171
|
version: '6.0'
|
152
172
|
- - ">="
|
153
173
|
- !ruby/object:Gem::Version
|
154
|
-
version: 6.0.
|
174
|
+
version: 6.0.3
|
155
175
|
type: :development
|
156
176
|
prerelease: false
|
157
177
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -161,7 +181,7 @@ dependencies:
|
|
161
181
|
version: '6.0'
|
162
182
|
- - ">="
|
163
183
|
- !ruby/object:Gem::Version
|
164
|
-
version: 6.0.
|
184
|
+
version: 6.0.3
|
165
185
|
- !ruby/object:Gem::Dependency
|
166
186
|
name: rspec
|
167
187
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,48 +202,54 @@ dependencies:
|
|
182
202
|
requirements:
|
183
203
|
- - "~>"
|
184
204
|
- !ruby/object:Gem::Version
|
185
|
-
version: '1.
|
205
|
+
version: '1.9'
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 1.9.1
|
186
209
|
type: :development
|
187
210
|
prerelease: false
|
188
211
|
version_requirements: !ruby/object:Gem::Requirement
|
189
212
|
requirements:
|
190
213
|
- - "~>"
|
191
214
|
- !ruby/object:Gem::Version
|
192
|
-
version: '1.
|
215
|
+
version: '1.9'
|
216
|
+
- - ">="
|
217
|
+
- !ruby/object:Gem::Version
|
218
|
+
version: 1.9.1
|
193
219
|
- !ruby/object:Gem::Dependency
|
194
220
|
name: rubocop-performance
|
195
221
|
requirement: !ruby/object:Gem::Requirement
|
196
222
|
requirements:
|
197
223
|
- - "~>"
|
198
224
|
- !ruby/object:Gem::Version
|
199
|
-
version: '1.
|
225
|
+
version: '1.9'
|
200
226
|
- - ">="
|
201
227
|
- !ruby/object:Gem::Version
|
202
|
-
version: 1.
|
228
|
+
version: 1.9.2
|
203
229
|
type: :development
|
204
230
|
prerelease: false
|
205
231
|
version_requirements: !ruby/object:Gem::Requirement
|
206
232
|
requirements:
|
207
233
|
- - "~>"
|
208
234
|
- !ruby/object:Gem::Version
|
209
|
-
version: '1.
|
235
|
+
version: '1.9'
|
210
236
|
- - ">="
|
211
237
|
- !ruby/object:Gem::Version
|
212
|
-
version: 1.
|
238
|
+
version: 1.9.2
|
213
239
|
- !ruby/object:Gem::Dependency
|
214
240
|
name: rubocop-rspec
|
215
241
|
requirement: !ruby/object:Gem::Requirement
|
216
242
|
requirements:
|
217
243
|
- - "~>"
|
218
244
|
- !ruby/object:Gem::Version
|
219
|
-
version: '2.
|
245
|
+
version: '2.2'
|
220
246
|
type: :development
|
221
247
|
prerelease: false
|
222
248
|
version_requirements: !ruby/object:Gem::Requirement
|
223
249
|
requirements:
|
224
250
|
- - "~>"
|
225
251
|
- !ruby/object:Gem::Version
|
226
|
-
version: '2.
|
252
|
+
version: '2.2'
|
227
253
|
- !ruby/object:Gem::Dependency
|
228
254
|
name: simplecov
|
229
255
|
requirement: !ruby/object:Gem::Requirement
|
@@ -244,14 +270,34 @@ dependencies:
|
|
244
270
|
requirements:
|
245
271
|
- - "~>"
|
246
272
|
- !ruby/object:Gem::Version
|
247
|
-
version: 0.
|
273
|
+
version: 0.3.3
|
248
274
|
type: :development
|
249
275
|
prerelease: false
|
250
276
|
version_requirements: !ruby/object:Gem::Requirement
|
251
277
|
requirements:
|
252
278
|
- - "~>"
|
253
279
|
- !ruby/object:Gem::Version
|
254
|
-
version: 0.
|
280
|
+
version: 0.3.3
|
281
|
+
- !ruby/object:Gem::Dependency
|
282
|
+
name: webmock
|
283
|
+
requirement: !ruby/object:Gem::Requirement
|
284
|
+
requirements:
|
285
|
+
- - "~>"
|
286
|
+
- !ruby/object:Gem::Version
|
287
|
+
version: '3.11'
|
288
|
+
- - ">="
|
289
|
+
- !ruby/object:Gem::Version
|
290
|
+
version: 3.11.2
|
291
|
+
type: :development
|
292
|
+
prerelease: false
|
293
|
+
version_requirements: !ruby/object:Gem::Requirement
|
294
|
+
requirements:
|
295
|
+
- - "~>"
|
296
|
+
- !ruby/object:Gem::Version
|
297
|
+
version: '3.11'
|
298
|
+
- - ">="
|
299
|
+
- !ruby/object:Gem::Version
|
300
|
+
version: 3.11.2
|
255
301
|
description: Configurable framework agnostic plain Ruby email validator. Verify email
|
256
302
|
via Regex, DNS and SMTP.
|
257
303
|
email:
|
@@ -293,6 +339,9 @@ files:
|
|
293
339
|
- lib/truemail/auditor.rb
|
294
340
|
- lib/truemail/configuration.rb
|
295
341
|
- lib/truemail/core.rb
|
342
|
+
- lib/truemail/dns/punycode_representer.rb
|
343
|
+
- lib/truemail/dns/resolver.rb
|
344
|
+
- lib/truemail/dns/worker.rb
|
296
345
|
- lib/truemail/executor.rb
|
297
346
|
- lib/truemail/log/event.rb
|
298
347
|
- lib/truemail/log/serializer/auditor_json.rb
|