This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

tools/pass: convert from GPG to age-based passage

- Replace pass wrapper to use passage with age backend
- Create new pass-otp tool for OTP functionality using oathtool
- Update passmenu to work with .age files in ~/.passage/store
- Maintain full compatibility with existing pass/OTP workflows

+127 -11
+1
machines/barnacle/configuration.nix
··· 38 38 pkgs.zed-editor 39 39 pkgs.nixd 40 40 pkgs.nil 41 + pkgs.age-plugin-se 41 42 ]; 42 43 43 44 # Use a custom configuration.nix location.
+100
tools/pass-otp/flake-module.nix
··· 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 + }
+23 -8
tools/pass/flake-module.nix
··· 2 2 { 3 3 perSystem = 4 4 { pkgs, system, ... }: 5 - let 6 - passWithOtp = pkgs.pass.withExtensions (ext: [ ext.pass-otp ]); 7 - in 8 5 { 9 - packages.pass = self.libWithPkgs.${system}.makeWrapper passWithOtp { 10 - runtimeInputs = [ pkgs.gnupg ]; 11 - preHook = '' 12 - gpg --import ${self.keys.pgp.yubi.key} &>/dev/null 13 - echo '${self.keys.pgp.yubi.id}:6:' | gpg --import-ownertrust &>/dev/null 6 + packages.pass = pkgs.writeShellApplication { 7 + name = "pass"; 8 + runtimeInputs = [ 9 + pkgs.passage 10 + pkgs.age-plugin-se 11 + self.packages.${system}.pass-otp 12 + ]; 13 + text = '' 14 + # Ensure age identity exists 15 + if [ ! -f ~/.passage/identities ]; then 16 + echo "Error: Age identity not found at ~/.passage/identities" 17 + echo "Please copy your age private key to ~/.passage/identities" 18 + exit 1 19 + fi 20 + 21 + # Handle OTP commands by delegating to pass-otp 22 + if [[ "''${1:-}" == "otp" ]]; then 23 + shift 24 + pass-otp "$@" 25 + else 26 + # Pass all other commands directly to passage 27 + passage "$@" 28 + fi 14 29 ''; 15 30 }; 16 31 };
+3 -3
tools/passmenu/flake-module.nix
··· 25 25 shift 26 26 fi 27 27 28 - prefix=''${PASSWORD_STORE_DIR-~/.password-store} 29 - password_files=( "$prefix"/**/*.gpg ) 28 + prefix=''${PASSWORD_STORE_DIR-~/.passage/store} 29 + password_files=( "$prefix"/**/*.age ) 30 30 password_files=( "''${password_files[@]#"$prefix"/}" ) 31 - password_files=( "''${password_files[@]%.gpg}" ) 31 + password_files=( "''${password_files[@]%.age}" ) 32 32 33 33 password=$(printf '%s\n' "''${password_files[@]}" | menu "$@") 34 34