truemail 0.1.1.2 → 0.1.1.3
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/.reek.yml +0 -6
- data/.rubocop.yml +0 -6
- data/Gemfile.lock +1 -1
- data/README.md +20 -20
- data/lib/truemail.rb +4 -2
- data/lib/truemail/configuration.rb +2 -0
- data/lib/truemail/core.rb +2 -0
- data/lib/truemail/validate/base.rb +6 -4
- data/lib/truemail/validate/mx.rb +6 -4
- data/lib/truemail/validate/regex.rb +3 -1
- data/lib/truemail/validate/smtp.rb +4 -2
- data/lib/truemail/validate/smtp/request.rb +22 -16
- data/lib/truemail/validate/smtp/response.rb +3 -1
- data/lib/truemail/validator.rb +5 -2
- data/lib/truemail/version.rb +3 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 047d26e7e9e7843b9db9f4bad1d45fc758a2db21e0b1b08f161dd798fdbb9019
|
4
|
+
data.tar.gz: 520f4f237023451512359176b728f2b1d4d85721a6ffa0924d0062f7a7e5fa6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31af7442e139b2812cf329ecd239df80bb56d989aa4e157f05253ec3f371539277389017550acd6000b171872716d2304420e9df11efbc7711681362c81d2d19
|
7
|
+
data.tar.gz: 15f647100c86ab2281fe3a62cd370616ac967340f84f0a19d9c3ae20984b9f7d02194a5fd57f3b9edba9725954077db1db94ca8ebadece4598a910095b74aaf2
|
data/.reek.yml
CHANGED
@@ -17,15 +17,9 @@ detectors:
|
|
17
17
|
|
18
18
|
UtilityFunction:
|
19
19
|
exclude:
|
20
|
-
- Truemail::Validate::Mx#mx_records
|
21
|
-
- Truemail::Validate::Smtp::Request#configuration
|
22
20
|
- Truemail::Validate::Smtp::Request#compose_from
|
23
21
|
- Truemail::Validator#select_validation_type
|
24
22
|
|
25
23
|
ControlParameter:
|
26
24
|
exclude:
|
27
25
|
- Truemail::GenerateEmailHelper#calculate_email_size
|
28
|
-
|
29
|
-
NilCheck:
|
30
|
-
exclude:
|
31
|
-
- Truemail::Validator#select_validation_type
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Truemail
|
2
2
|
|
3
|
-
[](https://badge.fury.io/rb/truemail) [](https://codeclimate.com/github/rubygarage/truemail/maintainability) [](https://codeclimate.com/github/rubygarage/truemail/test_coverage) [](https://badge.fury.io/rb/truemail) [](https://circleci.com/gh/rubygarage/truemail/tree/develop)
|
4
4
|
|
5
|
-
The
|
5
|
+
The Truemail gem helps you validate emails by regex pattern, presence of domain mx-records, and real existence of email account on a current email server.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -22,13 +22,13 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Email Validation Methods
|
24
24
|
|
25
|
-
Email validation is a tricky thing
|
25
|
+
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.
|
26
26
|
|
27
|
-
**Syntax Checking**:
|
27
|
+
**Syntax Checking**: Checks the email addresses via regex pattern.
|
28
28
|
|
29
|
-
**Mail Server Existence Check**:
|
29
|
+
**Mail Server Existence Check**: Checks the availability of the email address domain using DNS MX records.
|
30
30
|
|
31
|
-
**Mail Existence Check**:
|
31
|
+
**Mail Existence Check**: Checks if the email address really exists and can receive email via SMTP connections and email-sending emulation techniques.
|
32
32
|
|
33
33
|
## Usage
|
34
34
|
|
@@ -36,27 +36,27 @@ Email validation is a tricky thing to do properly. There are a number of differe
|
|
36
36
|
|
37
37
|
#### Set configuration
|
38
38
|
|
39
|
-
To have access for Truemail.configuration and gem features you must configure it first
|
39
|
+
To have an access for ```Truemail.configuration``` and gem features, you must configure it first as in the example below:
|
40
40
|
|
41
41
|
```ruby
|
42
42
|
Truemail.configure do |config|
|
43
|
-
# Required parameter.
|
43
|
+
# Required parameter. Must be an existing email on behalf of which verification will be performed
|
44
44
|
config.verifier_email = 'verifier@example.com'
|
45
45
|
|
46
|
-
# Optional parameter.
|
46
|
+
# Optional parameter. Must be an existing domain on behalf of which verification will be performed.
|
47
47
|
# By default verifier domain based on verifier email
|
48
48
|
config.verifier_domain = 'somedomain.com'
|
49
49
|
|
50
50
|
# Optional parameter. You can override default regex pattern
|
51
51
|
config.email_pattern = /regex_pattern/
|
52
52
|
|
53
|
-
# Optional parameter.
|
53
|
+
# Optional parameter. Connection timeout is equal to 2 ms by default.
|
54
54
|
config.connection_timeout = 1
|
55
55
|
|
56
|
-
# Optional parameter.
|
56
|
+
# Optional parameter. A SMTP server response timeout is equal to 2 ms by default.
|
57
57
|
config.response_timeout = 1
|
58
58
|
|
59
|
-
# Optional parameter. You can
|
59
|
+
# Optional parameter. You can predefine which type of validation will be used for domains.
|
60
60
|
# Available validation types: :regex, :mx, :smtp
|
61
61
|
# This configuration will be used over current or default validation type parameter
|
62
62
|
# All of validations for 'somedomain.com' will be processed with mx validation only
|
@@ -66,7 +66,7 @@ end
|
|
66
66
|
|
67
67
|
#### Read configuration
|
68
68
|
|
69
|
-
After successful configuration you can read current Truemail configuration instance anywhere in your application.
|
69
|
+
After successful configuration, you can read current Truemail configuration instance anywhere in your application.
|
70
70
|
|
71
71
|
```ruby
|
72
72
|
Truemail.configuration
|
@@ -113,9 +113,9 @@ Truemail.configuration
|
|
113
113
|
|
114
114
|
#### Regex validation
|
115
115
|
|
116
|
-
Validation with regex pattern is first validation level.
|
116
|
+
Validation with regex pattern is the first validation level.
|
117
117
|
|
118
|
-
|
118
|
+
Example of usage:
|
119
119
|
|
120
120
|
1. With default regex pattern
|
121
121
|
|
@@ -131,7 +131,7 @@ Truemail.validate('email@example.com', with: :regex)
|
|
131
131
|
@validation_type=:regex>
|
132
132
|
```
|
133
133
|
|
134
|
-
2. With custom regex pattern
|
134
|
+
2. With custom regex pattern. You should define your custom regex pattern in a gem configuration before.
|
135
135
|
|
136
136
|
```ruby
|
137
137
|
Truemail.configure do |config|
|
@@ -147,9 +147,9 @@ Truemail.validate('email@example.com', with: :regex)
|
|
147
147
|
|
148
148
|
#### MX validation
|
149
149
|
|
150
|
-
Validation by MX records is second validation level. It
|
150
|
+
Validation by MX records is second validation level. It uses Regex validation before launch. When regex validation has completed successfully then runs itself.
|
151
151
|
|
152
|
-
Example of
|
152
|
+
Example of usage:
|
153
153
|
|
154
154
|
```ruby
|
155
155
|
Truemail.configure do |config|
|
@@ -165,13 +165,13 @@ Truemail.validate('email@example.com', with: :mx)
|
|
165
165
|
|
166
166
|
#### SMTP validation
|
167
167
|
|
168
|
-
SMTP validation is a final, third validation level.
|
168
|
+
SMTP validation is a final, third validation level. This type of validation tries to check real existence of email account on a current email server. This validation runs a chain of previous validations, and if they're complete, successfully runs itself.
|
169
169
|
|
170
170
|
```code
|
171
171
|
[Regex validation] -> [MX validation] -> [SMTP validation]
|
172
172
|
```
|
173
173
|
|
174
|
-
By default you don't need pass with-parameter to use it. Example of
|
174
|
+
By default, you don't need pass with-parameter to use it. Example of usage is specified below:
|
175
175
|
|
176
176
|
```ruby
|
177
177
|
Truemail.configure do |config|
|
data/lib/truemail.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'truemail/version'
|
2
4
|
require 'truemail/core'
|
3
5
|
require 'truemail/configuration'
|
4
6
|
require 'truemail/validator'
|
5
7
|
|
6
8
|
module Truemail
|
7
|
-
INCOMPLETE_CONFIG = 'verifier_email is required parameter'
|
8
|
-
NOT_CONFIGURED = 'use Truemail.configure before'
|
9
|
+
INCOMPLETE_CONFIG = 'verifier_email is required parameter'
|
10
|
+
NOT_CONFIGURED = 'use Truemail.configure before'
|
9
11
|
|
10
12
|
class << self
|
11
13
|
def configuration
|
data/lib/truemail/core.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Truemail
|
2
4
|
module Validate
|
3
5
|
class Base
|
4
6
|
attr_reader :result
|
5
7
|
|
6
|
-
def initialize(result)
|
7
|
-
@result = result
|
8
|
-
end
|
9
|
-
|
10
8
|
def self.check(result)
|
11
9
|
new(result).run
|
12
10
|
end
|
13
11
|
|
12
|
+
def initialize(result)
|
13
|
+
@result = result
|
14
|
+
end
|
15
|
+
|
14
16
|
private
|
15
17
|
|
16
18
|
def success(condition)
|
data/lib/truemail/validate/mx.rb
CHANGED
@@ -1,22 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Truemail
|
2
4
|
module Validate
|
3
5
|
class Mx < Truemail::Validate::Base
|
4
6
|
require 'resolv'
|
5
7
|
|
6
|
-
ERROR = 'mx records not found'
|
8
|
+
ERROR = 'mx records not found'
|
7
9
|
|
8
10
|
def run
|
9
11
|
return false unless Truemail::Validate::Regex.check(result)
|
10
12
|
result.domain = result.email[Truemail::RegexConstant::REGEX_EMAIL_PATTERN, 3]
|
11
|
-
return true if success(!result.mail_servers.push(*mx_records
|
13
|
+
return true if success(!result.mail_servers.push(*mx_records).empty?)
|
12
14
|
add_error(Truemail::Validate::Mx::ERROR)
|
13
15
|
false
|
14
16
|
end
|
15
17
|
|
16
18
|
private
|
17
19
|
|
18
|
-
def mx_records
|
19
|
-
mx_records = Resolv::DNS.open { |dns| dns.getresources(domain, Resolv::DNS::Resource::IN::MX) }
|
20
|
+
def mx_records
|
21
|
+
mx_records = Resolv::DNS.open { |dns| dns.getresources(result.domain, Resolv::DNS::Resource::IN::MX) }
|
20
22
|
mx_records.sort_by(&:preference).map { |mx_record| mx_record.exchange.to_s }
|
21
23
|
end
|
22
24
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Truemail
|
2
4
|
module Validate
|
3
5
|
class Regex < Truemail::Validate::Base
|
4
|
-
ERROR = 'email does not match the regular expression'
|
6
|
+
ERROR = 'email does not match the regular expression'
|
5
7
|
|
6
8
|
def run
|
7
9
|
return true if success(Truemail.configuration.email_pattern.match?(result.email))
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Truemail
|
2
4
|
module Validate
|
3
5
|
class Smtp < Truemail::Validate::Base
|
4
|
-
ERROR = 'smtp error'
|
6
|
+
ERROR = 'smtp error'
|
5
7
|
|
6
8
|
attr_reader :smtp_results
|
7
9
|
|
@@ -38,7 +40,7 @@ module Truemail
|
|
38
40
|
end
|
39
41
|
|
40
42
|
def success_response?
|
41
|
-
|
43
|
+
smtp_results.map(&:response).any?(&:rcptto)
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
@@ -1,22 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Truemail
|
2
4
|
module Validate
|
3
5
|
class Smtp
|
4
|
-
|
5
|
-
CONNECTION_TIMEOUT_ERROR = 'connection timed out'.freeze
|
6
|
-
RESPONSE_TIMEOUT_ERROR = 'server response timeout'.freeze
|
7
|
-
CONNECTION_DROPPED = 'server dropped connection after response'.freeze
|
8
|
-
|
9
|
-
Request = Struct.new(:host, :email, :response, keyword_init: true) do
|
6
|
+
class Request
|
10
7
|
require 'net/smtp'
|
11
8
|
|
12
|
-
|
13
|
-
|
9
|
+
SMTP_PORT = 25
|
10
|
+
CONNECTION_TIMEOUT_ERROR = 'connection timed out'
|
11
|
+
RESPONSE_TIMEOUT_ERROR = 'server response timeout'
|
12
|
+
CONNECTION_DROPPED = 'server dropped connection after response'
|
13
|
+
|
14
|
+
attr_reader :host, :email, :response
|
15
|
+
|
16
|
+
def initialize(host:, email:)
|
17
|
+
@host = host
|
18
|
+
@email = email
|
19
|
+
@response = Truemail::Validate::Smtp::Response.new
|
14
20
|
end
|
15
21
|
|
16
22
|
def check_port
|
17
23
|
Timeout.timeout(configuration.connection_timeout) do
|
18
24
|
return response.port_opened =
|
19
|
-
!TCPSocket.new(host, Truemail::Validate::Smtp::SMTP_PORT).close
|
25
|
+
!TCPSocket.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).close
|
20
26
|
end
|
21
27
|
rescue Timeout::Error
|
22
28
|
response.port_opened = false
|
@@ -34,11 +40,11 @@ module Truemail
|
|
34
40
|
private
|
35
41
|
|
36
42
|
def configuration
|
37
|
-
Truemail.configuration.dup.freeze
|
43
|
+
@configuration ||= Truemail.configuration.dup.freeze
|
38
44
|
end
|
39
45
|
|
40
46
|
def session
|
41
|
-
Net::SMTP.new(host, Truemail::Validate::Smtp::SMTP_PORT).tap do |settings|
|
47
|
+
Net::SMTP.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).tap do |settings|
|
42
48
|
settings.open_timeout = configuration.connection_timeout
|
43
49
|
settings.read_timeout = configuration.response_timeout
|
44
50
|
end
|
@@ -46,9 +52,9 @@ module Truemail
|
|
46
52
|
|
47
53
|
def compose_from(error)
|
48
54
|
case error.class.name
|
49
|
-
when 'Net::OpenTimeout' then Truemail::Validate::Smtp::CONNECTION_TIMEOUT_ERROR
|
50
|
-
when 'Net::ReadTimeout' then Truemail::Validate::Smtp::RESPONSE_TIMEOUT_ERROR
|
51
|
-
when 'EOFError' then Truemail::Validate::Smtp::CONNECTION_DROPPED
|
55
|
+
when 'Net::OpenTimeout' then Truemail::Validate::Smtp::Request::CONNECTION_TIMEOUT_ERROR
|
56
|
+
when 'Net::ReadTimeout' then Truemail::Validate::Smtp::Request::RESPONSE_TIMEOUT_ERROR
|
57
|
+
when 'EOFError' then Truemail::Validate::Smtp::Request::CONNECTION_DROPPED
|
52
58
|
else error.message
|
53
59
|
end
|
54
60
|
end
|
@@ -73,8 +79,8 @@ module Truemail
|
|
73
79
|
end
|
74
80
|
|
75
81
|
def smtp_handshakes(smtp_request, smtp_response)
|
76
|
-
|
77
|
-
|
82
|
+
session_data.all? do |method, value|
|
83
|
+
smtp_response.public_send(:"#{method}=", smtp_resolver(smtp_request, method, value))
|
78
84
|
end
|
79
85
|
end
|
80
86
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Truemail
|
2
4
|
module Validate
|
3
5
|
class Smtp
|
4
|
-
RESPONSE_ATTRS = %i[port_opened connection helo mailfrom rcptto errors]
|
6
|
+
RESPONSE_ATTRS = %i[port_opened connection helo mailfrom rcptto errors].freeze
|
5
7
|
|
6
8
|
Response = Struct.new(*RESPONSE_ATTRS, keyword_init: true) do
|
7
9
|
def initialize(errors: {}, **args)
|
data/lib/truemail/validator.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Truemail
|
2
4
|
class Validator
|
3
5
|
RESULT_ATTRS = %i[success email domain mail_servers errors smtp_debug].freeze
|
@@ -14,7 +16,8 @@ module Truemail
|
|
14
16
|
|
15
17
|
def initialize(email, with: :smtp)
|
16
18
|
raise ArgumentError.new(with, :argument) unless VALIDATION_TYPES.include?(with)
|
17
|
-
@validation_type
|
19
|
+
@validation_type = select_validation_type(email, with)
|
20
|
+
@result = Result.new(email: email)
|
18
21
|
end
|
19
22
|
|
20
23
|
def run
|
@@ -26,7 +29,7 @@ module Truemail
|
|
26
29
|
|
27
30
|
def select_validation_type(email, current_validation_type)
|
28
31
|
domain = email[Truemail::RegexConstant::REGEX_EMAIL_PATTERN, 3]
|
29
|
-
Truemail.configuration
|
32
|
+
Truemail.configuration.validation_type_by_domain[domain] || current_validation_type
|
30
33
|
end
|
31
34
|
end
|
32
35
|
end
|
data/lib/truemail/version.rb
CHANGED