module SecondStep::MacOSNotify

Public Class Methods

_notify(message, options = {}, verbose = false) click to toggle source
# File lib/second_step/mac_os_notify.rb, line 17
def self._notify(message, options = {}, verbose = false)
  result = TerminalNotifier.execute(verbose, options.merge(:message => message))
  $? && $?.success? && _notify_result(result, options)
end
_notify_result(result, options = {}) click to toggle source
# File lib/second_step/mac_os_notify.rb, line 9
def self._notify_result(result, options = {})
  reply_option = options[:reply] || options['reply']
  if reply_option && !result.start_with?('@')
    result
  else
    result.length == 0 || result.downcase.gsub(/\W+/,'_').to_sym
  end
end
hash_to_array_with_only(hash, keys = nil) click to toggle source
# File lib/second_step/mac_os_notify.rb, line 21
def self.hash_to_array_with_only(hash, keys = nil)
  keys.zip(hash.values_at(*keys))
end
notify_login(from: 'Unknown', actions: %i[approve deny], action_text: 'Approve or Deny:', timeout: 5, ignore_label: 'Ignore', show_details: nil, **details) { |include?(result) ? result : :ignore| ... } click to toggle source

Returns an action from actions, or `:ignore` Action must be an array of symbols containing only word characters and non-neighboring underscores.

# File lib/second_step/mac_os_notify.rb, line 50
def self.notify_login(from: 'Unknown', actions: %i[approve deny], action_text: 'Approve or Deny:', timeout: 5, ignore_label: 'Ignore', show_details: nil, **details)
  if show_details
    show_details &= details.keys
  else
    show_details = details.keys
  end
  body_text = hash_to_array_with_only(details, show_details).map{|(k,v)| "#{k.to_s.capitalize}: #{v}"}.join(', ')
  subprocess = fork do
    begin
      if TerminalNotifier.available?
        result = _notify(body_text,
                         actions: actions.map{|s| s.to_s.capitalize}.join(','),
                         closeLabel: ignore_label,
                         dropdownLabel: action_text,
                         title: 'SecondStep',
                         subtitle: "Login Request from #{from}",
                         group: Process.pid,
                         sender: 'com.getsecondstep.macos.mac-notify',
                         timeout: timeout)
        if result
          if result == :_contentclicked
            result = notify_with_dialog(details.merge(from: from, actions: actions, action_text: action_text, ignore_label: ignore_label, show_details: show_details))
          end
          yield actions.include?(result) ? result : :ignore
        else
          raise NotificationError.new(result)
        end
      else
        result = notify_with_dialog(details.merge(from: from, actions: actions, action_text: action_text, ignore_label: ignore_label, show_details: show_details))
        yield actions.include?(result) ? result : :ignore
      end
    ensure
      TerminalNotifier.remove Process.pid
    end
  end
end
notify_with_dialog(details) click to toggle source
# File lib/second_step/mac_os_notify.rb, line 24
    def self.notify_with_dialog(details)
      buttons = details[:actions].map{ |action| "\"#{Shellwords.shellescape(action.to_s.capitalize)}\"" }
      escaped_from = Shellwords.shellescape details[:from]
      body_text = hash_to_array_with_only(details, details[:show_details]).map do |(k,v)|
        body_line = k.to_s.capitalize.split(' ')
        body_line.last << ':'
        Shellwords.join(body_line + v.to_s.split(' '))
      end.join('\n')
      icon_path = File.expand_path('../logo.png.icns', __FILE__)
      osascript = <<-osascript
try
  set dialogResult to display dialog "Login Request from #{escaped_from}\\n\\n#{body_text}" buttons {"Ignore",#{buttons.reverse.join(',')}} cancel button "Ignore" default button #{buttons.first} with title "SecondStep Login Request" with icon POSIX file "#{icon_path}"
  return the button returned of dialogResult
on error number -128
  return "ignore"
end try
      osascript
      result = IO.popen('osascript', 'r+') do |f|
        f.puts osascript
        f.close_write
        f.readlines
      end
      _notify_result result.first.chomp
    end