diff --git a/README.md b/README.md index 5c95bde..702550c 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,14 @@ The `bw` cli is great, but not very user-friendly. `bwzy` tries to make this quicker by caching the information and presenting it via the magnificient [fzf](https://junegunn.github.io/fzf/). # current features +- READ-ONLY ui - search based on name and folder - copy user/pass/totp - cache the items in shared memory (`/dev/shm/`) to make it fast -- cache does not persist through reboots +- cache does not persist through reboots (by default) - refresh/flush cache - preview items in `YAML` form +- auto-fill for hyprland # requirements @@ -24,15 +26,69 @@ The following software is needed by `bwzy`: - [OATH Toolkit](https://www.nongnu.org/oath-toolkit/) allows generating TOTP tokens - [charmbracelet - gum](https://github.com/charmbracelet/gum) for the loading spinner and color -it also expects `sed` and `awk` to be available +it also expects `grep`, `sed` and `awk` to be available + +Additinally, you will need clipboard and keyboard automation such as `wtype` and `wl-copy` under wayland. + +## configuration + +All configuration is done via environment variables, with defaults shown + +```bash +BWZY_CACHE=`/dev/shm/bwzy-cache` # where the passwords are cached +BWZY_KEEP_CACHE='true' # set to false and cache will be purged +BWZY_COPY_CMD='wl-copy' # the command to copy something to the clipboard +BWZY_TYPE_CMD='wtype' # the command used to type / send keyboard events +BWZY_HIDE_CMD='' # the command to hide bwzy +BWZY_REFOCUS_CMD='' # the command to refocuse the previous window +BWZY_COPY_AND_HIDE='true' # set to 'false' to not hide bwzy on copy +BWZY_NOTIFY_CMD='notify-send -i bitwarden' # send a notification +# cosmetic overrides which adjust the looks +BWZY_USER_SYMBOL='u+' +BWZY_PASS_SYMBOL='p+' +BWZY_TOTP_SYMBOL='t+' +BWZY_LINK_SYMBOL='l+' +BWZY_AUTO_SYMBOL='a+' +BWZY_FOLDER_SYMBOL='/' +BWZY_POINTER_SYMBOL='> ' +BWZY_PROMPT_SYMBOL='? ' +``` + +Note: under [hyprland](https://hypr.land/) the following works: +```bash +BWZY_HIDE_CMD=hyprctl dispatch movetoworkspacesilent special:tools,title:bwzy +BWZY_REFOCUS_CMD=hyprctl dispatch focuscurrentorlast +``` +which places the bwzy window launched vi the [bwzy.desktop](./bwzy.desktop) file into a special workspace when not needed. + +```bash +BWZY_USER_SYMBOL=' ' +BWZY_PASS_SYMBOL=' ' +BWZY_AUTO_SYMBOL=' ' +BWZY_TOTP_SYMBOL=' ' +BWZY_LINK_SYMBOL=' ' +BWZY_FOLDER_SYMBOL='/' +BWZY_POINTER_SYMBOL=' ' +BWZY_PROMPT_SYMBOL=' ' +``` ## arch install ```bash pacman -S fzf bitwarden-cli jq haskell-yaml oath-toolkit gum ``` +## install dependency + + +Arch Linux: +```bash +sudo pacman -S --needed wtype ydotool xdotool xvkbd wl-clipboard xclip xsel bat jq sed awk fzf +``` +## tips and tricks + +By default the cache is removed on reboot since it lives in `/dev/shm/`. if you have a secure encrypted file system you can override the cache location so that it persists during reboots. Be safe and know your risks. # feature ideas -- auto-fill -- "archive" feature to filter things +- ~~auto-fill~~ (done) +- ~~"archive" feature to filter thingsi~~ (done) - ability to edit an entry -- ability to add a new e.ntry +- ability to add a new entry diff --git a/bwzy b/bwzy index a52d07e..4cfec27 100755 --- a/bwzy +++ b/bwzy @@ -2,25 +2,31 @@ # Trap EXIT signal to clean up by default cleanup() { - echo "Cleaning up temporary directories..." + echo "Cleaning up temporary directory..." rm -rf "$BWZY_CACHE" } [[ "$BWZY_KEEP_CACHE" != 'true' ]] && trap cleanup EXIT # defaults BWZY_CACHE="${BWZY_CACHE:-/dev/shm/bwzy-cache}" +BWZY_FILTER="${BWZY_FILTER:-zz~ }" + BWZY_DEFAULT_OPTS=(--layout reverse --height 100%) BWZY_ONESHOT_OPTS=(--layout default --height 10 --no-header) -BWZY_ONESHOT_EXIT="+accept" + +bwzy_autofill=${BWZY_AUTOFILL_HELPER:-"$(dirname "$0")/bwzy-autofill"} + BWZY_POINTER_SYMBOL=${BWZY_POINTER_SYMBOL:-> } -BWZY_MARKER_SYMBOL=${BWZY_MARKER_SYMBOL:-! } BWZY_PROMPT_SYMBOL=${BWZY_PROMPT_SYMBOL:-? } BWZY_USER_SYMBOL=${BWZY_USER_SYMBOL:-u+} BWZY_PASS_SYMBOL=${BWZY_PASS_SYMBOL:-p+} BWZY_TOTP_SYMBOL=${BWZY_TOTP_SYMBOL:-t+} BWZY_LINK_SYMBOL=${BWZY_LINK_SYMBOL:-l+} BWZY_AUTO_SYMBOL=${BWZY_AUTO_SYMBOL:-a+} +BWZY_FOLDER_SYMBOL=${BWZY_FOLDER_SYMBOL:-/} +export GLAMOUR_STYLE=tokyo-night +# these are needed by the auto-completer export BWZY_COPY_CMD=${BWZY_COPY_CMD:-wl-copy} export BWZY_TYPE_CMD=${BWZY_TYPE_CMD:-wtype} @@ -30,6 +36,7 @@ bwzy is a fuzzy wrapper to the bitwarden cli Usage: `bwzy` will run the fuzzy selection `bwzy -1` exit after first action + `bwzy -a` show all items (no filter) `bwzy -s` syncs the vault `bwzy -f` force syncs the vault (implies `-s`) `bwzy -c` clears the cache @@ -37,35 +44,43 @@ Usage: `bwzy -h` shows this help EOH -# read in the options -CLEAR_CACHE=false -SYNC_CACHE=false -FORCE_SYNC=false -DEBUG=false +# set some defaults to override based on options +CLEAR_CACHE='false' +SYNC_CACHE='false' +FORCE_SYNC='false' +DEBUG='false' BWZY_OPTS=("${BWZY_DEFAULT_OPTS[@]}") -while getopts "dcfhs1" o; do +FILTER_ARG='-v' # argument to grep +ONESHOT='false' + +# read in the options +while getopts "acdfhis1" o; do case "${o}" in 1) + ONESHOT='true' BWZY_OPTS=( "${BWZY_ONESHOT_OPTS[@]}" ) - BWZY_EXIT=${BWZY_ONESHOT_EXIT} + ;; + a) + BWZY_FILTER='' + FILTER_ARG='' + ;; + c) + CLEAR_CACHE='true' + ;; + d) + DEBUG='true' + ;; + f) + FORCE_SYNC='true' + SYNC_CACHE='true' ;; h) # show help and exit echo "$HELP_TEXT" | gum format exit 0 ;; - d) - DEBUG=true - ;; - c) - CLEAR_CACHE=true - ;; - f) - FORCE_SYNC=true - SYNC_CACHE=true - ;; s) - SYNC_CACHE=true + SYNC_CACHE='true' ;; *) usage @@ -74,6 +89,8 @@ while getopts "dcfhs1" o; do done shift $((OPTIND-1)) +query=$* + # begin of main code function log() { [[ $DEBUG == 'true' ]] && gum log "$@" @@ -129,62 +146,70 @@ folder_sed=$(jq -r '.[] | [ "s@" , .id , "@" , .name , "@;" ] | join("")' < "$fo # define the logic here for use in fzf call jq_select_id="jq -r '.[] | select(.id == \"{1}\")" +pre_action="execute-silent($BWZY_REFOCUS_CMD && $BWZY_HIDE_CMD)" + # set up queries for the fields select_user="$jq_select_id | .login.username' <$items" select_pass="$jq_select_id | .login.password' <$items" select_totp="$jq_select_id | .login.totp' <$items | sed 's/.*secret=//; s/&.*//' | oathtool -b --totp -" select_link="$jq_select_id | .login.uris[1].uri' <$items" +select_user_pass_totp="$select_user; $select_pass; $select_totp" -copy_user="execute-silent($select_user | $BWZY_COPY_CMD)" -copy_pass="execute-silent($select_pass | $BWZY_COPY_CMD)" -copy_totp="execute-silent($select_totp | $BWZY_COPY_CMD)" -copy_link="execute-silent($select_link | $BWZY_COPY_CMD)" +if [[ $ONESHOT == 'true' ]]; then + copy_user="become($select_user)" + copy_pass="become($select_pass)" + copy_totp="become($select_totp)" + copy_link="become($select_link)" + auto_paste="become(($select_user_pass_totp))" +else + copy_user="execute-silent($select_user | $BWZY_COPY_CMD)" + copy_pass="execute-silent($select_pass | $BWZY_COPY_CMD)" + copy_totp="execute-silent($select_totp | $BWZY_COPY_CMD)" + copy_link="execute-silent($select_link | $BWZY_COPY_CMD)" + auto_paste="execute-silent(($select_user_pass_totp) | $bwzy_autofill)" -user_prompt="change-prompt($BWZY_USER_SYMBOL)" -pass_prompt="change-prompt($BWZY_PASS_SYMBOL)" -totp_prompt="change-prompt($BWZY_TOTP_SYMBOL)" -link_prompt="change-prompt($BWZY_LINK_SYMBOL)" - -bwzy_autofill="$(dirname "$0")/bwzy-autofill" # TODO: makde this configurable -auto_paste="execute-silent(($select_user; $select_pass; $select_totp) | $bwzy_autofill)" -auto_prompt="change-prompt($BWZY_AUTO_SYMBOL)" + copy_user="${pre_action}+${copy_user}+change-prompt($BWZY_USER_SYMBOL)" + copy_pass="${pre_action}+${copy_pass}+change-prompt($BWZY_PASS_SYMBOL)" + copy_totp="${pre_action}+${copy_totp}+change-prompt($BWZY_TOTP_SYMBOL)" + copy_link="${pre_action}+${copy_link}+change-prompt($BWZY_LINK_SYMBOL)" + auto_paste="${pre_action}+${auto_paste}+change-prompt($BWZY_AUTO_SYMBOL)" +fi preview_item="$jq_select_id' < $items | json2yaml | bat --color=always -p -l yaml" -read -r -d '' fzf_header <<'FZF_HEADER' -[c-/] 󰔡 preview [c-w] 󰔡 preview wrap [c-t] 󰔡 this help +read -r -d '' fzf_header <