#!/usr/bin/env bash-hammer #export IFS='\t\n' set +e require /system require /args # Helpers vault_is_json() { pass "$1" | jshon -Q &>/dev/null; } vault_exists() [[ -f "${Opts[store]}/$1.gpg" ]] check_argn() { # Check for the number of args the dumb way. (( $# < 2 )) && System.die 113 (( $# > 3 )) && System.die 113 declare length=$1 min=$2 max=$3 (( length < min )) && System.die 1 "Too few arguments" [[ "$max" ]] && { (( length > max )) && System.die 1 "Too many arguments" } return 0 } # Our options declare -A Opts Flags # Default Opts Opts[pw_len]=16 Opts[login]='fbt@fleshless.org' Opts[selection]="${X_SELECTION:-clipboard}" Opts[store]="$HOME/.password-store" Opts[tmp_dir]='/tmp' # Handle arguments Args error argv "$@" << 'end' flags -c Flags[clip] -e Flags[edit] -g Flags[pwgen] params -l Opts[pw_len] -u Opts[login] -s Opts[selection] end (( $? )) && System.die "$?" "$error" set -- "${argv[@]}" case "$1" in (new|show|add) Opts[action]=$1 shift ;; (cp|edit|git|grep|help|init|insert|ls|mv|rm) exec pass "$@" ;; esac case "${Opts[action]:-show}" in (new) check_argn "${#@}" 1 1; vault="$1" # Check if the damn thing already exists vault_exists "$vault" && System.die 1 "Vault '$vault' already exists" (( "${Flags[pwgen]}" )) && { new_pass=$(pwgen "${Opts[pw_len]}" 1) } pass insert -m "$vault" < <( jshon -Q -n {} \ -s "$new_pass" -i "password" \ -s "${Opts[login]}" -i "login" ) (( "${Flags[edit]}" )) && { pass edit "$vault" } (( "${Flags[clip]}" )) && { printf '%s' "$new_pass" | xclip -selection "${Opts[selection]}" } ;; (show) check_argn "${#@}" 1; vault=$1 for i in "${@:2}"; do items+=( -e "$i" ) done [[ "$items" ]] || items=( -e 'password' ) vault_exists "$vault" || System.die 1 "Vault does not exist: $1" if vault_is_json "$vault"; then pass=$(pass "$vault" | jshon "${items[@]}" -u) || { System.die $? "Failed to extract json data from $vault/$field" } else [[ "$2" ]] && err "Warning: ignoring '$field', because '$vault' is not a json vault" pass=$(pass "$vault") fi if (( "${Flags[clip]}" )); then printf '%s' "$pass" | xclip -selection "${Opts[selection]}" else printf '%s\n' "$pass" fi ;; (add) check_argn "${#@}" 2 3; vault=$1 field=$2; data=$3 vault_exists "$vault" || System.die 1 "Vault does not exist: $1" vault_is_json "$vault" || System.die 1 "Not a valid json vault: $1" json=$( pass "$vault" ) jshon -s "$data" -i "$field" <<< "$json" | pass insert -m "$vault" ;; (*) pass "$action" "$@";; esac