#!/bin/bash shopt -s nullglob globstar 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 [[ -f "$PREFIX/$1.gpg" ]] || die "otp/$1 does not exist" SITE="$1" else OTPFILES=( "$PREFIX"/**/*.gpg ) OTPFILES=( "${OTPFILES[@]#"$PREFIX"/}" ) OTPFILES=( "${OTPFILES[@]%.gpg}" ) SITE="$(printf '%s\n' "${OTPFILES[@]}" | fzf --height 8 --reverse --no-multi --prompt="Select Site: ")" if [[ ! "$SITE" ]]; then exit; fi fi URL="$(pass "otp/$SITE" 2>/dev/null | head -n1)" [[ "$?" == "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 &>/dev/null else xclip -o -selection "$X_SELECTION"; fi } setclip() { [[ -n "$CLIP" ]] || return 0 if command -v termux-clipboard-set; then termux-clipboard-set &>/dev/null 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 tput cnorm exit 0 } 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 )) BLANK=$(( $TOTAL - $FULL)) echo -n " " tput bold; tput setab 8; echo -ne "\r " tput setaf 8; tput setab 18; echo -n " " tput setaf 6; echo -n "$SITE" tput setaf 8; echo -n "  " tput sgr0 tput setaf 16; tput setab 18; echo -n "$CODE" tput setaf 8; echo -n " " for i in `seq $FULL`; do echo -n "█"; done echo -n "${BLOCKS[$PARTIAL]}" for i in `seq $BLANK`; do echo -n " "; done tput sgr0; tput setaf 18; echo -n "" tput sgr0 #sleep 0.1 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