A Wayland-native interface for conveniently using pass
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wofi-pass/wofi-pass

106 lines
2.7 KiB

#!/bin/sh
set -eu
help=0
autotype=0
TYPE_CMD="wl-copy"
_trim() {
var="$*"
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "$var"
}
# the explicit newlines here are funky, but needed due to command substitution
# stripping trailing newlines so `printf '%s\n' "$line"` cannot be used
_parse_fields() {
has_username=0
fields="$(pass show "$password" | tail -n +2 | cut -d: -f1 -s)"
field_list="password
"
for line in $fields; do
if [ "$line" = "username" ]; then
has_username=1
field_list="$field_list$line
"
elif [ "$line" = "otpauth" ]; then
field_list="${field_list}OTP
"
elif [ "$line" = autotype_always ]; then
autotype=1
else
field_list="$field_list$line
"
fi
done
if [ "$TYPE_CMD" = "wtype -" ] && [ "$has_username" -eq 1 ]; then
printf "autotype
"
fi
printf '%s' "$field_list"
}
_pass_field() {
_trim "$(pass show "$password" | tail -n+2 | grep "^${*}:.*$" | cut -d: -f1 -s --complement)"
}
_pass_get() {
if [ "$1" = "password" ]; then
pass show "$password" | { IFS= read -r pass; printf %s "$pass"; }
elif [ "$1" = "OTP" ]; then
pass otp "$password" | tail -n1 | { IFS= read -r pass; printf %s "$pass"; }
else
_pass_field "$@"
fi
}
_usage() {
printf "Usage: wofi-pass [options]\n"
printf " -a, --autotype autotype whatever entry is chosen\n"
printf " -h, --help show this help message\n"
printf " -s, --squash don't show field choice if password file only contains password\n"
printf " -t, --type type the selection instead of copying to clipboard\n"
}
OPTS="$(getopt --options ahst --longoptions autotype,help,squash,type -n 'wofi-pass' -- "$@")"
eval set -- "$OPTS"
while true; do
case "$1" in
-a | --autotype ) autotype=1; shift ;;
-h | --help ) help=1; shift ;;
-s | --squash ) squash=1; shift ;;
-t | --type ) TYPE_CMD="wtype -"; shift;;
-- ) shift; break ;;
* ) break ;;
esac
done
if [ "$help" -eq 1 ]; then
_usage >&2
exit 0
fi
cd "${PASSWORD_STORE_DIR:-$HOME/.password-store}"
password_files="$(find . -name "*.gpg" | sed "s/^\.\/\(.*\)\.gpg$/\1/")"
password=$(printf '%s\n' "$password_files" | wofi --dmenu)
[ -n "$password" ] || exit
field_list="$(_parse_fields)"
field_count="$(printf '%s' "$field_list" | wc -l)"
if [ "$squash" -eq 1 ] && [ "$field_count" -eq 0 ]; then
field="password"
elif [ "$autotype" -ne 1 ]; then
field=$(printf '%s\n' "$field_list" | wofi --dmenu)
fi
if [ "$field" = "autotype" ] || [ "$autotype" -eq 1 ]; then
username=$(_pass_get "username")
password=$(_pass_get "password")
printf '%s\t%s\n' "$username" "$password" | $TYPE_CMD
else
_pass_get "$field" | $TYPE_CMD
fi