This repository has no description
2.7 kB
92 lines
1{ ... }:
2{
3 perSystem =
4 { pkgs, ... }:
5 {
6 packages.pass-otp = pkgs.writeShellApplication {
7 name = "pass-otp";
8 runtimeInputs = [
9 pkgs.oath-toolkit
10 ];
11 text = ''
12 # Tool-agnostic OTP generator that accepts secret via stdin or args
13
14 show_usage() {
15 echo "Usage: pass-otp [--clip,-c] <secret>"
16 echo " echo <secret> | pass-otp [--clip,-c]"
17 echo ""
18 echo "Accepts OTP secret as argument or via stdin"
19 echo "Secret can be:"
20 echo " - Raw base32 secret"
21 echo " - otpauth:// URL"
22 echo " - Multi-line text with secret on line 2+"
23 }
24
25 clip=false
26 secret_input=""
27
28 # Parse arguments
29 while [[ $# -gt 0 ]]; do
30 case "$1" in
31 "--clip"|"-c")
32 clip=true
33 shift
34 ;;
35 "--help"|"-h")
36 show_usage
37 exit 0
38 ;;
39 *)
40 secret_input="$1"
41 shift
42 ;;
43 esac
44 done
45
46 # If no argument provided, read from stdin
47 if [[ -z "$secret_input" ]]; then
48 secret_input=$(cat)
49 fi
50
51 if [[ -z "$secret_input" ]]; then
52 echo "Error: No OTP secret provided"
53 show_usage
54 exit 1
55 fi
56
57 # Extract TOTP secret from input
58 if echo "$secret_input" | grep -q "^otpauth://"; then
59 # Extract secret from otpauth URL
60 secret_key=$(echo "$secret_input" | sed -n 's/.*secret=\([^&]*\).*/\1/p')
61 elif echo "$secret_input" | wc -l | grep -q "^1$"; then
62 # Single line - assume it's the raw secret
63 secret_key=$(echo "$secret_input" | tr -d ' ')
64 else
65 # Multi-line - assume secret is on line 2 or later
66 secret_key=$(echo "$secret_input" | tail -n +2 | head -n 1 | tr -d ' ')
67 fi
68
69 if [[ -z "$secret_key" ]]; then
70 echo "Error: Could not extract OTP secret from input"
71 exit 1
72 fi
73
74 # Generate OTP code
75 otp_code=$(oathtool --totp --base32 "$secret_key")
76
77 # Output or copy to clipboard
78 if [[ "$clip" == "true" ]]; then
79 if [[ "$(uname)" == "Darwin" ]]; then
80 echo -n "$otp_code" | pbcopy
81 echo "Copied OTP code to clipboard."
82 else
83 echo -n "$otp_code" | xclip -selection clipboard
84 echo "Copied OTP code to clipboard."
85 fi
86 else
87 echo "$otp_code"
88 fi
89 '';
90 };
91 };
92}