#!/bin/sh set -eu TYPE_CMD="wtype -" help=0 autotype=0 _trim() { var="$*" # remove leading whitespace characters var="${var#"${var%%[![:space:]]*}"}" # remove trailing whitespace characters var="${var%"${var##*[![:space:]]}"}" printf '%s' "$var" } _parse_fields() { has_username=0 # Note: \n can not be last, or it will be stripped by $() IFS=$(printf '\n\t') fields="$(pass show "$password" | tail -n +2 | cut -d: -f1 -s)" field_list="${field_list}password\n" for line in $fields; do if [ "$line" = "username" ]; then has_username=1 field_list="${field_list}$line\n" elif [ "$line" = "otpauth" ]; then field_list="${field_list}OTP\n" elif [ "$line" = autotype_always ]; then autotype=1 else field_list="${field_list}$line\n" fi done if [ "$typeit" -eq 1 ] && [ "$has_username" -eq 1 ]; then printf "autotype\n" fi printf '%s' "$field_list" unset IFS } _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 printf '%s' "$(_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 ) typeit=1; shift;; -- ) shift; break ;; * ) break ;; esac done if [ "$help" -eq 1 ]; then _usage >&2 exit 0 fi prefix=${PASSWORD_STORE_DIR-~/.password-store} password_files="$(find "$prefix" -name "*.gpg" -execdir basename {} .gpg ';')" password=$(printf '%s' "$password_files" | wofi --dmenu "$@") [ -n "$password" ] || exit field_list="$(_parse_fields)" field_count="$(echo "$field_list" | wc -l)" if [ "$squash" -eq 1 ] && [ "$field_count" -eq 1 ]; then field="password" elif [ "$autotype" -ne 1 ]; then field=$(printf '%s' "$field_list" | wofi --dmenu) fi if [ $typeit -eq 0 ]; then wl-copy "$(_pass_get "$field")" else if [ "$field" = "autotype" ] || [ "$autotype" -eq 1 ]; then username=$(_pass_get "username") password=$(_pass_get "password") printf "%b\t%b\n" "${username}" "${password}" | $TYPE_CMD else _pass_get "$field" | "$TYPE_CMD" fi fi