aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Hovorka <[email protected]>2020-06-05 17:12:07 -0600
committerAdam Hovorka <[email protected]>2020-06-05 17:12:07 -0600
commit7dc51d83483f5e5c8594a282c19c7ac5a34669d5 (patch)
treef8f5721965dc1dbaba2f43016c010e5c643736de
parent424a5386b0392ffe4377f4009f01ddf520a7bc64 (diff)
Add clipboard and completion to otp
-rwxr-xr-xbase/otp52
-rw-r--r--base/zsh/completion.zsh11
2 files changed, 53 insertions, 10 deletions
diff --git a/base/otp b/base/otp
index e8c11f9..cf1f278 100755
--- a/base/otp
+++ b/base/otp
@@ -2,18 +2,21 @@
shopt -s nullglob globstar
-PREFIX=${PASSWORD_STORE_DIR-~/.password-store}
-PREFIX="$PREFIX/otp"
-if [[ ! -d "$PREFIX" ]]; then
- echo "Pass OTP does not exist" >&1
+die() {
+ echo "$@" >&2
exit 1
+}
+
+PREFIX=${PASSWORD_STORE_DIR-~/.password-store}/otp
+[[ -d "$PREFIX" ]] || die "Pass OTP directory does not exist"
+
+if [[ "$1" == "-c" || "$1" == "--clip" ]]; then
+ CLIP=1
+ shift
fi
if [[ "$1" ]]; then
- if [[ ! -f "$PREFIX/$1.gpg" ]]; then
- echo "otp/$1 does not exist" >&1
- exit 1
- fi
+ [[ -f "$PREFIX/$1.gpg" ]] || die "otp/$1 does not exist"
SITE="$1"
else
OTPFILES=( "$PREFIX"/**/*.gpg )
@@ -25,14 +28,34 @@ else
fi
URL="$(pass "otp/$SITE" 2>/dev/null | head -n1)"
-if [[ "$?" != "0" ]]; then echo "Authentication failed" >&2; exit 1; fi
-PERIOD="$(echo "$URL" | sed 's/^.*period=\([0-9]\+\).*$/\1/')"
+[[ "$?" == "0" ]] || die "Authentication failed"
+PERIOD="$(echo "$URL" | sed -n 's/^.*period=\([0-9]\+\).*$/\1/p')"
+if [[ -z "$PERIOD" ]]; then PERIOD=30; fi
#BLOCKS=(" " "▏" "▎" "▍" "▌" "▋" "▊" "▉")
BLOCKS=(" " "▎" "▌" "▊")
TOTAL=$(( $PERIOD / 4 ))
echo
+X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}"
+
+getclip() {
+ [[ -n "$CLIP" ]] || return 0
+ if command -v termux-clipboard-get; then termux-clipboard-get
+ else xclip -o -selection "$X_SELECTION"; fi
+}
+
+setclip() {
+ [[ -n "$CLIP" ]] || return 0
+ if command -v termux-clipboard-set; then termux-clipboard-set
+ else xclip -selection "$X_SELECTION"; fi
+}
+
+BEFORE="$(getclip 2>/dev/null | base64)"
+
function finish {
+ # Clipboard managers frequently write their history out in plaintext, so we axe it here:
+ qdbus org.kde.klipper /klipper org.kde.klipper.klipper.clearClipboardHistory &>/dev/null
+ echo "$BEFORE" | base64 -d | setclip
echo -ne "\r"
tput el
tput cuu1
@@ -44,7 +67,13 @@ trap finish SIGINT SIGTERM SIGQUIT
tput civis
while :; do
+ OLDCODE="$CODE"
CODE="$(pass otp "otp/$SITE" 2>/dev/null)"
+ if [[ "$CODE" != "$OLDCODE" ]]; then
+ echo -n "$CODE" | setclip ||
+ die "Error: Could not copy data to the clipboard"
+ fi
+
WAIT=$(( $PERIOD - ( $(date +%s) % $PERIOD ) ))
FULL=$(( $WAIT / 4 ))
PARTIAL=$(( $WAIT % 4 ))
@@ -67,4 +96,7 @@ while :; do
read -rsn1 -t.1 INP
if [[ "$INP" = "q" || "$INP" = "Q" ||
"$INP" = "$(echo -ne "\e")" ]]; then finish; fi
+
+ NOW="$(getclip | base64)"
+ [[ $NOW != $(echo -n "$CODE" | base64) ]] && BEFORE="$NOW"
done
diff --git a/base/zsh/completion.zsh b/base/zsh/completion.zsh
index f9e452d..ae4d7c3 100644
--- a/base/zsh/completion.zsh
+++ b/base/zsh/completion.zsh
@@ -79,3 +79,14 @@ fi
zstyle -e ':completion:*:(ssh|scp|sftp|rsh|rsync):hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%[# ]*}//,/ })'
+_otp() {
+ local IFS=$'\n'
+ local prefix
+ _arguments : \
+ "-c[put it on the clipboard]" \
+ "--clip[put it on the clipboard]"
+ zstyle -s ":completion:${curcontext}:" prefix prefix || prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
+ _values -C 'passwords' ${$(find -L "$prefix/otp" \( -name .git -o -name .gpg-id \) -prune -o -type f -print 2>/dev/null | sed -e "s#${prefix}/otp/\{0,1\}##" -e 's#\.gpg##' -e 's#\\#\\\\#' | sort):-""}
+}
+
+compdef _otp otp