truemail 2.2.3 → 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 +7 -0
- data/.rubocop.yml +15 -0
- data/CHANGELOG.md +33 -0
- data/Gemfile.lock +28 -15
- data/LICENSE.txt +1 -1
- data/README.md +29 -0
- data/lib/truemail.rb +1 -1
- 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 +38 -30
- 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 +2 -1
- data/lib/truemail/log/serializer/validator_base.rb +1 -1
- 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 +3 -3
- 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 +5 -3
- metadata +47 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 280b30990301626ac98d8017552dfb3980cdca25e0023905cf46fc47f5360f32
|
|
4
|
+
data.tar.gz: '009e89519a4bc12be4d2c3d2cb33a8571af146ffe0998b0559274b0cd5224d1e'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 15cad3cce31888d867608331a8907d4257220d0f18ddaf2d8f98c40b9f568bf410346fc69a77fc5cc8c69d340ab9fec7c6f99c25a5d6ffe6436297c3781dcd1d
|
|
7
|
+
data.tar.gz: 85b3f6aca2f21867b96fe6544e228aae369ed660bb3f886b4546f1fff76c99f2b8d4c1a324c4668bcf83e4b64bb91105531d0c272cec485edb56146568e8c92b
|
data/.codeclimate.yml
CHANGED
data/.reek.yml
CHANGED
|
@@ -44,6 +44,8 @@ detectors:
|
|
|
44
44
|
- Truemail::Configuration#logger_options
|
|
45
45
|
- Truemail::Log::Serializer::Base#errors
|
|
46
46
|
- Truemail::Log::Serializer::ValidatorBase#replace_invalid_chars
|
|
47
|
+
- Truemail::Dns::Worker#nameserver_port
|
|
48
|
+
- Truemail::Configuration#check_dns_settings
|
|
47
49
|
|
|
48
50
|
ControlParameter:
|
|
49
51
|
exclude:
|
|
@@ -73,5 +75,10 @@ detectors:
|
|
|
73
75
|
exclude:
|
|
74
76
|
- Truemail::Configuration#logger=
|
|
75
77
|
|
|
78
|
+
TooManyConstants:
|
|
79
|
+
exclude:
|
|
80
|
+
- Truemail::Configuration
|
|
81
|
+
- Truemail::RegexConstant
|
|
82
|
+
|
|
76
83
|
exclude_paths:
|
|
77
84
|
- spec/support/helpers
|
data/.rubocop.yml
CHANGED
|
@@ -145,6 +145,9 @@ Style/HashExcept:
|
|
|
145
145
|
Style/EndlessMethod:
|
|
146
146
|
Enabled: true
|
|
147
147
|
|
|
148
|
+
Style/IfWithBooleanLiteralBranches:
|
|
149
|
+
Enabled: true
|
|
150
|
+
|
|
148
151
|
Layout/LineLength:
|
|
149
152
|
Max: 140
|
|
150
153
|
|
|
@@ -287,6 +290,18 @@ Lint/LambdaWithoutLiteralBlock:
|
|
|
287
290
|
Lint/RedundantDirGlobSort:
|
|
288
291
|
Enabled: true
|
|
289
292
|
|
|
293
|
+
Lint/NumberedParameterAssignment:
|
|
294
|
+
Enabled: true
|
|
295
|
+
|
|
296
|
+
Lint/OrAssignmentToConstant:
|
|
297
|
+
Enabled: true
|
|
298
|
+
|
|
299
|
+
Lint/SymbolConversion:
|
|
300
|
+
Enabled: true
|
|
301
|
+
|
|
302
|
+
Lint/TripleQuotes:
|
|
303
|
+
Enabled: true
|
|
304
|
+
|
|
290
305
|
Performance/AncestorsInclude:
|
|
291
306
|
Enabled: true
|
|
292
307
|
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
4
|
|
|
5
|
+
## [2.3.0] - 2020.02.05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Ability to use custom DNS gateway. Thanks [@le0pard](https://github.com/le0pard) for the great idea and [@verdi8](https://github.com/verdi8) for feature [request](https://github.com/truemail-rb/truemail/issues/126).
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
Truemail.configure do |config|
|
|
13
|
+
# Optional parameter. This option will provide to use custom DNS gateway when Truemail interacts
|
|
14
|
+
# with DNS. If you won't specify nameserver's ports DNS validation layer will use default DNS
|
|
15
|
+
# TCP/UDP port 53. By default Truemail uses DNS gateway from system settings and this option
|
|
16
|
+
# is equal to empty array.
|
|
17
|
+
config.dns = ['10.0.0.1', '10.0.0.2:5300']
|
|
18
|
+
end
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
- Added `Truemail::Dns::Resolver`
|
|
22
|
+
- Added `Truemail::Dns::Worker`
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Updated `Truemail::Configuration`, tests
|
|
27
|
+
- Updated `Truemail::Validate::Mx`, tests
|
|
28
|
+
- Updated `Truemail::Audit::Base`
|
|
29
|
+
- Updated `Truemail::Audit::Dns`, tests
|
|
30
|
+
- Updated `Truemail::Audit::Ptr`, tests
|
|
31
|
+
- Updated `Truemail::Log::Serializer::Base`, dependent tests
|
|
32
|
+
- Updated namespaces for stdlib classes
|
|
33
|
+
- Updated gem development dependencies
|
|
34
|
+
- Updated linters/codeclimate configs
|
|
35
|
+
- Updated gem runtime/development dependencies
|
|
36
|
+
- Updated gem documentation, changelog, version
|
|
37
|
+
|
|
5
38
|
## [2.2.3] - 2020.01.12
|
|
6
39
|
|
|
7
40
|
### Fixed
|
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
truemail (2.
|
|
5
|
-
simpleidn (~> 0.
|
|
4
|
+
truemail (2.3.0)
|
|
5
|
+
simpleidn (~> 0.2.1)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
|
|
10
|
+
addressable (2.7.0)
|
|
11
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
12
|
+
ast (2.4.2)
|
|
11
13
|
bundler-audit (0.7.0.1)
|
|
12
14
|
bundler (>= 1.2.0, < 3)
|
|
13
15
|
thor (>= 0.18, < 2)
|
|
@@ -15,15 +17,19 @@ GEM
|
|
|
15
17
|
childprocess (4.0.0)
|
|
16
18
|
coderay (1.1.3)
|
|
17
19
|
colorize (0.8.1)
|
|
18
|
-
concurrent-ruby (1.1.
|
|
20
|
+
concurrent-ruby (1.1.8)
|
|
21
|
+
crack (0.4.5)
|
|
22
|
+
rexml
|
|
19
23
|
diff-lcs (1.4.4)
|
|
20
|
-
|
|
24
|
+
dns_mock (1.2.0)
|
|
25
|
+
docile (1.3.5)
|
|
21
26
|
faker (2.15.1)
|
|
22
27
|
i18n (>= 1.6, < 2)
|
|
23
28
|
fasterer (0.8.3)
|
|
24
29
|
colorize (~> 0.7)
|
|
25
30
|
ruby_parser (>= 3.14.1)
|
|
26
|
-
|
|
31
|
+
hashdiff (1.0.1)
|
|
32
|
+
i18n (1.8.8)
|
|
27
33
|
concurrent-ruby (~> 1.0)
|
|
28
34
|
iniparse (1.5.0)
|
|
29
35
|
json (2.5.1)
|
|
@@ -45,6 +51,7 @@ GEM
|
|
|
45
51
|
byebug (~> 11.0)
|
|
46
52
|
pry (~> 0.13.0)
|
|
47
53
|
psych (3.3.0)
|
|
54
|
+
public_suffix (4.0.6)
|
|
48
55
|
rainbow (3.0.0)
|
|
49
56
|
rake (13.0.3)
|
|
50
57
|
reek (6.0.3)
|
|
@@ -63,11 +70,11 @@ GEM
|
|
|
63
70
|
rspec-expectations (3.10.1)
|
|
64
71
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
65
72
|
rspec-support (~> 3.10.0)
|
|
66
|
-
rspec-mocks (3.10.
|
|
73
|
+
rspec-mocks (3.10.2)
|
|
67
74
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
68
75
|
rspec-support (~> 3.10.0)
|
|
69
|
-
rspec-support (3.10.
|
|
70
|
-
rubocop (1.
|
|
76
|
+
rspec-support (3.10.2)
|
|
77
|
+
rubocop (1.9.1)
|
|
71
78
|
parallel (~> 1.10)
|
|
72
79
|
parser (>= 3.0.0.0)
|
|
73
80
|
rainbow (>= 2.2.2, < 4.0)
|
|
@@ -76,12 +83,12 @@ GEM
|
|
|
76
83
|
rubocop-ast (>= 1.2.0, < 2.0)
|
|
77
84
|
ruby-progressbar (~> 1.7)
|
|
78
85
|
unicode-display_width (>= 1.4.0, < 3.0)
|
|
79
|
-
rubocop-ast (1.4.
|
|
86
|
+
rubocop-ast (1.4.1)
|
|
80
87
|
parser (>= 2.7.1.5)
|
|
81
88
|
rubocop-performance (1.9.2)
|
|
82
89
|
rubocop (>= 0.90.0, < 2.0)
|
|
83
90
|
rubocop-ast (>= 0.4.0)
|
|
84
|
-
rubocop-rspec (2.
|
|
91
|
+
rubocop-rspec (2.2.0)
|
|
85
92
|
rubocop (~> 1.0)
|
|
86
93
|
rubocop-ast (>= 1.1.0)
|
|
87
94
|
ruby-progressbar (1.11.0)
|
|
@@ -93,9 +100,9 @@ GEM
|
|
|
93
100
|
json (>= 1.8, < 3)
|
|
94
101
|
simplecov-html (~> 0.10.0)
|
|
95
102
|
simplecov-html (0.10.2)
|
|
96
|
-
simpleidn (0.
|
|
103
|
+
simpleidn (0.2.1)
|
|
97
104
|
unf (~> 0.1.4)
|
|
98
|
-
thor (1.0
|
|
105
|
+
thor (1.1.0)
|
|
99
106
|
truemail-rspec (0.3.3)
|
|
100
107
|
faker (~> 2.15, >= 2.15.1)
|
|
101
108
|
rspec (~> 3.10)
|
|
@@ -104,6 +111,10 @@ GEM
|
|
|
104
111
|
unf_ext
|
|
105
112
|
unf_ext (0.0.7.7)
|
|
106
113
|
unicode-display_width (2.0.0)
|
|
114
|
+
webmock (3.11.2)
|
|
115
|
+
addressable (>= 2.3.6)
|
|
116
|
+
crack (>= 0.3.2)
|
|
117
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
107
118
|
|
|
108
119
|
PLATFORMS
|
|
109
120
|
ruby
|
|
@@ -111,6 +122,7 @@ PLATFORMS
|
|
|
111
122
|
DEPENDENCIES
|
|
112
123
|
bundler (~> 1.16)
|
|
113
124
|
bundler-audit (~> 0.7.0.1)
|
|
125
|
+
dns_mock (~> 1.2)
|
|
114
126
|
faker (~> 2.15, >= 2.15.1)
|
|
115
127
|
fasterer (~> 0.8.3)
|
|
116
128
|
json_matchers (~> 0.11.1)
|
|
@@ -119,12 +131,13 @@ DEPENDENCIES
|
|
|
119
131
|
rake (~> 13.0, >= 13.0.3)
|
|
120
132
|
reek (~> 6.0, >= 6.0.3)
|
|
121
133
|
rspec (~> 3.10)
|
|
122
|
-
rubocop (~> 1.
|
|
134
|
+
rubocop (~> 1.9, >= 1.9.1)
|
|
123
135
|
rubocop-performance (~> 1.9, >= 1.9.2)
|
|
124
|
-
rubocop-rspec (~> 2.
|
|
136
|
+
rubocop-rspec (~> 2.2)
|
|
125
137
|
simplecov (~> 0.17.1)
|
|
126
138
|
truemail!
|
|
127
139
|
truemail-rspec (~> 0.3.3)
|
|
140
|
+
webmock (~> 3.11, >= 3.11.2)
|
|
128
141
|
|
|
129
142
|
BUNDLED WITH
|
|
130
143
|
1.16.6
|
data/LICENSE.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2019-
|
|
3
|
+
Copyright (c) 2019-2021 Vladislav Trotsenko
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
|
@@ -132,6 +132,7 @@ You can use global gem configuration or custom independent configuration. Availa
|
|
|
132
132
|
- whitelisted domains
|
|
133
133
|
- whitelist validation
|
|
134
134
|
- blacklisted domains
|
|
135
|
+
- custom DNS gateway(s)
|
|
135
136
|
- RFC MX lookup flow
|
|
136
137
|
- SMTP fail fast
|
|
137
138
|
- SMTP safe check
|
|
@@ -201,6 +202,12 @@ Truemail.configure do |config|
|
|
|
201
202
|
# It is equal to empty array by default.
|
|
202
203
|
config.blacklisted_domains = ['somedomain1.com', 'somedomain2.com']
|
|
203
204
|
|
|
205
|
+
# Optional parameter. This option will provide to use custom DNS gateway when Truemail interacts
|
|
206
|
+
# with DNS. If you won't specify nameserver's ports DNS validation layer will use default DNS
|
|
207
|
+
# TCP/UDP port 53. By default Truemail uses DNS gateway from system settings and this option
|
|
208
|
+
# is equal to empty array.
|
|
209
|
+
config.dns = ['10.0.0.1', '10.0.0.2:54']
|
|
210
|
+
|
|
204
211
|
# Optional parameter. This option will provide to use not RFC MX lookup flow.
|
|
205
212
|
# It means that MX and Null MX records will be cheked on the DNS validation layer only.
|
|
206
213
|
# By default this option is disabled.
|
|
@@ -242,6 +249,7 @@ Truemail.configuration
|
|
|
242
249
|
@whitelisted_domains=[],
|
|
243
250
|
@whitelist_validation=true,
|
|
244
251
|
@blacklisted_domains=[],
|
|
252
|
+
@dns=[],
|
|
245
253
|
@verifier_domain="somedomain.com",
|
|
246
254
|
@verifier_email="verifier@example.com",
|
|
247
255
|
@not_rfc_mx_lookup_flow=true,
|
|
@@ -272,6 +280,7 @@ Truemail.configuration
|
|
|
272
280
|
@whitelisted_domains=[],
|
|
273
281
|
@whitelist_validation=true,
|
|
274
282
|
@blacklisted_domains=[],
|
|
283
|
+
@dns=[],
|
|
275
284
|
@verifier_domain="somedomain.com",
|
|
276
285
|
@verifier_email="verifier@example.com",
|
|
277
286
|
@not_rfc_mx_lookup_flow=true,
|
|
@@ -352,6 +361,7 @@ Truemail.validate('email@white-domain.com')
|
|
|
352
361
|
smtp_debug=nil>,
|
|
353
362
|
configuration=#<Truemail::Configuration:0x00005629f801bd28
|
|
354
363
|
@blacklisted_domains=["black-domain.com", "somedomain.com"],
|
|
364
|
+
@dns=[],
|
|
355
365
|
@connection_attempts=2,
|
|
356
366
|
@connection_timeout=2,
|
|
357
367
|
@default_validation_type=:smtp,
|
|
@@ -399,6 +409,7 @@ Truemail.validate('email@white-domain.com', with: :regex)
|
|
|
399
409
|
configuration=
|
|
400
410
|
#<Truemail::Configuration:0x0000563f0d2605c8
|
|
401
411
|
@blacklisted_domains=[],
|
|
412
|
+
@dns=[],
|
|
402
413
|
@connection_attempts=2,
|
|
403
414
|
@connection_timeout=2,
|
|
404
415
|
@default_validation_type=:smtp,
|
|
@@ -432,6 +443,7 @@ Truemail.validate('email@domain.com', with: :regex)
|
|
|
432
443
|
configuration=
|
|
433
444
|
#<Truemail::Configuration:0x0000563f0cd82ab0
|
|
434
445
|
@blacklisted_domains=[],
|
|
446
|
+
@dns=[],
|
|
435
447
|
@connection_attempts=2,
|
|
436
448
|
@connection_timeout=2,
|
|
437
449
|
@default_validation_type=:smtp,
|
|
@@ -467,6 +479,7 @@ Truemail.validate('email@black-domain.com')
|
|
|
467
479
|
configuration=
|
|
468
480
|
#<Truemail::Configuration:0x0000563f0d36f4f0
|
|
469
481
|
@blacklisted_domains=[],
|
|
482
|
+
@dns=[],
|
|
470
483
|
@connection_attempts=2,
|
|
471
484
|
@connection_timeout=2,
|
|
472
485
|
@default_validation_type=:smtp,
|
|
@@ -502,6 +515,7 @@ Truemail.validate('email@somedomain.com')
|
|
|
502
515
|
configuration=
|
|
503
516
|
#<Truemail::Configuration:0x0000563f0d3f8fc0
|
|
504
517
|
@blacklisted_domains=[],
|
|
518
|
+
@dns=[],
|
|
505
519
|
@connection_attempts=2,
|
|
506
520
|
@connection_timeout=2,
|
|
507
521
|
@default_validation_type=:smtp,
|
|
@@ -553,6 +567,7 @@ Truemail.validate('email@example.com', with: :regex)
|
|
|
553
567
|
configuration=
|
|
554
568
|
#<Truemail::Configuration:0x000055aa56a54d48
|
|
555
569
|
@blacklisted_domains=[],
|
|
570
|
+
@dns=[],
|
|
556
571
|
@connection_attempts=2,
|
|
557
572
|
@connection_timeout=2,
|
|
558
573
|
@default_validation_type=:smtp,
|
|
@@ -596,6 +611,7 @@ Truemail.validate('email@example.com', with: :regex)
|
|
|
596
611
|
configuration=
|
|
597
612
|
#<Truemail::Configuration:0x0000560e58d80830
|
|
598
613
|
@blacklisted_domains=[],
|
|
614
|
+
@dns=[],
|
|
599
615
|
@connection_attempts=2,
|
|
600
616
|
@connection_timeout=2,
|
|
601
617
|
@default_validation_type=:smtp,
|
|
@@ -650,6 +666,7 @@ Truemail.validate('email@example.com', with: :mx)
|
|
|
650
666
|
configuration=
|
|
651
667
|
#<Truemail::Configuration:0x0000559b6e44af70
|
|
652
668
|
@blacklisted_domains=[],
|
|
669
|
+
@dns=[],
|
|
653
670
|
@connection_attempts=2,
|
|
654
671
|
@connection_timeout=2,
|
|
655
672
|
@default_validation_type=:smtp,
|
|
@@ -695,6 +712,7 @@ Truemail.validate('email@example.com', with: :mx)
|
|
|
695
712
|
configuration=
|
|
696
713
|
#<Truemail::Configuration:0x0000559b6e44af70
|
|
697
714
|
@blacklisted_domains=[],
|
|
715
|
+
@dns=[],
|
|
698
716
|
@connection_attempts=2,
|
|
699
717
|
@connection_timeout=2,
|
|
700
718
|
@default_validation_type=:smtp,
|
|
@@ -769,6 +787,7 @@ Truemail.validate('email@example.com')
|
|
|
769
787
|
configuration=
|
|
770
788
|
#<Truemail::Configuration:0x00007fdc4504f5c8
|
|
771
789
|
@blacklisted_domains=[],
|
|
790
|
+
@dns=[],
|
|
772
791
|
@connection_attempts=2,
|
|
773
792
|
@connection_timeout=2,
|
|
774
793
|
@default_validation_type=:smtp,
|
|
@@ -812,6 +831,7 @@ Truemail.validate('email@example.com')
|
|
|
812
831
|
configuration=
|
|
813
832
|
#<Truemail::Configuration:0x00005615e87b9298
|
|
814
833
|
@blacklisted_domains=[],
|
|
834
|
+
@dns=[],
|
|
815
835
|
@connection_attempts=2,
|
|
816
836
|
@connection_timeout=2,
|
|
817
837
|
@default_validation_type=:smtp,
|
|
@@ -862,6 +882,7 @@ Truemail.validate('email@example.com')
|
|
|
862
882
|
configuration=
|
|
863
883
|
#<Truemail::Configuration:0x00005615e87b9298
|
|
864
884
|
@blacklisted_domains=[],
|
|
885
|
+
@dns=[],
|
|
865
886
|
@connection_attempts=2,
|
|
866
887
|
@connection_timeout=2,
|
|
867
888
|
@default_validation_type=:smtp,
|
|
@@ -924,6 +945,7 @@ Truemail.validate('email@example.com')
|
|
|
924
945
|
configuration=
|
|
925
946
|
#<Truemail::Configuration:0x00005615e87b9298
|
|
926
947
|
@blacklisted_domains=[],
|
|
948
|
+
@dns=[],
|
|
927
949
|
@connection_attempts=2,
|
|
928
950
|
@connection_timeout=2,
|
|
929
951
|
@default_validation_type=:smtp,
|
|
@@ -971,6 +993,7 @@ Truemail.validate('email@example.com')
|
|
|
971
993
|
configuration=
|
|
972
994
|
#<Truemail::Configuration:0x00005615e87b9298
|
|
973
995
|
@blacklisted_domains=[],
|
|
996
|
+
@dns=[],
|
|
974
997
|
@connection_attempts=2,
|
|
975
998
|
@connection_timeout=2,
|
|
976
999
|
@default_validation_type=:smtp,
|
|
@@ -1019,6 +1042,7 @@ Truemail.host_audit
|
|
|
1019
1042
|
configuration=
|
|
1020
1043
|
#<Truemail::Configuration:0x00005615e86327a8
|
|
1021
1044
|
@blacklisted_domains=[],
|
|
1045
|
+
@dns=[],
|
|
1022
1046
|
@connection_attempts=2,
|
|
1023
1047
|
@connection_timeout=2,
|
|
1024
1048
|
@default_validation_type=:smtp,
|
|
@@ -1046,6 +1070,7 @@ Truemail.host_audit
|
|
|
1046
1070
|
configuration=
|
|
1047
1071
|
#<Truemail::Configuration:0x00005615e86327a8
|
|
1048
1072
|
@blacklisted_domains=[],
|
|
1073
|
+
@dns=[],
|
|
1049
1074
|
@connection_attempts=2,
|
|
1050
1075
|
@connection_timeout=2,
|
|
1051
1076
|
@default_validation_type=:smtp,
|
|
@@ -1101,6 +1126,7 @@ Truemail::Log::Serializer::AuditorJson.call(Truemail.host_audit)
|
|
|
1101
1126
|
"whitelist_validation": false,
|
|
1102
1127
|
"whitelisted_domains": null,
|
|
1103
1128
|
"blacklisted_domains": null,
|
|
1129
|
+
"dns": null,
|
|
1104
1130
|
"not_rfc_mx_lookup_flow": false,
|
|
1105
1131
|
"smtp_fail_fast": false,
|
|
1106
1132
|
"smtp_safe_check": false,
|
|
@@ -1140,6 +1166,7 @@ Truemail::Log::Serializer::ValidatorJson.call(Truemail.validate('nonexistent_ema
|
|
|
1140
1166
|
"whitelist_validation": false,
|
|
1141
1167
|
"whitelisted_domains": null,
|
|
1142
1168
|
"blacklisted_domains": null,
|
|
1169
|
+
"dns": null,
|
|
1143
1170
|
"not_rfc_mx_lookup_flow": false,
|
|
1144
1171
|
"smtp_fail_fast": false,
|
|
1145
1172
|
"smtp_safe_check": false,
|
|
@@ -1181,6 +1208,7 @@ Truemail.host_audit.as_json
|
|
|
1181
1208
|
"whitelist_validation": false,
|
|
1182
1209
|
"whitelisted_domains": null,
|
|
1183
1210
|
"blacklisted_domains": null,
|
|
1211
|
+
"dns": null,
|
|
1184
1212
|
"not_rfc_mx_lookup_flow": false,
|
|
1185
1213
|
"smtp_fail_fast": false,
|
|
1186
1214
|
"smtp_safe_check": false,
|
|
@@ -1217,6 +1245,7 @@ Truemail.validate('nonexistent_email@bestweb.com.ua').as_json
|
|
|
1217
1245
|
"whitelist_validation": false,
|
|
1218
1246
|
"whitelisted_domains": null,
|
|
1219
1247
|
"blacklisted_domains": null,
|
|
1248
|
+
"dns": null,
|
|
1220
1249
|
"not_rfc_mx_lookup_flow": false,
|
|
1221
1250
|
"smtp_fail_fast": false,
|
|
1222
1251
|
"smtp_safe_check": false,
|
data/lib/truemail.rb
CHANGED
|
@@ -46,7 +46,7 @@ module Truemail
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def check_argument_type(argument)
|
|
49
|
-
raise_unless(argument.is_a?(String), Truemail::INVALID_TYPE, Truemail::TypeError)
|
|
49
|
+
raise_unless(argument.is_a?(::String), Truemail::INVALID_TYPE, Truemail::TypeError)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def determine_configuration(custom_configuration)
|
data/lib/truemail/audit/base.rb
CHANGED
data/lib/truemail/audit/dns.rb
CHANGED
data/lib/truemail/audit/ip.rb
CHANGED
data/lib/truemail/audit/ptr.rb
CHANGED
|
@@ -15,13 +15,14 @@ module Truemail
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
17
|
def current_host_reverse_lookup
|
|
18
|
-
IPAddr.new(current_host_ip).reverse
|
|
18
|
+
::IPAddr.new(current_host_ip).reverse
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def ptr_records
|
|
22
22
|
@ptr_records ||= Truemail::Wrapper.call(configuration: configuration) do
|
|
23
|
-
|
|
24
|
-
current_host_reverse_lookup,
|
|
23
|
+
Truemail::Dns::Resolver.ptr_records(
|
|
24
|
+
current_host_reverse_lookup,
|
|
25
|
+
configuration: configuration
|
|
25
26
|
).map { |ptr_record| ptr_record.name.to_s }
|
|
26
27
|
end || []
|
|
27
28
|
end
|
data/lib/truemail/auditor.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Truemail
|
|
4
4
|
class Auditor < Truemail::Executor
|
|
5
|
-
Result = Struct.new(:current_host_ip, :warnings, :configuration, keyword_init: true) do
|
|
5
|
+
Result = ::Struct.new(:current_host_ip, :warnings, :configuration, keyword_init: true) do
|
|
6
6
|
def initialize(warnings: {}, **args)
|
|
7
7
|
super
|
|
8
8
|
end
|
|
@@ -7,19 +7,23 @@ module Truemail
|
|
|
7
7
|
DEFAULT_CONNECTION_ATTEMPTS = 2
|
|
8
8
|
DEFAULT_VALIDATION_TYPE = :smtp
|
|
9
9
|
DEFAULT_LOGGER_OPTIONS = { tracking_event: :error, stdout: false, log_absolute_path: nil }.freeze
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
SETTERS = %i[
|
|
11
|
+
email_pattern
|
|
12
|
+
smtp_error_body_pattern
|
|
13
|
+
connection_timeout
|
|
14
|
+
response_timeout
|
|
15
|
+
connection_attempts
|
|
16
|
+
whitelisted_domains
|
|
17
|
+
blacklisted_domains
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
attr_reader :verifier_email,
|
|
14
21
|
:verifier_domain,
|
|
15
|
-
:connection_timeout,
|
|
16
|
-
:response_timeout,
|
|
17
|
-
:connection_attempts,
|
|
18
22
|
:default_validation_type,
|
|
19
23
|
:validation_type_by_domain,
|
|
20
|
-
:
|
|
21
|
-
:
|
|
22
|
-
|
|
24
|
+
:dns,
|
|
25
|
+
:logger,
|
|
26
|
+
*Truemail::Configuration::SETTERS
|
|
23
27
|
|
|
24
28
|
attr_accessor :whitelist_validation, :not_rfc_mx_lookup_flow, :smtp_fail_fast, :smtp_safe_check
|
|
25
29
|
|
|
@@ -30,13 +34,6 @@ module Truemail
|
|
|
30
34
|
tap(&block) if block
|
|
31
35
|
end
|
|
32
36
|
|
|
33
|
-
%i[email_pattern smtp_error_body_pattern].each do |method|
|
|
34
|
-
define_method("#{method}=") do |argument|
|
|
35
|
-
raise_unless(argument, __method__, argument.is_a?(Regexp))
|
|
36
|
-
instance_variable_set(:"@#{method}", argument)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
37
|
def verifier_email=(email)
|
|
41
38
|
validate_arguments(email, __method__)
|
|
42
39
|
@verifier_email = email.downcase
|
|
@@ -48,15 +45,8 @@ module Truemail
|
|
|
48
45
|
@verifier_domain = domain.downcase
|
|
49
46
|
end
|
|
50
47
|
|
|
51
|
-
%i[connection_timeout response_timeout connection_attempts].each do |method|
|
|
52
|
-
define_method("#{method}=") do |argument|
|
|
53
|
-
raise_unless(argument, __method__, argument.is_a?(Integer) && argument.positive?)
|
|
54
|
-
instance_variable_set(:"@#{method}", argument)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
48
|
def default_validation_type=(argument)
|
|
59
|
-
raise_unless(argument, __method__, argument.is_a?(Symbol) && Truemail::Validator::VALIDATION_TYPES.include?(argument))
|
|
49
|
+
raise_unless(argument, __method__, argument.is_a?(::Symbol) && Truemail::Validator::VALIDATION_TYPES.include?(argument))
|
|
60
50
|
@default_validation_type = argument
|
|
61
51
|
end
|
|
62
52
|
|
|
@@ -65,18 +55,31 @@ module Truemail
|
|
|
65
55
|
validation_type_by_domain.merge!(settings)
|
|
66
56
|
end
|
|
67
57
|
|
|
68
|
-
|
|
58
|
+
def argument_consistent?(argument)
|
|
59
|
+
case argument
|
|
60
|
+
when ::Array then check_domain_list(argument)
|
|
61
|
+
when ::Integer then argument.positive?
|
|
62
|
+
when ::Regexp then true
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
Truemail::Configuration::SETTERS.each do |method|
|
|
69
67
|
define_method("#{method}=") do |argument|
|
|
70
|
-
raise_unless(argument, __method__,
|
|
68
|
+
raise_unless(argument, __method__, argument_consistent?(argument))
|
|
71
69
|
instance_variable_set(:"@#{method}", argument)
|
|
72
70
|
end
|
|
73
71
|
end
|
|
74
72
|
|
|
73
|
+
def dns=(argument)
|
|
74
|
+
raise_unless(argument, __method__, argument.is_a?(::Array) && check_dns_settings(argument))
|
|
75
|
+
@dns = argument
|
|
76
|
+
end
|
|
77
|
+
|
|
75
78
|
def logger=(options)
|
|
76
79
|
tracking_event, stdout, log_absolute_path = logger_options(options)
|
|
77
80
|
valid_event = Truemail::Log::Event::TRACKING_EVENTS.key?(tracking_event)
|
|
78
81
|
stdout_only = stdout && log_absolute_path.nil?
|
|
79
|
-
file_only = log_absolute_path.is_a?(String)
|
|
82
|
+
file_only = log_absolute_path.is_a?(::String)
|
|
80
83
|
both_types = stdout && file_only
|
|
81
84
|
argument_info = valid_event ? log_absolute_path : tracking_event
|
|
82
85
|
raise_unless(argument_info, __method__, valid_event && (stdout_only || file_only || both_types))
|
|
@@ -89,7 +92,7 @@ module Truemail
|
|
|
89
92
|
|
|
90
93
|
private
|
|
91
94
|
|
|
92
|
-
def instance_initializer
|
|
95
|
+
def instance_initializer # rubocop:disable Metrics/MethodLength
|
|
93
96
|
{
|
|
94
97
|
email_pattern: Truemail::RegexConstant::REGEX_EMAIL_PATTERN,
|
|
95
98
|
smtp_error_body_pattern: Truemail::RegexConstant::REGEX_SMTP_ERROR_BODY_PATTERN,
|
|
@@ -101,6 +104,7 @@ module Truemail
|
|
|
101
104
|
whitelisted_domains: [],
|
|
102
105
|
whitelist_validation: false,
|
|
103
106
|
blacklisted_domains: [],
|
|
107
|
+
dns: [],
|
|
104
108
|
not_rfc_mx_lookup_flow: false,
|
|
105
109
|
smtp_fail_fast: false,
|
|
106
110
|
smtp_safe_check: false
|
|
@@ -137,13 +141,17 @@ module Truemail
|
|
|
137
141
|
end
|
|
138
142
|
|
|
139
143
|
def validate_validation_type(settings)
|
|
140
|
-
raise_unless(settings, 'hash with settings', settings.is_a?(Hash))
|
|
144
|
+
raise_unless(settings, 'hash with settings', settings.is_a?(::Hash))
|
|
141
145
|
settings.each do |domain, validation_type|
|
|
142
146
|
check_domain(domain)
|
|
143
147
|
check_validation_type(validation_type)
|
|
144
148
|
end
|
|
145
149
|
end
|
|
146
150
|
|
|
151
|
+
def check_dns_settings(dns_servers)
|
|
152
|
+
dns_servers.all? { |dns_server| Truemail::RegexConstant::REGEX_DNS_SERVER_ADDRESS_PATTERN.match?(dns_server.to_s) }
|
|
153
|
+
end
|
|
154
|
+
|
|
147
155
|
def logger_options(current_options)
|
|
148
156
|
Truemail::Configuration::DEFAULT_LOGGER_OPTIONS.merge(current_options).values
|
|
149
157
|
end
|
data/lib/truemail/core.rb
CHANGED
|
@@ -10,32 +10,28 @@ module Truemail
|
|
|
10
10
|
require_relative '../truemail/validator'
|
|
11
11
|
require_relative '../truemail/logger'
|
|
12
12
|
|
|
13
|
-
ConfigurationError = Class.new(StandardError)
|
|
14
|
-
TypeError = Class.new(StandardError)
|
|
15
|
-
|
|
16
|
-
ArgumentError = Class.new(StandardError) do
|
|
13
|
+
ConfigurationError = ::Class.new(::StandardError)
|
|
14
|
+
TypeError = ::Class.new(::StandardError)
|
|
15
|
+
ArgumentError = ::Class.new(::StandardError) do
|
|
17
16
|
def initialize(arg_value, arg_name)
|
|
18
17
|
super("#{arg_value} is not a valid #{arg_name}")
|
|
19
18
|
end
|
|
20
19
|
end
|
|
21
20
|
|
|
22
|
-
PunycodeRepresenter = Class.new do
|
|
23
|
-
require 'simpleidn'
|
|
24
|
-
|
|
25
|
-
def self.call(email)
|
|
26
|
-
return unless email.is_a?(String)
|
|
27
|
-
return email if email.ascii_only?
|
|
28
|
-
user, domain = email.split('@')
|
|
29
|
-
"#{user}@#{SimpleIDN.to_ascii(domain.downcase)}"
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
21
|
module RegexConstant
|
|
34
22
|
REGEX_DOMAIN = /[\p{L}0-9]+([\-.]{1}[\p{L}0-9]+)*\.\p{L}{2,63}/i.freeze
|
|
35
23
|
REGEX_EMAIL_PATTERN = /(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-.+]*)@(#{REGEX_DOMAIN})\z)/.freeze
|
|
36
24
|
REGEX_DOMAIN_PATTERN = /(?=\A.{4,255}\z)(\A#{REGEX_DOMAIN}\z)/.freeze
|
|
37
25
|
REGEX_DOMAIN_FROM_EMAIL = /\A.+@(.+)\z/.freeze
|
|
38
26
|
REGEX_SMTP_ERROR_BODY_PATTERN = /(?=.*550)(?=.*(user|account|customer|mailbox)).*/i.freeze
|
|
27
|
+
REGEX_PORT_NUMBER = /(6553[0-5]|655[0-2][0-9]\d|65[0-4](\d){2}|6[0-4](\d){3}|[1-5](\d){4}|[1-9](\d){0,3})/.freeze
|
|
28
|
+
REGEX_DNS_SERVER_ADDRESS_PATTERN = /\A((1\d|[1-9]|2[0-4])?\d|25[0-5])(\.\g<1>){3}(:#{REGEX_PORT_NUMBER})?\z/.freeze
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module Dns
|
|
32
|
+
require_relative '../truemail/dns/punycode_representer'
|
|
33
|
+
require_relative '../truemail/dns/worker'
|
|
34
|
+
require_relative '../truemail/dns/resolver'
|
|
39
35
|
end
|
|
40
36
|
|
|
41
37
|
module Audit
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Truemail
|
|
4
|
+
module Dns
|
|
5
|
+
PunycodeRepresenter = Class.new do
|
|
6
|
+
require 'simpleidn'
|
|
7
|
+
|
|
8
|
+
def self.call(email)
|
|
9
|
+
return unless email.is_a?(::String)
|
|
10
|
+
return email if email.ascii_only?
|
|
11
|
+
user, domain = email.split('@')
|
|
12
|
+
"#{user}@#{SimpleIDN.to_ascii(domain.downcase)}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Truemail
|
|
4
|
+
module Dns
|
|
5
|
+
class Resolver
|
|
6
|
+
WORKER_ACTIONS = %i[dns_lookup a_record a_records cname_records mx_records ptr_records].freeze
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
Truemail::Dns::Resolver::WORKER_ACTIONS.each do |worker_action|
|
|
10
|
+
define_method(worker_action) do |argument, configuration:|
|
|
11
|
+
Truemail::Dns::Worker.new(configuration.dns).public_send(worker_action, argument)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Truemail
|
|
4
|
+
module Dns
|
|
5
|
+
require 'resolv'
|
|
6
|
+
|
|
7
|
+
class Worker < ::Resolv::DNS
|
|
8
|
+
DEFAULT_DNS_PORT = 53
|
|
9
|
+
|
|
10
|
+
attr_reader :dns_gateway
|
|
11
|
+
|
|
12
|
+
def initialize(dns_servers)
|
|
13
|
+
super(dns_servers.empty? ? nil : config_info(dns_servers))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def dns_lookup(host_address)
|
|
17
|
+
getname(host_address).to_s
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def a_record(host_name)
|
|
21
|
+
getaddress(host_name).to_s
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def a_records(host_name)
|
|
25
|
+
getaddresses(host_name).map(&:to_s)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def cname_records(host_name)
|
|
29
|
+
getresources(host_name, ::Resolv::DNS::Resource::IN::CNAME)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def mx_records(host_name)
|
|
33
|
+
getresources(host_name, ::Resolv::DNS::Resource::IN::MX)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def ptr_records(host_address)
|
|
37
|
+
getresources(host_address, ::Resolv::DNS::Resource::IN::PTR)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def nameserver_port(server)
|
|
43
|
+
server_address, server_port = server.split(':')
|
|
44
|
+
[server_address, server_port ? server_port.to_i : Truemail::Dns::Worker::DEFAULT_DNS_PORT]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def config_info(dns_servers)
|
|
48
|
+
@dns_gateway = { nameserver_port: dns_servers.map { |server| nameserver_port(server) } }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -30,7 +30,7 @@ module Truemail
|
|
|
30
30
|
|
|
31
31
|
alias warnings errors
|
|
32
32
|
|
|
33
|
-
%i[validation_type_by_domain whitelisted_domains blacklisted_domains].each do |method|
|
|
33
|
+
%i[validation_type_by_domain whitelisted_domains blacklisted_domains dns].each do |method|
|
|
34
34
|
define_method(method) do
|
|
35
35
|
value = executor_configuration.public_send(method)
|
|
36
36
|
return if value.empty?
|
|
@@ -55,6 +55,7 @@ module Truemail
|
|
|
55
55
|
whitelist_validation: executor_configuration.whitelist_validation,
|
|
56
56
|
whitelisted_domains: whitelisted_domains,
|
|
57
57
|
blacklisted_domains: blacklisted_domains,
|
|
58
|
+
dns: dns,
|
|
58
59
|
not_rfc_mx_lookup_flow: executor_configuration.not_rfc_mx_lookup_flow,
|
|
59
60
|
smtp_fail_fast: executor_configuration.smtp_fail_fast,
|
|
60
61
|
smtp_safe_check: executor_configuration.smtp_safe_check,
|
|
@@ -20,8 +20,8 @@ module Truemail
|
|
|
20
20
|
enumerable_object.inject([]) do |formatted_data, (key, value)|
|
|
21
21
|
data =
|
|
22
22
|
case
|
|
23
|
-
when value.is_a?(Hash) then "\n#{printer(value)}"
|
|
24
|
-
when value.is_a?(Array) then value.join(', ')
|
|
23
|
+
when value.is_a?(::Hash) then "\n#{printer(value)}"
|
|
24
|
+
when value.is_a?(::Array) then value.join(', ')
|
|
25
25
|
else value
|
|
26
26
|
end
|
|
27
27
|
formatted_data << "#{key.to_s.tr('_', ' ')}: #{data}".chomp << "\n"
|
data/lib/truemail/logger.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Truemail
|
|
|
23
23
|
def init_log_file
|
|
24
24
|
output_file = Pathname(file)
|
|
25
25
|
return output_file if output_file.exist?
|
|
26
|
-
output_file.parent.mkpath && FileUtils.touch(output_file)
|
|
26
|
+
output_file.parent.mkpath && ::FileUtils.touch(output_file)
|
|
27
27
|
output_file
|
|
28
28
|
end
|
|
29
29
|
|
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
|
|
@@ -23,14 +23,14 @@ module Truemail
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def check_port
|
|
26
|
-
response.port_opened = Socket.tcp(
|
|
26
|
+
response.port_opened = ::Socket.tcp(
|
|
27
27
|
host,
|
|
28
28
|
Truemail::Validate::Smtp::Request::SMTP_PORT,
|
|
29
29
|
connect_timeout: configuration.connection_timeout,
|
|
30
30
|
&port_open_status
|
|
31
31
|
)
|
|
32
32
|
rescue => error
|
|
33
|
-
retry if attempts_exist? && error.is_a?(Errno::ETIMEDOUT)
|
|
33
|
+
retry if attempts_exist? && error.is_a?(::Errno::ETIMEDOUT)
|
|
34
34
|
response.port_opened = false
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -65,7 +65,7 @@ module Truemail
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def session
|
|
68
|
-
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|
|
|
69
69
|
settings.open_timeout = configuration.connection_timeout
|
|
70
70
|
settings.read_timeout = configuration.response_timeout
|
|
71
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,10 +31,11 @@ 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'
|
|
38
39
|
spec.add_development_dependency 'faker', '~> 2.15', '>= 2.15.1'
|
|
39
40
|
spec.add_development_dependency 'fasterer', '~> 0.8.3'
|
|
40
41
|
spec.add_development_dependency 'json_matchers', '~> 0.11.1'
|
|
@@ -43,9 +44,10 @@ Gem::Specification.new do |spec|
|
|
|
43
44
|
spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.3'
|
|
44
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', '~> 1.9', '>= 1.9.1'
|
|
47
48
|
spec.add_development_dependency 'rubocop-performance', '~> 1.9', '>= 1.9.2'
|
|
48
|
-
spec.add_development_dependency 'rubocop-rspec', '~> 2.
|
|
49
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
|
|
49
50
|
spec.add_development_dependency 'simplecov', '~> 0.17.1'
|
|
50
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: 2021-
|
|
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
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: 0.7.0.1
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
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'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: faker
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -188,20 +202,20 @@ dependencies:
|
|
|
188
202
|
requirements:
|
|
189
203
|
- - "~>"
|
|
190
204
|
- !ruby/object:Gem::Version
|
|
191
|
-
version: '1.
|
|
205
|
+
version: '1.9'
|
|
192
206
|
- - ">="
|
|
193
207
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: 1.
|
|
208
|
+
version: 1.9.1
|
|
195
209
|
type: :development
|
|
196
210
|
prerelease: false
|
|
197
211
|
version_requirements: !ruby/object:Gem::Requirement
|
|
198
212
|
requirements:
|
|
199
213
|
- - "~>"
|
|
200
214
|
- !ruby/object:Gem::Version
|
|
201
|
-
version: '1.
|
|
215
|
+
version: '1.9'
|
|
202
216
|
- - ">="
|
|
203
217
|
- !ruby/object:Gem::Version
|
|
204
|
-
version: 1.
|
|
218
|
+
version: 1.9.1
|
|
205
219
|
- !ruby/object:Gem::Dependency
|
|
206
220
|
name: rubocop-performance
|
|
207
221
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -228,14 +242,14 @@ dependencies:
|
|
|
228
242
|
requirements:
|
|
229
243
|
- - "~>"
|
|
230
244
|
- !ruby/object:Gem::Version
|
|
231
|
-
version: '2.
|
|
245
|
+
version: '2.2'
|
|
232
246
|
type: :development
|
|
233
247
|
prerelease: false
|
|
234
248
|
version_requirements: !ruby/object:Gem::Requirement
|
|
235
249
|
requirements:
|
|
236
250
|
- - "~>"
|
|
237
251
|
- !ruby/object:Gem::Version
|
|
238
|
-
version: '2.
|
|
252
|
+
version: '2.2'
|
|
239
253
|
- !ruby/object:Gem::Dependency
|
|
240
254
|
name: simplecov
|
|
241
255
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -264,6 +278,26 @@ dependencies:
|
|
|
264
278
|
- - "~>"
|
|
265
279
|
- !ruby/object:Gem::Version
|
|
266
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
|
|
267
301
|
description: Configurable framework agnostic plain Ruby email validator. Verify email
|
|
268
302
|
via Regex, DNS and SMTP.
|
|
269
303
|
email:
|
|
@@ -305,6 +339,9 @@ files:
|
|
|
305
339
|
- lib/truemail/auditor.rb
|
|
306
340
|
- lib/truemail/configuration.rb
|
|
307
341
|
- lib/truemail/core.rb
|
|
342
|
+
- lib/truemail/dns/punycode_representer.rb
|
|
343
|
+
- lib/truemail/dns/resolver.rb
|
|
344
|
+
- lib/truemail/dns/worker.rb
|
|
308
345
|
- lib/truemail/executor.rb
|
|
309
346
|
- lib/truemail/log/event.rb
|
|
310
347
|
- lib/truemail/log/serializer/auditor_json.rb
|