truemail 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a79768ed850e2481e1a818783ece53c2dcda4dc93e1b69c2c183fa7ba172f1e
4
- data.tar.gz: 51f0d6958b0036733feda8b9dea2226a9dcab65536c111e0c2a503fe32d742eb
3
+ metadata.gz: 7178be3e727f222d2858c31cdeaa2ddbaeb68aafd149153397f8de1605c1f59a
4
+ data.tar.gz: ac8ef85621ef89d43e486d2c1fda46902fde10332cfd2d4b2eb363da08900ad4
5
5
  SHA512:
6
- metadata.gz: 76f5d8eb6f238ef14bae1012df322ceafe53c149263be9230cce6e60c5ba729cdc7c66f8d0f7d4f780521aae2e91139b888b49239caceeccb4bc3def7970e9a0
7
- data.tar.gz: f472b4a46800af9c56303b99dd27854326a9afb040d33af11e8e0da12a1dd860cbcbe671ef879c1ef9f8c03065d2bbc1383e38954c845a60053d3f8be7075986
6
+ metadata.gz: 846814d9d1d62df1c7298bfb4c4e930029fc1c33fe270313c2020f82d19888b7d9aeabd60999406b015209d0058e9988934164e6a617563e0601a11b52730d09
7
+ data.tar.gz: 88aba85102b59a4c8313d6d8816a66c6dea9a1bf73ae9d1437676337f316b77d109a478ea7703ed281bb6f92ae887bbac1d8eb817d86411bc034252b68fe6bb7
data/.reek.yml CHANGED
@@ -12,13 +12,17 @@ detectors:
12
12
  - Truemail::Validate::Smtp::Request#run
13
13
  - Truemail::Validate::Smtp#run
14
14
  - Truemail::Validate::Mx#hosts_from_cname_records
15
- - Truemail::Configuration#initialize
15
+ - Truemail::Configuration#logger=
16
16
 
17
17
  TooManyInstanceVariables:
18
18
  exclude:
19
19
  - Truemail::Configuration
20
20
  - Truemail::Validate::Smtp::Request
21
21
 
22
+ TooManyMethods:
23
+ exclude:
24
+ - Truemail::Configuration
25
+
22
26
  Attribute:
23
27
  exclude:
24
28
  - Truemail::Configuration#whitelist_validation
@@ -48,7 +52,17 @@ detectors:
48
52
  - Truemail::Validate::Smtp#not_includes_user_not_found_errors
49
53
  - Truemail::GenerateEmailHelper#prepare_user_name
50
54
  - Truemail::ConfigurationHelper#create_configuration
55
+ - Truemail::Log::Serializer::Base#smtp_debug
56
+ - Truemail::Log::Serializer::Text#data_composer
51
57
 
52
58
  NilCheck:
53
59
  exclude:
54
60
  - Truemail::Validator#result_not_changed?
61
+ - Truemail::Configuration#logger=
62
+
63
+ BooleanParameter:
64
+ exclude:
65
+ - Truemail::Configuration#logger=
66
+
67
+ exclude_paths:
68
+ - spec/support/helpers/validator_helper.rb
@@ -0,0 +1,350 @@
1
+ # Changelog
2
+ 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).
3
+
4
+ ## [1.4.0] - 2019-10-28
5
+ ### Added
6
+ - Event logger (ability to output validation logs to stdout/file)
7
+ - JSON serializer for validator instance
8
+ - [Changelog](CHANGELOG.md)
9
+ - [Logo](https://repository-images.githubusercontent.com/173723932/6dffee00-e88e-11e9-94b6-c97aacc0df00)
10
+
11
+ Truemail gem allows to output tracking events to stdout/file or both of these. Please note, at least one of the outputs must exist. Tracking event by default is `:error`
12
+
13
+ **Available tracking events**
14
+
15
+ - `:all`, all detected events including success validation cases
16
+ - `:unrecognized_error`, unrecognized errors only (when `smtp_safe_check = true` and SMTP server does not return an exact answer that the email does not exist)
17
+ - `:recognized_error`, recognized errors only
18
+ - `:error`, recognized and unrecognized errors only
19
+
20
+ ```ruby
21
+ Truemail.configure do |config|
22
+ config.logger = { tracking_event: :all, stdout: true, log_absolute_path: '/home/app/log/truemail.log' }
23
+ end
24
+ ```
25
+
26
+ Also starting from this version Truemail has built in JSON serializer for `Truemail::Validator` instance, so you can represent your email validation result as json.
27
+
28
+ ```ruby
29
+ Truemail::Log::Serializer::Json.call(Truemail.validate('nonexistent_email@bestweb.com.ua'))
30
+ ```
31
+
32
+ ### Changed
33
+ - `Truemail::Configuration`
34
+ - `Truemail::Validator`
35
+ - `Truemail::Validate::Regex`
36
+ - `Truemail::VERSION`
37
+ - gem documentation
38
+ - gem description
39
+
40
+ ## [1.3.0] - 2019-09-16
41
+ ### Added
42
+ - Ability to create new `Truemail::Configuration` instance with block
43
+ - `Truemail::Validate::Smtp::Request::Configuration`
44
+
45
+ ### Changed
46
+ - `Truemail::Wrapper`
47
+ - `Truemail::Validate::Base`
48
+ - `Truemail::Validator`
49
+ - `Truemail::Validator::Result`
50
+ - `Truemail::Validate::Regex`
51
+ - `Truemail::Validate::Mx`
52
+ - `Truemail::Validate::Smtp`
53
+ - `Truemail::Validate::Smtp::Request`
54
+ - `Truemail::Audit::Base`
55
+ - `Truemail::Auditor`
56
+ - `Truemail::Audit::Ptr`
57
+ - `::Truemail` module
58
+ - `Truemail::VERSION`
59
+ - gem documentation
60
+ - gem description
61
+
62
+ ## [1.2.1] - 2019-06-27
63
+ ### Fixed
64
+ - Removed memoization from ```DomainListMatch#whitelisted_domain?```
65
+
66
+ ### Changed
67
+ - `Truemail::VERSION`
68
+ - gem documentation
69
+
70
+ ## [1.2.0] - 2019-06-26
71
+ ### Added
72
+ - Configurable option: validation for whitelisted domains only.
73
+
74
+ When email domain in whitelist and ```whitelist_validation``` is sets equal to ```true``` validation type will be passed to other validators. Validation of email which not contains whitelisted domain always will return ```false```.
75
+
76
+ ```ruby
77
+ Truemail.configure do |config|
78
+ config.verifier_email = 'verifier@example.com'
79
+ config.whitelisted_domains = ['white-domain.com']
80
+ config.whitelist_validation = true
81
+ end
82
+ ```
83
+
84
+ **Email has whitelisted domain**
85
+
86
+ ```ruby
87
+ Truemail.validate('email@white-domain.com', with: :regex)
88
+
89
+ #<Truemail::Validator:0x000055b8429f3490
90
+ @result=#<struct Truemail::Validator::Result
91
+ success=true,
92
+ email="email@white-domain.com",
93
+ domain=nil,
94
+ mail_servers=[],
95
+ errors={},
96
+ smtp_debug=nil>,
97
+ @validation_type=:regex>
98
+ ```
99
+ **Email hasn't whitelisted domain**
100
+
101
+ ```ruby
102
+ Truemail.validate('email@domain.com', with: :regex)
103
+
104
+ #<Truemail::Validator:0x000055b8429f3490
105
+ @result=#<struct Truemail::Validator::Result
106
+ success=false,
107
+ email="email@domain.com",
108
+ domain=nil,
109
+ mail_servers=[],
110
+ errors={},
111
+ smtp_debug=nil>,
112
+ @validation_type=:blacklist>
113
+ ```
114
+
115
+ ### Changed
116
+ - `Truemail::VERSION`
117
+ - gem documentation
118
+
119
+ ## [1.1.0] - 2019-06-18
120
+ ### Added
121
+ - Configurable default validation type, [issue details](https://github.com/rubygarage/truemail/issues/48)
122
+
123
+ You can predefine default validation type for ```Truemail.validate('email@email.com')``` call without with-parameter. Available validation types: ```:regex```, ```:mx```, ```:smtp```. By default validation type still remains ```:smtp```
124
+
125
+ ```ruby
126
+ Truemail.configure do |config|
127
+ config.verifier_email = 'verifier@example.com'
128
+ config.default_validation_type = :mx
129
+ end
130
+ ```
131
+
132
+ ### Changed
133
+ - `Truemail::VERSION`
134
+ - gem documentation
135
+
136
+ ## [1.0.1] - 2019-06-08
137
+ ### Added
138
+ - Result validation type marker for domain list match check
139
+
140
+ ```ruby
141
+ Truemail.validate('email@white-domain.com')
142
+
143
+ #<Truemail::Validator:0x000055b8429f3490
144
+ @result=#<struct Truemail::Validator::Result
145
+ success=true,
146
+ email="email@white-domain.com",
147
+ domain=nil,
148
+ mail_servers=[],
149
+ errors={},
150
+ smtp_debug=nil>,
151
+ @validation_type=:whitelist>
152
+
153
+ Truemail.validate('email@black-domain.com')
154
+
155
+ #<Truemail::Validator:0x000023y8429f3493
156
+ @result=#<struct Truemail::Validator::Result
157
+ success=false,
158
+ email="email@black-domain.com",
159
+ domain=nil,
160
+ mail_servers=[],
161
+ errors={},
162
+ smtp_debug=nil>,
163
+ @validation_type=:blacklist>
164
+ ```
165
+
166
+ ### Changed
167
+ - `Truemail::VERSION`
168
+ - gem documentation
169
+
170
+ ## [1.0] - 2019-06-04
171
+ ### Added
172
+ - Feature domain whitelist blacklist. Other validations will not processed even if it was defined in ```validation_type_for```.
173
+
174
+ ```ruby
175
+ Truemail.configure do |config|
176
+ # Optional parameter. Validation of email which contains whitelisted domain
177
+ # always will return true.
178
+ config.whitelisted_domains = ['somedomain1.com', 'somedomain2.com']
179
+
180
+ # Optional parameter. Validation of email which contains whitelisted domain
181
+ # always will return false.
182
+ config.blacklisted_domains = ['somedomain1.com', 'somedomain2.com']
183
+ end
184
+ ```
185
+ and
186
+
187
+ ```ruby
188
+ Truemail.configuration.whitelisted_domains = ['somedomain1.com', 'somedomain2.com']
189
+ Truemail.configuration.blacklisted_domains = ['somedomain1.com', 'somedomain2.com']
190
+ ```
191
+
192
+ ### Removed
193
+ - ```:skip``` validation type for ```validation_type_for```
194
+
195
+ ### Fixed
196
+ - error key in `lower_snake_case`
197
+
198
+ ### Changed
199
+ - `Truemail::VERSION`
200
+ - gem documentation
201
+
202
+ ## [0.2] - 2019-05-23
203
+ ### Added
204
+ - skip validation by domain for validation_type_for configuration option:
205
+
206
+ ```ruby
207
+ Truemail.configure do |config|
208
+ config.validation_type_for = { 'somedomain.com' => :skip }
209
+ end
210
+ ```
211
+ and
212
+ ```ruby
213
+ Truemail.configuration.validation_type_for = { 'somedomain.com' => :skip }
214
+ ```
215
+ ### Changed
216
+ - `Truemail::VERSION`
217
+ - gem documentation
218
+
219
+ ## [0.1.10] - 2019-05-10
220
+ ### Added
221
+ - SMTP error body configurable option, [issue details](https://github.com/rubygarage/truemail/issues/19)
222
+
223
+ ### Changed
224
+ - `Truemail::VERSION`
225
+ - gem documentation
226
+
227
+ ## [0.1.9] - 2019-04-29
228
+ ### Fixed
229
+ - Empty ptr constant
230
+
231
+ ## [0.1.8] - 2019-04-29
232
+ ### Added
233
+ - Reverse trace, [issue details](https://github.com/rubygarage/truemail/issues/18)
234
+
235
+ ### Fixed
236
+ - Behaviour of current host address resolver, [issue details](https://github.com/rubygarage/truemail/issues/18)
237
+
238
+ ### Changed
239
+ - `Truemail::VERSION`
240
+ - gem documentation
241
+
242
+ ## [0.1.7] - 2019-04-17
243
+ ### Added
244
+ - PTR record audit, [issue details](https://github.com/rubygarage/truemail/issues/18)
245
+
246
+ ### Changed
247
+ - `Truemail::VERSION`
248
+ - gem documentation
249
+
250
+ ## [0.1.6] - 2019-04-08
251
+ ### Added
252
+ - MX gem logic with [RFC 7505](https://tools.ietf.org/html/rfc7505), null MX record supporting, [issue details](https://github.com/rubygarage/truemail/issues/27)
253
+ - [Contributing guideline](CONTRIBUTING.md)
254
+
255
+ ### Fixed
256
+ - Multihomed MX records supporting, [issue details](https://github.com/rubygarage/truemail/issues/28)
257
+
258
+ ### Changed
259
+ - `Truemail::VERSION`
260
+ - gem documentation
261
+
262
+ ## [0.1.5] - 2019-04-05
263
+ ### Added
264
+ - Retries for ```Truemail::Validate::Smtp``` for cases when one mx server
265
+
266
+ ### Changed
267
+ - ```Truemail::Configuration``` class, please use ```.connection_attempts``` instead ```.retry_count```
268
+ - `Truemail::VERSION`
269
+ - gem documentation
270
+
271
+ ## [0.1.4] - 2019-04-01
272
+ ### Added
273
+ - Checking A record presence if ```MX``` and ```CNAME``` records not exist, [issue details](https://github.com/rubygarage/truemail/issues/10)
274
+ - Handling of ```CNAME``` records, [issue details](https://github.com/rubygarage/truemail/issues/11)
275
+ - Checking A record if ```MX``` and ```CNAME``` records not found, [issue details](https://github.com/rubygarage/truemail/issues/12)
276
+ - Supporting of multihomed MX records, conversion host names to ips, [issue details](https://github.com/rubygarage/truemail/issues/17)
277
+ - Timeout configuration for DNS resolver, [issue details](https://github.com/rubygarage/truemail/issues/13)
278
+ - ```.valid?``` helper
279
+
280
+ ### Changed
281
+ - `Truemail::VERSION`
282
+ - gem documentation
283
+
284
+ ## [0.1.3] - 2019-03-27
285
+ ### Added
286
+ - Independent domain name extractor to ```Truemail::Validate::Mx#run```
287
+
288
+ ### Fixed
289
+ - Default ```REGEX_EMAIL_PATTERN```, [issue details](https://github.com/rubygarage/truemail/issues/7)
290
+ * local part of address can't start with a dot or special symbol
291
+ * local part of address can include ```+``` symbol
292
+ - Default ```REGEX_DOMAIN_PATTERN```, [issue details](https://github.com/rubygarage/truemail/issues/8)
293
+ * TLD size increased up to 63 characters
294
+ - Case sensitive domain names, [issue details](https://github.com/rubygarage/truemail/issues/9)
295
+
296
+ ### Changed
297
+ - `Truemail::VERSION`
298
+ - gem documentation
299
+
300
+ ## [0.1.0] - 2019-03-26
301
+ ### Added
302
+ - 'SMTP safe check' option for cases when SMTP server does not return an exact answer that the email does not exist.
303
+
304
+ ```ruby
305
+ Truemail.configure do |config|
306
+ config.verifier_email = 'verifier@example.com'
307
+ config.smtp_safe_check = true
308
+ end
309
+
310
+ Truemail.validate('email@example.com')
311
+
312
+ # Successful SMTP validation
313
+ => #<Truemail::Validator:0x0000000002ca2c70
314
+ @result=
315
+ #<struct Truemail::Validator::Result
316
+ success=true,
317
+ email="email@example.com",
318
+ domain="example.com",
319
+ mail_servers=["mx1.example.com"],
320
+ errors={},
321
+ smtp_debug=
322
+ [#<Truemail::Validate::Smtp::Request:0x0000000002c95d40
323
+ @configuration=
324
+ #<Truemail::Configuration:0x0000000002c95b38
325
+ @connection_timeout=2,
326
+ @email_pattern=/regex_pattern/,
327
+ @response_timeout=2,
328
+ @smtp_safe_check=true,
329
+ @validation_type_by_domain={},
330
+ @verifier_domain="example.com",
331
+ @verifier_email="verifier@example.com">,
332
+ @email="email@example.com",
333
+ @host="mx1.example.com",
334
+ @response=
335
+ #<struct Truemail::Validate::Smtp::Response
336
+ port_opened=true,
337
+ connection=false,
338
+ helo=
339
+ #<Net::SMTP::Response:0x0000000002c934c8
340
+ @status="250",
341
+ @string="250 mx1.example.com\n">,
342
+ mailfrom=false,
343
+ rcptto=nil,
344
+ errors={:mailfrom=>"554 5.7.1 Client host blocked\n", :connection=>"server dropped connection after response"}>>,]>,
345
+ @validation_type=:smtp>
346
+ ```
347
+
348
+ ### Changed
349
+ - `Truemail::VERSION`
350
+ - gem documentation
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- truemail (1.3.0)
4
+ truemail (1.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -33,6 +33,9 @@ GEM
33
33
  iniparse (1.4.4)
34
34
  jaro_winkler (1.5.2)
35
35
  json (2.2.0)
36
+ json_matchers (0.11.1)
37
+ json_schema
38
+ json_schema (0.20.8)
36
39
  kwalify (0.7.2)
37
40
  method_source (0.9.2)
38
41
  overcommit (0.46.0)
@@ -57,19 +60,19 @@ GEM
57
60
  parser (>= 2.5.0.0, < 2.7, != 2.5.1.1)
58
61
  psych (~> 3.1.0)
59
62
  rainbow (>= 2.0, < 4.0)
60
- rspec (3.8.0)
61
- rspec-core (~> 3.8.0)
62
- rspec-expectations (~> 3.8.0)
63
- rspec-mocks (~> 3.8.0)
64
- rspec-core (3.8.0)
65
- rspec-support (~> 3.8.0)
66
- rspec-expectations (3.8.2)
63
+ rspec (3.9.0)
64
+ rspec-core (~> 3.9.0)
65
+ rspec-expectations (~> 3.9.0)
66
+ rspec-mocks (~> 3.9.0)
67
+ rspec-core (3.9.0)
68
+ rspec-support (~> 3.9.0)
69
+ rspec-expectations (3.9.0)
67
70
  diff-lcs (>= 1.2.0, < 2.0)
68
- rspec-support (~> 3.8.0)
69
- rspec-mocks (3.8.0)
71
+ rspec-support (~> 3.9.0)
72
+ rspec-mocks (3.9.0)
70
73
  diff-lcs (>= 1.2.0, < 2.0)
71
- rspec-support (~> 3.8.0)
72
- rspec-support (3.8.0)
74
+ rspec-support (~> 3.9.0)
75
+ rspec-support (3.9.0)
73
76
  rubocop (0.65.0)
74
77
  jaro_winkler (~> 1.5.1)
75
78
  parallel (~> 1.10)
@@ -103,6 +106,7 @@ DEPENDENCIES
103
106
  bundler (~> 1.16)
104
107
  bundler-audit
105
108
  ffaker
109
+ json_matchers
106
110
  overcommit
107
111
  pry-byebug
108
112
  rake
data/README.md CHANGED
@@ -1,16 +1,66 @@
1
- # Truemail
1
+ # <img src='https://repository-images.githubusercontent.com/173723932/6dffee00-e88e-11e9-94b6-c97aacc0df00' height='250' alt='Truemail - configurable plain Ruby email validator' />
2
2
 
3
3
  [![Maintainability](https://api.codeclimate.com/v1/badges/657aa241399927dcd2e2/maintainability)](https://codeclimate.com/github/rubygarage/truemail/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/657aa241399927dcd2e2/test_coverage)](https://codeclimate.com/github/rubygarage/truemail/test_coverage) [![CircleCI](https://circleci.com/gh/rubygarage/truemail/tree/master.svg?style=svg)](https://circleci.com/gh/rubygarage/truemail/tree/master) [![Gem Version](https://badge.fury.io/rb/truemail.svg)](https://badge.fury.io/rb/truemail) [![Downloads](https://img.shields.io/gem/dt/truemail.svg?colorA=004d99&colorB=0073e6)](https://rubygems.org/gems/truemail) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)
4
4
 
5
5
  The Truemail gem helps you validate emails via regex pattern, presence of DNS records, and real existence of email account on a current email server. Also Truemail gem allows performing an audit of the host in which runs.
6
6
 
7
+ ## Table of Contents
8
+
9
+ - [Synopsis](#synopsis)
10
+ - [Features](#features)
11
+ - [Installation](#installation)
12
+ - [Usage](#usage)
13
+ - [Configuration features](#configuration-features)
14
+ - [Setting global configuration](#setting-global-configuration)
15
+ - [Read global configuration](#read-global-configuration)
16
+ - [Update global configuration](#update-global-configuration)
17
+ - [Reset global configuration](#reset-global-configuration)
18
+ - [Using custom independent configuration](#using-custom-independent-configuration)
19
+ - [Validation features](#validation-features)
20
+ - [Whitelist/Blacklist check](#whitelist-blacklist-check)
21
+ - [Whitelist case](#whitelist-case)
22
+ - [Whitelist validation case](#whitelist-validation-case)
23
+ - [Blacklist case](#blacklist-case)
24
+ - [Duplication case](#duplication-case)
25
+ - [Regex validation](#regex-validation)
26
+ - [With default regex pattern](#with-default-regex-pattern)
27
+ - [With custom regex pattern](#with-custom-regex-pattern)
28
+ - [MX validation](#mx-validation)
29
+ - [SMTP validation](#smtp-validation)
30
+ - [SMTP safe check disabled](#smtp-safe-check-disabled)
31
+ - [SMTP safe check enabled](#smtp-safe-check-enabled)
32
+ - [Event logger](#event-logger)
33
+ - [Available tracking events](#available-tracking-events)
34
+ - [JSON serializer](#json-serializer)
35
+ - [Host audit features](#host-audit-features)
36
+ - [PTR audit](#ptr-audit)
37
+ - [Truemail helpers](#truemail-helpers)
38
+ - [.valid?](#valid)
39
+ - [Test environment](#test-environment)
40
+ - [Contributing](#contributing)
41
+ - [License](#license)
42
+ - [Code of Conduct](#code-of-conduct)
43
+ - [Versioning](#versioning)
44
+ - [Changelog](CHANGELOG.md)
45
+
46
+ ## Synopsis
47
+
48
+ Email validation is a tricky thing. There are a number of different ways to validate an email address and all mechanisms must conform with the best practices and provide proper validation. You can get more information about email validation techniques in our [blog](https://rubygarage.org/blog/how-to-validate-emails).
49
+
50
+ **Syntax Checking**: Checks the email addresses via regex pattern.
51
+
52
+ **Mail Server Existence Check**: Checks the availability of the email address domain using DNS records.
53
+
54
+ **Mail Existence Check**: Checks if the email address really exists and can receive email via SMTP connections and email-sending emulation techniques.
55
+
7
56
  ## Features
8
57
 
9
58
  - Configurable validator, validate only what you need
10
59
  - Zero runtime dependencies
11
- - Has whitelist/blacklist
12
- - Has simple SMTP debugger
13
- - 100% test coverage
60
+ - Whitelist/blacklist validation layers
61
+ - Simple SMTP debugger
62
+ - Event logger
63
+ - JSON serializer
14
64
 
15
65
  ## Installation
16
66
 
@@ -28,21 +78,28 @@ Or install it yourself as:
28
78
 
29
79
  $ gem install truemail
30
80
 
31
- ## Email Validation Methods
32
-
33
- Email validation is a tricky thing. There are a number of different ways to validate an email address and all mechanisms must conform with the best practices and provide proper validation. You can get more information about email validation techniques in our [blog](https://rubygarage.org/blog/how-to-validate-emails).
34
-
35
- **Syntax Checking**: Checks the email addresses via regex pattern.
36
-
37
- **Mail Server Existence Check**: Checks the availability of the email address domain using DNS records.
38
-
39
- **Mail Existence Check**: Checks if the email address really exists and can receive email via SMTP connections and email-sending emulation techniques.
40
-
41
81
  ## Usage
42
82
 
43
83
  ### Configuration features
44
84
 
45
- You can use global gem configuration or custom independent configuration.
85
+ You can use global gem configuration or custom independent configuration. Available configuration options:
86
+
87
+ - verifier email
88
+ - verifier domain
89
+ - email pattern
90
+ - SMTP error body pattern
91
+ - connection timeout
92
+ - response timeout
93
+ - connection attempts
94
+ - default validation type
95
+ - validation type for domains
96
+ - whitelisted domains
97
+ - whitelist validation
98
+ - blacklisted domains
99
+ - SMTP safe check
100
+ - event logger
101
+ - JSON serializer
102
+
46
103
 
47
104
  #### Setting global configuration
48
105
 
@@ -109,6 +166,11 @@ Truemail.configure do |config|
109
166
  # if SMTP server does not return an exact answer that the email does not exist
110
167
  # By default this option is disabled, available for SMTP validation only.
111
168
  config.smtp_safe_check = true
169
+
170
+ # Optional parameter. This option will enable tracking events. You can print tracking events to
171
+ # stdout, write to file or both of these. Tracking event by default is :error
172
+ # Available tracking event: :all, :unrecognized_error, :recognized_error, :error
173
+ config.logger = { tracking_event: :all, stdout: true, log_absolute_path: '/home/app/log/truemail.log' }
112
174
  end
113
175
  ```
114
176
 
@@ -131,7 +193,9 @@ Truemail.configuration
131
193
  @blacklisted_domains=[],
132
194
  @verifier_domain="somedomain.com",
133
195
  @verifier_email="verifier@example.com"
134
- @smtp_safe_check=true>
196
+ @smtp_safe_check=true,
197
+ @logger=#<Truemail::Logger:0x0000557f837450b0
198
+ @event=:all, @file="/home/app/log/truemail.log", @stdout=true>>
135
199
  ```
136
200
 
137
201
  ##### Update global configuration
@@ -157,7 +221,9 @@ Truemail.configuration
157
221
  @blacklisted_domains=[],
158
222
  @verifier_domain="somedomain.com",
159
223
  @verifier_email="verifier@example.com",
160
- @smtp_safe_check=true>
224
+ @smtp_safe_check=true,
225
+ @logger=#<Truemail::Logger:0x0000557f837450b0
226
+ @event=:all, @file="/home/app/log/truemail.log", @stdout=true>>
161
227
  ```
162
228
 
163
229
  ##### Reset global configuration
@@ -401,7 +467,7 @@ By default this validation not performs strictly following [RFC 5322](https://ww
401
467
 
402
468
  Example of usage:
403
469
 
404
- 1. With default regex pattern
470
+ ##### With default regex pattern
405
471
 
406
472
  ```ruby
407
473
  require 'truemail'
@@ -438,7 +504,9 @@ Truemail.validate('email@example.com', with: :regex)
438
504
  @validation_type=:regex>
439
505
  ```
440
506
 
441
- 2. With custom regex pattern. You should define your custom regex pattern in a gem configuration before.
507
+ ##### With custom regex pattern
508
+
509
+ You should define your custom regex pattern in a gem configuration before.
442
510
 
443
511
  ```ruby
444
512
  require 'truemail'
@@ -537,6 +605,8 @@ If total count of MX servers is equal to one, ```Truemail::Smtp``` validator wil
537
605
 
538
606
  By default, you don't need pass with-parameter to use it. Example of usage is specified below:
539
607
 
608
+ ###### SMTP safe check disabled
609
+
540
610
  With ```smtp_safe_check = false```
541
611
 
542
612
  ```ruby
@@ -627,6 +697,9 @@ Truemail.validate('email@example.com')
627
697
  @validation_type=:smtp>
628
698
  ```
629
699
 
700
+
701
+ ###### SMTP safe check enabled
702
+
630
703
  With ```smtp_safe_check = true```
631
704
 
632
705
  ```ruby
@@ -736,6 +809,62 @@ Truemail.validate('email@example.com')
736
809
  @validation_type=:smtp>
737
810
  ```
738
811
 
812
+ ### Event logger
813
+
814
+ Truemail gem allows to output tracking events to stdout/file or both of these. Please note, at least one of the outputs must exist. Tracking event by default is `:error`
815
+
816
+ ```ruby
817
+ Truemail.configure do |config|
818
+ config.logger = { tracking_event: :all, stdout: true, log_absolute_path: '/home/app/log/truemail.log' }
819
+ end
820
+ ```
821
+
822
+ #### Available tracking events
823
+
824
+ - `:all`, all detected events including success validation cases
825
+ - `:unrecognized_error`, unrecognized errors only (when `smtp_safe_check = true` and SMTP server does not return an exact answer that the email does not exist)
826
+ - `:recognized_error`, recognized errors only
827
+ - `:error`, recognized and unrecognized errors only
828
+
829
+ ### JSON serializer
830
+
831
+ Truemail has built in JSON serializer for `Truemail::Validator` instance, so you can represent your email validation result as json.
832
+
833
+ ```ruby
834
+ Truemail::Log::Serializer::Json.call(Truemail.validate('nonexistent_email@bestweb.com.ua'))
835
+
836
+ =>
837
+ # Serialized Truemail::Validator instance
838
+ {
839
+ "date": "2019-10-28 10:15:51 +0200",
840
+ "email": "nonexistent_email@bestweb.com.ua",
841
+ "validation_type": "smtp",
842
+ "success": false,
843
+ "errors": {
844
+ "smtp": "smtp error"
845
+ },
846
+ "smtp_debug": [
847
+ {
848
+ "mail_host": "213.180.193.89",
849
+ "port_opened": true,
850
+ "connection": true,
851
+ "errors": {
852
+ "rcptto": "550 5.7.1 No such user!\n"
853
+ }
854
+ }
855
+ ],
856
+ "configuration": {
857
+ "validation_type_by_domain": null,
858
+ "whitelist_validation": false,
859
+ "whitelisted_domains": null,
860
+ "blacklisted_domains": null,
861
+ "smtp_safe_check": false,
862
+ "email_pattern": "default gem value",
863
+ "smtp_error_body_pattern": "default gem value"
864
+ }
865
+ }
866
+ ```
867
+
739
868
  ### Host audit features
740
869
 
741
870
  Truemail gem allows performing an audit of the host in which runs. Only PTR record audit performs for today.
@@ -17,7 +17,8 @@ module Truemail
17
17
  :default_validation_type,
18
18
  :validation_type_by_domain,
19
19
  :whitelisted_domains,
20
- :blacklisted_domains
20
+ :blacklisted_domains,
21
+ :logger
21
22
 
22
23
  attr_accessor :whitelist_validation, :smtp_safe_check
23
24
 
@@ -72,6 +73,16 @@ module Truemail
72
73
  end
73
74
  end
74
75
 
76
+ def logger=(tracking_event: :error, stdout: false, log_absolute_path: nil)
77
+ valid_event = Truemail::Log::Event::TRACKING_EVENTS.keys.include?(tracking_event)
78
+ stdout_only = stdout && log_absolute_path.nil?
79
+ file_only = log_absolute_path.is_a?(String)
80
+ both_types = stdout && file_only
81
+ argument_info = valid_event ? log_absolute_path : tracking_event
82
+ raise_unless(argument_info, __method__, valid_event && (stdout_only || file_only || both_types))
83
+ @logger = Truemail::Logger.new(tracking_event, stdout, log_absolute_path)
84
+ end
85
+
75
86
  def complete?
76
87
  !!verifier_email
77
88
  end
@@ -7,6 +7,7 @@ module Truemail
7
7
  require 'truemail/wrapper'
8
8
  require 'truemail/auditor'
9
9
  require 'truemail/validator'
10
+ require 'truemail/logger'
10
11
 
11
12
  class ConfigurationError < StandardError; end
12
13
 
@@ -38,4 +39,11 @@ module Truemail
38
39
  require 'truemail/validate/smtp/response'
39
40
  require 'truemail/validate/smtp/request'
40
41
  end
42
+
43
+ module Log
44
+ require 'truemail/log/event'
45
+ require 'truemail/log/serializer/base'
46
+ require 'truemail/log/serializer/text'
47
+ require 'truemail/log/serializer/json'
48
+ end
41
49
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Log
5
+ class Event
6
+ TRACKING_EVENTS =
7
+ {
8
+ all: %i[success unrecognized_error recognized_error],
9
+ unrecognized_error: %i[unrecognized_error],
10
+ recognized_error: %i[recognized_error],
11
+ error: %i[unrecognized_error recognized_error]
12
+ }.freeze
13
+
14
+ def initialize(event, validator_instance)
15
+ validator_result = validator_instance.result
16
+ @event = event
17
+ @has_validation_errors = !validator_result.errors.empty?
18
+ @successful_validation = validator_result.success
19
+ @validation_smtp_debug = validator_result.smtp_debug
20
+ end
21
+
22
+ def valid?
23
+ Truemail::Log::Event::TRACKING_EVENTS[event].include?(action_level_log.first)
24
+ end
25
+
26
+ def log_level
27
+ action_level_log.last
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :event, :has_validation_errors, :successful_validation, :validation_smtp_debug
33
+
34
+ def action_level_log
35
+ @action_level_log ||=
36
+ case
37
+ when successful_validation && !validation_smtp_debug then [:success, ::Logger::INFO]
38
+ when successful_validation && validation_smtp_debug then [:unrecognized_error, ::Logger::WARN]
39
+ when !successful_validation && has_validation_errors then [:recognized_error, ::Logger::ERROR]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Log
5
+ module Serializer
6
+ class Base
7
+ DEFAULT_GEM_VALUE = 'default gem value'
8
+
9
+ def self.call(validator_instance)
10
+ new(validator_instance).serialize
11
+ end
12
+
13
+ def initialize(validator_instance)
14
+ @validation_type = validator_instance.validation_type
15
+ @validation_result = validator_instance.result
16
+ @validation_configuration = validation_result.configuration
17
+ end
18
+
19
+ def serialize; end
20
+
21
+ private
22
+
23
+ attr_reader :validation_type, :validation_result, :validation_configuration
24
+
25
+ def errors
26
+ validation_errors = validation_result.errors
27
+ return if validation_errors.empty?
28
+ validation_errors
29
+ end
30
+
31
+ def smtp_debug
32
+ validation_smtp_debug = validation_result.smtp_debug
33
+ return unless validation_smtp_debug
34
+ validation_smtp_debug.map do |smtp_request|
35
+ smtp_response = smtp_request.response
36
+ {
37
+ mail_host: smtp_request.host,
38
+ port_opened: smtp_response.port_opened,
39
+ connection: smtp_response.connection,
40
+ errors: smtp_response.errors
41
+ }
42
+ end
43
+ end
44
+
45
+ %i[validation_type_by_domain whitelisted_domains blacklisted_domains].each do |method|
46
+ define_method(method) do
47
+ value = validation_configuration.public_send(method)
48
+ return if value.empty?
49
+ value
50
+ end
51
+ end
52
+
53
+ %i[email_pattern smtp_error_body_pattern].each do |method|
54
+ define_method(method) do
55
+ value = validation_configuration.public_send(method)
56
+ default_pattern = Truemail::RegexConstant.const_get(
57
+ (method.eql?(:email_pattern) ? :regex_email_pattern : :regex_smtp_error_body_pattern).upcase
58
+ )
59
+ return Truemail::Log::Serializer::Base::DEFAULT_GEM_VALUE if value.eql?(default_pattern)
60
+ value
61
+ end
62
+ end
63
+
64
+ def configuration
65
+ {
66
+ validation_type_by_domain: validation_type_by_domain,
67
+ whitelist_validation: validation_configuration.whitelist_validation,
68
+ whitelisted_domains: whitelisted_domains,
69
+ blacklisted_domains: blacklisted_domains,
70
+ smtp_safe_check: validation_configuration.smtp_safe_check,
71
+ email_pattern: email_pattern,
72
+ smtp_error_body_pattern: smtp_error_body_pattern
73
+ }
74
+ end
75
+
76
+ def result
77
+ @result ||=
78
+ {
79
+ date: Time.now,
80
+ email: validation_result.email,
81
+ validation_type: validation_type,
82
+ success: validation_result.success,
83
+ errors: errors,
84
+ smtp_debug: smtp_debug,
85
+ configuration: configuration
86
+ }
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Log
5
+ module Serializer
6
+ class Json < Truemail::Log::Serializer::Base
7
+ def serialize
8
+ result.to_json
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Log
5
+ module Serializer
6
+ class Text < Truemail::Log::Serializer::Base
7
+ ATTEMPT = 'ATTEMPT #'
8
+
9
+ def serialize
10
+ <<~VALIDATION_LOGGER_INFO
11
+ #{txt_info_title}
12
+ #{txt_info_debug}
13
+ #{txt_info_configuration}
14
+ VALIDATION_LOGGER_INFO
15
+ end
16
+
17
+ private
18
+
19
+ def data_composer(enumerable_object)
20
+ enumerable_object.inject([]) do |formatted_data, (key, value)|
21
+ data =
22
+ case
23
+ when value.is_a?(Hash) then "\n#{printer(value)}"
24
+ when value.is_a?(Array) then value.join(', ')
25
+ else value
26
+ end
27
+ formatted_data << "#{key.to_s.tr('_', ' ')}: #{data}".chomp << "\n"
28
+ end
29
+ end
30
+
31
+ def collection_printer(collection)
32
+ collection.inject([]) { |array, hash| array << printer(hash) }.map.with_index do |item, index|
33
+ "\n#{Truemail::Log::Serializer::Text::ATTEMPT}#{index + 1}:\n#{item}\n"
34
+ end
35
+ end
36
+
37
+ def printer(enumerable_object)
38
+ if enumerable_object.is_a?(Hash)
39
+ data_composer(enumerable_object)
40
+ else
41
+ collection_printer(enumerable_object)
42
+ end.join.chomp
43
+ end
44
+
45
+ def error_info
46
+ validation_errors = result[:errors]
47
+ validation_errors ? " (#{printer(validation_errors).tr("\n", ', ')})" : validation_errors
48
+ end
49
+
50
+ def txt_info_title
51
+ validation_result = result[:success] ? 'was successful' : 'failed'
52
+ "Truemail #{result[:validation_type]} validation for #{result[:email]} #{validation_result}#{error_info}"
53
+ end
54
+
55
+ def txt_info_debug
56
+ result_smtp_debug = result[:smtp_debug]
57
+ "#{printer(result_smtp_debug)}\n" if result_smtp_debug
58
+ end
59
+
60
+ def txt_info_configuration
61
+ "CONFIGURATION SETTINGS:\n#{printer(result[:configuration].compact)}"
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Truemail
6
+ class Logger
7
+ attr_reader :event, :stdout, :file
8
+
9
+ def initialize(event, error_stdout, log_absolute_path)
10
+ @event = event
11
+ @stdout = error_stdout
12
+ @file = log_absolute_path
13
+ end
14
+
15
+ def push(validator_instance)
16
+ current_event = Truemail::Log::Event.new(event, validator_instance)
17
+ return unless current_event.valid?
18
+ create_logs(current_event.log_level, Truemail::Log::Serializer::Text.call(validator_instance))
19
+ end
20
+
21
+ private
22
+
23
+ def init_log_file
24
+ output_file = Pathname(file)
25
+ return output_file if output_file.exist?
26
+ output_file.parent.mkpath && FileUtils.touch(output_file)
27
+ output_file
28
+ end
29
+
30
+ def create_logs(log_level, serialized_object)
31
+ %i[stdout file].each do |output_type|
32
+ next unless public_send(output_type)
33
+ ::Logger.new(output_type.eql?(:stdout) ? $stdout : init_log_file).add(log_level) { serialized_object }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -6,10 +6,16 @@ module Truemail
6
6
  ERROR = 'email does not match the regular expression'
7
7
 
8
8
  def run
9
- return true if success(configuration.email_pattern.match?(result.email))
9
+ return true if success(match_regex_pattern?)
10
10
  add_error(Truemail::Validate::Regex::ERROR)
11
11
  false
12
12
  end
13
+
14
+ private
15
+
16
+ def match_regex_pattern?
17
+ configuration.email_pattern.match?(result.email)
18
+ end
13
19
  end
14
20
  end
15
21
  end
@@ -24,22 +24,31 @@ module Truemail
24
24
  def run
25
25
  Truemail::Validate::DomainListMatch.check(result)
26
26
  result_not_changed? ? Truemail::Validate.const_get(validation_type.capitalize).check(result) : update_validation_type
27
+ logger.push(self) if logger
27
28
  self
28
29
  end
29
30
 
30
31
  private
31
32
 
32
- def result_not_changed?
33
- result.success.nil?
33
+ def select_validation_type(email, current_validation_type)
34
+ domain = email[Truemail::RegexConstant::REGEX_EMAIL_PATTERN, 3]
35
+ result.configuration.validation_type_by_domain[domain] || current_validation_type
34
36
  end
35
37
 
36
38
  def update_validation_type
37
39
  @validation_type = result.success ? :whitelist : :blacklist
38
40
  end
39
41
 
40
- def select_validation_type(email, current_validation_type)
41
- domain = email[Truemail::RegexConstant::REGEX_EMAIL_PATTERN, 3]
42
- result.configuration.validation_type_by_domain[domain] || current_validation_type
42
+ def result_status
43
+ result.success
44
+ end
45
+
46
+ def result_not_changed?
47
+ result_status.nil?
48
+ end
49
+
50
+ def logger
51
+ result.configuration.logger
43
52
  end
44
53
  end
45
54
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- VERSION = '1.3.0'
4
+ VERSION = '1.4.0'
5
5
  end
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ['admin@bestweb.com.ua']
12
12
 
13
13
  spec.summary = %(truemail)
14
- spec.description = %(Configurable plain Ruby email validator. Verify email via Regex, DNS and SMTP. Be sure that email address exists)
14
+ spec.description = %(Configurable plain Ruby email validator. Verify email via Regex, DNS and SMTP. Be sure that email address exists.)
15
15
 
16
16
  spec.homepage = 'https://github.com/rubygarage/truemail'
17
17
  spec.license = 'MIT'
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency 'bundler', '~> 1.16'
27
27
  spec.add_development_dependency 'bundler-audit'
28
28
  spec.add_development_dependency 'ffaker'
29
+ spec.add_development_dependency 'json_matchers'
29
30
  spec.add_development_dependency 'overcommit'
30
31
  spec.add_development_dependency 'pry-byebug'
31
32
  spec.add_development_dependency 'rake'
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: 1.3.0
4
+ version: 1.4.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: 2019-09-16 00:00:00.000000000 Z
11
+ date: 2019-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: json_matchers
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: overcommit
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -165,7 +179,7 @@ dependencies:
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0'
167
181
  description: Configurable plain Ruby email validator. Verify email via Regex, DNS
168
- and SMTP. Be sure that email address exists
182
+ and SMTP. Be sure that email address exists.
169
183
  email:
170
184
  - admin@bestweb.com.ua
171
185
  executables: []
@@ -183,6 +197,7 @@ files:
183
197
  - ".rubocop.yml"
184
198
  - ".ruby-gemset"
185
199
  - ".ruby-version"
200
+ - CHANGELOG.md
186
201
  - CODE_OF_CONDUCT.md
187
202
  - CONTRIBUTING.md
188
203
  - Gemfile
@@ -198,6 +213,11 @@ files:
198
213
  - lib/truemail/auditor.rb
199
214
  - lib/truemail/configuration.rb
200
215
  - lib/truemail/core.rb
216
+ - lib/truemail/log/event.rb
217
+ - lib/truemail/log/serializer/base.rb
218
+ - lib/truemail/log/serializer/json.rb
219
+ - lib/truemail/log/serializer/text.rb
220
+ - lib/truemail/logger.rb
201
221
  - lib/truemail/validate/base.rb
202
222
  - lib/truemail/validate/domain_list_match.rb
203
223
  - lib/truemail/validate/mx.rb