truemail 0.1.1.2 → 0.1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Gem Version](https://badge.fury.io/rb/truemail.svg)](https://badge.fury.io/rb/truemail) [![CircleCI](https://circleci.com/gh/rubygarage/truemail/tree/
|
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) [![Gem Version](https://badge.fury.io/rb/truemail.svg)](https://badge.fury.io/rb/truemail) [![CircleCI](https://circleci.com/gh/rubygarage/truemail/tree/develop.svg?style=svg)](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