210 lines
6.4 KiB
Bash
210 lines
6.4 KiB
Bash
# ============================================================================
|
|
# Password Manager Integration for Zsh (LastPass Only)
|
|
# ============================================================================
|
|
# Unified interface for LastPass CLI
|
|
#
|
|
# Usage:
|
|
# pw list # List all items
|
|
# pw get <item> # Get password
|
|
# pw otp <item> # Get OTP/TOTP code
|
|
# pw search <query> # Search items
|
|
# pw copy <item> # Copy password to clipboard
|
|
#
|
|
# Supported: LastPass (lpass)
|
|
#
|
|
# Add to .zshrc:
|
|
# source ~/.dotfiles/zsh/functions/password-manager.zsh
|
|
# ============================================================================
|
|
|
|
# ============================================================================
|
|
# Configuration
|
|
# ============================================================================
|
|
|
|
# Colors
|
|
typeset -g PW_GREEN=$'\033[0;32m'
|
|
typeset -g PW_BLUE=$'\033[0;34m'
|
|
typeset -g PW_YELLOW=$'\033[1;33m'
|
|
typeset -g PW_CYAN=$'\033[0;36m'
|
|
typeset -g PW_RED=$'\033[0;31m'
|
|
typeset -g PW_NC=$'\033[0m'
|
|
|
|
# ============================================================================
|
|
# LastPass Functions
|
|
# ============================================================================
|
|
|
|
_lp_ensure_session() {
|
|
if ! lpass status -q 2>/dev/null; then
|
|
echo "Signing into LastPass..." >&2
|
|
lpass login "${LASTPASS_EMAIL:-}"
|
|
fi
|
|
}
|
|
|
|
_lp_list() {
|
|
_lp_ensure_session
|
|
lpass ls --format="%an\t%ag" 2>/dev/null
|
|
}
|
|
|
|
_lp_get() {
|
|
local item="$1"
|
|
local field="${2:-password}"
|
|
_lp_ensure_session
|
|
|
|
case "$field" in
|
|
password) lpass show --password "$item" 2>/dev/null ;;
|
|
username) lpass show --username "$item" 2>/dev/null ;;
|
|
url) lpass show --url "$item" 2>/dev/null ;;
|
|
notes) lpass show --notes "$item" 2>/dev/null ;;
|
|
*) lpass show --field="$field" "$item" 2>/dev/null ;;
|
|
esac
|
|
}
|
|
|
|
_lp_otp() {
|
|
local item="$1"
|
|
_lp_ensure_session
|
|
lpass show --otp "$item" 2>/dev/null
|
|
}
|
|
|
|
_lp_search() {
|
|
local query="$1"
|
|
_lp_ensure_session
|
|
lpass ls 2>/dev/null | grep -i "$query"
|
|
}
|
|
|
|
# ============================================================================
|
|
# Unified Interface
|
|
# ============================================================================
|
|
|
|
pw() {
|
|
local cmd="${1:-help}"
|
|
shift
|
|
|
|
# Check if lastpass is installed
|
|
if ! command -v lpass &>/dev/null; then
|
|
echo -e "${PW_RED}✗${PW_NC} LastPass CLI (lpass) not installed"
|
|
echo "Install with: yay -S lastpass-cli"
|
|
return 1
|
|
fi
|
|
|
|
case "$cmd" in
|
|
list|ls|l)
|
|
_lp_list
|
|
;;
|
|
|
|
get|g|show)
|
|
local item="$1"
|
|
local field="${2:-password}"
|
|
[[ -z "$item" ]] && { echo "Usage: pw get <item> [field]"; return 1; }
|
|
_lp_get "$item" "$field"
|
|
;;
|
|
|
|
otp|totp|2fa)
|
|
local item="$1"
|
|
[[ -z "$item" ]] && { echo "Usage: pw otp <item>"; return 1; }
|
|
_lp_otp "$item"
|
|
;;
|
|
|
|
search|find|s)
|
|
local query="$1"
|
|
[[ -z "$query" ]] && { echo "Usage: pw search <query>"; return 1; }
|
|
_lp_search "$query"
|
|
;;
|
|
|
|
copy|cp|c)
|
|
local item="$1"
|
|
local field="${2:-password}"
|
|
[[ -z "$item" ]] && { echo "Usage: pw copy <item> [field]"; return 1; }
|
|
|
|
local value=$(_lp_get "$item" "$field")
|
|
|
|
if [[ -n "$value" ]]; then
|
|
echo -n "$value" | xclip -selection clipboard 2>/dev/null || \
|
|
echo -n "$value" | xsel --clipboard 2>/dev/null || \
|
|
{ echo "Could not copy to clipboard"; return 1; }
|
|
echo "Copied to clipboard"
|
|
else
|
|
echo "Item not found or empty"
|
|
return 1
|
|
fi
|
|
;;
|
|
|
|
lock)
|
|
lpass logout -f 2>/dev/null
|
|
echo "Logged out of LastPass"
|
|
;;
|
|
|
|
help|--help|-h|*)
|
|
echo -e "${PW_BLUE}Password Manager CLI (LastPass)${PW_NC}"
|
|
echo
|
|
echo "Usage: pw <command> [args]"
|
|
echo
|
|
echo "Commands:"
|
|
echo " list List all items"
|
|
echo " get <item> [field] Get field (default: password)"
|
|
echo " otp <item> Get OTP/TOTP code"
|
|
echo " search <query> Search items"
|
|
echo " copy <item> [field] Copy to clipboard"
|
|
echo " lock Logout/lock session"
|
|
echo " help Show this help"
|
|
echo
|
|
echo "Fields: password, username, url, notes, or custom field name"
|
|
echo
|
|
echo "Examples:"
|
|
echo " pw get github"
|
|
echo " pw get github username"
|
|
echo " pw otp github"
|
|
echo " pw copy aws"
|
|
echo " pw search mail"
|
|
echo
|
|
echo "Install: yay -S lastpass-cli"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# ============================================================================
|
|
# Aliases
|
|
# ============================================================================
|
|
|
|
alias pwl='pw list'
|
|
alias pwg='pw get'
|
|
alias pwc='pw copy'
|
|
alias pws='pw search'
|
|
|
|
# ============================================================================
|
|
# FZF Integration (if available)
|
|
# ============================================================================
|
|
|
|
if command -v fzf &>/dev/null; then
|
|
# Interactive password selection and copy
|
|
pwf() {
|
|
if ! command -v lpass &>/dev/null; then
|
|
echo "LastPass CLI not installed"
|
|
return 1
|
|
fi
|
|
|
|
local item=$(_lp_list | fzf --height=40% --reverse | cut -f1)
|
|
|
|
if [[ -n "$item" ]]; then
|
|
pw copy "$item"
|
|
fi
|
|
}
|
|
|
|
# Interactive OTP selection and copy
|
|
pwof() {
|
|
if ! command -v lpass &>/dev/null; then
|
|
echo "LastPass CLI not installed"
|
|
return 1
|
|
fi
|
|
|
|
local item=$(_lp_list | fzf --height=40% --reverse | cut -f1)
|
|
|
|
if [[ -n "$item" ]]; then
|
|
local otp=$(pw otp "$item")
|
|
if [[ -n "$otp" ]]; then
|
|
echo -n "$otp" | xclip -selection clipboard 2>/dev/null || \
|
|
echo -n "$otp" | xsel --clipboard 2>/dev/null
|
|
echo "OTP copied: $otp"
|
|
fi
|
|
fi
|
|
}
|
|
fi
|