Skip to content
Open
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This plugin relies on the following:
In any tmux mode:

- `prefix + u` - list login items in a bottom pane.
- `prefix + C` - clear the cache of tmux-1password.

## Install

Expand Down Expand Up @@ -170,6 +171,12 @@ Items come in the following format from which the filter operates:
]
```

## Security

This plugin is based on using `op list-items` to get a filtered list of passwords from your vault, and them asking for the password you want with `op get-item`. To improve the performance, we've added a cache file which has a TTL of 30 minutes and stores a simple list containing your account names and the related IDs.

**No password is stored on the disk,** just a simple pointer to be used in the future when you ask to fetch a specific password.

## Prior art

Also see:
Expand Down
3 changes: 3 additions & 0 deletions plugin.tmux
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ main() {
done

local -r opt_key="$(get_tmux_option "@1password-key" "u")"
local -r clear_key="$(get_tmux_option "@1password-key" "C")"

tmux bind-key "$opt_key" \
run "tmux split-window -l 10 \"$CURRENT_DIR/scripts/main.sh '#{pane_id}'\""

tmux bind-key "$clear_key" run "$CURRENT_DIR/scripts/main.sh clear-cache"
}

main "$@"
52 changes: 50 additions & 2 deletions scripts/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ source "./spinner.sh"

# ------------------------------------------------------------------------------

declare -r TMP_TOKEN_FILE="$HOME/.op_tmux_token_tmp"
declare -r TMP_TOKEN_FILE="/tmp/tmux-op-token"
declare -r CACHE_FILE="/tmp/tmux-op-items"
declare -r CACHE_TTL=1800 # 30 minutes, since we cannot fetch passwords with invalid session token

declare -r OPT_SUBDOMAIN="$(get_tmux_option "@1password-subdomain" "my")"
declare -r OPT_VAULT="$(get_tmux_option "@1password-vault" "")"
Expand Down Expand Up @@ -46,7 +48,29 @@ op_get_session() {
}

get_op_items() {
clear_old_cache

if [[ -e $CACHE_FILE ]]; then
echo "$(cat $CACHE_FILE)"
else
fetch_items
fi
}

clear_old_cache() {
if [[ -e $CACHE_FILE ]]; then
local last_update="$(stat -c %Y $CACHE_FILE)"
local now="$(date +%s)"
local seconds_since_last_update="$(($now-$last_update))"

# Remove cache file if last cache was from 30 minutes ago
if [[ $seconds_since_last_update < $CACHE_TTL ]]; then
rm $CACHE_FILE
fi
fi
}

fetch_items() {
# The structure (we need) looks like the following:
# [
# {
Expand Down Expand Up @@ -84,6 +108,14 @@ get_op_items() {
| jq "$JQ_FILTER" --raw-output
}

cache_items() {
local items=$1

if ! [[ -e $CACHE_FILE ]]; then
echo "$items" > $CACHE_FILE
fi
}

get_op_item_password() {
local -r ITEM_UUID="$1"

Expand Down Expand Up @@ -127,6 +159,22 @@ get_op_item_password() {
# ------------------------------------------------------------------------------

main() {
local -r command=$@

if [[ $command == "clear-cache" ]]; then
clear_cache
else
prompt_op $@
fi
}

clear_cache() {
rm $CACHE_FILE

display_message "Cache cleared"
}

prompt_op() {
local -r ACTIVE_PANE="$1"

local items
Expand All @@ -153,6 +201,7 @@ main() {
spinner_stop
fi

cache_items "$items"
selected_item_name="$(echo "$items" | awk -F ',' '{ print $1 }' | fzf --no-multi)"

if [[ -n "$selected_item_name" ]]; then
Expand All @@ -170,7 +219,6 @@ main() {
# Clear clipboard
clear_clipboard 30
else

# Use `send-keys`
tmux send-keys -t "$ACTIVE_PANE" "$selected_item_password"
fi
Expand Down