#!/bin/bash set -eo pipefail [ -n "$DEBUG" ] && set -x printpass=${_SECM_PRINT:-} printraw=${_SECM_PRINTRAW:-} listandexit= while getopts Plrh opt; do case ${opt} in P) printpass=1 ;; r) printraw=1 ;; l) listandexit=1 ;; h | ?) echo "usage: secretmenu [-bp] [-Pr] [-l] [query]" echo exit 2 ;; esac done shift $((OPTIND - 1)) # check requirements for tool in bemenu fd flock fzf jq rbw; do if ! command -v "$tool" >/dev/null; then printf "%s: %s not installed but required\n" "$(basename "$0")" "$tool" >&2 exit 1 fi done __menu() { if [ -t 1 ]; then echo "terminal mode not implemented" exit 1 fi MENU_PROMPT="󰌆 secret" menu -l10 --accept-single ${@:+--filter "$@"} } __list_secrets() { rbw list --fields name,user,folder,id | column -t -s $'\t' } __query_secret() { # query by the last space-separated item (id) local id=${1##* } echo "$id" >&2 rbw get --raw -- "$id" 2>&1 # jq '.data + (.fields|map({(.name|@text|ascii_downcase): .value})|add)' -r | column -s: -t } if [ -n "$printraw" ]; then __handle() { jq } elif [ -n "$printpass" ]; then __handle() { jq -r '.data.password' } else # copy to clipboard __handle() { jq -r '.data.username, .data.password' | awk 'NR==2 {system("wl-copy -n \"" $0 "\"");hit+=1} NR==1 {system("wl-copy -n -p \"" $0 "\"");hit+=1} END{if(hit==0){print("no secret found") >/dev/stderr; exit(1);}}' } fi # main if [ -n "$listandexit" ]; then __list_secrets exit 0 fi # ensure only one menu runs at a time lockfile="$XDG_RUNTIME_DIR"/secretmenu.lock [ "$FLOCKER" != "$lockfile" ] && exec env FLOCKER="$lockfile" _SECM_PRINT="$printpass" _SECM_PRINTRAW="$printraw" flock -ew 30 "$lockfile" "$0" "$@" trap '{ env UNSAFE=1 rm $lockfile 2>/dev/null || true; }' EXIT TERM INT ico=$(iconez -fs -n dialog-password-symbolic) trap '{ notify-send -a secretmenu -i "${ico}" -c error "secretmenu: failed :(" "pipefail"; exit 1; }' ERR pw=$(__list_secrets | __menu "$@") __query_secret "$pw" | __handle __ok=$? [ -n "$printpass" ] && exit "$__ok" if [ "$__ok" -eq 0 ]; then notify-send \ -a secretmenu \ -i "${ico}" \ 'secretmenu: secret copied' \ 'will be removed after next paste' fi exit "$__ok"