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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57ce495b7ea8e70dc9788b5d5528f3386a57d69233f645ab665f1a187ca08e08
4
- data.tar.gz: e5696bb995de86253fec296cd6985ddb5a26f93ccc24e4a95a21b5f4ded05681
3
+ metadata.gz: 280b30990301626ac98d8017552dfb3980cdca25e0023905cf46fc47f5360f32
4
+ data.tar.gz: '009e89519a4bc12be4d2c3d2cb33a8571af146ffe0998b0559274b0cd5224d1e'
5
5
  SHA512:
6
- metadata.gz: 3ac657676afa3a27b5b2192ec7650fd742200fd4a0d5da7a21346f4a3fb75bc2038b1183d4ebdf63ad0fcd579f05169bff6bebdf1a9c2817092d634a7974a30f
7
- data.tar.gz: 3f7f43b6ee28ef483c5fdd9a31fb615f98c688e849e0363370e59d3818d3a572272c50daa7a4422dd1f12b0c5ada49e12468f8016e9a17144fc94354d6478eb7
6
+ metadata.gz: 15cad3cce31888d867608331a8907d4257220d0f18ddaf2d8f98c40b9f568bf410346fc69a77fc5cc8c69d340ab9fec7c6f99c25a5d6ffe6436297c3781dcd1d
7
+ data.tar.gz: 85b3f6aca2f21867b96fe6544e228aae369ed660bb3f886b4546f1fff76c99f2b8d4c1a324c4668bcf83e4b64bb91105531d0c272cec485edb56146568e8c92b
data/.codeclimate.yml CHANGED
@@ -7,7 +7,7 @@ checks:
7
7
  plugins:
8
8
  rubocop:
9
9
  enabled: true
10
- channel: rubocop-1-5
10
+ channel: rubocop-1-9
11
11
 
12
12
  reek:
13
13
  enabled: true
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.2.3)
5
- simpleidn (~> 0.1.1)
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
- ast (2.4.1)
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.7)
20
+ concurrent-ruby (1.1.8)
21
+ crack (0.4.5)
22
+ rexml
19
23
  diff-lcs (1.4.4)
20
- docile (1.3.4)
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
- i18n (1.8.7)
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.1)
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.1)
70
- rubocop (1.8.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.0)
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.1.0)
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.1.1)
103
+ simpleidn (0.2.1)
97
104
  unf (~> 0.1.4)
98
- thor (1.0.1)
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.8, >= 1.8.1)
134
+ rubocop (~> 1.9, >= 1.9.1)
123
135
  rubocop-performance (~> 1.9, >= 1.9.2)
124
- rubocop-rspec (~> 2.1)
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-2020 Vladislav Trotsenko
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)
@@ -5,7 +5,6 @@ module Truemail
5
5
  class Base < Truemail::Worker
6
6
  require 'net/http'
7
7
  require 'ipaddr'
8
- require 'resolv'
9
8
 
10
9
  private
11
10
 
@@ -14,7 +14,7 @@ module Truemail
14
14
 
15
15
  def a_record
16
16
  Truemail::Wrapper.call(configuration: configuration) do
17
- Resolv::DNS.new.getaddress(verifier_domain).to_s
17
+ Truemail::Dns::Resolver.a_record(verifier_domain, configuration: configuration)
18
18
  end
19
19
  end
20
20
 
@@ -15,7 +15,7 @@ module Truemail
15
15
  private
16
16
 
17
17
  def detect_ip_via_ipify
18
- Net::HTTP.get(URI(Truemail::Audit::Ip::GET_MY_IP_URL))
18
+ ::Net::HTTP.get(URI(Truemail::Audit::Ip::GET_MY_IP_URL))
19
19
  end
20
20
 
21
21
  def detect_current_host_ip
@@ -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
- Resolv::DNS.new.getresources(
24
- current_host_reverse_lookup, Resolv::DNS::Resource::IN::PTR
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
@@ -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
- attr_reader :email_pattern,
12
- :smtp_error_body_pattern,
13
- :verifier_email,
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
- :whitelisted_domains,
21
- :blacklisted_domains,
22
- :logger
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
- %i[whitelisted_domains blacklisted_domains].each do |method|
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__, argument.is_a?(Array) && check_domain_list(argument))
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
@@ -13,7 +13,7 @@ module Truemail
13
13
  def result
14
14
  @result ||=
15
15
  {
16
- date: Time.now,
16
+ date: ::Time.now,
17
17
  current_host_ip: executor_result.current_host_ip,
18
18
  warnings: warnings(executor_result.warnings),
19
19
  configuration: configuration
@@ -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,
@@ -34,7 +34,7 @@ module Truemail
34
34
  def result
35
35
  @result ||=
36
36
  {
37
- date: Time.now,
37
+ date: ::Time.now,
38
38
  email: executor_result.email,
39
39
  validation_type: validation_type,
40
40
  success: executor_result.success,
@@ -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"
@@ -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
 
@@ -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
@@ -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
@@ -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.3'
4
+ VERSION = '2.3.0'
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,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.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 '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.8', '>= 1.8.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.1'
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.2.3
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-01-12 00:00:00.000000000 Z
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.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
@@ -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.8'
205
+ version: '1.9'
192
206
  - - ">="
193
207
  - !ruby/object:Gem::Version
194
- version: 1.8.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.8'
215
+ version: '1.9'
202
216
  - - ">="
203
217
  - !ruby/object:Gem::Version
204
- version: 1.8.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.1'
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.1'
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