This repository has no description
0

Configure Feed

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

keys: refactor to use separate default.nix

+135 -113
+133
keys/default.nix
··· 1 + # Key structure exposed without nixpkgs dependency 2 + # Uses only Nix builtins 3 + let 4 + # Helper: split string by delimiter (returns only non-empty string parts) 5 + splitString = sep: str: builtins.filter builtins.isString (builtins.split sep str); 6 + 7 + # Helper: get last element of list 8 + last = list: builtins.elemAt list (builtins.length list - 1); 9 + 10 + # Helper: check if list is non-empty 11 + 12 + # Helper: unique elements in a list 13 + unique = 14 + list: builtins.foldl' (acc: elem: if builtins.elem elem acc then acc else acc ++ [ elem ]) [ ] list; 15 + 16 + # Helper to read age keys with different types 17 + readAgeKeys = 18 + baseDir: 19 + let 20 + dir = baseDir + "/age"; 21 + in 22 + if builtins.pathExists dir then 23 + let 24 + allFiles = builtins.readDir dir; 25 + fileNames = builtins.attrNames allFiles; 26 + 27 + # Process a single file and return { name, public?, identity? } 28 + processFile = 29 + fileName: 30 + let 31 + fileType = allFiles.${fileName}; 32 + parts = splitString "\\." fileName; 33 + baseName = builtins.head parts; 34 + extension = if builtins.length parts > 1 then last parts else ""; 35 + in 36 + if fileType == "regular" then 37 + if extension == "age" then 38 + { 39 + name = baseName; 40 + public = builtins.readFile (dir + "/${fileName}"); 41 + identity = null; 42 + } 43 + else if extension == "identity" then 44 + { 45 + name = baseName; 46 + public = null; 47 + identity = builtins.readFile (dir + "/${fileName}"); 48 + } 49 + else 50 + null 51 + else 52 + null; 53 + 54 + # Process all files 55 + processed = builtins.filter (x: x != null) (map processFile fileNames); 56 + 57 + # Merge entries with same base name 58 + merged = builtins.foldl' ( 59 + acc: entry: 60 + let 61 + existing = 62 + acc.${entry.name} or { 63 + public = null; 64 + identity = null; 65 + }; 66 + in 67 + acc 68 + // { 69 + ${entry.name} = { 70 + public = if entry.public != null then entry.public else existing.public; 71 + identity = if entry.identity != null then entry.identity else existing.identity; 72 + }; 73 + } 74 + ) { } processed; 75 + in 76 + merged 77 + else 78 + { }; 79 + 80 + # Helper to read SSH keys (handle key pairs and encrypted private keys) 81 + readSshKeys = 82 + baseDir: 83 + let 84 + dir = baseDir + "/ssh"; 85 + in 86 + if builtins.pathExists dir then 87 + let 88 + allFiles = builtins.readDir dir; 89 + fileNames = builtins.attrNames allFiles; 90 + 91 + # Extract base names (remove all suffixes) 92 + keyNames = unique (map (name: builtins.head (splitString "\\." name)) fileNames); 93 + in 94 + builtins.listToAttrs ( 95 + map ( 96 + keyName: 97 + let 98 + publicKeyFile = dir + "/${keyName}.pub"; 99 + encryptedPrivateKeyFile = dir + "/${keyName}.age"; 100 + hasPublicKey = builtins.pathExists publicKeyFile; 101 + hasEncryptedPrivateKey = builtins.pathExists encryptedPrivateKeyFile; 102 + in 103 + { 104 + name = keyName; 105 + value = { 106 + public = if hasPublicKey then builtins.readFile publicKeyFile else null; 107 + # Expose encrypted private keys (safe), but never unencrypted ones 108 + private = if hasEncryptedPrivateKey then encryptedPrivateKeyFile else null; 109 + encrypted = hasEncryptedPrivateKey; 110 + }; 111 + } 112 + ) keyNames 113 + ) 114 + else 115 + { }; 116 + 117 + baseDir = ./.; 118 + in 119 + { 120 + # SSH keys (handle both public and private key files) 121 + ssh = readSshKeys baseDir; 122 + 123 + # PGP/GPG keys - define directly with metadata 124 + pgp = { 125 + yubi_pgp = { 126 + key = ./pgp/yubi_pgp.pgp; 127 + id = "DBCD757846069B392EA9401D6657BE8A8D1EE807"; 128 + }; 129 + }; 130 + 131 + # Age keys (public keys only) 132 + age = readAgeKeys baseDir; 133 + }
+2 -113
keys/flake-module.nix
··· 1 - { lib, ... }: 2 - let 3 - # Helper to read age keys with different types 4 - readAgeKeys = 5 - baseDir: 6 - let 7 - dir = baseDir + "/age"; 8 - in 9 - if builtins.pathExists dir then 10 - let 11 - allFiles = builtins.readDir dir; 12 - # Group files by base name and type 13 - processFile = 14 - name: type: 15 - if type == "regular" then 16 - let 17 - parts = lib.splitString "." name; 18 - baseName = builtins.head parts; 19 - extension = if builtins.length parts > 1 then lib.last parts else ""; 20 - in 21 - { 22 - name = baseName; 23 - value = 24 - if extension == "age" then 25 - { 26 - public = builtins.readFile (dir + "/${name}"); 27 - identity = null; 28 - } 29 - else if extension == "identity" then 30 - { 31 - public = null; 32 - identity = builtins.readFile (dir + "/${name}"); 33 - } 34 - else 35 - null; 36 - } 37 - else 38 - null; 39 - 40 - # Process all files and merge by base name 41 - fileAttrs = lib.filterAttrs (_n: v: v != null) (lib.mapAttrs processFile allFiles); 42 - 43 - # Merge entries with same base name 44 - mergeEntries = lib.foldl' ( 45 - acc: entry: 46 - let 47 - existing = 48 - acc.${entry.name} or { 49 - public = null; 50 - identity = null; 51 - }; 52 - merged = { 53 - public = if entry.value.public != null then entry.value.public else existing.public; 54 - identity = if entry.value.identity != null then entry.value.identity else existing.identity; 55 - }; 56 - in 57 - acc // { ${entry.name} = merged; } 58 - ) { } (lib.attrValues fileAttrs); 59 - in 60 - mergeEntries 61 - else 62 - { }; 63 - 64 - # Helper to read SSH keys (handle key pairs and encrypted private keys) 65 - readSshKeys = 66 - baseDir: 67 - let 68 - dir = baseDir + "/ssh"; 69 - in 70 - if builtins.pathExists dir then 71 - let 72 - allFiles = builtins.readDir dir; 73 - # Group files by their base name (remove all suffixes) 74 - keyNames = lib.unique ( 75 - map (name: builtins.head (lib.splitString "." name)) (builtins.attrNames allFiles) 76 - ); 77 - in 78 - lib.listToAttrs ( 79 - map ( 80 - keyName: 81 - let 82 - publicKeyFile = dir + "/${keyName}.pub"; 83 - encryptedPrivateKeyFile = dir + "/${keyName}.age"; 84 - hasPublicKey = builtins.pathExists publicKeyFile; 85 - hasEncryptedPrivateKey = builtins.pathExists encryptedPrivateKeyFile; 86 - in 87 - lib.nameValuePair keyName { 88 - public = if hasPublicKey then builtins.readFile publicKeyFile else null; 89 - # Expose encrypted private keys (safe), but never unencrypted ones 90 - private = if hasEncryptedPrivateKey then encryptedPrivateKeyFile else null; 91 - encrypted = hasEncryptedPrivateKey; 92 - } 93 - ) keyNames 94 - ) 95 - else 96 - { }; 97 - 98 - in 1 + { ... }: 99 2 { 100 - flake.keys = { 101 - # SSH keys (handle both public and private key files) 102 - ssh = readSshKeys ./.; 103 - 104 - # PGP/GPG keys - define directly with metadata 105 - pgp = { 106 - yubi_pgp = { 107 - key = ./pgp/yubi_pgp.pgp; 108 - id = "DBCD757846069B392EA9401D6657BE8A8D1EE807"; 109 - }; 110 - }; 111 - 112 - # Age keys (public keys only) 113 - age = readAgeKeys ./.; 114 - }; 3 + flake.keys = import ./.; 115 4 }