summaryrefslogtreecommitdiff
path: root/tw/home/files/passmenu
blob: abeb98fb2e4b35825a9bb7f360053b6320e12d7f (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/bin/sh -e

usage() {
  cat << EOF
$(basename "$0") [-c | -p | -a]

  -c, --clip       copy the user-selected password to the clipboard
  -p, --type-pass  auto-type the user-selected password only
  -a, --type-all   auto-type the user-selected username <tab> password
  -h, --help       show this help message and exit
  -v, --version    show the program version number and exit

Later options override conflicting earlier ones.
If no option is given, -c/--clip is the default.
GNU-style combination of short options (e.g. -pa) is not supported.

Abnormal exit codes:
  1    no password selected by user
  2    invalid command-line argument
  3    internal error

(C) 2019-2022 Timo Wilken; MIT Licence.
Adapted from https://git.zx2c4.com/password-store/tree/contrib/dmenu/passmenu.
EOF
}

version() {
  # Changelog:
  # 1.0.0 (2019-??-??) initial version
  # 1.0.1 (2022-07-17) script formatting; throw away passwords asap
  # 1.0.2 (2022-10-??) remove fix_xdotool; this should be done on login
  echo "$(basename "$0") 1.0.2"
}

password_names() {
  find "${PASSWORD_STORE_DIR-$HOME/.password-store}" -name '*.gpg' -type f \
       -printf '%P\n' | sed 's/\.gpg$//'
}

extract_key() {
  sed -rn "s/^$1:\\s+(.+)\$/\\1/p"
}

type_stdin() {
  tr -d '\n' | xdotool getactivewindow type --clearmodifiers --file -
}

## Command-line arguments
mode=clip
while [ $# -gt 0 ]; do
  case "$1" in
    -o|--type-otp)  mode=type-otp; shift;;
    -p|--type-pass) mode=type-pass; shift;;
    -a|--type-all)  mode=type-all; shift;;
    -c|--clip)      mode=clip; shift;;
    -h|--help)      usage; exit;;
    -v|--version)   version; exit;;

    *)
      echo "$(basename "$0"): unknown option: $1" >&2
      usage >&2
      exit 2;;
  esac
done

## Password selection menu
password_name=$(password_names | rofi -dmenu -i -p Password -no-custom)
[ -n "$password_name" ] || exit 1

## Password typing
case "$mode" in
  clip)
    # Suppress "copied ... to clipboard" notice on stdout.
    pass show --clip "$password_name" > /dev/null;;

  type-otp)
    pass otp "$password_name" | type_stdin;;

  type-*)
    entry=$(pass show "$password_name")
    if [ "$mode" = type-all ]; then
      echo "$entry" | extract_key username | type_stdin
      xdotool getactivewindow key Tab
    fi
    echo "$entry" | head -1 | type_stdin
    unset entry;;

  *)
    echo "$(basename "$0"): internal error: unknown mode: $mode" >&2
    exit 3;;
esac