lib/truemail/configuration.rb
# frozen_string_literal: true
module Truemail
class Configuration
DEFAULT_CONNECTION_TIMEOUT = 2
DEFAULT_RESPONSE_TIMEOUT = 2
DEFAULT_CONNECTION_ATTEMPTS = 2
DEFAULT_VALIDATION_TYPE = :smtp
DEFAULT_SMTP_PORT = 25
DEFAULT_LOGGER_OPTIONS = {
tracking_event: :error,
stdout: false,
log_absolute_path: nil
}.freeze
SETTERS = %i[
email_pattern
smtp_error_body_pattern
connection_timeout
response_timeout
connection_attempts
whitelisted_emails
blacklisted_emails
whitelisted_domains
blacklisted_domains
blacklisted_mx_ip_addresses
dns
smtp_port
].freeze
attr_reader :verifier_email,
:verifier_domain,
:default_validation_type,
:validation_type_by_domain,
:logger,
*Truemail::Configuration::SETTERS
attr_accessor :whitelist_validation, :not_rfc_mx_lookup_flow, :smtp_fail_fast, :smtp_safe_check
def initialize(&block)
instance_initializer.each do |instace_variable, value|
instance_variable_set(:"@#{instace_variable}", value)
end
tap(&block) if block
end
def verifier_email=(email)
validate_arguments(email, __method__)
@verifier_email = email.downcase
default_verifier_domain
end
def verifier_domain=(domain)
validate_arguments(domain, __method__)
@verifier_domain = domain.downcase
end
def default_validation_type=(argument)
raise_unless(argument, __method__, argument.is_a?(::Symbol) && Truemail::Validator::VALIDATION_TYPES.include?(argument))
@default_validation_type = argument
end
def validation_type_for=(settings)
validate_validation_type(settings)
validation_type_by_domain.merge!(settings)
end
def argument_consistent?(method, argument)
case argument
when ::Array then items_match_regex?(argument, regex_by_method(method))
when ::Integer then argument.positive?
when ::Regexp then true
end
end
Truemail::Configuration::SETTERS.each do |method|
define_method(:"#{method}=") do |argument|
raise_unless(argument, __method__, argument_consistent?(method, argument))
instance_variable_set(:"@#{method}", argument)
end
end
def logger=(options)
raise_unless(options, __method__, options.is_a?(::Hash))
@logger = Truemail::Logger::Builder.call(Truemail::Configuration::DEFAULT_LOGGER_OPTIONS, **options)
end
def complete?
!!verifier_email
end
private
def instance_initializer # rubocop:disable Metrics/MethodLength
{
email_pattern: Truemail::RegexConstant::REGEX_EMAIL_PATTERN,
smtp_error_body_pattern: Truemail::RegexConstant::REGEX_SMTP_ERROR_BODY_PATTERN,
connection_timeout: Truemail::Configuration::DEFAULT_CONNECTION_TIMEOUT,
response_timeout: Truemail::Configuration::DEFAULT_RESPONSE_TIMEOUT,
connection_attempts: Truemail::Configuration::DEFAULT_CONNECTION_ATTEMPTS,
default_validation_type: Truemail::Configuration::DEFAULT_VALIDATION_TYPE,
smtp_port: Truemail::Configuration::DEFAULT_SMTP_PORT,
validation_type_by_domain: {},
whitelisted_emails: [],
blacklisted_emails: [],
whitelisted_domains: [],
whitelist_validation: false,
blacklisted_domains: [],
blacklisted_mx_ip_addresses: [],
dns: [],
not_rfc_mx_lookup_flow: false,
smtp_fail_fast: false,
smtp_safe_check: false
}
end
def raise_unless(argument_context, argument_name, condition)
raise Truemail::ArgumentError.new(argument_context, argument_name) unless condition
end
def match_regex?(regex_pattern, object)
regex_pattern.match?(object.to_s)
end
def validate_arguments(argument, method)
regex_pattern = Truemail::RegexConstant.const_get("regex_#{method[/\A.+_(.+)=\z/, 1]}_pattern".upcase)
raise_unless(argument, method, match_regex?(regex_pattern, argument))
end
def default_verifier_domain
self.verifier_domain ||= verifier_email[Truemail::RegexConstant::REGEX_EMAIL_PATTERN, 3]
end
def regex_by_method(method)
return Truemail::RegexConstant::REGEX_IP_ADDRESS_PATTERN if method.eql?(:blacklisted_mx_ip_addresses)
return Truemail::RegexConstant::REGEX_DNS_SERVER_ADDRESS_PATTERN if method.eql?(:dns)
return Truemail::RegexConstant::REGEX_SIMPLE_EMAIL_PATTERN if method[/email/]
Truemail::RegexConstant::REGEX_DOMAIN_PATTERN
end
def items_match_regex?(items, regex_pattern)
items.all? { |item| match_regex?(regex_pattern, item) }
end
def check_validation_type(validation_type)
raise_unless(validation_type, 'validation type', Truemail::Validator::VALIDATION_TYPES.include?(validation_type))
end
def validate_validation_type(settings)
raise_unless(settings, 'hash with settings', settings.is_a?(::Hash))
settings.each do |domain, validation_type|
raise_unless(domain, 'domain', match_regex?(Truemail::RegexConstant::REGEX_DOMAIN_PATTERN, domain))
check_validation_type(validation_type)
end
end
end
end