MacOS – How to automate pasting of password into SecurityAgent

applescriptautomatormacos

On OS X 10.8.x I had an Automator service set up to paste a password from clipboard into the password window that pops up for mounting an encrypted disk.

I don't wish to store the password in my keychain, and it is long and tedious to type out.

I never got the applescript within the Automator service quite right. It would generate an error, but it still got the job done (i.e. the password was pasted). Since upgrading to Yosemite it seems the script in the Automator service doesn't work at all. The error generated indicates "window 1" doesn't exist.

Here is what I had:

tell application "System Events" to tell process "SecurityAgent"
set value of text field 1 of window 1 to (the clipboard)
if exists (text field 2 of window 1) then
    set value of text field 2 of window 1 to (the clipboard)
end if
click button 1 of group 1 of window 1
end tell

I don't recall where I got this from, but some of it may have come from here

I know very little about AppleScript, and would appreciate some help fine tuning (or completely rewriting) this script so that it does the following:

  1. Checks there is data in the clipboard
  2. Checks the SecurityAgent window is active (or in some way ensures it can be interacted with, to avoid generating an error)
  3. Pastes the content of clipboard
  4. Clicks the 'Unlock' button

I don't know if it is possible, but it would be handy if it also brought 1Password to the foreground and activated "Copy password" (which is a menu option in the "Items" menu). I can, however, have Automator actions perform that task. But it would be nice to see (for learning) how to achieve that with AppleScript.

Best Answer

With thanks to input from markhunte and tetsujin, I came up with the following solution. With all things considered, the exact requirements evolved to the following:

  1. Ensure a SecurityAgent dialog is actually present so that script doesn't run otherwise.
  2. Reposition the SecurityAgent dialog because it can readily get in the way in its default position.
  3. Display a message which will stay on top of 1Password, but is not generated through 1password, instructing the user to select the correct item in 1Password
  4. Automatically copy the password for current 1Password item
  5. Delay the script long enough for the password to actually end up in the clipboard, before the script attempts pasting it.
  6. Paste the clipboard into the SecurityAgent, and submit it.

I came up with the following solution:

set appName to "SecurityAgent"
set passApp to "1Password 5" (* set this to the name of your password manager *)

tell application "System Events"
     if not (exists window 1 of process appName) then -- test if SecurityAgent window exists
         return -- abort if SecurityAgent window does not exist
     end if
 end tell
 tell application "System Events"
    set position of window 1 of process appName to {10, 10} -- move SecurityAgent window out of the way 
 end tell
 tell application passApp
      activate -- bring 1Password to the forefront, run it if not running
 end tell
 tell application "System Events"
    tell application "SystemUIServer"
      set answer to display dialog "Make sure correct 1Password item is actively selected (i.e. click it again if it was previously selected), then click “Continue” to proceed." buttons {"Continue"}
    end tell
    tell process passApp
    (* If you are not using 1Password, you may need to change the menu item clicks, below, to whatever is correct in your particular password manager *)
        click menu item "copy password" of menu "item" of menu bar 1
        delay 1
        set appData to the clipboard
    end tell
    tell application "System Events"
        tell process appName
            set value of text field 1 of window 1 to appData
            if exists (text field 2 of window 1) then
                set value of text field 2 of window 1 to appData
                click button 1 of window 1
            else
                click button 2 of window 1
            end if
         end tell
     end tell
end tell

I made the whole script conditional on the presence of SecurityAgent, because this script will be assigned to a keyboard shortcut, and if that key combination is inadvertently selected by the user, I'd rather they not be bothered with an unexpected script process.

If there are ways in which I could refine or improve this solution, please advise. I am very happy to be learning more about AppleScript.

FINAL UPDATES: Had to make one final change. It turned out the button numbers for CANCEL and OK change around from the SecurityAgent instance for creating an encrypted disk/disk-image, and for when opening an encrypted disk/disk-image. So I had to modify the IF THEN statement right near the end to handle each scenario.