From b560a593f21feaba1e4b4c11a8adc50c1a84281d Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Fri, 8 Mar 2024 11:23:49 +0100 Subject: Add clip extension --- extension/clip.bash | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ extension/otp.bash | 4 +++ extension/prompt.bash | 2 ++ 3 files changed, 83 insertions(+) create mode 100755 extension/clip.bash (limited to 'extension') diff --git a/extension/clip.bash b/extension/clip.bash new file mode 100755 index 0000000..b6e572e --- /dev/null +++ b/extension/clip.bash @@ -0,0 +1,77 @@ +#!/bin/bash + +# The clipboard code was taken from pass + +X_SELECTION="${CRYPT_X_SELECTION:-clipboard}" +CLIP_TIME="${CRYPT_STORE_CLIP_TIME:-45}" +BASE64="base64" + +_clip() { + if [[ -n $WAYLAND_DISPLAY ]]; then + local copy_cmd=( wl-copy ) + local paste_cmd=( wl-paste -n ) + if [[ $X_SELECTION == primary ]]; then + copy_cmd+=( --primary ) + paste_cmd+=( --primary ) + fi + local display_name="$WAYLAND_DISPLAY" + elif [[ -n $DISPLAY ]]; then + local copy_cmd=( xclip -selection "$X_SELECTION" ) + local paste_cmd=( xclip -o -selection "$X_SELECTION" ) + local display_name="$DISPLAY" + else + error "No X11 or Wayland display detected" + fi + + if [[ "$2" == "clear" ]]; then + local sleep_argv0="password store sleep on display $display_name" + + # NOTE: base64 is needed to store binary data in bash + pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.5 + local before="$("${paste_cmd[@]}" 2>/dev/null | $BASE64)" + echo -n "$1" | "${copy_cmd[@]}" || error "Could not copy data to the clipboard" + ( + ( exec -a "$sleep_argv0" bash <<< "trap 'kill %1' TERM; sleep '$CLIP_TIME' & wait" ) + local now="$("${paste_cmd[@]}" | $BASE64)" + [[ $now != $(echo -n "$1" | $BASE64) ]] && before="$now" + qdbus org.kde.klipper /klipper org.kde.klipper.klipper.clearClipboardHistory &>/dev/null + echo "$before" | $BASE64 -d | "${copy_cmd[@]}" + ) >/dev/null 2>&1 & disown + echo "Copied $NAME to clipboard. Will clear in $CLIP_TIME seconds." + else + echo -n "$1" | "${copy_cmd[@]}" || error "Could not copy data to the clipboard" + echo "Copied $NAME to clipboard" + fi +} + +clip_file() { + local opts noclear=clear + opts="$($GETOPT -o '' -l clip-persistent -n "$PROGRAM" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + --clip-persistent) noclear=; shift ;; + --) shift; break ;; + esac done + _clip "$(<"$FILE")" "$noclear" +} + +clip_wrap() { + local cmd="$1" args=() clip=0 noclear=clear + shift + + # NOTE: For whatever reason here I didn't use getopt + for a in "$@"; do + case $a in + -c|--clip) clip=1 ;; + --clip-persistent) clip=1; noclear= ;; + *) args+="$a" ;; + esac + done + + if [[ $clip -eq 1 ]]; then + _clip "$(eval "$cmd" "${args[@]}")" "$noclear" + else + eval "$cmd" "${args[@]}" + fi +} diff --git a/extension/otp.bash b/extension/otp.bash index 6eb8266..62045bb 100755 --- a/extension/otp.bash +++ b/extension/otp.bash @@ -1,3 +1,7 @@ +#!/bin/bash + +# The OTP parsing code was taken from pass-otp + _otp_parse() { urldecode() { local url_encoded="${1//+/ }" diff --git a/extension/prompt.bash b/extension/prompt.bash index 9c5c350..26d8f4b 100755 --- a/extension/prompt.bash +++ b/extension/prompt.bash @@ -1,3 +1,5 @@ +#!/bin/bash + single_prompt() { local inp read -r -p "Enter contents of $NAME ($ENTRY): " -e inp -- cgit v1.2.3