diff --git a/README.md b/README.md index f660af4..4ec38ca 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,26 @@ ![Screenshot](https://github.com/Angoll/KPass/blob/master/example.gif) -## Features +## New Features + +## Select entry and press ⏎ to use default menu options: +- Copy Password +- Copy Username +- Copy TOTP +- Copy URL +- Open Database in KeePassXC +- Settings + +# Shortcuts: +### ⌘ - Copy Password Directly | Bypass Menu +### ⇧ - Copy Username Directly | Bypass Menu +### ⌥ - Copy TOTP Code Directly | Bypass Menu +### ⌃ - Copy/Paste URL Directly | Bypass Menu + +# Changes +Menu, TOTP, URL added by CDoug. + +## Previous Features - List all entries from a KeePassXC database - Get the password for the selected entry, and put it in the clipboard @@ -23,7 +42,9 @@ - jq installed ( ) #### Configuration - +Configure the workflow by either: +Selecting "Configure Workflow" from the workflow menu in Alfred and choosing your KeePassXC database to use. +- or - Run **kpassinit** KPass Setup and follow the instructions: 1. Select the KeePassXC database file diff --git a/back.png b/back.png new file mode 100644 index 0000000..dfa903a Binary files /dev/null and b/back.png differ diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..86b999e Binary files /dev/null and b/icon.png differ diff --git a/info.plist b/info.plist new file mode 100644 index 0000000..1c7893a --- /dev/null +++ b/info.plist @@ -0,0 +1,1882 @@ + + + + + bundleid + com.aglezllinas.kpass + category + Tools + connections + + 0E061607-446F-42B1-A61D-7141645CC099 + + + destinationuid + 72E9F265-FF7B-474C-9A9C-A18348E3C9D2 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 18273CFC-8C6D-497B-BAC6-1983953354D0 + + + destinationuid + 72E9F265-FF7B-474C-9A9C-A18348E3C9D2 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 2758F511-8CD2-4755-AA69-10159D17EC90 + + + destinationuid + E35451E7-54B1-4C83-8C9E-F9B96B0C3016 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 283F690A-36C6-4B64-A552-EA75B23FA3EF + + + destinationuid + 80C0730D-9C4C-4D46-8AC5-EE827B744F5B + modifiers + 0 + modifiersubtext + + vitoclose + + + + 2A5D5B0F-63B4-47A8-8BD4-2C9D58576D59 + + + destinationuid + 7DD3BDE5-A157-42E5-9376-F681FB50A4EE + modifiers + 0 + modifiersubtext + + vitoclose + + + + 4052074F-1000-43E3-86F0-E5A618169D2E + + + destinationuid + 99246AFC-B7C5-4DFF-9BF1-9BBE6589F303 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 57089C57-FE2F-46CE-B8EF-AA89DE97018E + + + destinationuid + B99B170E-3A3C-44EC-A9B7-D6CE6E209DB7 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 6305EDB2-9809-4074-B448-ACA6C5A96BD4 + + + destinationuid + A8FEB5EC-A1B2-4490-BE46-DF67E9D75FFB + modifiers + 0 + modifiersubtext + + vitoclose + + + + 72E9F265-FF7B-474C-9A9C-A18348E3C9D2 + + + destinationuid + 75198F5E-917B-4A6C-BF0C-091140474506 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 7DD3BDE5-A157-42E5-9376-F681FB50A4EE + + + destinationuid + 2758F511-8CD2-4755-AA69-10159D17EC90 + modifiers + 524288 + modifiersubtext + Copy TOTP Directly | Bypass Menu + vitoclose + + + + destinationuid + 4052074F-1000-43E3-86F0-E5A618169D2E + modifiers + 262144 + modifiersubtext + Copy/Paste URL Directly | Bypass Menu + vitoclose + + + + destinationuid + 82C5E557-E391-454E-A490-2EAF22853FB7 + modifiers + 0 + modifiersubtext + + vitoclose + + + + destinationuid + D92BF33C-614F-4057-97C1-A9DE77A397E5 + modifiers + 1048576 + modifiersubtext + Copy Password Directly | Bypass Menu + vitoclose + + + + destinationuid + 0E061607-446F-42B1-A61D-7141645CC099 + modifiers + 131072 + modifiersubtext + Copy Username Directly | Bypass Menu + vitoclose + + + + 82C5E557-E391-454E-A490-2EAF22853FB7 + + + destinationuid + 7BAAC131-49C4-497B-B5C8-2831DBD24D66 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 86B11BB2-F440-40D5-8472-8099A8BDD571 + + + destinationuid + 8F53E19D-FE8A-425D-88CE-3C088EC6D278 + modifiers + 0 + modifiersubtext + + sourceoutputuid + D9745E2A-3260-489A-8394-234F2069ECFC + vitoclose + + + + destinationuid + 75198F5E-917B-4A6C-BF0C-091140474506 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 8B5C36B3-321C-4FDB-90B9-48F255AB499B + + + destinationuid + E35451E7-54B1-4C83-8C9E-F9B96B0C3016 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 8F53E19D-FE8A-425D-88CE-3C088EC6D278 + + + destinationuid + D2060C49-72E1-43CE-8F43-EAAD6E3816A2 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 94CBB6C8-1A78-4884-B09E-7D149D18A4D8 + + + destinationuid + 8B5C36B3-321C-4FDB-90B9-48F255AB499B + modifiers + 0 + modifiersubtext + + sourceoutputuid + 455C3BD8-C9BD-4FDB-8A22-A05DD343467A + vitoclose + + + + destinationuid + 57089C57-FE2F-46CE-B8EF-AA89DE97018E + modifiers + 0 + modifiersubtext + + sourceoutputuid + 988BC641-80A7-4F29-8462-94836A76CD8A + vitoclose + + + + destinationuid + 18273CFC-8C6D-497B-BAC6-1983953354D0 + modifiers + 0 + modifiersubtext + + sourceoutputuid + 70BDE505-581F-418A-9056-646C50C90885 + vitoclose + + + + destinationuid + ECA51978-EF5B-47A3-8195-7B1ABE74A48A + modifiers + 0 + modifiersubtext + + sourceoutputuid + 3AF0D805-468B-4B6F-8026-CB6E8D8F2CFE + vitoclose + + + + destinationuid + 32F72B66-664B-49CD-8E36-565FF4F64662 + modifiers + 0 + modifiersubtext + + sourceoutputuid + 491BF767-92BB-42F4-81FF-754778E29B7D + vitoclose + + + + destinationuid + 1B76A840-C42A-4E83-8CE2-DBF920F6E7AB + modifiers + 0 + modifiersubtext + + sourceoutputuid + EAABC324-2EFE-42AA-A72C-36A56B82D598 + vitoclose + + + + destinationuid + D3071C93-8EC0-4371-BBD9-3D2A80932B2D + modifiers + 0 + modifiersubtext + + vitoclose + + + + 99246AFC-B7C5-4DFF-9BF1-9BBE6589F303 + + + destinationuid + 12FBD320-2BCA-4186-AEED-7FE183BB71A5 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 9A459034-29D0-43FE-9F0A-1B01FB14F247 + + + destinationuid + 6305EDB2-9809-4074-B448-ACA6C5A96BD4 + modifiers + 0 + modifiersubtext + + vitoclose + + + + A8FEB5EC-A1B2-4490-BE46-DF67E9D75FFB + + + destinationuid + 94CBB6C8-1A78-4884-B09E-7D149D18A4D8 + modifiers + 0 + modifiersubtext + + vitoclose + + + + B3AAFA83-E7EB-4D37-A92B-45083BE9D555 + + + destinationuid + 283F690A-36C6-4B64-A552-EA75B23FA3EF + modifiers + 0 + modifiersubtext + + vitoclose + + + + B99B170E-3A3C-44EC-A9B7-D6CE6E209DB7 + + + destinationuid + 75198F5E-917B-4A6C-BF0C-091140474506 + modifiers + 0 + modifiersubtext + + vitoclose + + + + D92BF33C-614F-4057-97C1-A9DE77A397E5 + + + destinationuid + B99B170E-3A3C-44EC-A9B7-D6CE6E209DB7 + modifiers + 0 + modifiersubtext + + vitoclose + + + + E35451E7-54B1-4C83-8C9E-F9B96B0C3016 + + + destinationuid + 86B11BB2-F440-40D5-8472-8099A8BDD571 + modifiers + 0 + modifiersubtext + + vitoclose + + + + ECA51978-EF5B-47A3-8195-7B1ABE74A48A + + + destinationuid + 99246AFC-B7C5-4DFF-9BF1-9BBE6589F303 + modifiers + 0 + modifiersubtext + + vitoclose + + + + + createdby + agonzalez + description + Integration for KeepassXC + disabled + + name + KPass + objects + + + config + + externaltriggerid + _displayMenu + passinputasargument + + passvariables + + workflowbundleid + self + + type + alfred.workflow.output.callexternaltrigger + uid + D2060C49-72E1-43CE-8F43-EAAD6E3816A2 + version + 1 + + + config + + lastpathcomponent + + onlyshowifquerypopulated + + removeextension + + text + Failed to get TOTP + title + TOTP not found for entry + + type + alfred.workflow.output.notification + uid + 8F53E19D-FE8A-425D-88CE-3C088EC6D278 + version + 1 + + + config + + concurrently + + escaping + 102 + script + #Get the 6 digit TOTP code of a specific entry in the database if there is one using keepassxc-cli +export PATH='/bin:/usr/local/bin/:/usr/bin:/Applications/KeePassXC.app/Contents/MacOS/:/opt/homebrew/bin:${PATH}' +function get_TOTP { + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show --key-file "${keePassKeyFile}" -q -t "${database}" "$1" + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show -q -t "${database}" "$1" + fi +} + +function get_errorInfo { + exec 3<&1 + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R --key-file "${keePassKeyFile}" -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + fi + exec 3>&- +} + +data=$(get_TOTP "$1") +if [ $? -ne 0 ]; then + echo $(get_errorInfo) +else + echo -n $data +fi + scriptargtype + 1 + scriptfile + + type + 0 + + type + alfred.workflow.action.script + uid + E35451E7-54B1-4C83-8C9E-F9B96B0C3016 + version + 2 + + + config + + conditions + + + inputstring + + matchcasesensitive + + matchmode + 4 + matchstring + Enter password to unlock + outputlabel + Go Back + uid + D9745E2A-3260-489A-8394-234F2069ECFC + + + elselabel + copy TOTP + hideelse + + + type + alfred.workflow.utility.conditional + uid + 86B11BB2-F440-40D5-8472-8099A8BDD571 + version + 1 + + + config + + argument + + passthroughargument + + variables + + + type + alfred.workflow.utility.argument + uid + 2758F511-8CD2-4755-AA69-10159D17EC90 + version + 1 + + + config + + argument + {var:xentry} + passthroughargument + + variables + + + type + alfred.workflow.utility.argument + uid + 8B5C36B3-321C-4FDB-90B9-48F255AB499B + version + 1 + + + config + + argument + + passthroughargument + + variables + + + type + alfred.workflow.utility.argument + uid + 4052074F-1000-43E3-86F0-E5A618169D2E + version + 1 + + + config + + externaltriggerid + _displayMenu + passinputasargument + + passvariables + + workflowbundleid + self + + type + alfred.workflow.output.callexternaltrigger + uid + 7BAAC131-49C4-497B-B5C8-2831DBD24D66 + version + 1 + + + config + + alfredfiltersresults + + alfredfiltersresultsmatchmode + 2 + argumenttreatemptyqueryasnil + + argumenttrimmode + 0 + argumenttype + 1 + escaping + 118 + keyword + kpass + queuedelaycustom + 10 + queuedelayimmediatelyinitially + + queuedelaymode + 2 + queuemode + 1 + runningsubtext + Please loading database... + script + export PATH='/bin:/usr/local/bin/:/usr/bin:/Applications/KeePassXC.app/Contents/MacOS/:/opt/homebrew/bin:${PATH}' + +function get_db_keys { + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli search --key-file "${keePassKeyFile}" "${database}" - -q + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli search "${database}" - -q + fi +} + +function get_keys { + if [ -z "${cacheFile}" ]; then + get_db_keys + else + # Cache is enabled + if [ -f "${cacheFile}" ]; then + lastModifiedTime=$(GetFileInfo -d "${cacheFile}") + else + lastModifiedTime=$(date +"%m/%d/%Y %H:%M:%S") + fi + lastModifiedTime=$(date -jf "%m/%d/%Y %H:%M:%S" "${lastModifiedTime}" +%s) + currTime=$(date +%s) + interval=$( expr $currTime - $lastModifiedTime ) + if [ ! -f "${cacheFile}" ] || [ "${interval}" -gt "${cacheTimeout}" ]; then + # Update cache + echo "$(get_db_keys)" > "${cacheFile}" + fi + # Get keys from the cache + cat "${cacheFile}" | grep -i "${query}" + fi +} + +function get_errorInfo { + exec 3<&1 + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli search --key-file "${keePassKeyFile}" "${database}" - -q 2>&3 + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli search "${database}" - -q 2>&3 + fi + exec 3>&- +} + +if [[ -z "${database}" ]] || [[ -z "${keychain}" ]]; +then + echo "{\"items\": [{\"title\":\"Not configured, please run: kpassinit\"}]}"; + exit +fi + +keys=($(get_keys)) +if [ $? -ne 0 ]; then + info=$(get_errorInfo | sed 's/"/\\"/g') + info=${info//$'\n'/} + echo "{\"items\": [{\"title\":\"Error listing database, please check config: Error: ${info}\"}]}"; + exit +else + echo ${keys[@]} | sed 's/ \//\n\//g' | awk -v iconPath="${PWD}/icon.png" '{printf "{\"uid\":\"%s\", \"title\":\"%s\", \"subtitle\":\"%s\", \"arg\":\"%s\", \"autocomplete\": \"%s\", \"icon\":{\"type\":\"png\", \"path\": \"%s\"}}", $0, substr($0,2, length($0)), $0, $0, $0, iconPath}' | jq -c -s '{"items": .}' +fi + + scriptargtype + 0 + scriptfile + + subtext + + title + KpassLoader + type + 0 + withspace + + + type + alfred.workflow.input.scriptfilter + uid + 7DD3BDE5-A157-42E5-9376-F681FB50A4EE + version + 3 + + + config + + availableviaurlhandler + + triggerid + _kpass + + type + alfred.workflow.trigger.external + uid + 2A5D5B0F-63B4-47A8-8BD4-2C9D58576D59 + version + 1 + + + config + + argument + + passthroughargument + + variables + + xentry + {query} + + + type + alfred.workflow.utility.argument + uid + 82C5E557-E391-454E-A490-2EAF22853FB7 + version + 1 + + + config + + concurrently + + escaping + 102 + script + export PATH='/bin:/usr/local/bin/:/usr/bin:/Applications/KeePassXC.app/Contents/MacOS/:/opt/homebrew/bin:${PATH}' + +function get_keys { + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show --key-file "${keePassKeyFile}" -q -a Password "${database}" "$1" + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show -q -a Password "${database}" "$1" + fi +} + +function get_errorInfo { + exec 3<&1 + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R --key-file "${keePassKeyFile}" -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + fi + exec 3>&- +} + + +data=$(get_keys "$1") +if [ $? -ne 0 ]; then + echo $(get_errorInfo) +else + echo -n $data +fi + scriptargtype + 1 + scriptfile + + type + 0 + + type + alfred.workflow.action.script + uid + B99B170E-3A3C-44EC-A9B7-D6CE6E209DB7 + version + 2 + + + config + + autopaste + + clipboardtext + {query} + ignoredynamicplaceholders + + transient + + + type + alfred.workflow.output.clipboard + uid + 75198F5E-917B-4A6C-BF0C-091140474506 + version + 3 + + + config + + concurrently + + escaping + 102 + script + export PATH='/bin:/usr/local/bin/:/usr/bin:/Applications/KeePassXC.app/Contents/MacOS/:/opt/homebrew/bin:${PATH}' + +function get_username { + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show --key-file "${keePassKeyFile}" -q -a Username "${database}" "$1" + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show -q -a Username "${database}" "$1" + fi +} + +function get_errorInfo { + exec 3<&1 + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R --key-file "${keePassKeyFile}" -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + fi + exec 3>&- +} + + +data=$(get_username "$1") +if [ $? -ne 0 ]; then + echo $(get_errorInfo) +else + echo -n $data +fi + scriptargtype + 1 + scriptfile + + type + 0 + + type + alfred.workflow.action.script + uid + 72E9F265-FF7B-474C-9A9C-A18348E3C9D2 + version + 2 + + + config + + argument + {var:xentry} + passthroughargument + + variables + + + type + alfred.workflow.utility.argument + uid + 57089C57-FE2F-46CE-B8EF-AA89DE97018E + version + 1 + + + config + + argument + {var:xentry} + passthroughargument + + variables + + + type + alfred.workflow.utility.argument + uid + 18273CFC-8C6D-497B-BAC6-1983953354D0 + version + 1 + + + config + + argument + + passthroughargument + + variables + + + type + alfred.workflow.utility.argument + uid + D92BF33C-614F-4057-97C1-A9DE77A397E5 + version + 1 + + + config + + argument + + passthroughargument + + variables + + + type + alfred.workflow.utility.argument + uid + 0E061607-446F-42B1-A61D-7141645CC099 + version + 1 + + + config + + conditions + + + inputstring + {var:route} + matchcasesensitive + + matchmode + 0 + matchstring + pass + outputlabel + pass + uid + 988BC641-80A7-4F29-8462-94836A76CD8A + + + inputstring + {var:route} + matchcasesensitive + + matchmode + 0 + matchstring + user + outputlabel + user + uid + 70BDE505-581F-418A-9056-646C50C90885 + + + inputstring + {var:route} + matchcasesensitive + + matchmode + 0 + matchstring + url + outputlabel + url + uid + 3AF0D805-468B-4B6F-8026-CB6E8D8F2CFE + + + inputstring + {var:route} + matchcasesensitive + + matchmode + 0 + matchstring + totp + outputlabel + totp + uid + 455C3BD8-C9BD-4FDB-8A22-A05DD343467A + + + inputstring + {var:route} + matchcasesensitive + + matchmode + 0 + matchstring + settings + outputlabel + settings + uid + 491BF767-92BB-42F4-81FF-754778E29B7D + + + inputstring + {var:route} + matchcasesensitive + + matchmode + 0 + matchstring + back + outputlabel + back + uid + EAABC324-2EFE-42AA-A72C-36A56B82D598 + + + elselabel + open DB + hideelse + + + type + alfred.workflow.utility.conditional + uid + 94CBB6C8-1A78-4884-B09E-7D149D18A4D8 + version + 1 + + + config + + autopaste + + clipboardtext + {query} + ignoredynamicplaceholders + + transient + + + type + alfred.workflow.output.clipboard + uid + 12FBD320-2BCA-4186-AEED-7FE183BB71A5 + version + 3 + + + config + + concurrently + + escaping + 102 + script + #Get the URL of a specific entry in the database +export PATH='/bin:/usr/local/bin/:/usr/bin:/Applications/KeePassXC.app/Contents/MacOS/:/opt/homebrew/bin:${PATH}' +function get_url { + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show --key-file "${keePassKeyFile}" -q -a URL "${database}" "$1" + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show -q -a URL "${database}" "$1" + fi +} + +function get_errorInfo { + exec 3<&1 + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R --key-file "${keePassKeyFile}" -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + fi + exec 3>&- +} + +data=$(get_url "$1") +if [ $? -ne 0 ]; then + echo $(get_errorInfo) +else + echo -n $data +fi + scriptargtype + 1 + scriptfile + + type + 0 + + type + alfred.workflow.action.script + uid + 99246AFC-B7C5-4DFF-9BF1-9BBE6589F303 + version + 2 + + + config + + availableviaurlhandler + + triggerid + _displayMenu + + type + alfred.workflow.trigger.external + uid + 9A459034-29D0-43FE-9F0A-1B01FB14F247 + version + 1 + + + config + + argumenttrimmode + 0 + argumenttype + 1 + fixedorder + + items + [{"imagefile":"f5384a9f3b5c25866e7a9d3ae7695edc5314091c.png","title":"Password","arg":"pass","subtitle":"Copy The Password 🔐 {var:xentry}"},{"imagefile":"f5384a9f3b5c25866e7a9d3ae7695edc5314091c.png","title":"Username","arg":"user","subtitle":"Copy The Username 🔐 {var:xentry}"},{"imagefile":"f5384a9f3b5c25866e7a9d3ae7695edc5314091c.png","title":"URL","arg":"url","subtitle":"Copy URL in Front App 🌎 {var:xentry}"},{"imagefile":"f5384a9f3b5c25866e7a9d3ae7695edc5314091c.png","title":"TOTP Code","arg":"totp","subtitle":"Copy the 6 digit TOTP code 🚦 {var:xentry}"},{"imagefile":"7f90844dbe74bce6b23ef4d1efdb60e666f4f744.png","title":"Open Databse in KeePassXC","arg":"database","subtitle":"{var:database}"},{"imagefile":"283ea61ad84289b2778e711013dd8f4a986a18b8.png","title":"Settings","arg":"settings","subtitle":"Edit Settings"},{"imagefile":"f14e77e0e9cd66bcea6195b7693ba50a93cdb51f.png","title":"{var:goBack} Go Back","arg":"back","subtitle":"Start Over"}] + matchmode + 2 + runningsubtext + + subtext + {var:xentry} + title + Menu Options + withspace + + + type + alfred.workflow.input.listfilter + uid + 6305EDB2-9809-4074-B448-ACA6C5A96BD4 + version + 1 + + + config + + argument + {var:xentry} + passthroughargument + + variables + + + type + alfred.workflow.utility.argument + uid + ECA51978-EF5B-47A3-8195-7B1ABE74A48A + version + 1 + + + config + + externaltriggerid + _settings + passinputasargument + + passvariables + + workflowbundleid + self + + type + alfred.workflow.output.callexternaltrigger + uid + 32F72B66-664B-49CD-8E36-565FF4F64662 + version + 1 + + + config + + argument + + passthroughargument + + variables + + route + {query} + + + type + alfred.workflow.utility.argument + uid + A8FEB5EC-A1B2-4490-BE46-DF67E9D75FFB + version + 1 + + + config + + externaltriggerid + _kpass + passinputasargument + + passvariables + + workflowbundleid + self + + type + alfred.workflow.output.callexternaltrigger + uid + 1B76A840-C42A-4E83-8CE2-DBF920F6E7AB + version + 1 + + + config + + openwith + + sourcefile + {var:database} + + type + alfred.workflow.action.openfile + uid + D3071C93-8EC0-4371-BBD9-3D2A80932B2D + version + 3 + + + config + + argumenttype + 2 + keyword + kpassinit + subtext + Configure the kpass integration + text + KPass Setup + withspace + + + type + alfred.workflow.input.keyword + uid + 283F690A-36C6-4B64-A552-EA75B23FA3EF + version + 1 + + + config + + concurrently + + escaping + 68 + script + ObjC.import('stdlib'); + +var app = Application.currentApplication() +app.includeStandardAdditions = true; + +var alfredApp = Application('com.runningwithcrayons.Alfred'); +var bundleId = $.getenv('alfred_workflow_bundleid') +var keychainItem = $.getenv('keychainItem') + +if (! keychainItem) { + keychainItem = "KPass_AlfredWorkflow" +} + + +try { + // Ask for KeepasxXC Database + var database = app.chooseFile({ + withPrompt: "Please select the KeepassXC database to use:", + multipleSelectionsAllowed: false, + // ofType: ["dyn.ah62d4rv4ge8003dcta"] //.kdbx extension type identifier + }) + // ofType was found with the osascript (AS): + // set dbFile to choose file with prompt "Select .kdbx file:" + // info for dbFile + + // Ask for a keychain + var keychains = app.doShellScript("security list-keychains -d user | awk '{print substr($1, 2, length($1) - 2);}'").split('\r') + var keychain = app.chooseFromList(keychains, { + withPrompt: "Select the keychain to store the password:", + emptySelectionAllowed: false, + multipleSelectionAllowed: false + }); + keychain = keychain[0] + + // Ask for KeepassXC Database password + var response = app.displayDialog("KeePassXC Database password", { + defaultAnswer: "", + buttons: ["Cancel", "Continue"], + defaultButton: "Continue", + hiddenAnswer: true, + withTitle: "Please introduce the Database Password", + withIcon: Path("/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Lockedicon.icns") + }); + + // Get password and esscape it + password = response.textReturned.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); + + // Create a new password + response = app.doShellScript("security add-generic-password -a $(id -un) -c 'kaiw' -C 'kaiw' -D 'KeepasXC Integration' -j 'Alfred KeepasXC Integration Database' -s '"+ keychainItem + "' -w '" + password + "' -U " + keychain); + + // Ask for KeepassXC Keyfile + var response = app.displayDialog("KeePassXC Database Keyfile", { + defaultAnswer: "", + buttons: ["Cancel", "Continue"], + defaultButton: "Continue", + hiddenAnswer: false, + withTitle: "[Optionally] Please introduce the path of the keyfile", + withIcon: Path("/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Lockedicon.icns") + }); + + // Get keyfile if any + keePassKeyFile = response.textReturned.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); + + // Configure Alfred env variables + alfredApp.setConfiguration('keychain', { + toValue: keychain.replace(/(^")|("$)/,""), + inWorkflow: bundleId, + exportable: false + }); + + alfredApp.setConfiguration('keychainItem', { + toValue: keychainItem.toString(), + inWorkflow: bundleId, + exportable: true + }); + + alfredApp.setConfiguration('keePassKeyFile', { + toValue: keePassKeyFile.toString(), + inWorkflow: bundleId, + exportable: false + }); + + alfredApp.setConfiguration('database', { + toValue: database.toString(), + inWorkflow: bundleId, + exportable: false + }); + + // Done + app.displayDialog("KPass Workflow configured correctly", { + buttons: ["Ok"], + defaultButton: "Ok" + }); + // displayAlert: }); + +} +catch (err) { + app.displayDialog("KPass Workflow could not be configured: "+ err.message, { + buttons: ["Ok"], + defaultButton: "Ok" + }); +} + scriptargtype + 1 + scriptfile + + type + 7 + + type + alfred.workflow.action.script + uid + 80C0730D-9C4C-4D46-8AC5-EE827B744F5B + version + 2 + + + config + + availableviaurlhandler + + triggerid + _settings + + type + alfred.workflow.trigger.external + uid + B3AAFA83-E7EB-4D37-A92B-45083BE9D555 + version + 1 + + + readme + # KPass - An Alfred KeePassXC Workflow +This workflow enables to retreive passwords from a KeePassXC database. +## Get KeePassXC - https://keepassxc.org/download/ + +The workflow uses the keepassxc-cli to interact with KeePassXC. + +The CLI is accessable just by having KeePassXC installed. + +Password is stored in Keychain for automatic usage. +- 🚨 Security Issue - (Anyone authenticated on current user can open DB!!!) +- 📋 Todo: Trigger TouchID event to authenticate with timeout. + +## Select entry and press ⏎ to use default menu options: +- Copy Password +- Copy Username +- Copy TOTP +- Copy URL +- Open Database in KeePassXC +- Settings + +# Shortcuts: +### ⌘ - Copy Password Directly | Bypass Menu +### ⇧ - Copy Username Directly | Bypass Menu +### ⌥ - Copy TOTP Code Directly | Bypass Menu +### ⌃ - Copy/Paste URL Directly | Bypass Menu + +# Changes +Menu, TOTP, URL added by CDoug. + uidata + + 0E061607-446F-42B1-A61D-7141645CC099 + + colorindex + 2 + xpos + 370 + ypos + 290 + + 12FBD320-2BCA-4186-AEED-7FE183BB71A5 + + note + Copy/Paste > Front App + xpos + 950 + ypos + 355 + + 18273CFC-8C6D-497B-BAC6-1983953354D0 + + colorindex + 2 + xpos + 990 + ypos + 250 + + 1B76A840-C42A-4E83-8CE2-DBF920F6E7AB + + colorindex + 9 + xpos + 560 + ypos + 445 + + 2758F511-8CD2-4755-AA69-10159D17EC90 + + colorindex + 3 + xpos + 370 + ypos + 60 + + 283F690A-36C6-4B64-A552-EA75B23FA3EF + + colorindex + 1 + xpos + 175 + ypos + 565 + + 2A5D5B0F-63B4-47A8-8BD4-2C9D58576D59 + + colorindex + 9 + xpos + 30 + ypos + 145 + + 32F72B66-664B-49CD-8E36-565FF4F64662 + + colorindex + 1 + xpos + 580 + ypos + 415 + + 4052074F-1000-43E3-86F0-E5A618169D2E + + colorindex + 8 + xpos + 370 + ypos + 100 + + 57089C57-FE2F-46CE-B8EF-AA89DE97018E + + colorindex + 11 + xpos + 780 + ypos + 250 + + 6305EDB2-9809-4074-B448-ACA6C5A96BD4 + + colorindex + 10 + xpos + 175 + ypos + 385 + + 72E9F265-FF7B-474C-9A9C-A18348E3C9D2 + + colorindex + 2 + note + Username + xpos + 1030 + ypos + 220 + + 75198F5E-917B-4A6C-BF0C-091140474506 + + note + copy attribute + xpos + 1290 + ypos + 220 + + 7BAAC131-49C4-497B-B5C8-2831DBD24D66 + + colorindex + 10 + xpos + 370 + ypos + 145 + + 7DD3BDE5-A157-42E5-9376-F681FB50A4EE + + colorindex + 9 + xpos + 175 + ypos + 145 + + 80C0730D-9C4C-4D46-8AC5-EE827B744F5B + + colorindex + 1 + xpos + 370 + ypos + 565 + + 82C5E557-E391-454E-A490-2EAF22853FB7 + + colorindex + 10 + xpos + 330 + ypos + 175 + + 86B11BB2-F440-40D5-8472-8099A8BDD571 + + colorindex + 3 + xpos + 950 + ypos + 50 + + 8B5C36B3-321C-4FDB-90B9-48F255AB499B + + colorindex + 3 + xpos + 780 + ypos + 60 + + 8F53E19D-FE8A-425D-88CE-3C088EC6D278 + + xpos + 1160 + ypos + 15 + + 94CBB6C8-1A78-4884-B09E-7D149D18A4D8 + + colorindex + 10 + xpos + 425 + ypos + 330 + + 99246AFC-B7C5-4DFF-9BF1-9BBE6589F303 + + colorindex + 8 + note + URL + xpos + 820 + ypos + 355 + + 9A459034-29D0-43FE-9F0A-1B01FB14F247 + + colorindex + 10 + xpos + 30 + ypos + 385 + + A8FEB5EC-A1B2-4490-BE46-DF67E9D75FFB + + colorindex + 10 + xpos + 370 + ypos + 415 + + B3AAFA83-E7EB-4D37-A92B-45083BE9D555 + + colorindex + 1 + xpos + 30 + ypos + 565 + + B99B170E-3A3C-44EC-A9B7-D6CE6E209DB7 + + colorindex + 11 + note + Password + xpos + 820 + ypos + 220 + + D2060C49-72E1-43CE-8F43-EAAD6E3816A2 + + colorindex + 10 + xpos + 1290 + ypos + 15 + + D3071C93-8EC0-4371-BBD9-3D2A80932B2D + + note + Open DB in KeePassXC + xpos + 820 + ypos + 480 + + D92BF33C-614F-4057-97C1-A9DE77A397E5 + + colorindex + 11 + xpos + 370 + ypos + 250 + + E35451E7-54B1-4C83-8C9E-F9B96B0C3016 + + colorindex + 3 + note + TOTP Code + xpos + 820 + ypos + 30 + + ECA51978-EF5B-47A3-8195-7B1ABE74A48A + + colorindex + 8 + xpos + 780 + ypos + 385 + + + userconfigurationconfig + + + config + + default + + filtermode + 0 + placeholder + Select_Your_Database.kdbx + required + + + description + KeePassDB File .kdbx + label + database + type + filepicker + variable + database + + + config + + default + + filtermode + 0 + placeholder + + required + + + description + KeePassDB File .kdbx + label + database2 + type + filepicker + variable + database_2 + + + config + + default + + filtermode + 0 + placeholder + Select your KeyFile1 + required + + + description + This corrisponds to KDB1 if your database uses one. + label + keePassKeyFile + type + filepicker + variable + keePassKeyFile + + + config + + default + + filtermode + 0 + placeholder + Select your KeyFile2 + required + + + description + This corrisponds to KDB2 if your database uses one. + label + keePassKeyFile2 + type + filepicker + variable + keePassKeyFile_2 + + + variables + + cacheFile + + cacheTimeout + 60 + database_2_old + + database_old + /Users/cdoug/Dropbox/Web/WebShareRMWP/RMWP-Web.kdbx + keePassKeyFile_2_old + + keePassKeyFile_old + + keychain + /Users/cdoug/Library/Keychains/login.keychain-db + keychainItem + KPass_AlfredWorkflow + + variablesdontexport + + keePassKeyFile_old + cacheFile + database_2_old + keePassKeyFile_2_old + keychain + database_old + + version + 2.7 + webaddress + https://github.com/Angoll/KPass + + diff --git a/kplogo.png b/kplogo.png new file mode 100644 index 0000000..295af86 Binary files /dev/null and b/kplogo.png differ diff --git a/scripts/getTOTP.sh b/scripts/getTOTP.sh new file mode 100644 index 0000000..1264274 --- /dev/null +++ b/scripts/getTOTP.sh @@ -0,0 +1,30 @@ +#Get the 6 digit TOTP code of a specific entry in the database if there is one using keepassxc-cli +export PATH='/bin:/usr/local/bin/:/usr/bin:/Applications/KeePassXC.app/Contents/MacOS/:/opt/homebrew/bin:${PATH}' +function get_TOTP { + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show --key-file "${keePassKeyFile}" -q -t "${database}" "$1" + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show -q -t "${database}" "$1" + fi +} + +function get_errorInfo { + exec 3<&1 + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R --key-file "${keePassKeyFile}" -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + fi + exec 3>&- +} + +data=$(get_TOTP "$1") +if [ $? -ne 0 ]; then + echo $(get_errorInfo) +else + echo -n $data +fi \ No newline at end of file diff --git a/scripts/getURL.sh b/scripts/getURL.sh new file mode 100644 index 0000000..e6fb6c6 --- /dev/null +++ b/scripts/getURL.sh @@ -0,0 +1,30 @@ +#Get the URL of a specific entry in the database +export PATH='/bin:/usr/local/bin/:/usr/bin:/Applications/KeePassXC.app/Contents/MacOS/:/opt/homebrew/bin:${PATH}' +function get_url { + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show --key-file "${keePassKeyFile}" -q -a URL "${database}" "$1" + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" |\ + keepassxc-cli show -q -a URL "${database}" "$1" + fi +} + +function get_errorInfo { + exec 3<&1 + if [ ! -z "${keePassKeyFile}" ]; then + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R --key-file "${keePassKeyFile}" -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + else + security find-generic-password -a $(id -un) -c 'kpas' -C 'kpas' -s "${keychainItem}" -w "${keychain}" 2>&3 |\ + keepassxc-cli ls -R -f "$database" 2>&3 | grep -Ev '(/|\[empty\]?)$' + fi + exec 3>&- +} + +data=$(get_url "$1") +if [ $? -ne 0 ]; then + echo $(get_errorInfo) +else + echo -n $data +fi \ No newline at end of file diff --git a/settings.png b/settings.png new file mode 100644 index 0000000..f530e51 Binary files /dev/null and b/settings.png differ