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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -1
- data/.reek.yml +9 -0
- data/.rubocop.yml +60 -0
- data/CHANGELOG.md +77 -0
- data/Gemfile.lock +62 -44
- data/LICENSE.txt +1 -1
- data/README.md +49 -20
- data/bin/console +3 -10
- 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 +39 -31
- 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/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 +11 -9
- metadata +55 -24
data/lib/truemail/validate/mx.rb
CHANGED
@@ -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 =
|
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).
|
49
|
-
|
50
|
-
end
|
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
|
-
|
65
|
+
Truemail::Dns::Resolver.a_record(hostname, configuration: configuration)
|
68
66
|
end
|
69
67
|
|
70
68
|
def hosts_from_cname_records?
|
71
|
-
cname_records =
|
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 =
|
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
|
-
|
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 '
|
39
|
-
spec.add_development_dependency '
|
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.
|
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.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.
|
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.
|
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:
|
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.
|
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,47 @@ 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
|
+
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:
|
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:
|
82
|
+
version: '2.16'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: fasterer
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
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:
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
213
|
+
version: '1.9'
|
200
214
|
- - ">="
|
201
215
|
- !ruby/object:Gem::Version
|
202
|
-
version: 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.
|
223
|
+
version: '1.9'
|
210
224
|
- - ">="
|
211
225
|
- !ruby/object:Gem::Version
|
212
|
-
version: 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.
|
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.
|
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.
|
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.
|
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
|