From 7dc51d83483f5e5c8594a282c19c7ac5a34669d5 Mon Sep 17 00:00:00 2001 From: Adam Hovorka Date: Fri, 5 Jun 2020 17:12:07 -0600 Subject: Add clipboard and completion to otp --- base/otp | 52 +++++++++++++++++++++++++++++++++++++++---------- base/zsh/completion.zsh | 11 +++++++++++ 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 -- cgit v1.2.3-70-g09d2