This repository has no description
3.6 kB
100 lines
1{ self, ... }:
2{
3 perSystem =
4 { pkgs, system, ... }:
5 {
6 packages.pass-otp = pkgs.writeShellApplication {
7 name = "pass-otp";
8 runtimeInputs = [ pkgs.passage pkgs.oath-toolkit ];
9 text = ''
10 # Handle OTP commands for passage-based password store
11
12 show_usage() {
13 echo "Usage: pass-otp [show] [--clip,-c] pass-name"
14 echo " pass-otp insert [--secret,-s] [--issuer,-i issuer] [--account,-a account] [--echo,-e] pass-name"
15 }
16
17 case "''${1:-}" in
18 "")
19 show_usage
20 exit 1
21 ;;
22 "show")
23 shift
24 clip=false
25 pass_name="''${1:-}"
26 ;;
27 "--clip"|"-c")
28 shift
29 clip=true
30 pass_name="''${1:-}"
31
32 if [[ -z "$pass_name" ]]; then
33 show_usage
34 exit 1
35 fi
36
37 # Get the OTP secret from passage
38 if secret=$(passage show "$pass_name" 2>/dev/null); then
39 # Extract TOTP secret (assume it's on a line starting with "otpauth://" or just the secret)
40 if echo "$secret" | grep -q "otpauth://"; then
41 # Extract secret from otpauth URL
42 secret_key=$(echo "$secret" | grep "otpauth://" | sed -n 's/.*secret=\([^&]*\).*/\1/p')
43 else
44 # Assume the secret is on the second line or find a base32-looking string
45 secret_key=$(echo "$secret" | tail -n +2 | head -n 1 | tr -d ' ')
46 fi
47
48 if [[ -n "$secret_key" ]]; then
49 otp_code=$(oathtool --totp --base32 "$secret_key")
50 if [[ "$clip" == "true" ]]; then
51 if [[ "$(uname)" == "Darwin" ]]; then
52 echo -n "$otp_code" | pbcopy
53 echo "Copied OTP code to clipboard."
54 else
55 echo -n "$otp_code" | xclip -selection clipboard
56 echo "Copied OTP code to clipboard."
57 fi
58 else
59 echo "$otp_code"
60 fi
61 else
62 echo "Error: Could not extract OTP secret from $pass_name"
63 exit 1
64 fi
65 else
66 echo "Error: Could not read password entry $pass_name"
67 exit 1
68 fi
69 ;;
70 "insert")
71 shift
72 echo "OTP insert not yet implemented for passage. Please add OTP secrets manually."
73 exit 1
74 ;;
75 *)
76 # Default to show
77 pass_name="$1"
78 if secret=$(passage show "$pass_name" 2>/dev/null); then
79 if echo "$secret" | grep -q "otpauth://"; then
80 secret_key=$(echo "$secret" | grep "otpauth://" | sed -n 's/.*secret=\([^&]*\).*/\1/p')
81 else
82 secret_key=$(echo "$secret" | tail -n +2 | head -n 1 | tr -d ' ')
83 fi
84
85 if [[ -n "$secret_key" ]]; then
86 oathtool --totp --base32 "$secret_key"
87 else
88 echo "Error: Could not extract OTP secret from $pass_name"
89 exit 1
90 fi
91 else
92 echo "Error: Could not read password entry $pass_name"
93 exit 1
94 fi
95 ;;
96 esac
97 '';
98 };
99 };
100}