Compare commits
5 Commits
727d6c3da9
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| e9ac72d162 | |||
| e68498cd42 | |||
| 2b9e446876 | |||
| 7313f718df | |||
| 233e463f87 |
+81
@@ -405,6 +405,87 @@ dov = {
|
||||
};
|
||||
#+end_src
|
||||
|
||||
** YubiKey
|
||||
Provides PAM U2F authentication (touch YubiKey for login/sudo) and a seamless SSH agent backed by the YubiKey PIV applet.
|
||||
|
||||
#+begin_src nix
|
||||
dov = {
|
||||
yubikey.enable = true;
|
||||
};
|
||||
#+end_src
|
||||
|
||||
*** PAM U2F (login & sudo)
|
||||
After enabling the module and rebuilding, enroll your YubiKey:
|
||||
|
||||
1. Create the YubiKey config directory:
|
||||
#+begin_src sh
|
||||
mkdir -p ~/.config/Yubico
|
||||
#+end_src
|
||||
|
||||
2. Generate the U2F key mapping (touch YubiKey when prompted):
|
||||
#+begin_src bash
|
||||
nix-shell -p pam_u2f --run 'pamu2fcfg -u fujin' > ~/.config/Yubico/u2f_keys
|
||||
#+end_src
|
||||
|
||||
*Nushell users:* use ~out>~ instead of ~>~:
|
||||
#+begin_src
|
||||
nix-shell -p pam_u2f --run 'pamu2fcfg -u fujin' out> ~/.config/Yubico/u2f_keys
|
||||
#+end_src
|
||||
|
||||
3. Add a backup YubiKey (optional):
|
||||
#+begin_src bash
|
||||
nix-shell -p pam_u2f --run 'pamu2fcfg -u fujin -n' >> ~/.config/Yubico/u2f_keys
|
||||
#+end_src
|
||||
|
||||
4. Rebuild and switch:
|
||||
#+begin_src sh
|
||||
sudo nixos-rebuild switch --flake .#fujin
|
||||
#+end_src
|
||||
|
||||
5. Test:
|
||||
#+begin_src sh
|
||||
sudo true # should prompt to touch YubiKey
|
||||
#+end_src
|
||||
|
||||
The default mode is =sufficient= (touch key *or* type password). If the key is absent or not enrolled, the normal password prompt follows — you cannot lock yourself out.
|
||||
|
||||
*** SSH with FIDO2-backed keys
|
||||
The module enables the standard OpenSSH agent (not GPG agent's SSH emulation, which doesn't reliably support =-sk= keys). The YubiKey uses FIDO2 — the same interface that PAM U2F uses — so no PIV/pcscd setup is needed for SSH.
|
||||
|
||||
1. Generate a FIDO2-backed SSH key (one-time, touch YubiKey when prompted):
|
||||
#+begin_src sh
|
||||
ssh-keygen -t ed25519-sk -C "yubikey@fujin"
|
||||
#+end_src
|
||||
|
||||
*Resident key* (recoverable on a new machine without the stub file):
|
||||
#+begin_src sh
|
||||
ssh-keygen -t ed25519-sk -O resident -C "yubikey@fujin"
|
||||
#+end_src
|
||||
|
||||
2. Load the key into the agent (once per login session, enter passphrase):
|
||||
#+begin_src sh
|
||||
ssh-add ~/.ssh/id_ed25519_sk
|
||||
#+end_src
|
||||
|
||||
*After a rebuild*, log out and back in so the shell picks up the new =SSH_AUTH_SOCK=. In an existing session:
|
||||
#+begin_src sh
|
||||
export SSH_AUTH_SOCK=/run/user/$(id -u)/ssh-agent
|
||||
#+end_src
|
||||
|
||||
3. Copy the public key to remote hosts:
|
||||
#+begin_src sh
|
||||
ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub susano
|
||||
#+end_src
|
||||
|
||||
4. Test:
|
||||
#+begin_src sh
|
||||
ssh susano # touch YubiKey, no password
|
||||
#+end_src
|
||||
|
||||
Each SSH authentication requires a physical YubiKey touch. The passphrase is only asked when loading the key into the agent (step 2), not per-connection.
|
||||
|
||||
*Note:* The key stub (~/.ssh/id_ed25519_sk) is tied to this specific generation — regenerating produces a different key. Back it up or use =-O resident=.
|
||||
|
||||
* Notes and Configuration Details
|
||||
** Remote Build Configuration
|
||||
To leverage remote builds (e.g., building fujin configurations on izanagi), you need to set up SSH keys for the root user:
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Backlog
|
||||
|
||||
<!-- SECTION: ENTRIES -->
|
||||
|
||||
<!-- SECTION: Nixos -->
|
||||
|
||||
- [ ] [P2] Add nushell completion for rebuild script *(priority: P2)*
|
||||
|
||||
<!-- SECTION: HISTORY -->
|
||||
|
||||
<!-- SECTION: Nixos -->
|
||||
|
||||
| Timestamp | Item ID | Action | Details |
|
||||
|-----------|---------|--------|---------|
|
||||
| 2026-07-26T11:58:28.175Z | n-dk597m | item_created | Add nushell completion for rebuild script |
|
||||
|
||||
<!-- SECTION: INTEGRITY -->
|
||||
|
||||
<!-- saved: 2026-07-26T11:58:28Z | checksum: sha256:1805e1b08cf2b01e73cdd1dd28269bd5ccf5ccdeaf584ff43d5a68edd3d17cfc | entries: 1 | history: 1 -->
|
||||
Generated
+137
-173
@@ -20,11 +20,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782073106,
|
||||
"narHash": "sha256-dnS5SaZlPqR1E0dPXaPc+lFkBwLUbAgbwsVMk7uA6dY=",
|
||||
"lastModified": 1784368054,
|
||||
"narHash": "sha256-zF1iJkBQSDWmRO4/LEeHR1SpKY0lqZaxkoQJpPS9K9U=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "aquamarine",
|
||||
"rev": "6d6e2384f381def4ea4ea81543cba4bbdac72457",
|
||||
"rev": "9b5f14d9483445e766294eb8fbe0b8f370269ed0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -127,11 +127,11 @@
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783009466,
|
||||
"narHash": "sha256-Y4rMf21OEgsoD5Fexu5FoqLJEdDGOIttZ5uM9acIM0s=",
|
||||
"lastModified": 1784907296,
|
||||
"narHash": "sha256-UYyGETnsSfPDTFIq/+1Uwe0C5fhqE2cgFXpYHnv8cUc=",
|
||||
"owner": "9001",
|
||||
"repo": "copyparty",
|
||||
"rev": "be31a744852a4c04db4c046c91b509ee163e2b61",
|
||||
"rev": "10db4236bf864a2f57b3cb2db42eb93a456ea698",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -166,11 +166,11 @@
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783102384,
|
||||
"narHash": "sha256-DGkEbz6R7XORnFmWsHwIW0pM55QKAVmtm0OAOJvTUUY=",
|
||||
"lastModified": 1785062976,
|
||||
"narHash": "sha256-3PQYC0Gm9NfAJbko6JTtFBlujtXWm7L5VZpUVJRu04c=",
|
||||
"owner": "nix-community",
|
||||
"repo": "emacs-overlay",
|
||||
"rev": "8eb5fada90f17ad128506ed6b2b5b2369494719b",
|
||||
"rev": "ecf4a1a2d40f5cf118e7ffa255212ffba6036151",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -183,11 +183,11 @@
|
||||
"firefox-gnome-theme": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1779670703,
|
||||
"narHash": "sha256-UdfMivNMwCCqQsYDg5pSz8X2IOaOrIZLIIy+Bg3CO2o=",
|
||||
"lastModified": 1782007937,
|
||||
"narHash": "sha256-PbnJr+eB+9Czol3ReI83dUgEhcn0sDK6TSy6ODTQm88=",
|
||||
"owner": "rafaelmardojai",
|
||||
"repo": "firefox-gnome-theme",
|
||||
"rev": "942159e73e40bf785816f7f1f5feed9ef3d7c8f9",
|
||||
"rev": "981bd332015397fb1ca033fa982bd61635160c78",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -254,11 +254,29 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1778716662,
|
||||
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
|
||||
"lastModified": 1782949081,
|
||||
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
|
||||
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_3": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772408722,
|
||||
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -300,24 +318,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_3": {
|
||||
"inputs": {
|
||||
"systems": "systems_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1681202837,
|
||||
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"fromYaml": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@@ -376,43 +376,23 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gnome-shell": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1767737596,
|
||||
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
|
||||
"host": "gitlab.gnome.org",
|
||||
"lastModified": 1776175984,
|
||||
"narHash": "sha256-RJFlFW8GiMei6oqUGrMkGEvVqOH8U7Q8abc1yK4VKD8=",
|
||||
"owner": "GNOME",
|
||||
"repo": "gnome-shell",
|
||||
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
|
||||
"type": "github"
|
||||
"rev": "e0fdc4c13250e9a9b8ea9594c83925274f4a5dca",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
"host": "gitlab.gnome.org",
|
||||
"owner": "GNOME",
|
||||
"ref": "50.1",
|
||||
"repo": "gnome-shell",
|
||||
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
|
||||
"type": "github"
|
||||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
@@ -444,11 +424,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1781497404,
|
||||
"narHash": "sha256-9GAF8sSsnkyCVCWkomXR0T+zdSxyUlfPt6neQidimdg=",
|
||||
"lastModified": 1783963347,
|
||||
"narHash": "sha256-r376E2XpakiXwModDHIxlvB6qLq4iFVEq730vxOO4JY=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "1285cd3d6882a9847f2d56ed5541b3350c8a6162",
|
||||
"rev": "a45a7c451455a51ae740ec3bce4024b312809c29",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -532,11 +512,11 @@
|
||||
"xdph": "xdph"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783110106,
|
||||
"narHash": "sha256-PRnnFkTfQ+sQHSrcWw0512zEMNp5/1WHJeVuDf6FmxI=",
|
||||
"lastModified": 1784980432,
|
||||
"narHash": "sha256-MZQi0zqZ8c7eIxhhQzC5z7PHh8LWGRRjYqkX0GYbYBg=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "14fa1fd0273973b7a40966b4fa9e081d6bf67dae",
|
||||
"revCount": 7549,
|
||||
"rev": "453d96e92739a2a0b865cf9166d48ba14ec14b7b",
|
||||
"revCount": 7646,
|
||||
"type": "git",
|
||||
"url": "https://github.com/hyprwm/Hyprland"
|
||||
},
|
||||
@@ -578,11 +558,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782563850,
|
||||
"narHash": "sha256-rs/EzgrgPHbCtJjFZN4aR1HYldH/0NtGAempWVpWQTs=",
|
||||
"lastModified": 1784196523,
|
||||
"narHash": "sha256-ahtKMGXFJdlQNhatQm1+BBU/pGfGYnAqQt3vWvq4p8s=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-guiutils",
|
||||
"rev": "5ba080ee036c30cb2485f2647ff8a61f7aa08178",
|
||||
"rev": "a6ccb6cb112ed5a244c0191fb972347ecfa893e0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -608,11 +588,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782769258,
|
||||
"narHash": "sha256-HAhqQOoz4S0gzIOMnClL49B+rMT7zdp3UDWeqxtMs/k=",
|
||||
"lastModified": 1784102347,
|
||||
"narHash": "sha256-piRpwar7VZI3YviYo0a/UMFz9+rLesfv3nRLGKxjVGg=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-plugins",
|
||||
"rev": "71b8953d7d92dbebe87a6ff9895bdd30e7495873",
|
||||
"rev": "7644cecdb947060682891a0db2a0cdc5c0b9e704",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -739,11 +719,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783002634,
|
||||
"narHash": "sha256-xGqHIUK0wIZoW7SiMalwvO6uGOO/VrlQwoRobpE7dDI=",
|
||||
"lastModified": 1784323413,
|
||||
"narHash": "sha256-XnAVV+H4f8Xdv0yZcSwJ5kCjLyE8fHxPeLX6a3HSrAU=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "41fb809557abd29a57151b6e1aaeabd05f9437e1",
|
||||
"rev": "5f03477ab3a005ff27c527486f551883535aea2f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -811,11 +791,11 @@
|
||||
"nixpkgs": "nixpkgs_6"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783008200,
|
||||
"narHash": "sha256-7019KmcP2U7kx3l60Z5Pgc5SRwbTMHJ2CDuJ/kdhlFA=",
|
||||
"lastModified": 1783209925,
|
||||
"narHash": "sha256-NO94JBjSI4jHPaSxXhaZDv3oT7lKpoCzLxjAbWdSjwc=",
|
||||
"owner": "Lxtharia",
|
||||
"repo": "minegrub-theme",
|
||||
"rev": "32272c8e674635c2aefae8fbe2243084dccc6ea0",
|
||||
"rev": "d0aec4523e1800c3196227dc420d326891292508",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -846,11 +826,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1781513248,
|
||||
"narHash": "sha256-YLeEcfvlQiNXP9bVoIwyB+NMjMxJmkwv/y+AP/7RWYo=",
|
||||
"lastModified": 1784537139,
|
||||
"narHash": "sha256-cfJ+PdNNx++NukHKATYBNBnNdIudcDt/BJ7VbFhXx9Q=",
|
||||
"owner": "Mic92",
|
||||
"repo": "nix-ld",
|
||||
"rev": "b320f5cb8b7f141c224c3631539cd0c45fcf7ee3",
|
||||
"rev": "9fef86f17a711a04399b0f0bf5d8fb7680d5f13b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -900,11 +880,11 @@
|
||||
"nixpkgs": "nixpkgs_7"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782562157,
|
||||
"narHash": "sha256-a7+T6QSeowynwZ1ZJJbP8T8ntAytvrui8kFGJmIZt2c=",
|
||||
"lastModified": 1784723954,
|
||||
"narHash": "sha256-1CfD8ZUjCkTgjsneLZ/lxCHhgDfqxxE7/GX0MmsgiqA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "a9cf7546a938c737b079e738de73934a13de9784",
|
||||
"rev": "a017f5b72210026af5b3ac5949f08d94380a6fbd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -945,13 +925,28 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib_2": {
|
||||
"locked": {
|
||||
"lastModified": 1772328832,
|
||||
"narHash": "sha256-e+/T/pmEkLP6BHhYjx6GmwP5ivonQQn0bJdH9YrRB+Q=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "c185c7a5e5dd8f9add5b2f8ebeff00888b070742",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1782847225,
|
||||
"narHash": "sha256-JC9PjqKYG9ve5U8aDOLQipp3+KLANBHUvGdLZlxzdKI=",
|
||||
"lastModified": 1784856561,
|
||||
"narHash": "sha256-J+Bx1Z6Oeoj2FgnBhRMKyUhhtDoOpTgXYaVLZpDjW4A=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "95ca1e203c0750115fd4a6f17d5a245dfe6b1edd",
|
||||
"rev": "597283ad8aa0b331c788e97c4c262d58877074ef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -963,25 +958,11 @@
|
||||
},
|
||||
"nixpkgs_10": {
|
||||
"locked": {
|
||||
"lastModified": 1682134069,
|
||||
"narHash": "sha256-TnI/ZXSmRxQDt2sjRYK/8j8iha4B4zP2cnQCZZ3vp7k=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "fd901ef4bf93499374c5af385b2943f5801c0833",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_11": {
|
||||
"locked": {
|
||||
"lastModified": 1781074563,
|
||||
"narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=",
|
||||
"lastModified": 1784007870,
|
||||
"narHash": "sha256-djcLt/JJphyNt4eDY9XTly+/WbCK5lqWq9lSgCmJkkQ=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca",
|
||||
"rev": "18b9261cb3294b6d2a06d03f96872827b8fe2698",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1023,11 +1004,11 @@
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1782723713,
|
||||
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
|
||||
"lastModified": 1784796856,
|
||||
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
|
||||
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1039,11 +1020,11 @@
|
||||
},
|
||||
"nixpkgs_5": {
|
||||
"locked": {
|
||||
"lastModified": 1782467914,
|
||||
"narHash": "sha256-pGvFkM8N0xEkIIXDe5YYfbEAvHrk4IxBrjB/x8OomhE=",
|
||||
"lastModified": 1784356753,
|
||||
"narHash": "sha256-12KrbMiWLcf8m7pCvAtZh1ZrgF85ZXDXvfR/fWTKy84=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e73de5be04e0eff4190a1432b946d469c794e7b4",
|
||||
"rev": "61b7c44c4073f0b827768aff0049561b5110ea5a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1121,11 +1102,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783105496,
|
||||
"narHash": "sha256-ZoNxJhEDgEIAH8PM1Qmx6pTzhD6ICkGAe+GYuLKsLq0=",
|
||||
"lastModified": 1785062220,
|
||||
"narHash": "sha256-p3Wxo+5p0Y6E3LwA3DdwMMse/GtcaPUmqLilPVfJPe4=",
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia",
|
||||
"rev": "2abf8758481fa82cc5e5bf5a53269107293cc7ff",
|
||||
"rev": "e1a4d27f2f2494db2c6e7636b514d1770b16c776",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1146,11 +1127,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1780281641,
|
||||
"narHash": "sha256-M/+hUKoKbHXpV0xGVfELbN1Ds1aoe3pL5p5/t46YhVo=",
|
||||
"lastModified": 1783439237,
|
||||
"narHash": "sha256-WUr8JF2v3n4Y30E5dxv4sAgNJXpVDBoCQNoQ/V4+n4o=",
|
||||
"owner": "nix-community",
|
||||
"repo": "NUR",
|
||||
"rev": "30f9ae2f04174de63ba8bcf3580ca90843b28a01",
|
||||
"rev": "b70bb66c7bcd162642f3a609bc16843c7059f503",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1162,18 +1143,17 @@
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_2",
|
||||
"gitignore": "gitignore_2",
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1781733627,
|
||||
"narHash": "sha256-U3yTuGBnmXvXoQI3qkpfEDsn9RovQPAjN7ndRco+3u0=",
|
||||
"lastModified": 1784288435,
|
||||
"narHash": "sha256-ReRHaLgr/uVqdD8afFSn+myXIfpHeOhP0yYe0TJqAA8=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "3bbec39bc90eadfa031e6f3b77272f3f60803e39",
|
||||
"rev": "43b3c1ab9d40fb1dbb008f451988a91e375825e9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1264,11 +1244,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783104586,
|
||||
"narHash": "sha256-vSLKc7m34/g5xH4dwmNZSqxc5OcHeE3qiG3EIz6bJKs=",
|
||||
"lastModified": 1783174389,
|
||||
"narHash": "sha256-aCWC8ngycU7OdJrU2+Je3qf+1a2ykuBvpPhZT/9tXMc=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "1ebd41717762d837d5115f7108522c29cdb00fbb",
|
||||
"rev": "f1406619a3884cd5c47992a70b8b35c9c0fcb4c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1285,11 +1265,11 @@
|
||||
"nix-filter": "nix-filter"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782237065,
|
||||
"narHash": "sha256-Oxtr8k+qu4Kd/7BJ5eo8Pfoje8PDIO1YK2+mhCkHRhQ=",
|
||||
"lastModified": 1784576463,
|
||||
"narHash": "sha256-XVm8Bi8XasjMP2VOisrPAuJvrB6+rQZW+/TL9kr2Ogs=",
|
||||
"owner": "zjeffer",
|
||||
"repo": "split-monitor-workspaces",
|
||||
"rev": "968a6a603cabf8ab8f5ce5a402e8ed3bfcae69ce",
|
||||
"rev": "c8a03d993f71a3ae73179ce354e7a54859055f02",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1318,11 +1298,11 @@
|
||||
"tinted-zed": "tinted-zed"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783101802,
|
||||
"narHash": "sha256-/Ti+wDco0f3C9s94RxyBKJyc0BklwYh0a/jFWKeHNYw=",
|
||||
"lastModified": 1784676123,
|
||||
"narHash": "sha256-ndyanKzw90yX2nUVFmTuYqXidUNymtMfgmIHyNdhht0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "stylix",
|
||||
"rev": "718c14e8ecba215a65ff955c187fadb9732ddd01",
|
||||
"rev": "66714e5ce44269ecc58c20d9196da8dbe1b27a31",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1376,21 +1356,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_4": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"thefuck": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
@@ -1432,11 +1397,11 @@
|
||||
"tinted-schemes": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1777806186,
|
||||
"narHash": "sha256-PDF0/wObw4nIsSBeXVYLsloXOiphXCgIdsrNcVXguKs=",
|
||||
"lastModified": 1781968807,
|
||||
"narHash": "sha256-yYO3Vw2M0y3TAUqt+9+Mj0zwP3XDTF5/PXcPhhFQ1ZM=",
|
||||
"owner": "tinted-theming",
|
||||
"repo": "schemes",
|
||||
"rev": "0c94645546f4f3ddac77a1a5fce54eb95bf50795",
|
||||
"rev": "2ccef2f4b22e3cab5a9292811f7133a07eeba4a7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1448,11 +1413,11 @@
|
||||
"tinted-tmux": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1778379944,
|
||||
"narHash": "sha256-wPDFzMGSlARlw0Sfsn48Q2+jPSfk6N0Ng6BC/d+7Q24=",
|
||||
"lastModified": 1782012462,
|
||||
"narHash": "sha256-2iDiD8DQLwS1lGuD9TS8WlvNyDoTs6krWntJbtB2zGo=",
|
||||
"owner": "tinted-theming",
|
||||
"repo": "tinted-tmux",
|
||||
"rev": "fe0203a198690e71a5ff11e08812a4673de3678d",
|
||||
"rev": "8c4e750f738a742bd73377ee41d3dadedebedef4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1464,11 +1429,11 @@
|
||||
"tinted-zed": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1778378178,
|
||||
"narHash": "sha256-OXPXRIQgGwV77HjYRryOHguh4ALX96jkg+tseLkGgHA=",
|
||||
"lastModified": 1782009766,
|
||||
"narHash": "sha256-VUhBjpGvWqHI7rWeyMYb/u87YJSXHKfVV6S+IelWeO8=",
|
||||
"owner": "tinted-theming",
|
||||
"repo": "base16-zed",
|
||||
"rev": "9cd816033ff969415b190722cddf134e78a5665f",
|
||||
"rev": "5e8350bcd354e3241ab681a265fa6ef060c40be1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1479,11 +1444,11 @@
|
||||
},
|
||||
"unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1782723713,
|
||||
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
|
||||
"lastModified": 1784796856,
|
||||
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
|
||||
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1500,11 +1465,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783099620,
|
||||
"narHash": "sha256-prQSM9PGnrfSaqknJOZ3DCQKbpMiXAWLVC5SHbjLcJ4=",
|
||||
"lastModified": 1784913159,
|
||||
"narHash": "sha256-JWq0BfjO4ktpH5USfQNQzdvHpIDT8fSKD5K7LvdMRFs=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "b2e4390ff35319c52935d6a700b615da4c0f204d",
|
||||
"rev": "079a3b5d1aa6a719920a51316253b7d6dd22738d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1541,15 +1506,14 @@
|
||||
},
|
||||
"vscode-server": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_3",
|
||||
"nixpkgs": "nixpkgs_10"
|
||||
"flake-parts": "flake-parts_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1770124655,
|
||||
"narHash": "sha256-yHmd2B13EtBUPLJ+x0EaBwNkQr9LTne1arLVxT6hSnY=",
|
||||
"lastModified": 1784312229,
|
||||
"narHash": "sha256-2uHCSUw341o3my1R0U0YCfbnMEazylxb58evWsjGL50=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-vscode-server",
|
||||
"rev": "92ce71c3ba5a94f854e02d57b14af4997ab54ef0",
|
||||
"rev": "2f984dfbe7e5271b5c413d3e734374cc1306c921",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1586,11 +1550,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782311043,
|
||||
"narHash": "sha256-07zLc2M3/ax+JsjxGTft17/Joua41LHE9/9AC/F9zeU=",
|
||||
"lastModified": 1784371182,
|
||||
"narHash": "sha256-S8A1lezEalltWcCp3gAic5lssS0xTSISK6fKODefhOk=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"rev": "882ad01e195ce201b07c618bbee44a0cad8b9e5a",
|
||||
"rev": "08d99f727944dd15e4740090305e31c5fb92a50a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1602,14 +1566,14 @@
|
||||
"zen-browser": {
|
||||
"inputs": {
|
||||
"home-manager": "home-manager_2",
|
||||
"nixpkgs": "nixpkgs_11"
|
||||
"nixpkgs": "nixpkgs_10"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783063269,
|
||||
"narHash": "sha256-XVOopPVgoWPlhuJajUYNTK/M9j/L/llD6vdH5JE9EKs=",
|
||||
"lastModified": 1785039979,
|
||||
"narHash": "sha256-vZjuRK0UgvChYGMeQ8daxiETJ5KQyGx+8u8YHdw5e/g=",
|
||||
"owner": "0xc000022070",
|
||||
"repo": "zen-browser-flake",
|
||||
"rev": "b86380c97016a1c79f535f286a34c0f5b4270a1b",
|
||||
"rev": "6f5e680db7d105ecf02b4e0d752d48d9083da6c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -6,7 +6,8 @@ let
|
||||
cfg = config.dov.dynamic-theme;
|
||||
schemes = "${pkgs.base16-schemes}/share/themes";
|
||||
|
||||
# Single source of truth for builtin themes
|
||||
# Curated defaults — covers the popular schemes without blowing up
|
||||
# build memory. Users can add more via `dov.dynamic-theme.themes`.
|
||||
builtinThemes = {
|
||||
gruvbox = {
|
||||
dark = "${schemes}/gruvbox-dark-hard.yaml";
|
||||
@@ -16,9 +17,42 @@ let
|
||||
dark = "${schemes}/catppuccin-mocha.yaml";
|
||||
light = "${schemes}/catppuccin-latte.yaml";
|
||||
};
|
||||
nord = {
|
||||
dark = "${schemes}/nord.yaml";
|
||||
light = "${schemes}/nord-light.yaml";
|
||||
};
|
||||
solarized = {
|
||||
dark = "${schemes}/solarized-dark.yaml";
|
||||
light = "${schemes}/solarized-light.yaml";
|
||||
};
|
||||
tokyo-night = {
|
||||
dark = "${schemes}/tokyo-night-dark.yaml";
|
||||
light = "${schemes}/tokyo-night-light.yaml";
|
||||
};
|
||||
rose-pine = {
|
||||
dark = "${schemes}/rose-pine.yaml";
|
||||
light = "${schemes}/rose-pine-dawn.yaml";
|
||||
};
|
||||
one = {
|
||||
dark = "${schemes}/onedark.yaml";
|
||||
light = "${schemes}/one-light.yaml";
|
||||
};
|
||||
material = {
|
||||
dark = "${schemes}/material-darker.yaml";
|
||||
light = "${schemes}/material-lighter.yaml";
|
||||
};
|
||||
google = {
|
||||
dark = "${schemes}/google-dark.yaml";
|
||||
light = "${schemes}/google-light.yaml";
|
||||
};
|
||||
github = {
|
||||
dark = "${schemes}/github-dark.yaml";
|
||||
light = "${schemes}/github.yaml";
|
||||
};
|
||||
};
|
||||
|
||||
# Generate all theme-variant combinations
|
||||
# Generate all theme-variant combinations from the configured themes.
|
||||
# Each theme produces a "-dark" and "-light" variant.
|
||||
themeVariants = concatMapAttrs (name: theme: {
|
||||
"${name}-dark" = { scheme = theme.dark; polarity = "dark"; };
|
||||
"${name}-light" = { scheme = theme.light; polarity = "light"; };
|
||||
@@ -112,28 +146,42 @@ in {
|
||||
};
|
||||
});
|
||||
default = builtinThemes;
|
||||
description = "Available themes with dark and light variants";
|
||||
description = ''
|
||||
Available themes with dark and light variants. Each entry
|
||||
generates two specialisations (`<name>-dark` and
|
||||
`<name>-light`). Add more here to extend the defaults.
|
||||
'';
|
||||
};
|
||||
|
||||
doomThemes = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {
|
||||
gruvbox-dark = "doom-gruvbox";
|
||||
gruvbox-light = "doom-one-light";
|
||||
catppuccin-dark = "doom-one";
|
||||
catppuccin-light = "doom-one-light";
|
||||
};
|
||||
# Auto-generate sane defaults from the configured themes, then
|
||||
# overlay specific overrides for schemes that ship a dedicated
|
||||
# doom-theme.
|
||||
default =
|
||||
let
|
||||
generated = concatMapAttrs (name: _: {
|
||||
"${name}-dark" = "doom-one";
|
||||
"${name}-light" = "doom-one-light";
|
||||
}) cfg.themes;
|
||||
in generated // {
|
||||
"gruvbox-dark" = "doom-gruvbox";
|
||||
"solarized-dark" = "doom-solarized-dark";
|
||||
"solarized-light" = "doom-solarized-light";
|
||||
"tokyo-night-dark" = "doom-tokyo-night";
|
||||
"nord-dark" = "doom-nordic";
|
||||
"material-dark" = "doom-material";
|
||||
"rose-pine-dark" = "doom-rose-pine";
|
||||
"catppuccin-dark" = "doom-catppuccin-mocha";
|
||||
"catppuccin-light" = "doom-catppuccin-latte";
|
||||
};
|
||||
description = ''
|
||||
Mapping from theme variant name (e.g. "gruvbox-dark") to the Doom
|
||||
Emacs theme symbol (e.g. "doom-gruvbox") that theme-switch will
|
||||
live-load via emacsclient when switching to that variant. Variants
|
||||
absent from this map are left unchanged in Emacs.
|
||||
|
||||
Only themes actually installed in Doom will load; the defaults use
|
||||
themes bundled with doom-themes (so they work out of the box, though
|
||||
catppuccin variants fall back to generic dark/light). For accurate
|
||||
catppuccin colours, install the `catppuccin-theme` Emacs package and
|
||||
map the variants to `catppuccin-mocha` / `catppuccin-latte`.
|
||||
Mapping from variant name (e.g. "gruvbox-dark") to the Doom
|
||||
Emacs theme symbol. Defaults are auto-generated from the
|
||||
configured themes (dark → doom-one, light → doom-one-light)
|
||||
with overrides for schemes that have a dedicated doom-theme.
|
||||
Only themes installed in Doom will load; others are silently
|
||||
skipped.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -213,5 +261,21 @@ in {
|
||||
Install.WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
}
|
||||
|
||||
# Nushell tab-completion: declares `theme-switch`'s argument signature
|
||||
# so nushell completes variant names natively (takes priority over
|
||||
# carapace's generic fallback). `extraConfig` is `types.lines`, so it
|
||||
# merges cleanly with the carapace completer from hm-modules/shell/nu.
|
||||
(mkIf config.programs.nushell.enable {
|
||||
programs.nushell.extraConfig = ''
|
||||
def "nu-complete theme-variants" [] {
|
||||
"${availableVariants}" | split row " "
|
||||
}
|
||||
|
||||
extern theme-switch [
|
||||
variant: string@"nu-complete theme-variants"
|
||||
]
|
||||
'';
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -121,6 +121,8 @@
|
||||
display-manager.ly.enable = true;
|
||||
|
||||
gaming.enable = true;
|
||||
|
||||
yubikey.enable = true;
|
||||
};
|
||||
|
||||
###
|
||||
|
||||
@@ -15,5 +15,6 @@
|
||||
./gitlab
|
||||
./jenkins
|
||||
./gaming
|
||||
./yubikey
|
||||
];
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ listener {
|
||||
|
||||
listener {
|
||||
timeout = 300 # 5min
|
||||
on-timeout = loginctl lock-session # lock screen when timeout has passed
|
||||
on-timeout = hyprlock # lock screen when timeout has passed
|
||||
}
|
||||
|
||||
# listener {
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.dov.yubikey;
|
||||
in {
|
||||
options.dov.yubikey = {
|
||||
enable = mkEnableOption "YubiKey integration (PAM U2F + SSH agent)";
|
||||
|
||||
pamControl = mkOption {
|
||||
type = types.enum [ "sufficient" "required" ];
|
||||
default = "sufficient";
|
||||
description = ''
|
||||
PAM control flag for U2F authentication.
|
||||
- "sufficient": touch YubiKey OR type password (default).
|
||||
Can't lock yourself out — if the key is missing or not
|
||||
enrolled, the normal password prompt follows.
|
||||
- "required": touch YubiKey AND type password (true 2FA).
|
||||
'';
|
||||
};
|
||||
|
||||
pamServices = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "login" "sudo" ];
|
||||
description = ''
|
||||
PAM services to enable U2F for. Scoped per-service rather
|
||||
than globally so that e.g. sshd is not affected.
|
||||
'';
|
||||
};
|
||||
|
||||
authFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Central U2F authfile path. When null, uses the default
|
||||
per-user location (~/.config/Yubico/u2f_keys). Set to a
|
||||
nix-store path for a central, non-user-writable mapping.
|
||||
|
||||
Generate mappings with:
|
||||
pamu2fcfg -u <username>
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
# --- Shared infrastructure: smart card daemon + device access ---
|
||||
# hardware.gpgSmartcards installs the CCID udev rules that give
|
||||
# pcscd permission to open the YubiKey's smart-card USB interface.
|
||||
hardware.gpgSmartcards.enable = true;
|
||||
services.pcscd.enable = true;
|
||||
services.udev.packages = with pkgs; [
|
||||
yubikey-personalization
|
||||
libfido2
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
yubikey-manager # `ykman` CLI
|
||||
pam_u2f # `pamu2fcfg` for key enrollment
|
||||
libfido2 # `fido2-token` management
|
||||
];
|
||||
}
|
||||
|
||||
# --- PAM U2F: touch YubiKey for login / sudo ---
|
||||
{
|
||||
security.pam.u2f = {
|
||||
enable = true;
|
||||
control = cfg.pamControl;
|
||||
settings = {
|
||||
cue = true; # "Please touch the device."
|
||||
interactive = true; # "Insert your U2F device, then press ENTER."
|
||||
nouserok = true; # fall through to password if key not enrolled yet
|
||||
} // optionalAttrs (cfg.authFile != null) {
|
||||
inherit (cfg) authFile;
|
||||
};
|
||||
};
|
||||
|
||||
# Enable U2F per-service, not globally (avoids enabling for sshd).
|
||||
security.pam.services = genAttrs cfg.pamServices (_: {
|
||||
u2fAuth = true;
|
||||
});
|
||||
}
|
||||
|
||||
# --- SSH agent for FIDO2 (-sk) keys ---
|
||||
# yubikey-agent is incompatible with YubiKey firmware 5.7.x (PIV
|
||||
# management key auth changed). GPG agent's SSH emulation doesn't
|
||||
# reliably handle -sk keys. Use the standard OpenSSH agent instead,
|
||||
# which is the same software stack that created the key.
|
||||
{
|
||||
programs.gnupg.agent.enableSSHSupport = mkForce false;
|
||||
programs.ssh.startAgent = true;
|
||||
}
|
||||
]);
|
||||
}
|
||||
Reference in New Issue
Block a user