truemail 1.8.0 → 2.0.1

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.
@@ -5,6 +5,7 @@ require_relative 'truemail/core'
5
5
  module Truemail
6
6
  INCOMPLETE_CONFIG = 'verifier_email is required parameter'
7
7
  NOT_CONFIGURED = 'use Truemail.configure before or pass custom configuration'
8
+ INVALID_TYPE = 'email should be a String'
8
9
 
9
10
  class << self
10
11
  def configuration(&block)
@@ -25,10 +26,12 @@ module Truemail
25
26
  end
26
27
 
27
28
  def validate(email, custom_configuration: nil, **options)
29
+ check_argument_type(email)
28
30
  Truemail::Validator.new(email, configuration: determine_configuration(custom_configuration), **options).run
29
31
  end
30
32
 
31
33
  def valid?(email, **options)
34
+ check_argument_type(email)
32
35
  validate(email, **options).result.valid?
33
36
  end
34
37
 
@@ -38,8 +41,12 @@ module Truemail
38
41
 
39
42
  private
40
43
 
41
- def raise_unless(condition, message)
42
- raise Truemail::ConfigurationError, message unless condition
44
+ def raise_unless(condition, message, error_class = Truemail::ConfigurationError)
45
+ raise error_class, message unless condition
46
+ end
47
+
48
+ def check_argument_type(argument)
49
+ raise_unless(argument.is_a?(String), Truemail::INVALID_TYPE, Truemail::TypeError)
43
50
  end
44
51
 
45
52
  def determine_configuration(custom_configuration)
@@ -3,7 +3,7 @@
3
3
  module Truemail
4
4
  module Audit
5
5
  class Dns < Truemail::Audit::Base
6
- VERIFIER_DOMAIN_NOT_REFER = 'a record of verifier domain not refers to current host ip address'
6
+ VERIFIER_DOMAIN_NOT_REFER = 'A-record of verifier domain not refers to current host ip address'
7
7
 
8
8
  def run
9
9
  return if verifier_domain_refer_to_current_host_ip?
@@ -3,8 +3,8 @@
3
3
  module Truemail
4
4
  module Audit
5
5
  class Ptr < Truemail::Audit::Base
6
- PTR_NOT_FOUND = 'ptr record for current host ip address was not found'
7
- PTR_NOT_REFER = 'ptr record does not reference to current verifier domain'
6
+ PTR_NOT_FOUND = 'PTR-record for current host ip address was not found'
7
+ PTR_NOT_REFER = 'PTR-record does not reference to current verifier domain'
8
8
 
9
9
  def run
10
10
  return add_warning(Truemail::Audit::Ptr::PTR_NOT_FOUND) if ptr_records.empty?
@@ -1,15 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- class Auditor
4
+ class Auditor < Truemail::Executor
5
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
9
9
  end
10
10
 
11
- attr_reader :result
12
-
13
11
  def initialize(configuration:)
14
12
  @result = Truemail::Auditor::Result.new(configuration: configuration)
15
13
  end
@@ -18,5 +16,9 @@ module Truemail
18
16
  Truemail::Audit::Ip.check(result)
19
17
  self
20
18
  end
19
+
20
+ def as_json
21
+ Truemail::Log::Serializer::AuditorJson.call(self)
22
+ end
21
23
  end
22
24
  end
@@ -6,6 +6,7 @@ module Truemail
6
6
  DEFAULT_RESPONSE_TIMEOUT = 2
7
7
  DEFAULT_CONNECTION_ATTEMPTS = 2
8
8
  DEFAULT_VALIDATION_TYPE = :smtp
9
+ DEFAULT_LOGGER_OPTIONS = { tracking_event: :error, stdout: false, log_absolute_path: nil }.freeze
9
10
 
10
11
  attr_reader :email_pattern,
11
12
  :smtp_error_body_pattern,
@@ -71,7 +72,8 @@ module Truemail
71
72
  end
72
73
  end
73
74
 
74
- def logger=(tracking_event: :error, stdout: false, log_absolute_path: nil)
75
+ def logger=(options)
76
+ tracking_event, stdout, log_absolute_path = logger_options(options)
75
77
  valid_event = Truemail::Log::Event::TRACKING_EVENTS.key?(tracking_event)
76
78
  stdout_only = stdout && log_absolute_path.nil?
77
79
  file_only = log_absolute_path.is_a?(String)
@@ -109,7 +111,7 @@ module Truemail
109
111
  end
110
112
 
111
113
  def validate_arguments(argument, method)
112
- constant = Truemail::RegexConstant.const_get("regex_#{method[/\A.+_(.+)\=\z/, 1]}_pattern".upcase)
114
+ constant = Truemail::RegexConstant.const_get("regex_#{method[/\A.+_(.+)=\z/, 1]}_pattern".upcase)
113
115
  raise_unless(argument, method, constant.match?(argument.to_s))
114
116
  end
115
117
 
@@ -140,5 +142,9 @@ module Truemail
140
142
  check_validation_type(validation_type)
141
143
  end
142
144
  end
145
+
146
+ def logger_options(current_options)
147
+ Truemail::Configuration::DEFAULT_LOGGER_OPTIONS.merge(current_options).values
148
+ end
143
149
  end
144
150
  end
@@ -4,12 +4,14 @@ module Truemail
4
4
  require_relative '../truemail/version'
5
5
  require_relative '../truemail/configuration'
6
6
  require_relative '../truemail/worker'
7
+ require_relative '../truemail/executor'
7
8
  require_relative '../truemail/wrapper'
8
9
  require_relative '../truemail/auditor'
9
10
  require_relative '../truemail/validator'
10
11
  require_relative '../truemail/logger'
11
12
 
12
13
  ConfigurationError = Class.new(StandardError)
14
+ TypeError = Class.new(StandardError)
13
15
 
14
16
  ArgumentError = Class.new(StandardError) do
15
17
  def initialize(arg_value, arg_name)
@@ -29,8 +31,8 @@ module Truemail
29
31
  end
30
32
 
31
33
  module RegexConstant
32
- REGEX_DOMAIN = /[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}/i.freeze
33
- REGEX_EMAIL_PATTERN = /(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@(#{REGEX_DOMAIN})\z)/.freeze
34
+ REGEX_DOMAIN = /[\p{L}0-9]+([\-.]{1}[\p{L}0-9]+)*\.\p{L}{2,63}/i.freeze
35
+ REGEX_EMAIL_PATTERN = /(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|.|+]*)@(#{REGEX_DOMAIN})\z)/.freeze
34
36
  REGEX_DOMAIN_PATTERN = /(?=\A.{4,255}\z)(\A#{REGEX_DOMAIN}\z)/.freeze
35
37
  REGEX_DOMAIN_FROM_EMAIL = /\A.+@(.+)\z/.freeze
36
38
  REGEX_SMTP_ERROR_BODY_PATTERN = /(?=.*550)(?=.*(user|account|customer|mailbox)).*/i.freeze
@@ -56,7 +58,9 @@ module Truemail
56
58
  module Log
57
59
  require_relative '../truemail/log/event'
58
60
  require_relative '../truemail/log/serializer/base'
59
- require_relative '../truemail/log/serializer/text'
60
- require_relative '../truemail/log/serializer/json'
61
+ require_relative '../truemail/log/serializer/auditor_json'
62
+ require_relative '../truemail/log/serializer/validator_base'
63
+ require_relative '../truemail/log/serializer/validator_text'
64
+ require_relative '../truemail/log/serializer/validator_json'
61
65
  end
62
66
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ class Executor
5
+ attr_reader :result
6
+
7
+ def run; end
8
+
9
+ def as_json; end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Log
5
+ module Serializer
6
+ class AuditorJson < Truemail::Log::Serializer::Base
7
+ def serialize
8
+ result.to_json
9
+ end
10
+
11
+ private
12
+
13
+ def result
14
+ @result ||=
15
+ {
16
+ date: Time.now,
17
+ current_host_ip: executor_result.current_host_ip,
18
+ warnings: warnings(executor_result.warnings),
19
+ configuration: configuration
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -4,47 +4,35 @@ module Truemail
4
4
  module Log
5
5
  module Serializer
6
6
  class Base
7
+ require 'json'
8
+
7
9
  DEFAULT_GEM_VALUE = 'default gem value'
8
10
 
9
- def self.call(validator_instance)
10
- new(validator_instance).serialize
11
+ def self.call(executor_instance)
12
+ new(executor_instance).serialize
11
13
  end
12
14
 
13
- def initialize(validator_instance)
14
- @validation_type = validator_instance.validation_type
15
- @validation_result = validator_instance.result
16
- @validation_configuration = validation_result.configuration
15
+ def initialize(executor_instance)
16
+ @executor_result = executor_instance.result
17
+ @executor_configuration = executor_result.configuration
17
18
  end
18
19
 
19
20
  def serialize; end
20
21
 
21
22
  private
22
23
 
23
- attr_reader :validation_type, :validation_result, :validation_configuration
24
+ attr_reader :executor_result, :executor_configuration
24
25
 
25
- def errors
26
- validation_errors = validation_result.errors
27
- return if validation_errors.empty?
28
- validation_errors
26
+ def errors(executor_result_target)
27
+ return if executor_result_target.empty?
28
+ executor_result_target
29
29
  end
30
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
31
+ alias warnings errors
44
32
 
45
33
  %i[validation_type_by_domain whitelisted_domains blacklisted_domains].each do |method|
46
34
  define_method(method) do
47
- value = validation_configuration.public_send(method)
35
+ value = executor_configuration.public_send(method)
48
36
  return if value.empty?
49
37
  value
50
38
  end
@@ -52,7 +40,7 @@ module Truemail
52
40
 
53
41
  %i[email_pattern smtp_error_body_pattern].each do |method|
54
42
  define_method(method) do
55
- value = validation_configuration.public_send(method)
43
+ value = executor_configuration.public_send(method)
56
44
  default_pattern = Truemail::RegexConstant.const_get(
57
45
  (method.eql?(:email_pattern) ? :regex_email_pattern : :regex_smtp_error_body_pattern).upcase
58
46
  )
@@ -64,28 +52,15 @@ module Truemail
64
52
  def configuration
65
53
  {
66
54
  validation_type_by_domain: validation_type_by_domain,
67
- whitelist_validation: validation_configuration.whitelist_validation,
55
+ whitelist_validation: executor_configuration.whitelist_validation,
68
56
  whitelisted_domains: whitelisted_domains,
69
57
  blacklisted_domains: blacklisted_domains,
70
- not_rfc_mx_lookup_flow: validation_configuration.not_rfc_mx_lookup_flow,
71
- smtp_safe_check: validation_configuration.smtp_safe_check,
58
+ not_rfc_mx_lookup_flow: executor_configuration.not_rfc_mx_lookup_flow,
59
+ smtp_safe_check: executor_configuration.smtp_safe_check,
72
60
  email_pattern: email_pattern,
73
61
  smtp_error_body_pattern: smtp_error_body_pattern
74
62
  }
75
63
  end
76
-
77
- def result
78
- @result ||=
79
- {
80
- date: Time.now,
81
- email: validation_result.email,
82
- validation_type: validation_type,
83
- success: validation_result.success,
84
- errors: errors,
85
- smtp_debug: smtp_debug,
86
- configuration: configuration
87
- }
88
- end
89
64
  end
90
65
  end
91
66
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Log
5
+ module Serializer
6
+ class ValidatorBase < Truemail::Log::Serializer::Base
7
+ def initialize(executor_instance)
8
+ @validation_type = executor_instance.validation_type
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :validation_type
15
+
16
+ def smtp_debug
17
+ validation_smtp_debug = executor_result.smtp_debug
18
+ return unless validation_smtp_debug
19
+ validation_smtp_debug.map do |smtp_request|
20
+ smtp_response = smtp_request.response
21
+ {
22
+ mail_host: smtp_request.host,
23
+ port_opened: smtp_response.port_opened,
24
+ connection: smtp_response.connection,
25
+ errors: smtp_response.errors
26
+ }
27
+ end
28
+ end
29
+
30
+ def result
31
+ @result ||=
32
+ {
33
+ date: Time.now,
34
+ email: executor_result.email,
35
+ validation_type: validation_type,
36
+ success: executor_result.success,
37
+ errors: errors(executor_result.errors),
38
+ smtp_debug: smtp_debug,
39
+ configuration: configuration
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -3,7 +3,7 @@
3
3
  module Truemail
4
4
  module Log
5
5
  module Serializer
6
- class Json < Truemail::Log::Serializer::Base
6
+ class ValidatorJson < Truemail::Log::Serializer::ValidatorBase
7
7
  def serialize
8
8
  result.to_json
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Truemail
4
4
  module Log
5
5
  module Serializer
6
- class Text < Truemail::Log::Serializer::Base
6
+ class ValidatorText < Truemail::Log::Serializer::ValidatorBase
7
7
  ATTEMPT = 'ATTEMPT #'
8
8
 
9
9
  def serialize
@@ -30,7 +30,7 @@ module Truemail
30
30
 
31
31
  def collection_printer(collection)
32
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"
33
+ "\n#{Truemail::Log::Serializer::ValidatorText::ATTEMPT}#{index + 1}:\n#{item}\n"
34
34
  end
35
35
  end
36
36
 
@@ -15,7 +15,7 @@ module Truemail
15
15
  def push(validator_instance)
16
16
  current_event = Truemail::Log::Event.new(event, validator_instance)
17
17
  return unless current_event.valid?
18
- create_logs(current_event.log_level, Truemail::Log::Serializer::Text.call(validator_instance))
18
+ create_logs(current_event.log_level, Truemail::Log::Serializer::ValidatorText.call(validator_instance))
19
19
  end
20
20
 
21
21
  private
@@ -31,8 +31,8 @@ module Truemail
31
31
  end
32
32
 
33
33
  def run
34
- session.start do |smtp_request|
35
- response.connection = true
34
+ session.start(configuration.verifier_domain) do |smtp_request|
35
+ response.connection = response.helo = true
36
36
  smtp_handshakes(smtp_request, response)
37
37
  end
38
38
  rescue => error
@@ -83,7 +83,6 @@ module Truemail
83
83
 
84
84
  def session_data
85
85
  {
86
- helo: configuration.verifier_domain,
87
86
  mailfrom: configuration.verifier_email,
88
87
  rcptto: email
89
88
  }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- class Validator
4
+ class Validator < Truemail::Executor
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
 
@@ -16,9 +16,9 @@ module Truemail
16
16
  alias_method :valid?, :success
17
17
  end
18
18
 
19
- attr_reader :validation_type, :result
19
+ attr_reader :validation_type
20
20
 
21
- def initialize(email, with: nil, configuration:)
21
+ def initialize(email, configuration:, with: nil)
22
22
  with ||= configuration.default_validation_type
23
23
  raise Truemail::ArgumentError.new(with, :argument) unless Truemail::Validator::VALIDATION_TYPES.include?(with)
24
24
  @result = Truemail::Validator::Result.new(email: email, configuration: configuration)
@@ -33,7 +33,7 @@ module Truemail
33
33
  end
34
34
 
35
35
  def as_json
36
- Truemail::Log::Serializer::Json.call(self)
36
+ Truemail::Log::Serializer::ValidatorJson.call(self)
37
37
  end
38
38
 
39
39
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- VERSION = '1.8.0'
4
+ VERSION = '2.0.1'
5
5
  end
@@ -13,9 +13,17 @@ Gem::Specification.new do |spec|
13
13
  spec.summary = %(truemail)
14
14
  spec.description = %(Configurable framework agnostic plain Ruby email validator. Verify email via Regex, DNS and SMTP.)
15
15
 
16
- spec.homepage = 'https://github.com/rubygarage/truemail'
16
+ spec.homepage = 'https://github.com/truemail-rb/truemail'
17
17
  spec.license = 'MIT'
18
18
 
19
+ spec.metadata = {
20
+ 'homepage_uri' => 'https://truemail-rb.org',
21
+ 'changelog_uri' => 'https://github.com/truemail-rb/truemail/blob/master/CHANGELOG.md',
22
+ 'source_code_uri' => 'https://github.com/truemail-rb/truemail',
23
+ 'documentation_uri' => 'https://truemail-rb.org/truemail-gem',
24
+ 'bug_tracker_uri' => 'https://github.com/truemail-rb/truemail/issues'
25
+ }
26
+
19
27
  spec.required_ruby_version = '>= 2.5.0'
20
28
 
21
29
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
@@ -26,18 +34,18 @@ Gem::Specification.new do |spec|
26
34
  spec.add_runtime_dependency 'simpleidn', '~> 0.1.1'
27
35
 
28
36
  spec.add_development_dependency 'bundler', '~> 1.16'
29
- spec.add_development_dependency 'bundler-audit', '~> 0.6.1'
37
+ spec.add_development_dependency 'bundler-audit', '~> 0.7.0.1'
30
38
  spec.add_development_dependency 'fasterer', '~> 0.8.3'
31
- spec.add_development_dependency 'ffaker', '~> 2.14'
39
+ spec.add_development_dependency 'ffaker', '~> 2.17'
32
40
  spec.add_development_dependency 'json_matchers', '~> 0.11.1'
33
- spec.add_development_dependency 'overcommit', '~> 0.53.0'
41
+ spec.add_development_dependency 'overcommit', '~> 0.57.0'
34
42
  spec.add_development_dependency 'pry-byebug', '~> 3.9'
35
43
  spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.1'
36
- spec.add_development_dependency 'reek', '~> 6.0'
44
+ spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.2'
37
45
  spec.add_development_dependency 'rspec', '~> 3.9'
38
- spec.add_development_dependency 'rubocop', '~> 0.79.0'
39
- spec.add_development_dependency 'rubocop-performance', '~> 1.5', '>= 1.5.2'
40
- spec.add_development_dependency 'rubocop-rspec', '~> 1.39'
46
+ spec.add_development_dependency 'rubocop', '~> 0.93.1'
47
+ spec.add_development_dependency 'rubocop-performance', '~> 1.8', '>= 1.8.1'
48
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.43', '>= 1.43.2'
41
49
  spec.add_development_dependency 'simplecov', '~> 0.17.1'
42
- spec.add_development_dependency 'truemail-rspec', '~> 0.1.2'
50
+ spec.add_development_dependency 'truemail-rspec', '~> 0.2.1'
43
51
  end