module Client

This module provides the common functionality that will be needed for local and cloud module. @client_type defines if the gem is being used for local-lockbox or cloud-version.

Attributes

downloaded[RW]
message_ids[RW]
total_emails[RW]

Public Instance Methods

depcrecated_encrypt(data) click to toggle source
# File lib/client.rb, line 182
def depcrecated_encrypt(data)
  cipher = OpenSSL::Cipher::AES.new(256, :CFB)
  cipher.encrypt

  yml_config = config

  key_iv_exists = (yml_config['key'] && yml_config['iv']) ? (!yml_config['key'].empty? && !yml_config['iv'].empty? ) : false

  if key_iv_exists
    # this condition must be true for cloud version
    cipher.key = Base64.decode64(File.read(yml_config['key']))
    cipher.iv = Base64.decode64(File.read(yml_config['iv']))
  else
    cipher.key = key = cipher.random_key
    cipher.iv = iv = cipher.random_iv

    key_path, iv_path = save_aes_key_iv(key, iv)

    yml_config['key'] = key_path
    yml_config['iv'] = iv_path

    update_config(yml_config)
  end

  encrypted = cipher.update(data)
  Base64.encode64(encrypted)
end
encrypt(data) click to toggle source
# File lib/client.rb, line 178
def encrypt(data)
  Base64.encode64(data)
end
errors() click to toggle source
# File lib/client.rb, line 33
def errors
  @errors
end
fetch_emails(&process_email_block) click to toggle source

retrieve_emails

retrieve any mail from a folder, followin specified serach condition for any mail retrieved call a specified block

# File lib/client.rb, line 84
def fetch_emails(&process_email_block)

  @message_ids.each_with_index do |message_id, i|
    begin
      # fetch all the email contents
      data = @imap.uid_fetch(message_id, "RFC822")
      data.each do |d|
        msg = d.attr['RFC822']
        # instantiate a Mail object to avoid further IMAP parameters nightmares
        mail = Mail.read_from_string msg

        # call the block with mail object as param
        process_email_block.call mail, i, i == @message_ids.length-1, message_id

        # mark as read
        if @mark_as_read
          @imap.store(message_id, "+FLAGS", [:Seen])
        end
      end
    rescue => e
      unless logger.nil?
        logger.info "Issue processing email for uuid ##{message_id}, #{e.message}"
      end

      logToLoggly({event:"EMAIL_SYNC_FAILED", env: @env, storage: @client_type, email: @current_user_email, uuid: message_id, error: e.message})
      raise e
    end
  end
end
imap_connection(server, username, password, exitOnFail = true) click to toggle source

imap_connection

connect the app with imap server

# File lib/client.rb, line 42
def imap_connection(server, username, password, exitOnFail = true)
  # connect to IMAP server
  @imap = Net::IMAP.new server, ssl: true, certs: nil, verify: false

  Net::IMAP.debug = @net_imap_debug

  # http://ruby-doc.org/stdlib-2.1.5/libdoc/net/imap/rdoc/Net/IMAP.html#method-i-capability
  capabilities = @imap.capability

  @logger.debug("imap capabilities: #{capabilities.join(',')}") if @debug

  if @client_type == 'local'
    unless capabilities.include? "IDLE" || @debug
      @logger.info "'IDLE' IMAP capability not available in server: #{server}"
      @imap.disconnect
      exit if exitOnFail
    end
  end

  begin
    # login
    @imap.login username, password
    @errors = nil
  rescue Net::IMAP::NoResponseError => e
    # mostly due to credentials error
    @errors = {exception: e}
  rescue Net::IMAP::BadResponseError => e
    @errors = {exception: e}
  rescue
    @errors = {exception: e}
  end

  # return IMAP connection handler
  @imap
end
init_messages(label, search_condition = ['ALL']) click to toggle source
# File lib/client.rb, line 115
def init_messages label, search_condition = ['ALL']

  # examine will read email and sets flags unread
  # https://stackoverflow.com/questions/16516464/read-gmail-xoauth-mails-without-marking-it-read
  @imap.examine label

  @message_ids = @imap.uid_search(search_condition)
  @total_emails = @message_ids.length
  downloaded_email = getMessageUUIds("#{@download_path}meta/")
  downloaded_email = downloaded_email.collect{|i| i.to_i}

  @downloaded = downloaded_email.length
  @downloaded = @downloaded - 2 if @downloaded > 1
  @downloaded = [@downloaded, @total_emails].min

  @message_ids = @message_ids - downloaded_email
  @message_ids = @message_ids&.sort {|msg_a, msg_b| msg_b <=> msg_a}

  if @debug
    if @message_ids.empty?
      @logger.info "No new emails found..."
    elsif downloaded_email.any?
      @logger.info "Found emails saved in your #{@client_type}. Downloading only #{@message_ids.count} new emails..."
    else
      @logger.info "Downloading #{@message_ids.count} emails."
    end
  end

end
logToLoggly(messageBody) click to toggle source
# File lib/client.rb, line 226
def logToLoggly(messageBody)

  if(@logglyTag)
    begin
      HTTParty.post("http://logs-01.loggly.com/bulk/0d67f93b-6568-4b00-9eca-97d0ea0bd5a1/tag/#{@logglyTag}/",
                    body: messageBody.to_json,
                    headers: { 'Content-Type' => 'application/json' } )
    rescue
      true
    end

  else
    if @debug && !@logger.nil?
      @logger.info "Logging to Loggly disabled"
      @logger.info messageBody
    end
  end

end
logger() click to toggle source
# File lib/client.rb, line 29
def logger
  @logger
end
process_email(mail, uid, stamp = nil) click to toggle source

Process each email downloaded from imap-server and creates meta file that will be sent over to the navi-ai service. Meta will content information like: ['from', 'to', 'cc', …, 'body_url']. This information is then used by navi-ai to parse the body content.

# File lib/client.rb, line 149
def process_email(mail, uid, stamp = nil)
  meta = Hash.new
  custom_uid = (Time.now.to_f * 1000).to_s + "_" + mail.__id__.to_s

  meta["from"] = mail[:from].to_s
  meta["to"] = mail[:to].to_s
  meta["cc"] = mail[:cc].to_s
  meta["subject"] = mail.subject
  meta["date"] = mail.date.to_s


  if mail.multipart?
    for i in 0...mail.parts.length
      m = download(mail.parts[i], custom_uid)
      meta.merge!(m) unless m.nil?
    end
  else
    m = download(mail, custom_uid)
    meta.merge!(m) unless m.nil?
  end

  if stamp.nil?
    save(meta, "meta/#{uid.to_s + '_' + custom_uid}")
  else
    save(meta, "meta/#{uid.to_s + '_' + custom_uid}", stamp)
  end

end
setupLoggly(tag) click to toggle source
# File lib/client.rb, line 246
def setupLoggly(tag)
  @logglyTag = tag
end
shutdown(imap) click to toggle source

If the gem is being used for local-lockbox mode, after fetching all emails, the process will go idle mode. If user send the interrupt command, it will call shutdown to disconnect the connection with imap server

# File lib/client.rb, line 217
def shutdown(imap)
  imap.idle_done
  imap.logout unless imap.disconnected?
  imap.disconnect

  @logger.info "#{$0} has ended (crowd applauds)"
  exit 0
end
time_now() click to toggle source
# File lib/client.rb, line 210
def time_now
  Time.now.utc.iso8601(3)
end