class ConnectionImap

Handles the Imap configuration and connection

Constants

STORE_FILE
STORE_PATH

Public Class Methods

new(config, config_file) click to toggle source

reads the config file and sets `@config`

# File lib/connection/imap.rb, line 13
def initialize(config, config_file)
  get_or_create_pstore
  @config = config
  @config_file = config_file
end

Public Instance Methods

append_message(protocol, network, address, message, message_id, flags = nil, date_time = nil) click to toggle source

Appends message to mailbox `date_time`: Time Connects and disconnects at the beginning and end of the method

if the connection is not defined/ connected already
# File lib/connection/imap.rb, line 153
def append_message(protocol, network, address, message, message_id, flags = nil, date_time = nil)
  unless msg_appended?(message_id)
    connect unless connected_and_authenticated?

    target_mailbox = get_mailbox(protocol, address, network)
    create_mailbox_path(target_mailbox)
    @connection.examine(target_mailbox)

    if @connection.search(['HEADER', 'MESSAGE-ID', message.message_id]).empty?
      @connection.append(target_mailbox, message.to_s, flags, date_time)
    end
    store_msg_appended(message_id)
  end
end
check_password() click to toggle source
# File lib/connection/imap.rb, line 71
def check_password
  unless @config['imap']['password']
    # Get imap password
    prompt = TTY::Prompt.new
    @config['imap']['password'] = prompt.mask(
      'Enter your imap password', required: true
    )
  end
end
configuration_wizard() click to toggle source

Run the IMAP configuration

# File lib/connection/imap.rb, line 41
def configuration_wizard
  connection_configuration = ConnectionConfigurationImap.new(@config)
  result = connection_configuration.configuration_wizard
  if result['save']
    result['config']['imap'].delete('password')
    new_config_json = JSON.pretty_generate(result['config'])
    File.write(@config_file, new_config_json)
  end
end
configure_and_connect() click to toggle source

Configures the IMAP server settings then tests the connection

# File lib/connection/imap.rb, line 97
def configure_and_connect
  if !configuration_wizard # TODO: - wire up to connection configuration
    exit
  else
    test_connection
  end
end
connect() click to toggle source

Connect to the IMAP server, attempting 'LOGIN' then 'PLAIN'

# File lib/connection/imap.rb, line 52
def connect
  check_password
  @connection ||= Net::IMAP.new(@config['imap']['server'], @config['imap']['port'], @config['imap']['ssl'])
  res = true
  unless connected_and_authenticated?
    begin
      @connection.authenticate('LOGIN', @config['imap']['username'], @config['imap']['password'])
    rescue StandardError
      begin
        @connection.authenticate('PLAIN', @config['imap']['username'], @config['imap']['password'])
      rescue StandardError => e
        puts "IMAP failed to connect: #{e}"
        res = false
      end
    end
  end
  res
end
connected_and_authenticated?() click to toggle source

Attempts to list mailboxes (folders). If length > 0, then wemust be authenticated

# File lib/connection/imap.rb, line 175
def connected_and_authenticated?
  !@connection.disconnected? && !@connection.list('', '*').empty?
rescue StandardError => e
  false
end
create_mailbox_path(target_mailbox) click to toggle source

Create the folder path for the mailbox according to chosen folder format

# File lib/connection/imap.rb, line 137
def create_mailbox_path(target_mailbox)
  return if @connection.list('', target_mailbox)

  folders = target_mailbox.split(delimiter)
  mbox = []
  (0...folders.length).each_with_index do |_folder, index|
    mbox.push(folders[index])
    mbox_as_str = mbox.join(delimiter)
    @connection.create(mbox_as_str) unless @connection.list('', mbox_as_str)
  end
end
delimiter() click to toggle source

Sets the connection delimiter

# File lib/connection/imap.rb, line 82
def delimiter
  if @delimiter.nil?
    folders = list_folders
    @delimiter = folders[0][:delim]
  end
  @delimiter
end
disconnect() click to toggle source

Disconnects from the server

# File lib/connection/imap.rb, line 91
def disconnect
  @connection.disconnect unless @connection.nil? || @connection.disconnected?
  @connection = nil
end
get_mailbox(protocol, address, network) click to toggle source

Returns the target mailbox for the message according to the folder structre and Inbox preferences

# File lib/connection/imap.rb, line 114
def get_mailbox(protocol, address, network)
  p_address = case protocol
              when 'ethereum'
                "0x#{address}"
              else
                address
              end

  if @config['mailchain']['mainnet_to_inbox'] && network.downcase == 'mainnet'
    'Inbox'
  else
    case @config['mailchain']['folders']
    when 'by_address'
      # 'Address>Protocol>Network'
      "Inbox#{delimiter}#{p_address}#{delimiter}#{protocol}#{delimiter}#{network}"
    when 'by_network'
      # 'Protocol>Network>Address'
      "Inbox#{delimiter}#{protocol}#{delimiter}#{network}#{delimiter}#{p_address}"
    end
  end
end
get_or_create_pstore() click to toggle source

Check for pstore, and create if not exist

# File lib/connection/imap.rb, line 20
def get_or_create_pstore
  (FileUtils.mkdir_p(STORE_PATH) unless File.exist?(STORE_FILE))
  @pstore = PStore.new(STORE_FILE, true)
end
list_folders() click to toggle source

Lists folders

# File lib/connection/imap.rb, line 169
def list_folders
  connect
  @connection.list('', '*')
end
msg_appended?(message_id) click to toggle source

Checks if MD5 hexdigest of message_id as key, with prefix 'append_' returns a true value from the database. Stored as md5 hash to obfuscate message ids. Returns true or false

# File lib/connection/imap.rb, line 35
def msg_appended?(message_id)
  message_id_hash = Digest::MD5.hexdigest(message_id)
  @pstore.transaction { @pstore['append_' + message_id_hash] } == true
end
store_msg_appended(message_id) click to toggle source

Records in pstore with the MD5 hexdigest of message_id as key, with prefix 'append_' and value as true. Stored as md5 hash to obfuscate message ids.

# File lib/connection/imap.rb, line 27
def store_msg_appended(message_id)
  message_id_hash = Digest::MD5.hexdigest(message_id)
  @pstore.transaction { @pstore['append_' + message_id_hash] = true }
end
test_connection() click to toggle source

Tests the connection to the IMAP server

# File lib/connection/imap.rb, line 106
def test_connection
  puts 'Testing IMAP connection...'
  puts 'IMAP connection was successful' if connect
  disconnect unless @connection.disconnected?
  true
end