Class: Email::Verification::Verifier

Inherits:
Object
  • Object
show all
Defined in:
lib/email/verification/verifier.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mode: :interactive) ⇒ Verifier

Returns a new instance of Verifier.



6
7
8
9
10
11
# File 'lib/email/verification/verifier.rb', line 6

def initialize(mode: :interactive)
  self.mode             =   mode&.to_sym
  self.cli              =   self.mode.eql?(:interactive) ? ::HighLine.new : nil
  
  set_mapping
end

Instance Attribute Details

#cliObject

Returns the value of attribute cli.



4
5
6
# File 'lib/email/verification/verifier.rb', line 4

def cli
  @cli
end

#mappingObject

Returns the value of attribute mapping.



4
5
6
# File 'lib/email/verification/verifier.rb', line 4

def mapping
  @mapping
end

#modeObject

Returns the value of attribute mode.



4
5
6
# File 'lib/email/verification/verifier.rb', line 4

def mode
  @mode
end

Instance Method Details

#capture_cli_input(email) ⇒ Object



102
103
104
# File 'lib/email/verification/verifier.rb', line 102

def capture_cli_input(email)
  self.cli.ask("Please enter the code or URL sent to #{email}:")&.strip
end

#determine_email_service(email_address) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/email/verification/verifier.rb', line 83

def determine_email_service(email_address)
  email_domain              =   email_address&.split('@')&.last&.strip
  
  detected_service          =   catch(:service_detection) do
    self.mapping.each do |service, domains|
      if domains.include?(email_domain)
        detected_service    =   service.to_sym
        throw :service_detection, detected_service
      end
    end unless email_domain.to_s.empty?
  end
  
  return detected_service
end

#perform_retrieval(verifier, email:, password: nil, mailboxes: %w(Inbox),, count: :all, settings: {}, proxy: nil, wait: 3, retries: 3) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/email/verification/verifier.rb', line 49

def perform_retrieval(verifier, email:, password: nil, mailboxes: %w(Inbox), count: :all, settings: {}, proxy: nil, wait: 3, retries: 3)
  result        =   nil
  
  if password.to_s.empty? && self.mode.eql?(:interactive)
    puts "[Email::Verification::Verifier] - #{Time.now}: Password wasn't provided, you need to manually retrieve the code or URL from the account #{email}."
    result      =   capture_cli_input(email)
  elsif password.to_s.empty? && self.mode.eql?(:automatic)
    raise ::Email::Verification::Errors::InvalidCredentialsError.new("Password wasn't provided for #{email} and automatic mode is enabled. Please provide a password or switch to interactive mode.")
  else
    if settings_provided?(settings) && !wait.nil? && !retries.nil?
      result    =   retrieve_with_retries(verifier, email: email, password: password, mailboxes: mailboxes, count: count, settings: settings, proxy: proxy, wait: wait, retries: retries)
    else
      result    =   verifier.retrieve_verification_code(email: email, password: password, mailboxes: mailboxes, count: count, settings: settings, proxy: proxy)
    end
  end
  
  return result
end

#retrieve_verification_code(email:, password:, mailboxes: %w(Inbox),, count: :all, settings: {}, proxy: nil, wait: 3, retries: 3) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/email/verification/verifier.rb', line 21

def retrieve_verification_code(email:, password:, mailboxes: %w(Inbox), count: :all, settings: {}, proxy: nil, wait: 3, retries: 3)
  service       =   determine_email_service(email)
  result        =   nil
  
  begin
    result      =   case service
      when :gmail
        perform_retrieval(::Email::Verification::Gmail.new, email: email, password: password, mailboxes: mailboxes, count: count, settings: settings, proxy: proxy, wait: wait, retries: retries)
      when :hotmail
        perform_retrieval(::Email::Verification::Hotmail.new, email: email, password: password, mailboxes: mailboxes, count: count, settings: settings, proxy: proxy, wait: wait, retries: retries)
      when :protonmail, :tutanota
        if self.mode.eql?(:interactive)
          puts "[Email::Verification::Verifier] - #{Time.now}: You're using an email account that doesn't have support for POP3 or IMAP. You have to manually retrieve the code or URL from the account and post it below."
          capture_cli_input(email)
        else
          raise ::Email::Verification::Errors::ImapNotSupportedError.new("#{service} doesn't have support for IMAP or POP3 retrieval! Please switch to interactive mode or use another provider!")
        end
      else
        nil
    end
  
  rescue Net::HTTPClientException => e
    raise ::Email::Verification::Errors::InvalidProxyError.new("Proxy isn't working, please retry with a new proxy!")
  end
  
  return result
end

#retrieve_with_retries(verifier, email:, password: nil, mailboxes: %w(Inbox),, count: :all, settings: {}, proxy: nil, wait: 3, retries: 3) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/email/verification/verifier.rb', line 68

def retrieve_with_retries(verifier, email:, password: nil, mailboxes: %w(Inbox), count: :all, settings: {}, proxy: nil, wait: 3, retries: 3)
  result        =   nil
  
  begin
    result      =   verifier.retrieve_verification_code(email: email, password: password, mailboxes: mailboxes, count: count, settings: settings, proxy: proxy)
    
    if result.to_s.empty?
      sleep wait if wait
      retries  -=  1
    end
  end while result.to_s.empty? && retries > 0
  
  return result
end

#set_mappingObject



13
14
15
16
17
18
19
# File 'lib/email/verification/verifier.rb', line 13

def set_mapping
  mappings_path         =   File.join(File.dirname(__FILE__), "data/domains.yml")
  
  if ::File.exists?(mappings_path)
    self.mapping        =   YAML.load_file(mappings_path)
  end
end

#settings_provided?(settings = {}) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/email/verification/verifier.rb', line 98

def settings_provided?(settings = {})
  settings && !settings.empty?
end