From d19d535d851eedc73a56f562e7cdf652f43891ca Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 20 Oct 2025 20:01:07 -0500 Subject: [PATCH 01/61] fix: made crab-hole dns accessible from other devices --- .../nixos/defiant/configuration.nix | 2 +- .../server/crab-hole/crab-hole.nix | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index c2b8fc5..fdf7356 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -348,7 +348,7 @@ openFirewall = true; show_doc = true; downstreams = { - loopback = { + host = { enable = true; openFirewall = true; }; diff --git a/modules/nixos-modules/server/crab-hole/crab-hole.nix b/modules/nixos-modules/server/crab-hole/crab-hole.nix index 58ff660..bde1d76 100644 --- a/modules/nixos-modules/server/crab-hole/crab-hole.nix +++ b/modules/nixos-modules/server/crab-hole/crab-hole.nix @@ -27,9 +27,19 @@ in { show_doc = lib.mkEnableOption "OpenAPI documentation (loads content from third party websites)"; downstreams = { - loopback = { - enable = lib.mkEnableOption "loopback downstream DNS server on localhost:53"; - openFirewall = lib.mkEnableOption "automatic port forwarding for the loopback downstream"; + host = { + enable = lib.mkEnableOption "host downstream DNS server accessible from network on all interfaces"; + port = lib.mkOption { + type = lib.types.port; + default = 53; + description = "Port for the host downstream DNS server to listen on."; + }; + openFirewall = lib.mkEnableOption "automatic port forwarding for the host downstream"; + disableSystemdResolved = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to automatically disable systemd-resolved when using port 53. Set to false if you want to handle the conflict manually."; + }; }; }; @@ -82,6 +92,24 @@ in { }; config = lib.mkIf cfg.enable { + # Assertions for proper configuration + assertions = [ + { + assertion = !(cfg.downstreams.host.enable && cfg.downstreams.host.port == 53 && config.services.resolved.enable && cfg.downstreams.host.disableSystemdResolved); + message = "crab-hole host downstream cannot use port 53 while systemd-resolved is enabled. Either disable systemd-resolved or use a different port."; + } + { + assertion = !(cfg.downstreams.host.enable && cfg.downstreams.host.port == 53 && !cfg.downstreams.host.disableSystemdResolved && config.services.resolved.enable); + message = "crab-hole host downstream is configured to use port 53 but systemd-resolved is still enabled and disableSystemdResolved is false. Set disableSystemdResolved = true or manually disable systemd-resolved."; + } + ]; + + # Automatically disable systemd-resolved if using port 53 + services.resolved.enable = lib.mkIf (cfg.downstreams.host.enable && cfg.downstreams.host.port == 53 && cfg.downstreams.host.disableSystemdResolved) (lib.mkForce false); + + # Configure DNS nameservers when disabling systemd-resolved + networking.nameservers = lib.mkIf (cfg.downstreams.host.enable && cfg.downstreams.host.port == 53 && cfg.downstreams.host.disableSystemdResolved) (lib.mkDefault ["127.0.0.1" "1.1.1.1" "8.8.8.8"]); + services.crab-hole.settings = lib.mkMerge [ { api = { @@ -92,12 +120,12 @@ in { downstream = cfg.extraDownstreams; upstream.name_servers = cfg.extraUpstreams; } - (lib.mkIf cfg.downstreams.loopback.enable { + (lib.mkIf cfg.downstreams.host.enable { downstream = [ { protocol = "udp"; - listen = "localhost"; - port = 53; + listen = "0.0.0.0"; + port = cfg.downstreams.host.port; } ]; }) @@ -136,8 +164,8 @@ in { (lib.mkIf cfg.openFirewall { allowedTCPPorts = [cfg.port]; }) - (lib.mkIf (cfg.downstreams.loopback.enable && cfg.downstreams.loopback.openFirewall) { - allowedUDPPorts = [53]; + (lib.mkIf (cfg.downstreams.host.enable && cfg.downstreams.host.openFirewall) { + allowedUDPPorts = [cfg.downstreams.host.port]; }) ]; }; From 290c0692bb394071c470f35e96ceb08ec987f7fe Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 20 Oct 2025 20:24:28 -0500 Subject: [PATCH 02/61] feat: added block list to crab-hole --- .../nixos/defiant/configuration.nix | 1 + .../server/crab-hole/crab-hole.nix | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index fdf7356..6908eb7 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -354,6 +354,7 @@ }; }; upstreams.cloudFlare.enable = true; + blocklists.ad_malware.enable = true; }; qbittorrent = { diff --git a/modules/nixos-modules/server/crab-hole/crab-hole.nix b/modules/nixos-modules/server/crab-hole/crab-hole.nix index bde1d76..d76323a 100644 --- a/modules/nixos-modules/server/crab-hole/crab-hole.nix +++ b/modules/nixos-modules/server/crab-hole/crab-hole.nix @@ -89,6 +89,23 @@ in { default = []; description = "List of additional upstream DNS server configurations."; }; + + blocklists = { + ad_malware = { + enable = lib.mkEnableOption "Host file for blocking ads and malware"; + url = lib.mkOption { + type = lib.types.str; + default = "http://sbc.io/hosts/hosts"; + description = "URL of the ad and malware blocklist host file"; + }; + }; + }; + + extraBlocklists = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + description = "Additional blocklist URLs to be added to the configuration"; + }; }; config = lib.mkIf cfg.enable { @@ -119,7 +136,11 @@ in { }; downstream = cfg.extraDownstreams; upstream.name_servers = cfg.extraUpstreams; + blocklist.lists = cfg.extraBlocklists; } + (lib.mkIf cfg.blocklists.ad_malware.enable { + blocklist.lists = [cfg.blocklists.ad_malware.url]; + }) (lib.mkIf cfg.downstreams.host.enable { downstream = [ { From f21777b1fbe69d747e84f0a7bd5eed85a62f576e Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 20 Oct 2025 20:55:35 -0500 Subject: [PATCH 03/61] fix: fixed pre and post commit hook behavior --- .hooks/post-commit | 10 +++++++++- .hooks/post-merge | 26 ++++++++++++++++++++------ .hooks/pre-commit | 24 +++++++++++++++++------- .hooks/pre-merge-commit | 4 ++-- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/.hooks/post-commit b/.hooks/post-commit index 56c439d..03a160d 100755 --- a/.hooks/post-commit +++ b/.hooks/post-commit @@ -3,4 +3,12 @@ echo "restoring stashed changes" -git stash pop -q +# Find the most recent pre-commit stash and restore it +recent_stash=$(git stash list | grep "pre-commit-stash-" | head -n 1 | cut -d: -f1) + +if [ -n "$recent_stash" ]; then + echo "Found recent pre-commit stash: $recent_stash" + git stash pop -q "$recent_stash" +else + echo "No pre-commit stash found to restore" +fi diff --git a/.hooks/post-merge b/.hooks/post-merge index 11fb20c..06fabc3 100755 --- a/.hooks/post-merge +++ b/.hooks/post-merge @@ -4,14 +4,28 @@ # Get current branch name current_branch=$(git branch --show-current) -# Only restore stash if we're on main branch and a merge just completed +# Only perform actions if we're on main branch and a merge just completed if [ "$current_branch" = "main" ]; then - # Check if there are any stashes to restore - if git stash list | grep -q "stash@"; then - echo "Post-merge: restoring stashed changes on main branch" - git stash pop -q + echo "Post-merge on main branch - running nix flake check" + + # Run nix flake check after merge into main + nix flake check + + if [ ! $? -eq 0 ]; then + echo "Warning: nix flake check failed after merge into main" + echo "Please fix the issues as soon as possible" else - echo "Post-merge: no stash to restore on main branch" + echo "nix flake check passed after merge" + fi + + # Check if there are any pre-commit stashes to restore + recent_stash=$(git stash list | grep "pre-commit-stash-" | head -n 1 | cut -d: -f1) + + if [ -n "$recent_stash" ]; then + echo "Post-merge: restoring pre-commit stash on main branch" + git stash pop -q "$recent_stash" + else + echo "Post-merge: no pre-commit stash to restore on main branch" fi else echo "Post-merge: no action needed on branch '$current_branch'" diff --git a/.hooks/pre-commit b/.hooks/pre-commit index f98c64f..74cbc64 100755 --- a/.hooks/pre-commit +++ b/.hooks/pre-commit @@ -1,14 +1,24 @@ #!/usr/bin/env nix-shell #! nix-shell -i bash ../shell.nix -echo "stashing all uncommitted changes" -git stash -q --keep-index +# Get current branch name +current_branch=$(git branch --show-current) -echo "checking flakes all compile" -nix flake check +echo "stashing all uncommitted changes with named stash (excluding hooks)" +git stash push -q --keep-index -m "pre-commit-stash-$(date +%s)" -- ':!.hooks/' -if [ ! $? -eq 0 ]; then - exit 1 +# Only run nix flake check if we're on main branch +if [ "$current_branch" = "main" ]; then + echo "On main branch - checking flakes all compile" + nix flake check + + if [ ! $? -eq 0 ]; then + echo "Error: nix flake check failed on main branch" + exit 1 + fi + echo "nix flake check passed" +else + echo "Not on main branch - skipping nix flake check" fi echo "running linter" @@ -19,4 +29,4 @@ RESULT=$? echo "adding lint changes to commit" git add -u -exit $RESULT \ No newline at end of file +exit $RESULT diff --git a/.hooks/pre-merge-commit b/.hooks/pre-merge-commit index 9edaf92..9b7b41d 100755 --- a/.hooks/pre-merge-commit +++ b/.hooks/pre-merge-commit @@ -17,8 +17,8 @@ fi if [ "$target_branch" = "main" ]; then echo "Merging into main branch - running nix flake check..." - echo "stashing all uncommitted changes" - git stash -q --keep-index + echo "stashing all uncommitted changes with named stash (excluding hooks)" + git stash push -q --keep-index -m "pre-merge-stash-$(date +%s)" -- ':!.hooks/' echo "checking flakes all compile" nix flake check From 539af51473126cf2a715803d80d21b5a7bfdcd13 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Tue, 21 Oct 2025 18:52:38 -0500 Subject: [PATCH 04/61] disabled crab-hole --- configurations/nixos/defiant/configuration.nix | 2 +- modules/nixos-modules/server/crab-hole/impermanence.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index 6908eb7..6d2925a 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -343,7 +343,7 @@ }; crab-hole = { - enable = true; + enable = false; port = 8085; openFirewall = true; show_doc = true; diff --git a/modules/nixos-modules/server/crab-hole/impermanence.nix b/modules/nixos-modules/server/crab-hole/impermanence.nix index 455e593..8e1182c 100644 --- a/modules/nixos-modules/server/crab-hole/impermanence.nix +++ b/modules/nixos-modules/server/crab-hole/impermanence.nix @@ -5,7 +5,7 @@ }: let workingDirectory = "/var/lib/private/crab-hole"; in { - config = lib.mkIf (config.services.immich.enable && config.host.impermanence.enable) { + config = lib.mkIf (config.services.crab-hole.enable && config.host.impermanence.enable) { assertions = [ { assertion = From 3f107f8d1eed9b38ae1270d61c283e1aed480ffa Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Tue, 21 Oct 2025 19:35:56 -0500 Subject: [PATCH 05/61] fix: fixed home manager impermanence activation on defiant --- configurations/home-manager/git/default.nix | 2 ++ configurations/home-manager/leyla/default.nix | 2 ++ modules/home-manager-modules/impermanence.nix | 16 ++++++++++------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/configurations/home-manager/git/default.nix b/configurations/home-manager/git/default.nix index 2276e7a..1ea29cc 100644 --- a/configurations/home-manager/git/default.nix +++ b/configurations/home-manager/git/default.nix @@ -1,4 +1,6 @@ {osConfig, ...}: { + impermanence.fallbackPersistence.enable = false; + home = { username = osConfig.users.users.git.name; homeDirectory = osConfig.users.users.git.home; diff --git a/configurations/home-manager/leyla/default.nix b/configurations/home-manager/leyla/default.nix index eba7f7b..8a37754 100644 --- a/configurations/home-manager/leyla/default.nix +++ b/configurations/home-manager/leyla/default.nix @@ -12,6 +12,8 @@ ]; config = { + impermanence.enable = osConfig.host.impermanence.enable; + # Home Manager needs a bit of information about you and the paths it should # manage. home = { diff --git a/modules/home-manager-modules/impermanence.nix b/modules/home-manager-modules/impermanence.nix index dc9eae9..6c75edd 100644 --- a/modules/home-manager-modules/impermanence.nix +++ b/modules/home-manager-modules/impermanence.nix @@ -8,21 +8,25 @@ in { options.impermanence = { enable = lib.mkEnableOption "impermanence for home directory"; + fallbackPersistence.enable = lib.mkOption { + type = lib.types.bool; + default = true; + }; }; config = lib.mkMerge [ (lib.mkIf config.impermanence.enable { assertions = [ { - assertion = osConfig.impermanence.enable; - message = "impermanence can not be enabled for a user when it is not enabled for a configuration"; + assertion = osConfig.host.impermanence.enable; + message = "impermanence can not be enabled for a user when it is not enabled for the system"; } ]; }) - (lib.mkIf osConfig.host.impermanence.enable { - # If impermanence is not enabled for this user but system impermanence is enabled, - # persist the entire home directory as fallback - home.persistence."/persist/home/${config.home.username}" = lib.mkIf (!cfg.enable) { + # If impermanence is not enabled for this user but system impermanence is enabled, + # persist the entire home directory as fallback + (lib.mkIf (osConfig.host.impermanence.enable && !cfg.enable && cfg.fallbackPersistence.enable) { + home.persistence."/persist/home/${config.home.username}" = { directories = ["."]; allowOther = true; }; From 455a98810abeefa12186e6484569131db4240a73 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Tue, 21 Oct 2025 20:03:52 -0500 Subject: [PATCH 06/61] feat: enabled crab-hole --- configurations/nixos/defiant/configuration.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index 6d2925a..6908eb7 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -343,7 +343,7 @@ }; crab-hole = { - enable = false; + enable = true; port = 8085; openFirewall = true; show_doc = true; From b17f8d49d5f3bd141ccc1a8e287c5f6b8b2acd76 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Tue, 21 Oct 2025 20:32:24 -0500 Subject: [PATCH 07/61] build: updated flake.lock --- flake.lock | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/flake.lock b/flake.lock index bb7e3a6..09349a6 100644 --- a/flake.lock +++ b/flake.lock @@ -46,11 +46,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1760673822, - "narHash": "sha256-h+liPhhMw1yYvkDGLHzQJQShQs+yLjNgjfAyZX+sRrM=", + "lastModified": 1761019419, + "narHash": "sha256-lOzy4BGZtPxxNOzDEwfy3lcb7enl53f1wYP/JVWwSHg=", "owner": "rycee", "repo": "nur-expressions", - "rev": "5cca27f1bb30a26140d0cf60ab34daa45b4fa11f", + "rev": "727c8a012382db77e14d72ce1fe4e19be3206ce6", "type": "gitlab" }, "original": { @@ -133,11 +133,11 @@ ] }, "locked": { - "lastModified": 1760662441, - "narHash": "sha256-mlDqR1Ntgs9uYYEAUR1IhamKBO0lxoNS4zGLzEZaY0A=", + "lastModified": 1761081701, + "narHash": "sha256-IwpfaKg5c/WWQiy8b5QGaVPMvoEQ2J6kpwRFdpVpBNQ=", "owner": "nix-community", "repo": "home-manager", - "rev": "722792af097dff5790f1a66d271a47759f477755", + "rev": "9b4a2a7c4fbd75b422f00794af02d6edb4d9d315", "type": "github" }, "original": { @@ -207,11 +207,11 @@ ] }, "locked": { - "lastModified": 1759342933, - "narHash": "sha256-mdlUFcrOfvT0Pm+Hko/6aR3xf1ao5JA2iem4KsEVjP4=", + "lastModified": 1760821194, + "narHash": "sha256-UCsJ8eDuHL14u2GFIYEY/drtZ6jht5zN/G/6QNlEy2g=", "owner": "utensils", "repo": "mcp-nixos", - "rev": "50b02bcba32b941d2ec48fedef68641702ca5b0f", + "rev": "0ae453f38d0f088c31d4678da3a12b183165986f", "type": "github" }, "original": { @@ -268,11 +268,11 @@ ] }, "locked": { - "lastModified": 1760720017, - "narHash": "sha256-ALb+L8zaP6IJ3BigQJ+ih7NqmaptzL/CbkNkLbhmsGE=", + "lastModified": 1761011896, + "narHash": "sha256-p6oWYhpJGIV76tJExGUFRkir29yCTUYLsnKmnhzW2C0=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "b0897a5d1d5829eb67ca7168680873ee7a0d52b8", + "rev": "0a74c6a180110ac18584780eeff31e302b0bf8a4", "type": "github" }, "original": { @@ -283,11 +283,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1760106635, - "narHash": "sha256-2GoxVaKWTHBxRoeUYSjv0AfSOx4qw5CWSFz2b+VolKU=", + "lastModified": 1760958188, + "narHash": "sha256-2m1S4jl+GEDtlt2QqeHil8Ny456dcGSKJAM7q3j/BFU=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "9ed85f8afebf2b7478f25db0a98d0e782c0ed903", + "rev": "d6645c340ef7d821602fd2cd199e8d1eed10afbc", "type": "github" }, "original": { @@ -315,11 +315,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1760524057, - "narHash": "sha256-EVAqOteLBFmd7pKkb0+FIUyzTF61VKi7YmvP1tw4nEw=", + "lastModified": 1760878510, + "narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "544961dfcce86422ba200ed9a0b00dd4b1486ec5", + "rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67", "type": "github" }, "original": { @@ -370,11 +370,11 @@ ] }, "locked": { - "lastModified": 1760393368, - "narHash": "sha256-8mN3kqyqa2PKY0wwZ2UmMEYMcxvNTwLaOrrDsw6Qi4E=", + "lastModified": 1760998189, + "narHash": "sha256-ee2e1/AeGL5X8oy/HXsZQvZnae6XfEVdstGopKucYLY=", "owner": "Mic92", "repo": "sops-nix", - "rev": "ab8d56e85b8be14cff9d93735951e30c3e86a437", + "rev": "5a7d18b5c55642df5c432aadb757140edfeb70b3", "type": "github" }, "original": { From db8d36dadc3edff29eecf85137d5c5048c4a5960 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Tue, 21 Oct 2025 20:39:16 -0500 Subject: [PATCH 08/61] build: updated mapillary uploader hash --- modules/common-modules/pkgs/mapillary-uploader.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/common-modules/pkgs/mapillary-uploader.nix b/modules/common-modules/pkgs/mapillary-uploader.nix index 9ae2ea7..acff772 100644 --- a/modules/common-modules/pkgs/mapillary-uploader.nix +++ b/modules/common-modules/pkgs/mapillary-uploader.nix @@ -9,7 +9,7 @@ src = fetchurl { url = "http://tools.mapillary.com/uploader/download/linux/${version}"; name = "mapillary-uploader.AppImage"; - sha256 = "sha256-OY3SiMHUyjwPDrPWfa+mFg2BHZrz6GG/9/D5sCP2Da8="; + sha256 = "sha256-hpWdfeuhYylO+SFD3BsKI0s/xtObCDd5OcuJ6i/aEuI="; }; appimageContents = appimageTools.extractType2 { From 466926b919bbc929aece6cb0f21c6cc62cd13a06 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Tue, 21 Oct 2025 20:44:53 -0500 Subject: [PATCH 09/61] refactor: updated git configuration --- configurations/home-manager/eve/packages.nix | 8 +++++--- configurations/home-manager/leyla/packages/git.nix | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/configurations/home-manager/eve/packages.nix b/configurations/home-manager/eve/packages.nix index 73195c4..fb8d8a4 100644 --- a/configurations/home-manager/eve/packages.nix +++ b/configurations/home-manager/eve/packages.nix @@ -32,9 +32,11 @@ in { (lib.mkIf (config.user.isDesktopUser || config.user.isTerminalUser) { git = { enable = true; - userName = "Eve"; - userEmail = "evesnrobins@gmail.com"; - extraConfig.init.defaultBranch = "main"; + settings = { + user.name = "Eve"; + user.email = "evesnrobins@gmail.com"; + init.defaultBranch = "main"; + }; }; openssh = { diff --git a/configurations/home-manager/leyla/packages/git.nix b/configurations/home-manager/leyla/packages/git.nix index 568cd7a..499e37b 100644 --- a/configurations/home-manager/leyla/packages/git.nix +++ b/configurations/home-manager/leyla/packages/git.nix @@ -2,9 +2,11 @@ config = { programs = { git = { - userName = "Leyla Becker"; - userEmail = "git@jan-leila.com"; - extraConfig.init.defaultBranch = "main"; + settings = { + user.name = "Leyla Becker"; + user.email = "git@jan-leila.com"; + init.defaultBranch = "main"; + }; }; }; }; From 4dd285c1229a15ad051f432219897f9b3c93d0c8 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 24 Oct 2025 12:45:17 -0500 Subject: [PATCH 10/61] feat: refactored reverse proxy to be a normally named module --- .../nixos/defiant/configuration.nix | 31 ++-- modules/nixos-modules/server/actual/proxy.nix | 23 ++- .../nixos-modules/server/bazarr/default.nix | 1 - modules/nixos-modules/server/bazarr/proxy.nix | 28 ---- modules/nixos-modules/server/default.nix | 2 +- .../server/flaresolverr/default.nix | 1 - .../server/flaresolverr/proxy.nix | 28 ---- .../nixos-modules/server/forgejo/default.nix | 2 +- .../nixos-modules/server/forgejo/proxy.nix | 25 ++- .../server/home-assistant/default.nix | 2 +- .../server/home-assistant/proxy.nix | 36 ++-- modules/nixos-modules/server/immich/proxy.nix | 39 +++-- .../nixos-modules/server/jackett/default.nix | 1 - .../nixos-modules/server/jackett/proxy.nix | 28 ---- .../nixos-modules/server/jellyfin/proxy.nix | 33 ++-- .../nixos-modules/server/lidarr/default.nix | 1 - modules/nixos-modules/server/lidarr/proxy.nix | 28 ---- .../nixos-modules/server/panoramax/proxy.nix | 36 ++-- .../server/paperless/default.nix | 1 - .../nixos-modules/server/paperless/proxy.nix | 33 ++-- .../nixos-modules/server/radarr/default.nix | 1 - modules/nixos-modules/server/radarr/proxy.nix | 28 ---- .../server/reverseProxy/default.nix | 6 + .../server/reverseProxy/impermanence.nix | 21 +++ .../server/reverseProxy/reverseProxy.nix | 158 ++++++++++++++++++ .../nixos-modules/server/reverse_proxy.nix | 128 -------------- modules/nixos-modules/server/searx/proxy.nix | 28 +++- .../nixos-modules/server/sonarr/default.nix | 1 - modules/nixos-modules/server/sonarr/proxy.nix | 28 ---- 29 files changed, 352 insertions(+), 426 deletions(-) delete mode 100644 modules/nixos-modules/server/bazarr/proxy.nix delete mode 100644 modules/nixos-modules/server/flaresolverr/proxy.nix delete mode 100644 modules/nixos-modules/server/jackett/proxy.nix delete mode 100644 modules/nixos-modules/server/lidarr/proxy.nix delete mode 100644 modules/nixos-modules/server/radarr/proxy.nix create mode 100644 modules/nixos-modules/server/reverseProxy/default.nix create mode 100644 modules/nixos-modules/server/reverseProxy/impermanence.nix create mode 100644 modules/nixos-modules/server/reverseProxy/reverseProxy.nix delete mode 100644 modules/nixos-modules/server/reverse_proxy.nix delete mode 100644 modules/nixos-modules/server/sonarr/proxy.nix diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index 6908eb7..91a8c2c 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -102,11 +102,6 @@ directories = ["leyla_documents" "eve_documents" "users_documents" "media"]; }; }; - reverse_proxy = { - enable = true; - enableACME = true; - hostname = "jan-leila.com"; - }; postgres = { extraUsers = { leyla = { @@ -237,6 +232,16 @@ gnome.enable = true; }; + # Enable new reverse proxy system + reverseProxy = { + enable = true; + openFirewall = true; + acme = { + enable = true; + email = "jan-leila@protonmail.com"; + }; + }; + ollama = { enable = true; exposePort = true; @@ -294,33 +299,33 @@ jellyfin = { enable = true; - subdomain = "media"; - extraSubdomains = ["jellyfin"]; + domain = "media.jan-leila.com"; + extraDomains = ["jellyfin.jan-leila.com"]; }; immich = { enable = true; - subdomain = "photos"; + domain = "photos.jan-leila.com"; }; forgejo = { enable = true; - subdomain = "git"; + domain = "git.jan-leila.com"; }; searx = { enable = true; - subdomain = "search"; + domain = "search.jan-leila.com"; }; actual = { enable = false; - subdomain = "budget"; + domain = "budget.jan-leila.com"; }; home-assistant = { enable = true; - subdomain = "home"; + domain = "home.jan-leila.com"; openFirewall = true; database = "postgres"; @@ -333,7 +338,7 @@ paperless = { enable = true; - subdomain = "documents"; + domain = "documents.jan-leila.com"; passwordFile = config.sops.secrets."services/paperless_password".path; }; diff --git a/modules/nixos-modules/server/actual/proxy.nix b/modules/nixos-modules/server/actual/proxy.nix index 6ca51e4..bf1711a 100644 --- a/modules/nixos-modules/server/actual/proxy.nix +++ b/modules/nixos-modules/server/actual/proxy.nix @@ -4,17 +4,26 @@ ... }: { options.services.actual = { - subdomain = lib.mkOption { + domain = lib.mkOption { type = lib.types.str; - default = "actual"; - description = "subdomain of base domain that actual will be hosted at"; + description = "domain that actual will be hosted at"; + default = "actual.arpa"; + }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for actual"; + default = []; }; }; - config = lib.mkIf (config.services.actual.enable && config.host.reverse_proxy.enable) { - host = { - reverse_proxy.subdomains.${config.services.actual.subdomain} = { - target = "http://localhost:${toString config.services.actual.settings.port}"; + config = lib.mkIf (config.services.actual.enable && config.services.reverseProxy.enable) { + services.reverseProxy.services.actual = { + target = "http://localhost:${toString config.services.actual.settings.port}"; + domain = config.services.actual.domain; + extraDomains = config.services.actual.extraDomains; + + settings = { + forwardHeaders.enable = true; }; }; }; diff --git a/modules/nixos-modules/server/bazarr/default.nix b/modules/nixos-modules/server/bazarr/default.nix index f39d940..86dbb4b 100644 --- a/modules/nixos-modules/server/bazarr/default.nix +++ b/modules/nixos-modules/server/bazarr/default.nix @@ -1,6 +1,5 @@ {...}: { imports = [ - ./proxy.nix ./impermanence.nix ]; } diff --git a/modules/nixos-modules/server/bazarr/proxy.nix b/modules/nixos-modules/server/bazarr/proxy.nix deleted file mode 100644 index fe310d8..0000000 --- a/modules/nixos-modules/server/bazarr/proxy.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - lib, - config, - ... -}: { - options.services.bazarr = { - subdomain = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Subdomain for reverse proxy. If null, service will be local only."; - }; - extraSubdomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - description = "Extra subdomains for reverse proxy."; - }; - }; - - config = lib.mkIf (config.services.bazarr.enable && config.services.bazarr.subdomain != null) { - host.reverse_proxy.subdomains.bazarr = { - subdomain = config.services.bazarr.subdomain; - extraSubdomains = config.services.bazarr.extraSubdomains; - target = "http://127.0.0.1:6767"; - websockets.enable = true; - forwardHeaders.enable = true; - }; - }; -} diff --git a/modules/nixos-modules/server/default.nix b/modules/nixos-modules/server/default.nix index 57874d5..4981f28 100644 --- a/modules/nixos-modules/server/default.nix +++ b/modules/nixos-modules/server/default.nix @@ -1,6 +1,6 @@ {...}: { imports = [ - ./reverse_proxy.nix + ./reverseProxy ./fail2ban.nix ./postgres.nix ./network_storage diff --git a/modules/nixos-modules/server/flaresolverr/default.nix b/modules/nixos-modules/server/flaresolverr/default.nix index f39d940..86dbb4b 100644 --- a/modules/nixos-modules/server/flaresolverr/default.nix +++ b/modules/nixos-modules/server/flaresolverr/default.nix @@ -1,6 +1,5 @@ {...}: { imports = [ - ./proxy.nix ./impermanence.nix ]; } diff --git a/modules/nixos-modules/server/flaresolverr/proxy.nix b/modules/nixos-modules/server/flaresolverr/proxy.nix deleted file mode 100644 index 5b8dd4c..0000000 --- a/modules/nixos-modules/server/flaresolverr/proxy.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - lib, - config, - ... -}: { - options.services.flaresolverr = { - subdomain = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Subdomain for reverse proxy. If null, service will be local only."; - }; - extraSubdomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - description = "Extra subdomains for reverse proxy."; - }; - }; - - config = lib.mkIf (config.services.flaresolverr.enable && config.services.flaresolverr.subdomain != null) { - host.reverse_proxy.subdomains.flaresolverr = { - subdomain = config.services.flaresolverr.subdomain; - extraSubdomains = config.services.flaresolverr.extraSubdomains; - target = "http://127.0.0.1:${toString config.services.flaresolverr.port}"; - websockets.enable = true; - forwardHeaders.enable = true; - }; - }; -} diff --git a/modules/nixos-modules/server/forgejo/default.nix b/modules/nixos-modules/server/forgejo/default.nix index 1fdc8d9..5d0e7ad 100644 --- a/modules/nixos-modules/server/forgejo/default.nix +++ b/modules/nixos-modules/server/forgejo/default.nix @@ -31,7 +31,7 @@ in { lfs.enable = true; settings = { server = { - DOMAIN = "${config.services.forgejo.subdomain}.${config.host.reverse_proxy.hostname}"; + DOMAIN = config.services.forgejo.reverseProxy.domain; HTTP_PORT = httpPort; START_SSH_SERVER = true; SSH_LISTEN_PORT = sshPort; diff --git a/modules/nixos-modules/server/forgejo/proxy.nix b/modules/nixos-modules/server/forgejo/proxy.nix index 51f769d..bde59d1 100644 --- a/modules/nixos-modules/server/forgejo/proxy.nix +++ b/modules/nixos-modules/server/forgejo/proxy.nix @@ -7,16 +7,29 @@ httpPort = const.httpPort; in { options.services.forgejo = { - subdomain = lib.mkOption { - type = lib.types.str; - description = "subdomain of base domain that forgejo will be hosted at"; - default = "forgejo"; + reverseProxy = { + domain = lib.mkOption { + type = lib.types.str; + description = "domain that forgejo will be hosted at"; + default = "git.jan-leila.com"; + }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for forgejo"; + default = []; + }; }; }; - config = lib.mkIf (config.services.forgejo.enable && config.host.reverse_proxy.enable) { - host.reverse_proxy.subdomains.${config.services.forgejo.subdomain} = { + config = lib.mkIf (config.services.forgejo.enable && config.services.reverseProxy.enable) { + services.reverseProxy.services.forgejo = { target = "http://localhost:${toString httpPort}"; + domain = config.services.forgejo.reverseProxy.domain; + extraDomains = config.services.forgejo.reverseProxy.extraDomains; + + settings = { + forwardHeaders.enable = true; + }; }; networking.firewall.allowedTCPPorts = [ diff --git a/modules/nixos-modules/server/home-assistant/default.nix b/modules/nixos-modules/server/home-assistant/default.nix index 83d8ba7..4b1846b 100644 --- a/modules/nixos-modules/server/home-assistant/default.nix +++ b/modules/nixos-modules/server/home-assistant/default.nix @@ -82,7 +82,7 @@ login_attempts_threshold = 10; }; homeassistant = { - external_url = "https://${config.services.home-assistant.subdomain}.${config.host.reverse_proxy.hostname}"; + external_url = "https://${config.services.home-assistant.domain}"; # internal_url = "http://192.168.1.2:8123"; }; recorder.db_url = "postgresql://@/${config.services.home-assistant.configDir}"; diff --git a/modules/nixos-modules/server/home-assistant/proxy.nix b/modules/nixos-modules/server/home-assistant/proxy.nix index ba8f20d..1075c59 100644 --- a/modules/nixos-modules/server/home-assistant/proxy.nix +++ b/modules/nixos-modules/server/home-assistant/proxy.nix @@ -4,29 +4,33 @@ ... }: { options.services.home-assistant = { - subdomain = lib.mkOption { + domain = lib.mkOption { type = lib.types.str; - description = "subdomain of base domain that home-assistant will be hosted at"; - default = "home-assistant"; + description = "domain that home-assistant will be hosted at"; + default = "home-assistant.arpa"; + }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for home-assistant"; + default = []; }; }; - config = lib.mkIf (config.host.reverse_proxy.enable && config.services.home-assistant.enable) { - host = { - reverse_proxy.subdomains.${config.services.home-assistant.subdomain} = { - target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; + config = lib.mkIf (config.services.reverseProxy.enable && config.services.home-assistant.enable) { + services.reverseProxy.services.home-assistant = { + target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; + domain = config.services.home-assistant.domain; + extraDomains = config.services.home-assistant.extraDomains; - websockets.enable = true; + settings = { + proxyWebsockets.enable = true; forwardHeaders.enable = true; - extraConfig = '' - add_header Upgrade $http_upgrade; - add_header Connection \"upgrade\"; - - proxy_buffering off; - - proxy_read_timeout 90; - ''; + # Custom timeout settings + proxyHeaders = { + enable = true; + timeout = 90; + }; }; }; }; diff --git a/modules/nixos-modules/server/immich/proxy.nix b/modules/nixos-modules/server/immich/proxy.nix index dae2420..a50ea1e 100644 --- a/modules/nixos-modules/server/immich/proxy.nix +++ b/modules/nixos-modules/server/immich/proxy.nix @@ -4,31 +4,34 @@ ... }: { options.services.immich = { - subdomain = lib.mkOption { + domain = lib.mkOption { type = lib.types.str; - description = "subdomain of base domain that immich will be hosted at"; - default = "immich"; + description = "domain that immich will be hosted at"; + default = "immich.arpa"; + }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for immich"; + default = []; }; }; - config = lib.mkIf (config.services.immich.enable && config.host.reverse_proxy.enable) { - host = { - reverse_proxy.subdomains.${config.services.immich.subdomain} = { - target = "http://localhost:${toString config.services.immich.port}"; + config = lib.mkIf (config.services.immich.enable && config.services.reverseProxy.enable) { + services.reverseProxy.services.immich = { + target = "http://localhost:${toString config.services.immich.port}"; + domain = config.services.immich.domain; + extraDomains = config.services.immich.extraDomains; - websockets.enable = true; + settings = { + proxyWebsockets.enable = true; forwardHeaders.enable = true; + maxBodySize = 50000; - extraConfig = '' - # allow large file uploads - client_max_body_size 50000M; - - # set timeout - proxy_read_timeout 600s; - proxy_send_timeout 600s; - send_timeout 600s; - proxy_redirect off; - ''; + # Custom timeout settings + proxyHeaders = { + enable = true; + timeout = 600; + }; }; }; }; diff --git a/modules/nixos-modules/server/jackett/default.nix b/modules/nixos-modules/server/jackett/default.nix index f39d940..86dbb4b 100644 --- a/modules/nixos-modules/server/jackett/default.nix +++ b/modules/nixos-modules/server/jackett/default.nix @@ -1,6 +1,5 @@ {...}: { imports = [ - ./proxy.nix ./impermanence.nix ]; } diff --git a/modules/nixos-modules/server/jackett/proxy.nix b/modules/nixos-modules/server/jackett/proxy.nix deleted file mode 100644 index af5fa79..0000000 --- a/modules/nixos-modules/server/jackett/proxy.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - lib, - config, - ... -}: { - options.services.jackett = { - subdomain = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Subdomain for reverse proxy. If null, service will be local only."; - }; - extraSubdomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - description = "Extra subdomains for reverse proxy."; - }; - }; - - config = lib.mkIf (config.services.jackett.enable && config.services.jackett.subdomain != null) { - host.reverse_proxy.subdomains.jackett = { - subdomain = config.services.jackett.subdomain; - extraSubdomains = config.services.jackett.extraSubdomains; - target = "http://127.0.0.1:9117"; - websockets.enable = true; - forwardHeaders.enable = true; - }; - }; -} diff --git a/modules/nixos-modules/server/jellyfin/proxy.nix b/modules/nixos-modules/server/jellyfin/proxy.nix index 1020a19..f803ecb 100644 --- a/modules/nixos-modules/server/jellyfin/proxy.nix +++ b/modules/nixos-modules/server/jellyfin/proxy.nix @@ -6,33 +6,30 @@ jellyfinPort = 8096; in { options.services.jellyfin = { - subdomain = lib.mkOption { + domain = lib.mkOption { type = lib.types.str; - description = "subdomain of base domain that jellyfin will be hosted at"; - default = "jellyfin"; + description = "domain that jellyfin will be hosted at"; + default = "jellyfin.arpa"; }; - extraSubdomains = lib.mkOption { + extraDomains = lib.mkOption { type = lib.types.listOf lib.types.str; - description = "ex subdomain of base domain that jellyfin will be hosted at"; + description = "extra domains that should be configured for jellyfin"; default = []; }; }; - config = lib.mkIf (config.services.jellyfin.enable && config.host.reverse_proxy.enable) { - host.reverse_proxy.subdomains.jellyfin = { + config = lib.mkIf (config.services.jellyfin.enable && config.services.reverseProxy.enable) { + services.reverseProxy.services.jellyfin = { target = "http://localhost:${toString jellyfinPort}"; + domain = config.services.jellyfin.domain; + extraDomains = config.services.jellyfin.extraDomains; - subdomain = config.services.jellyfin.subdomain; - extraSubdomains = config.services.jellyfin.extraSubdomains; - - forwardHeaders.enable = true; - - extraConfig = '' - client_max_body_size 20M; - add_header X-Content-Type-Options "nosniff"; - - proxy_buffering off; - ''; + settings = { + forwardHeaders.enable = true; + maxBodySize = 20; + noSniff.enable = true; + proxyBuffering.enable = false; + }; }; }; } diff --git a/modules/nixos-modules/server/lidarr/default.nix b/modules/nixos-modules/server/lidarr/default.nix index f39d940..86dbb4b 100644 --- a/modules/nixos-modules/server/lidarr/default.nix +++ b/modules/nixos-modules/server/lidarr/default.nix @@ -1,6 +1,5 @@ {...}: { imports = [ - ./proxy.nix ./impermanence.nix ]; } diff --git a/modules/nixos-modules/server/lidarr/proxy.nix b/modules/nixos-modules/server/lidarr/proxy.nix deleted file mode 100644 index 0146ccf..0000000 --- a/modules/nixos-modules/server/lidarr/proxy.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - lib, - config, - ... -}: { - options.services.lidarr = { - subdomain = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Subdomain for reverse proxy. If null, service will be local only."; - }; - extraSubdomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - description = "Extra subdomains for reverse proxy."; - }; - }; - - config = lib.mkIf (config.services.lidarr.enable && config.services.lidarr.subdomain != null) { - host.reverse_proxy.subdomains.lidarr = { - subdomain = config.services.lidarr.subdomain; - extraSubdomains = config.services.lidarr.extraSubdomains; - target = "http://127.0.0.1:8686"; - websockets.enable = true; - forwardHeaders.enable = true; - }; - }; -} diff --git a/modules/nixos-modules/server/panoramax/proxy.nix b/modules/nixos-modules/server/panoramax/proxy.nix index 79f9326..35bc79b 100644 --- a/modules/nixos-modules/server/panoramax/proxy.nix +++ b/modules/nixos-modules/server/panoramax/proxy.nix @@ -4,31 +4,29 @@ ... }: { options.services.panoramax = { - subdomain = lib.mkOption { + domain = lib.mkOption { type = lib.types.str; - description = "subdomain of base domain that panoramax will be hosted at"; - default = "panoramax"; + description = "domain that panoramax will be hosted at"; + default = "panoramax.arpa"; + }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for panoramax"; + default = []; }; }; - config = lib.mkIf (config.services.panoramax.enable && config.host.reverse_proxy.enable) { - host = { - reverse_proxy.subdomains.${config.services.panoramax.subdomain} = { - target = "http://localhost:${toString config.services.panoramax.port}"; + config = lib.mkIf (config.services.panoramax.enable && config.services.reverseProxy.enable) { + services.reverseProxy.services.panoramax = { + target = "http://localhost:${toString config.services.panoramax.port}"; + domain = config.services.panoramax.domain; + extraDomains = config.services.panoramax.extraDomains; - websockets.enable = true; + settings = { + proxyWebsockets.enable = true; forwardHeaders.enable = true; - - extraConfig = '' - # allow large file uploads for panoramic images - client_max_body_size 100M; - - # set timeout for image processing - proxy_read_timeout 300s; - proxy_send_timeout 300s; - send_timeout 300s; - proxy_redirect off; - ''; + maxBodySize = 100000; + timeout = 300; }; }; }; diff --git a/modules/nixos-modules/server/paperless/default.nix b/modules/nixos-modules/server/paperless/default.nix index a6878eb..d2bc930 100644 --- a/modules/nixos-modules/server/paperless/default.nix +++ b/modules/nixos-modules/server/paperless/default.nix @@ -22,7 +22,6 @@ config = lib.mkIf config.services.paperless.enable { services.paperless = { - domain = "${config.services.paperless.subdomain}.${config.host.reverse_proxy.hostname}"; configureTika = true; settings = { PAPERLESS_DBENGINE = "postgresql"; diff --git a/modules/nixos-modules/server/paperless/proxy.nix b/modules/nixos-modules/server/paperless/proxy.nix index 2910f07..e79c8d9 100644 --- a/modules/nixos-modules/server/paperless/proxy.nix +++ b/modules/nixos-modules/server/paperless/proxy.nix @@ -4,25 +4,30 @@ ... }: { options.services.paperless = { - subdomain = lib.mkOption { - type = lib.types.str; - description = "subdomain of base domain that paperless will be hosted at"; - default = "paperless"; + reverseProxy = { + domain = lib.mkOption { + type = lib.types.str; + description = "domain that paperless will be hosted at"; + default = "paperless.arpa"; + }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for paperless"; + default = []; + }; }; }; - config = lib.mkIf (config.services.paperless.enable && config.host.reverse_proxy.enable) { - host = { - reverse_proxy.subdomains.${config.services.paperless.subdomain} = { - target = "http://${config.services.paperless.address}:${toString config.services.paperless.port}"; + config = lib.mkIf (config.services.paperless.enable && config.services.reverseProxy.enable) { + services.reverseProxy.services.paperless = { + target = "http://${config.services.paperless.address}:${toString config.services.paperless.port}"; + domain = config.services.paperless.reverseProxy.domain; + extraDomains = config.services.paperless.reverseProxy.extraDomains; - websockets.enable = true; + settings = { + proxyWebsockets.enable = true; forwardHeaders.enable = true; - - extraConfig = '' - # allow large file uploads - client_max_body_size 50000M; - ''; + maxBodySize = 50000; }; }; }; diff --git a/modules/nixos-modules/server/radarr/default.nix b/modules/nixos-modules/server/radarr/default.nix index f39d940..86dbb4b 100644 --- a/modules/nixos-modules/server/radarr/default.nix +++ b/modules/nixos-modules/server/radarr/default.nix @@ -1,6 +1,5 @@ {...}: { imports = [ - ./proxy.nix ./impermanence.nix ]; } diff --git a/modules/nixos-modules/server/radarr/proxy.nix b/modules/nixos-modules/server/radarr/proxy.nix deleted file mode 100644 index ec5f575..0000000 --- a/modules/nixos-modules/server/radarr/proxy.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - lib, - config, - ... -}: { - options.services.radarr = { - subdomain = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Subdomain for reverse proxy. If null, service will be local only."; - }; - extraSubdomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - description = "Extra subdomains for reverse proxy."; - }; - }; - - config = lib.mkIf (config.services.radarr.enable && config.services.radarr.subdomain != null) { - host.reverse_proxy.subdomains.radarr = { - subdomain = config.services.radarr.subdomain; - extraSubdomains = config.services.radarr.extraSubdomains; - target = "http://127.0.0.1:7878"; - websockets.enable = true; - forwardHeaders.enable = true; - }; - }; -} diff --git a/modules/nixos-modules/server/reverseProxy/default.nix b/modules/nixos-modules/server/reverseProxy/default.nix new file mode 100644 index 0000000..5d57175 --- /dev/null +++ b/modules/nixos-modules/server/reverseProxy/default.nix @@ -0,0 +1,6 @@ +{...}: { + imports = [ + ./reverseProxy.nix + ./impermanence.nix + ]; +} diff --git a/modules/nixos-modules/server/reverseProxy/impermanence.nix b/modules/nixos-modules/server/reverseProxy/impermanence.nix new file mode 100644 index 0000000..7af55df --- /dev/null +++ b/modules/nixos-modules/server/reverseProxy/impermanence.nix @@ -0,0 +1,21 @@ +{ + lib, + config, + ... +}: let + dataDir = "/var/lib/acme"; +in { + config = lib.mkIf (config.host.impermanence.enable && config.services.reverseProxy.enable) { + environment.persistence."/persist/system/root" = { + enable = true; + hideMounts = true; + directories = [ + { + directory = dataDir; + user = "acme"; + group = "acme"; + } + ]; + }; + }; +} diff --git a/modules/nixos-modules/server/reverseProxy/reverseProxy.nix b/modules/nixos-modules/server/reverseProxy/reverseProxy.nix new file mode 100644 index 0000000..5b8357f --- /dev/null +++ b/modules/nixos-modules/server/reverseProxy/reverseProxy.nix @@ -0,0 +1,158 @@ +{ + lib, + config, + ... +}: { + options.services.reverseProxy = { + enable = lib.mkEnableOption "turn on the reverse proxy"; + openFirewall = lib.mkEnableOption "open the firewall"; + ports = { + http = lib.mkOption { + type = lib.types.port; + description = "HTTP port for the reverse proxy"; + default = 80; + }; + https = lib.mkOption { + type = lib.types.port; + description = "HTTPS port for the reverse proxy"; + default = 443; + }; + }; + acme = { + enable = lib.mkOption { + type = lib.types.bool; + description = "enable ACME certificate management"; + default = true; + }; + email = lib.mkOption { + type = lib.types.str; + description = "email address for ACME certificate registration"; + }; + }; + services = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { + options = { + target = lib.mkOption { + type = lib.types.str; + description = "what url will all traffic to this application be forwarded to"; + }; + domain = lib.mkOption { + type = lib.types.str; + description = "what is the default subdomain to be used for this application to be used for"; + default = name; + }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for this domain"; + default = []; + }; + settings = { + certificateRenewal.enable = lib.mkOption { + type = lib.types.bool; + description = "auto renew certificates"; + default = true; + }; + forceSSL.enable = lib.mkOption { + type = lib.types.bool; + description = "auto renew certificates"; + default = true; + }; + proxyHeaders = { + enable = lib.mkEnableOption "should we proxy headers"; + timeout = lib.mkOption { + type = lib.types.int; + default = 60; + }; + }; + proxyWebsockets.enable = lib.mkEnableOption "should the default config proxy websockets"; + forwardHeaders.enable = lib.mkEnableOption "should the default config contain forward headers"; + noSniff.enable = lib.mkEnableOption "should the no sniff flags be set"; + proxyBuffering.enable = lib.mkOption { + type = lib.types.bool; + description = "should proxy buffering be enabled"; + default = true; + }; + maxBodySize = lib.mkOption { + type = lib.types.nullOr lib.types.int; + description = ""; + default = null; + }; + }; + }; + })); + }; + }; + + config = let + httpPort = config.services.reverseProxy.ports.http; + httpsPort = config.services.reverseProxy.ports.https; + in + lib.mkIf config.services.reverseProxy.enable { + security.acme = lib.mkIf config.services.reverseProxy.acme.enable { + acceptTerms = true; + defaults.email = config.services.reverseProxy.acme.email; + }; + + services.nginx = { + enable = true; + virtualHosts = lib.mkMerge ( + lib.lists.flatten ( + lib.attrsets.mapAttrsToList ( + name: service: let + hostConfig = { + forceSSL = service.settings.forceSSL.enable; + enableACME = service.settings.certificateRenewal.enable; + locations = { + "/" = { + proxyPass = service.target; + proxyWebsockets = service.settings.proxyWebsockets.enable; + recommendedProxySettings = service.settings.forwardHeaders.enable; + extraConfig = let + # Client upload size configuration + maxBodySizeConfig = + lib.optionalString (service.settings.maxBodySize != null) + "client_max_body_size ${toString service.settings.maxBodySize}M;"; + + # Security header configuration + noSniffConfig = + lib.optionalString service.settings.noSniff.enable + "add_header X-Content-Type-Options nosniff;"; + + # Proxy buffering configuration + proxyBufferingConfig = + lib.optionalString (!service.settings.proxyBuffering.enable) + "proxy_buffering off;"; + + # Proxy timeout configuration + proxyTimeoutConfig = + lib.optionalString service.settings.proxyHeaders.enable + '' + proxy_read_timeout ${toString service.settings.proxyHeaders.timeout}s; + proxy_connect_timeout ${toString service.settings.proxyHeaders.timeout}s; + proxy_send_timeout ${toString service.settings.proxyHeaders.timeout}s; + ''; + in + maxBodySizeConfig + noSniffConfig + proxyBufferingConfig + proxyTimeoutConfig; + }; + }; + }; + in ( + [ + { + ${service.domain} = hostConfig; + } + ] + ++ builtins.map (domain: {${domain} = hostConfig;}) + service.extraDomains + ) + ) + config.services.reverseProxy.services + ) + ); + }; + networking.firewall.allowedTCPPorts = lib.mkIf config.services.reverseProxy.openFirewall [ + httpPort + httpsPort + ]; + }; +} diff --git a/modules/nixos-modules/server/reverse_proxy.nix b/modules/nixos-modules/server/reverse_proxy.nix deleted file mode 100644 index 26b4374..0000000 --- a/modules/nixos-modules/server/reverse_proxy.nix +++ /dev/null @@ -1,128 +0,0 @@ -{ - lib, - config, - ... -}: let - dataDir = "/var/lib/acme"; - httpPort = 80; - httpsPort = 443; -in { - options.host.reverse_proxy = { - enable = lib.mkEnableOption "turn on the reverse proxy"; - hostname = lib.mkOption { - type = lib.types.str; - description = "what host name are we going to be proxying from"; - }; - forceSSL = lib.mkOption { - type = lib.types.bool; - description = "force connections to use https"; - default = config.host.reverse_proxy.enableACME; - }; - enableACME = lib.mkOption { - type = lib.types.bool; - description = "auto renew certificates"; - default = true; - }; - subdomains = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { - options = { - subdomain = lib.mkOption { - type = lib.types.str; - description = "what is the default subdomain to be used for this application to be used for"; - default = name; - }; - extraSubdomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - description = "extra domains that should be configured for this domain"; - default = []; - }; - - target = lib.mkOption { - type = lib.types.str; - description = "what url will all traffic to this application be forwarded to"; - }; - - websockets.enable = lib.mkEnableOption "should the default config proxy websockets"; - - forwardHeaders.enable = lib.mkEnableOption "should the default config contain forward headers"; - - extraConfig = lib.mkOption { - type = lib.types.lines; - default = ""; - description = '' - These lines go to the end of the upstream verbatim. - ''; - }; - }; - })); - }; - }; - - config = lib.mkIf config.host.reverse_proxy.enable (lib.mkMerge [ - { - security.acme = lib.mkIf config.host.reverse_proxy.enableACME { - acceptTerms = true; - defaults.email = "jan-leila@protonmail.com"; - }; - - services.nginx = { - enable = true; - virtualHosts = lib.mkMerge ( - lib.lists.flatten ( - lib.attrsets.mapAttrsToList ( - name: value: let - hostConfig = { - forceSSL = config.host.reverse_proxy.forceSSL; - enableACME = config.host.reverse_proxy.enableACME; - locations = { - "/" = { - proxyPass = value.target; - proxyWebsockets = value.websockets.enable; - recommendedProxySettings = value.forwardHeaders.enable; - extraConfig = - value.extraConfig; - }; - }; - }; - in ( - [ - { - ${"${value.subdomain}.${config.host.reverse_proxy.hostname}"} = hostConfig; - } - ] - ++ builtins.map (subdomain: {${"${subdomain}.${config.host.reverse_proxy.hostname}"} = hostConfig;}) - value.extraSubdomains - ) - ) - config.host.reverse_proxy.subdomains - ) - ); - }; - - networking.firewall.allowedTCPPorts = [ - httpPort - httpsPort - ]; - } - (lib.mkIf config.host.impermanence.enable { - # TODO: figure out how to write an assertion for this - # assertions = [ - # { - # assertion = security.acme.certs..directory == dataDir; - # message = "postgres data directory does not match persistence"; - # } - # ]; - environment.persistence."/persist/system/root" = { - enable = true; - hideMounts = true; - directories = [ - { - directory = dataDir; - user = "acme"; - group = "acme"; - } - ]; - }; - }) - ]); -} diff --git a/modules/nixos-modules/server/searx/proxy.nix b/modules/nixos-modules/server/searx/proxy.nix index 0c1eae1..aca5e36 100644 --- a/modules/nixos-modules/server/searx/proxy.nix +++ b/modules/nixos-modules/server/searx/proxy.nix @@ -4,18 +4,28 @@ ... }: { options.services.searx = { - subdomain = lib.mkOption { - type = lib.types.str; - description = "subdomain of base domain that searx will be hosted at"; - default = "searx"; + reverseProxy = { + domain = lib.mkOption { + type = lib.types.str; + description = "domain that searx will be hosted at"; + default = "searx.arpa"; + }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for searx"; + default = []; + }; }; }; - config = lib.mkIf (config.services.searx.enable && config.host.reverse_proxy.enable) { - host = { - reverse_proxy.subdomains.searx = { - subdomain = config.services.searx.subdomain; - target = "http://localhost:${toString config.services.searx.settings.server.port}"; + config = lib.mkIf (config.services.searx.enable && config.services.reverseProxy.enable) { + services.reverseProxy.services.searx = { + target = "http://localhost:${toString config.services.searx.settings.server.port}"; + domain = config.services.searx.reverseProxy.domain; + extraDomains = config.services.searx.reverseProxy.extraDomains; + + settings = { + forwardHeaders.enable = true; }; }; }; diff --git a/modules/nixos-modules/server/sonarr/default.nix b/modules/nixos-modules/server/sonarr/default.nix index f39d940..86dbb4b 100644 --- a/modules/nixos-modules/server/sonarr/default.nix +++ b/modules/nixos-modules/server/sonarr/default.nix @@ -1,6 +1,5 @@ {...}: { imports = [ - ./proxy.nix ./impermanence.nix ]; } diff --git a/modules/nixos-modules/server/sonarr/proxy.nix b/modules/nixos-modules/server/sonarr/proxy.nix deleted file mode 100644 index 22b90a6..0000000 --- a/modules/nixos-modules/server/sonarr/proxy.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - lib, - config, - ... -}: { - options.services.sonarr = { - subdomain = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Subdomain for reverse proxy. If null, service will be local only."; - }; - extraSubdomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - description = "Extra subdomains for reverse proxy."; - }; - }; - - config = lib.mkIf (config.services.sonarr.enable && config.services.sonarr.subdomain != null) { - host.reverse_proxy.subdomains.sonarr = { - subdomain = config.services.sonarr.subdomain; - extraSubdomains = config.services.sonarr.extraSubdomains; - target = "http://127.0.0.1:8989"; - websockets.enable = true; - forwardHeaders.enable = true; - }; - }; -} From ad04be6534fb45e12630d2cffdea15dc82eaa48f Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 24 Oct 2025 12:49:36 -0500 Subject: [PATCH 11/61] feat: removed unused podman module --- modules/nixos-modules/server/default.nix | 1 - modules/nixos-modules/server/podman.nix | 73 ------------------------ 2 files changed, 74 deletions(-) delete mode 100644 modules/nixos-modules/server/podman.nix diff --git a/modules/nixos-modules/server/default.nix b/modules/nixos-modules/server/default.nix index 4981f28..e4a68c2 100644 --- a/modules/nixos-modules/server/default.nix +++ b/modules/nixos-modules/server/default.nix @@ -4,7 +4,6 @@ ./fail2ban.nix ./postgres.nix ./network_storage - ./podman.nix ./actual ./bazarr diff --git a/modules/nixos-modules/server/podman.nix b/modules/nixos-modules/server/podman.nix deleted file mode 100644 index 9301140..0000000 --- a/modules/nixos-modules/server/podman.nix +++ /dev/null @@ -1,73 +0,0 @@ -{ - lib, - config, - ... -}: { - options.host.podman = { - enable = lib.mkEnableOption "should podman be enabled on this computer"; - macvlan = { - subnet = lib.mkOption { - type = lib.types.str; - description = "Subnet for macvlan address range"; - }; - gateway = lib.mkOption { - type = lib.types.str; - description = "Gateway for macvlan"; - # TODO: see if we can default this to systemd network gateway - }; - networkInterface = lib.mkOption { - type = lib.types.str; - description = "Parent network interface for macvlan"; - # TODO: see if we can default this some interface? - }; - }; - }; - config = lib.mkIf config.host.podman.enable { - systemd = { - services = { - # "podman-network-macvlan" = { - # path = [pkgs.podman]; - # serviceConfig = { - # Type = "oneshot"; - # RemainAfterExit = true; - # ExecStop = "podman network rm -f macvlan"; - # }; - # script = '' - # podman network inspect macvlan || podman network create --driver macvlan --subnet ${config.host.podman.macvlan.subnet} --gateway ${config.host.podman.macvlan.gateway} --opt parent=${config.host.podman.macvlan.networkInterface} macvlan - # ''; - # partOf = ["podman-compose-root.target"]; - # wantedBy = ["podman-compose-root.target"]; - # }; - }; - # disable computer sleeping - targets = { - # Root service - # When started, this will automatically create all resources and start - # the containers. When stopped, this will teardown all resources. - "podman-compose-root" = { - unitConfig = { - Description = "Root target for podman targets."; - }; - wantedBy = ["multi-user.target"]; - }; - }; - }; - - virtualisation = { - # Runtime - podman = { - enable = true; - autoPrune.enable = true; - dockerCompat = true; - # defaultNetwork.settings = { - # # Required for container networking to be able to use names. - # dns_enabled = true; - # }; - }; - - oci-containers = { - backend = "podman"; - }; - }; - }; -} From 0f5507c32800aaa8b2f215c6bf4ea1987ada6e6e Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 24 Oct 2025 13:08:13 -0500 Subject: [PATCH 12/61] refactor: split configurations for fail2ban, postgres, and qbittorent into folders --- modules/nixos-modules/server/default.nix | 6 +- modules/nixos-modules/server/fail2ban.nix | 74 ----------- .../nixos-modules/server/fail2ban/default.nix | 6 + .../server/fail2ban/fail2ban.nix | 51 ++++++++ .../server/fail2ban/impermanence.nix | 27 ++++ modules/nixos-modules/server/postgres.nix | 121 ------------------ .../nixos-modules/server/postgres/default.nix | 6 + .../server/postgres/impermanence.nix | 27 ++++ .../server/postgres/postgres.nix | 98 ++++++++++++++ modules/nixos-modules/server/qbittorent.nix | 65 ---------- .../server/qbittorent/default.nix | 6 + .../server/qbittorent/impermanence.nix | 54 ++++++++ .../server/qbittorent/qbittorent.nix | 18 +++ 13 files changed, 296 insertions(+), 263 deletions(-) delete mode 100644 modules/nixos-modules/server/fail2ban.nix create mode 100644 modules/nixos-modules/server/fail2ban/default.nix create mode 100644 modules/nixos-modules/server/fail2ban/fail2ban.nix create mode 100644 modules/nixos-modules/server/fail2ban/impermanence.nix delete mode 100644 modules/nixos-modules/server/postgres.nix create mode 100644 modules/nixos-modules/server/postgres/default.nix create mode 100644 modules/nixos-modules/server/postgres/impermanence.nix create mode 100644 modules/nixos-modules/server/postgres/postgres.nix delete mode 100644 modules/nixos-modules/server/qbittorent.nix create mode 100644 modules/nixos-modules/server/qbittorent/default.nix create mode 100644 modules/nixos-modules/server/qbittorent/impermanence.nix create mode 100644 modules/nixos-modules/server/qbittorent/qbittorent.nix diff --git a/modules/nixos-modules/server/default.nix b/modules/nixos-modules/server/default.nix index e4a68c2..2b33089 100644 --- a/modules/nixos-modules/server/default.nix +++ b/modules/nixos-modules/server/default.nix @@ -1,8 +1,8 @@ {...}: { imports = [ ./reverseProxy - ./fail2ban.nix - ./postgres.nix + ./fail2ban + ./postgres ./network_storage ./actual @@ -17,7 +17,7 @@ ./lidarr ./panoramax ./paperless - ./qbittorent.nix + ./qbittorent ./radarr ./searx ./sonarr diff --git a/modules/nixos-modules/server/fail2ban.nix b/modules/nixos-modules/server/fail2ban.nix deleted file mode 100644 index d19aeeb..0000000 --- a/modules/nixos-modules/server/fail2ban.nix +++ /dev/null @@ -1,74 +0,0 @@ -{ - lib, - pkgs, - config, - ... -}: let - dataFolder = "/var/lib/fail2ban"; - dataFile = "fail2ban.sqlite3"; -in { - config = lib.mkIf config.services.fail2ban.enable (lib.mkMerge [ - { - environment.etc = { - "fail2ban/filter.d/nginx.local".text = lib.mkIf config.services.nginx.enable ( - pkgs.lib.mkDefault (pkgs.lib.mkAfter '' - [Definition] - failregex = "limiting requests, excess:.* by zone.*client: " - '') - ); - }; - - services.fail2ban = { - maxretry = 5; - ignoreIP = [ - # Whitelist local networks - "10.0.0.0/8" - "172.16.0.0/12" - "192.168.0.0/16" - - # tail scale tailnet - "100.64.0.0/10" - "fd7a:115c:a1e0::/48" - ]; - bantime = "24h"; # Ban IPs for one day on the first ban - bantime-increment = { - enable = true; # Enable increment of bantime after each violation - formula = "ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)"; - maxtime = "168h"; # Do not ban for more than 1 week - overalljails = true; # Calculate the ban time based on all the violations - }; - jails = { - nginx-iptables.settings = lib.mkIf config.services.nginx.enable { - enabled = true; - filter = "nginx"; - action = ''iptables-multiport[name=HTTP, port="http,https"]''; - backend = "auto"; - findtime = 600; - bantime = 600; - maxretry = 5; - }; - # TODO; figure out if there is any fail2ban things we can do on searx - # searx-iptables.settings = lib.mkIf config.services.searx.enable {}; - }; - }; - } - (lib.mkIf config.host.impermanence.enable { - assertions = [ - { - assertion = config.services.fail2ban.daemonSettings.Definition.dbfile == "${dataFolder}/${dataFile}"; - message = "fail2ban data file does not match persistence"; - } - ]; - - environment.persistence."/persist/system/root" = { - directories = [ - { - directory = dataFolder; - user = "fail2ban"; - group = "fail2ban"; - } - ]; - }; - }) - ]); -} diff --git a/modules/nixos-modules/server/fail2ban/default.nix b/modules/nixos-modules/server/fail2ban/default.nix new file mode 100644 index 0000000..30fca99 --- /dev/null +++ b/modules/nixos-modules/server/fail2ban/default.nix @@ -0,0 +1,6 @@ +{...}: { + imports = [ + ./fail2ban.nix + ./impermanence.nix + ]; +} diff --git a/modules/nixos-modules/server/fail2ban/fail2ban.nix b/modules/nixos-modules/server/fail2ban/fail2ban.nix new file mode 100644 index 0000000..261c68f --- /dev/null +++ b/modules/nixos-modules/server/fail2ban/fail2ban.nix @@ -0,0 +1,51 @@ +{ + lib, + pkgs, + config, + ... +}: { + config = lib.mkIf config.services.fail2ban.enable { + environment.etc = { + "fail2ban/filter.d/nginx.local".text = lib.mkIf config.services.nginx.enable ( + pkgs.lib.mkDefault (pkgs.lib.mkAfter '' + [Definition] + failregex = "limiting requests, excess:.* by zone.*client: " + '') + ); + }; + + services.fail2ban = { + maxretry = 5; + ignoreIP = [ + # Whitelist local networks + "10.0.0.0/8" + "172.16.0.0/12" + "192.168.0.0/16" + + # tail scale tailnet + "100.64.0.0/10" + "fd7a:115c:a1e0::/48" + ]; + bantime = "24h"; # Ban IPs for one day on the first ban + bantime-increment = { + enable = true; # Enable increment of bantime after each violation + formula = "ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)"; + maxtime = "168h"; # Do not ban for more than 1 week + overalljails = true; # Calculate the ban time based on all the violations + }; + jails = { + nginx-iptables.settings = lib.mkIf config.services.nginx.enable { + enabled = true; + filter = "nginx"; + action = ''iptables-multiport[name=HTTP, port="http,https"]''; + backend = "auto"; + findtime = 600; + bantime = 600; + maxretry = 5; + }; + # TODO; figure out if there is any fail2ban things we can do on searx + # searx-iptables.settings = lib.mkIf config.services.searx.enable {}; + }; + }; + }; +} diff --git a/modules/nixos-modules/server/fail2ban/impermanence.nix b/modules/nixos-modules/server/fail2ban/impermanence.nix new file mode 100644 index 0000000..5bc4673 --- /dev/null +++ b/modules/nixos-modules/server/fail2ban/impermanence.nix @@ -0,0 +1,27 @@ +{ + lib, + config, + ... +}: let + dataFolder = "/var/lib/fail2ban"; + dataFile = "fail2ban.sqlite3"; +in { + config = lib.mkIf (config.services.fail2ban.enable && config.host.impermanence.enable) { + assertions = [ + { + assertion = config.services.fail2ban.daemonSettings.Definition.dbfile == "${dataFolder}/${dataFile}"; + message = "fail2ban data file does not match persistence"; + } + ]; + + environment.persistence."/persist/system/root" = { + directories = [ + { + directory = dataFolder; + user = "fail2ban"; + group = "fail2ban"; + } + ]; + }; + }; +} diff --git a/modules/nixos-modules/server/postgres.nix b/modules/nixos-modules/server/postgres.nix deleted file mode 100644 index 71ce44c..0000000 --- a/modules/nixos-modules/server/postgres.nix +++ /dev/null @@ -1,121 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - dataDir = "/var/lib/postgresql/16"; - adminUsers = lib.lists.filter (user: user.isAdmin) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); - clientUsers = lib.lists.filter (user: user.isClient) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); - createUsers = lib.lists.filter (user: user.createUser) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); - createDatabases = lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraDatabases; -in { - options = { - host.postgres = { - enable = lib.mkEnableOption "enable postgres"; - extraUsers = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { - options = { - name = lib.mkOption { - type = lib.types.str; - default = name; - }; - isAdmin = lib.mkOption { - type = lib.types.bool; - default = false; - }; - isClient = lib.mkOption { - type = lib.types.bool; - default = false; - }; - createUser = lib.mkOption { - type = lib.types.bool; - default = false; - }; - }; - })); - default = {}; - }; - extraDatabases = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { - options = { - name = lib.mkOption { - type = lib.types.str; - default = name; - }; - }; - })); - default = {}; - }; - }; - }; - - config = lib.mkIf config.host.postgres.enable (lib.mkMerge [ - { - services = { - postgresql = { - enable = true; - package = pkgs.postgresql_16; - ensureUsers = - [ - { - name = "postgres"; - } - ] - ++ ( - builtins.map (user: { - name = user.name; - ensureDBOwnership = true; - }) - createUsers - ); - ensureDatabases = builtins.map (database: database.name) createDatabases; - identMap = - '' - # ArbitraryMapName systemUser DBUser - - # Administration Users - superuser_map root postgres - superuser_map postgres postgres - '' - + ( - lib.strings.concatLines (builtins.map (user: "superuser_map ${user.name} postgres") adminUsers) - ) - + '' - - # Client Users - '' - + ( - lib.strings.concatLines (builtins.map (user: "user_map ${user.name} ${user.name}") clientUsers) - ); - # configuration here lets users access the db that matches their name and lets user postgres access everything - authentication = pkgs.lib.mkOverride 10 '' - # type database DBuser origin-address auth-method optional_ident_map - local all postgres peer map=superuser_map - local sameuser all peer map=user_map - ''; - }; - }; - } - - (lib.mkIf config.host.impermanence.enable { - assertions = [ - { - assertion = config.services.postgresql.dataDir == dataDir; - message = "postgres data directory does not match persistence"; - } - ]; - environment.persistence."/persist/system/root" = { - enable = true; - hideMounts = true; - directories = [ - { - directory = dataDir; - user = "postgres"; - group = "postgres"; - } - ]; - }; - }) - ]); -} diff --git a/modules/nixos-modules/server/postgres/default.nix b/modules/nixos-modules/server/postgres/default.nix new file mode 100644 index 0000000..abf4ade --- /dev/null +++ b/modules/nixos-modules/server/postgres/default.nix @@ -0,0 +1,6 @@ +{...}: { + imports = [ + ./postgres.nix + ./impermanence.nix + ]; +} diff --git a/modules/nixos-modules/server/postgres/impermanence.nix b/modules/nixos-modules/server/postgres/impermanence.nix new file mode 100644 index 0000000..6c2d295 --- /dev/null +++ b/modules/nixos-modules/server/postgres/impermanence.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + ... +}: let + dataDir = "/var/lib/postgresql/16"; +in { + config = lib.mkIf (config.host.postgres.enable && config.host.impermanence.enable) { + assertions = [ + { + assertion = config.services.postgresql.dataDir == dataDir; + message = "postgres data directory does not match persistence"; + } + ]; + environment.persistence."/persist/system/root" = { + enable = true; + hideMounts = true; + directories = [ + { + directory = dataDir; + user = "postgres"; + group = "postgres"; + } + ]; + }; + }; +} diff --git a/modules/nixos-modules/server/postgres/postgres.nix b/modules/nixos-modules/server/postgres/postgres.nix new file mode 100644 index 0000000..e76857c --- /dev/null +++ b/modules/nixos-modules/server/postgres/postgres.nix @@ -0,0 +1,98 @@ +{ + config, + lib, + pkgs, + ... +}: let + adminUsers = lib.lists.filter (user: user.isAdmin) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); + clientUsers = lib.lists.filter (user: user.isClient) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); + createUsers = lib.lists.filter (user: user.createUser) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); + createDatabases = lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraDatabases; +in { + options = { + host.postgres = { + enable = lib.mkEnableOption "enable postgres"; + extraUsers = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { + options = { + name = lib.mkOption { + type = lib.types.str; + default = name; + }; + isAdmin = lib.mkOption { + type = lib.types.bool; + default = false; + }; + isClient = lib.mkOption { + type = lib.types.bool; + default = false; + }; + createUser = lib.mkOption { + type = lib.types.bool; + default = false; + }; + }; + })); + default = {}; + }; + extraDatabases = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { + options = { + name = lib.mkOption { + type = lib.types.str; + default = name; + }; + }; + })); + default = {}; + }; + }; + }; + + config = lib.mkIf config.host.postgres.enable { + services = { + postgresql = { + enable = true; + package = pkgs.postgresql_16; + ensureUsers = + [ + { + name = "postgres"; + } + ] + ++ ( + builtins.map (user: { + name = user.name; + ensureDBOwnership = true; + }) + createUsers + ); + ensureDatabases = builtins.map (database: database.name) createDatabases; + identMap = + '' + # ArbitraryMapName systemUser DBUser + + # Administration Users + superuser_map root postgres + superuser_map postgres postgres + '' + + ( + lib.strings.concatLines (builtins.map (user: "superuser_map ${user.name} postgres") adminUsers) + ) + + '' + + # Client Users + '' + + ( + lib.strings.concatLines (builtins.map (user: "user_map ${user.name} ${user.name}") clientUsers) + ); + # configuration here lets users access the db that matches their name and lets user postgres access everything + authentication = pkgs.lib.mkOverride 10 '' + # type database DBuser origin-address auth-method optional_ident_map + local all postgres peer map=superuser_map + local sameuser all peer map=user_map + ''; + }; + }; + }; +} diff --git a/modules/nixos-modules/server/qbittorent.nix b/modules/nixos-modules/server/qbittorent.nix deleted file mode 100644 index 2d54587..0000000 --- a/modules/nixos-modules/server/qbittorent.nix +++ /dev/null @@ -1,65 +0,0 @@ -{ - lib, - config, - ... -}: let - qbittorent_profile_directory = "/var/lib/qBittorrent/"; -in { - options.services.qbittorrent = { - mediaDir = lib.mkOption { - type = lib.types.path; - description = lib.mdDoc '' - The directory to create to store qbittorrent media. - ''; - }; - }; - - config = lib.mkIf config.services.qbittorrent.enable (lib.mkMerge [ - (lib.mkIf config.host.impermanence.enable { - fileSystems."/persist/system/qbittorrent".neededForBoot = true; - - host.storage.pool.extraDatasets = { - # sops age key needs to be available to pre persist for user generation - "persist/system/qbittorrent" = { - type = "zfs_fs"; - mountpoint = "/persist/system/qbittorrent"; - options = { - canmount = "on"; - }; - }; - }; - - assertions = [ - { - assertion = config.services.qbittorrent.profileDir == qbittorent_profile_directory; - message = "qbittorrent data directory does not match persistence"; - } - ]; - - environment.persistence = { - "/persist/system/root" = { - directories = [ - { - directory = qbittorent_profile_directory; - user = "qbittorrent"; - group = "qbittorrent"; - } - ]; - }; - - "/persist/system/qbittorrent" = { - enable = true; - hideMounts = true; - directories = [ - { - directory = config.services.qbittorrent.mediaDir; - user = "qbittorrent"; - group = "qbittorrent"; - mode = "1775"; - } - ]; - }; - }; - }) - ]); -} diff --git a/modules/nixos-modules/server/qbittorent/default.nix b/modules/nixos-modules/server/qbittorent/default.nix new file mode 100644 index 0000000..f7511e6 --- /dev/null +++ b/modules/nixos-modules/server/qbittorent/default.nix @@ -0,0 +1,6 @@ +{...}: { + imports = [ + ./qbittorent.nix + ./impermanence.nix + ]; +} diff --git a/modules/nixos-modules/server/qbittorent/impermanence.nix b/modules/nixos-modules/server/qbittorent/impermanence.nix new file mode 100644 index 0000000..da47d1a --- /dev/null +++ b/modules/nixos-modules/server/qbittorent/impermanence.nix @@ -0,0 +1,54 @@ +{ + lib, + config, + ... +}: let + qbittorent_profile_directory = "/var/lib/qBittorrent/"; +in { + config = lib.mkIf (config.services.qbittorrent.enable && config.host.impermanence.enable) { + fileSystems."/persist/system/qbittorrent".neededForBoot = true; + + host.storage.pool.extraDatasets = { + # sops age key needs to be available to pre persist for user generation + "persist/system/qbittorrent" = { + type = "zfs_fs"; + mountpoint = "/persist/system/qbittorrent"; + options = { + canmount = "on"; + }; + }; + }; + + assertions = [ + { + assertion = config.services.qbittorrent.profileDir == qbittorent_profile_directory; + message = "qbittorrent data directory does not match persistence"; + } + ]; + + environment.persistence = { + "/persist/system/root" = { + directories = [ + { + directory = qbittorent_profile_directory; + user = "qbittorrent"; + group = "qbittorrent"; + } + ]; + }; + + "/persist/system/qbittorrent" = { + enable = true; + hideMounts = true; + directories = [ + { + directory = config.services.qbittorrent.mediaDir; + user = "qbittorrent"; + group = "qbittorrent"; + mode = "1775"; + } + ]; + }; + }; + }; +} diff --git a/modules/nixos-modules/server/qbittorent/qbittorent.nix b/modules/nixos-modules/server/qbittorent/qbittorent.nix new file mode 100644 index 0000000..44603c8 --- /dev/null +++ b/modules/nixos-modules/server/qbittorent/qbittorent.nix @@ -0,0 +1,18 @@ +{ + lib, + config, + ... +}: { + options.services.qbittorrent = { + mediaDir = lib.mkOption { + type = lib.types.path; + description = lib.mdDoc '' + The directory to create to store qbittorrent media. + ''; + }; + }; + + config = lib.mkIf config.services.qbittorrent.enable { + # Main qbittorrent configuration goes here if needed + }; +} From c2435883f1e9a1e945ad50bd62fdcf2ec492f3ef Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 24 Oct 2025 15:01:16 -0500 Subject: [PATCH 13/61] fix: fixed domains for searx and paperless --- .../nixos-modules/server/paperless/proxy.nix | 19 ++++++------------- modules/nixos-modules/server/searx/proxy.nix | 19 ++++++------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/modules/nixos-modules/server/paperless/proxy.nix b/modules/nixos-modules/server/paperless/proxy.nix index e79c8d9..04c8304 100644 --- a/modules/nixos-modules/server/paperless/proxy.nix +++ b/modules/nixos-modules/server/paperless/proxy.nix @@ -4,25 +4,18 @@ ... }: { options.services.paperless = { - reverseProxy = { - domain = lib.mkOption { - type = lib.types.str; - description = "domain that paperless will be hosted at"; - default = "paperless.arpa"; - }; - extraDomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - description = "extra domains that should be configured for paperless"; - default = []; - }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for paperless"; + default = []; }; }; config = lib.mkIf (config.services.paperless.enable && config.services.reverseProxy.enable) { services.reverseProxy.services.paperless = { target = "http://${config.services.paperless.address}:${toString config.services.paperless.port}"; - domain = config.services.paperless.reverseProxy.domain; - extraDomains = config.services.paperless.reverseProxy.extraDomains; + domain = config.services.paperless.domain; + extraDomains = config.services.paperless.extraDomains; settings = { proxyWebsockets.enable = true; diff --git a/modules/nixos-modules/server/searx/proxy.nix b/modules/nixos-modules/server/searx/proxy.nix index aca5e36..fbc80e0 100644 --- a/modules/nixos-modules/server/searx/proxy.nix +++ b/modules/nixos-modules/server/searx/proxy.nix @@ -4,25 +4,18 @@ ... }: { options.services.searx = { - reverseProxy = { - domain = lib.mkOption { - type = lib.types.str; - description = "domain that searx will be hosted at"; - default = "searx.arpa"; - }; - extraDomains = lib.mkOption { - type = lib.types.listOf lib.types.str; - description = "extra domains that should be configured for searx"; - default = []; - }; + extraDomains = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "extra domains that should be configured for searx"; + default = []; }; }; config = lib.mkIf (config.services.searx.enable && config.services.reverseProxy.enable) { services.reverseProxy.services.searx = { target = "http://localhost:${toString config.services.searx.settings.server.port}"; - domain = config.services.searx.reverseProxy.domain; - extraDomains = config.services.searx.reverseProxy.extraDomains; + domain = config.services.searx.domain; + extraDomains = config.services.searx.extraDomains; settings = { forwardHeaders.enable = true; From 7f740607133c55d32b2e5bb328563c7bda3791fa Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sat, 25 Oct 2025 01:55:58 -0500 Subject: [PATCH 14/61] chore: updated task list in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f8c7ecf..23a4966 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,6 @@ nix multi user, multi system, configuration with `sops` secret management, `home ## Tech Debt - [ ] monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/) - [ ] migrate away from flakes and move to npins -- [ ] rework the reverse_proxy.nix file so that it is a normally named service. Then also change it so that we can hook into it with both a base domain and a subdomain to make migrating to vpn accessible services easier ## Broken things - [ ] figure out steam vr things? @@ -73,12 +72,13 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] offline access for nfs mounts (overlay with rsync might be a good option here? https://www.spinics.net/lists/linux-unionfs/msg07105.html note about nfs4 and overlay fs) - [ ] figure out why syncthing and jellyfins permissions don't propagate downwards - [ ] make radarr, sonarr, and bazarr accessible over vpn -- [ ] move searx, home-assistant, actual, jellyfin, paperless, and immich to only be accessible via vpn +- [ ] move searx, home-assistant, actual, vikunja, jellyfin, paperless, and immich to only be accessible via vpn ## Services - [ ] vikunja service for project management - [ ] Create Tor guard/relay server - [ ] mastodon instance +- [ ] screeps server ## DevOps - [ ] wake on LAN for updates From ecec04a9ce84c62555b31ced2378d490681245d8 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sat, 25 Oct 2025 02:31:11 -0500 Subject: [PATCH 15/61] feat: added per service enable options for reverseProxy configs --- modules/nixos-modules/server/actual/proxy.nix | 6 +++++- modules/nixos-modules/server/forgejo/proxy.nix | 6 +++++- modules/nixos-modules/server/home-assistant/proxy.nix | 8 +++++++- modules/nixos-modules/server/immich/proxy.nix | 8 +++++++- modules/nixos-modules/server/jellyfin/proxy.nix | 8 +++++++- modules/nixos-modules/server/panoramax/proxy.nix | 8 +++++++- modules/nixos-modules/server/paperless/proxy.nix | 8 +++++++- modules/nixos-modules/server/searx/proxy.nix | 8 +++++++- 8 files changed, 52 insertions(+), 8 deletions(-) diff --git a/modules/nixos-modules/server/actual/proxy.nix b/modules/nixos-modules/server/actual/proxy.nix index bf1711a..9d37574 100644 --- a/modules/nixos-modules/server/actual/proxy.nix +++ b/modules/nixos-modules/server/actual/proxy.nix @@ -14,9 +14,13 @@ description = "extra domains that should be configured for actual"; default = []; }; + reverseProxy.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.actual.enable && config.services.reverseProxy.enable; + }; }; - config = lib.mkIf (config.services.actual.enable && config.services.reverseProxy.enable) { + config = lib.mkIf config.services.actual.reverseProxy.enable { services.reverseProxy.services.actual = { target = "http://localhost:${toString config.services.actual.settings.port}"; domain = config.services.actual.domain; diff --git a/modules/nixos-modules/server/forgejo/proxy.nix b/modules/nixos-modules/server/forgejo/proxy.nix index bde59d1..c2d3131 100644 --- a/modules/nixos-modules/server/forgejo/proxy.nix +++ b/modules/nixos-modules/server/forgejo/proxy.nix @@ -8,6 +8,10 @@ in { options.services.forgejo = { reverseProxy = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.forgejo.enable && config.services.reverseProxy.enable; + }; domain = lib.mkOption { type = lib.types.str; description = "domain that forgejo will be hosted at"; @@ -21,7 +25,7 @@ in { }; }; - config = lib.mkIf (config.services.forgejo.enable && config.services.reverseProxy.enable) { + config = lib.mkIf config.services.forgejo.reverseProxy.enable { services.reverseProxy.services.forgejo = { target = "http://localhost:${toString httpPort}"; domain = config.services.forgejo.reverseProxy.domain; diff --git a/modules/nixos-modules/server/home-assistant/proxy.nix b/modules/nixos-modules/server/home-assistant/proxy.nix index 1075c59..b756459 100644 --- a/modules/nixos-modules/server/home-assistant/proxy.nix +++ b/modules/nixos-modules/server/home-assistant/proxy.nix @@ -14,9 +14,15 @@ description = "extra domains that should be configured for home-assistant"; default = []; }; + reverseProxy = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.reverseProxy.enable && config.services.home-assistant.enable; + }; + }; }; - config = lib.mkIf (config.services.reverseProxy.enable && config.services.home-assistant.enable) { + config = lib.mkIf config.services.home-assistant.reverseProxy.enable { services.reverseProxy.services.home-assistant = { target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; domain = config.services.home-assistant.domain; diff --git a/modules/nixos-modules/server/immich/proxy.nix b/modules/nixos-modules/server/immich/proxy.nix index a50ea1e..9c8c165 100644 --- a/modules/nixos-modules/server/immich/proxy.nix +++ b/modules/nixos-modules/server/immich/proxy.nix @@ -14,9 +14,15 @@ description = "extra domains that should be configured for immich"; default = []; }; + reverseProxy = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.immich.enable && config.services.reverseProxy.enable; + }; + }; }; - config = lib.mkIf (config.services.immich.enable && config.services.reverseProxy.enable) { + config = lib.mkIf config.services.immich.reverseProxy.enable { services.reverseProxy.services.immich = { target = "http://localhost:${toString config.services.immich.port}"; domain = config.services.immich.domain; diff --git a/modules/nixos-modules/server/jellyfin/proxy.nix b/modules/nixos-modules/server/jellyfin/proxy.nix index f803ecb..35289e7 100644 --- a/modules/nixos-modules/server/jellyfin/proxy.nix +++ b/modules/nixos-modules/server/jellyfin/proxy.nix @@ -16,9 +16,15 @@ in { description = "extra domains that should be configured for jellyfin"; default = []; }; + reverseProxy = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.jellyfin.enable && config.services.reverseProxy.enable; + }; + }; }; - config = lib.mkIf (config.services.jellyfin.enable && config.services.reverseProxy.enable) { + config = lib.mkIf config.services.jellyfin.reverseProxy.enable { services.reverseProxy.services.jellyfin = { target = "http://localhost:${toString jellyfinPort}"; domain = config.services.jellyfin.domain; diff --git a/modules/nixos-modules/server/panoramax/proxy.nix b/modules/nixos-modules/server/panoramax/proxy.nix index 35bc79b..7cd7111 100644 --- a/modules/nixos-modules/server/panoramax/proxy.nix +++ b/modules/nixos-modules/server/panoramax/proxy.nix @@ -14,9 +14,15 @@ description = "extra domains that should be configured for panoramax"; default = []; }; + reverseProxy = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.panoramax.enable && config.services.reverseProxy.enable; + }; + }; }; - config = lib.mkIf (config.services.panoramax.enable && config.services.reverseProxy.enable) { + config = lib.mkIf config.services.panoramax.reverseProxy.enable { services.reverseProxy.services.panoramax = { target = "http://localhost:${toString config.services.panoramax.port}"; domain = config.services.panoramax.domain; diff --git a/modules/nixos-modules/server/paperless/proxy.nix b/modules/nixos-modules/server/paperless/proxy.nix index 04c8304..9d152c9 100644 --- a/modules/nixos-modules/server/paperless/proxy.nix +++ b/modules/nixos-modules/server/paperless/proxy.nix @@ -9,9 +9,15 @@ description = "extra domains that should be configured for paperless"; default = []; }; + reverseProxy = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.paperless.enable && config.services.reverseProxy.enable; + }; + }; }; - config = lib.mkIf (config.services.paperless.enable && config.services.reverseProxy.enable) { + config = lib.mkIf config.services.paperless.reverseProxy.enable { services.reverseProxy.services.paperless = { target = "http://${config.services.paperless.address}:${toString config.services.paperless.port}"; domain = config.services.paperless.domain; diff --git a/modules/nixos-modules/server/searx/proxy.nix b/modules/nixos-modules/server/searx/proxy.nix index fbc80e0..e994e4a 100644 --- a/modules/nixos-modules/server/searx/proxy.nix +++ b/modules/nixos-modules/server/searx/proxy.nix @@ -9,9 +9,15 @@ description = "extra domains that should be configured for searx"; default = []; }; + reverseProxy = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.searx.enable && config.services.reverseProxy.enable; + }; + }; }; - config = lib.mkIf (config.services.searx.enable && config.services.reverseProxy.enable) { + config = lib.mkIf config.services.searx.reverseProxy.enable { services.reverseProxy.services.searx = { target = "http://localhost:${toString config.services.searx.settings.server.port}"; domain = config.services.searx.domain; From a8af8930fa8f835bc2697aae88e3b9ddb9bf7a10 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sat, 25 Oct 2025 02:37:53 -0500 Subject: [PATCH 16/61] feat: added per service enable options for fail2ban configs --- .../nixos/defiant/configuration.nix | 2 +- .../nixos-modules/server/forgejo/fail2ban.nix | 11 +++- .../server/home-assistant/fail2ban.nix | 66 +++++++++++-------- .../nixos-modules/server/immich/fail2ban.nix | 11 +++- 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index 91a8c2c..ae897ce 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -310,7 +310,7 @@ forgejo = { enable = true; - domain = "git.jan-leila.com"; + reverseProxy.domain = "git.jan-leila.com"; }; searx = { diff --git a/modules/nixos-modules/server/forgejo/fail2ban.nix b/modules/nixos-modules/server/forgejo/fail2ban.nix index 213c804..dfe221a 100644 --- a/modules/nixos-modules/server/forgejo/fail2ban.nix +++ b/modules/nixos-modules/server/forgejo/fail2ban.nix @@ -4,7 +4,16 @@ pkgs, ... }: { - config = lib.mkIf (config.services.forgejo.enable && config.services.fail2ban.enable) { + options.services.forgejo = { + fail2ban = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.forgejo.enable && config.services.fail2ban.enable; + }; + }; + }; + + config = lib.mkIf config.services.forgejo.fail2ban.enable { environment.etc = { "fail2ban/filter.d/forgejo.local".text = lib.mkIf config.services.forgejo.enable ( pkgs.lib.mkDefault (pkgs.lib.mkAfter '' diff --git a/modules/nixos-modules/server/home-assistant/fail2ban.nix b/modules/nixos-modules/server/home-assistant/fail2ban.nix index 6ac5900..25194ef 100644 --- a/modules/nixos-modules/server/home-assistant/fail2ban.nix +++ b/modules/nixos-modules/server/home-assistant/fail2ban.nix @@ -3,36 +3,46 @@ pkgs, config, ... -}: -lib.mkIf (config.services.fail2ban.enable && config.services.home-assistant.enable) { - environment.etc = { - "fail2ban/filter.d/hass.local".text = ( - pkgs.lib.mkDefault (pkgs.lib.mkAfter '' - [INCLUDES] - before = common.conf - - [Definition] - failregex = ^%(__prefix_line)s.*Login attempt or request with invalid authentication from .*$ - - ignoreregex = - - [Init] - datepattern = ^%%Y-%%m-%%d %%H:%%M:%%S - '') - ); +}: { + options.services.home-assistant = { + fail2ban = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.fail2ban.enable && config.services.home-assistant.enable; + }; + }; }; - services.fail2ban = { - jails = { - home-assistant-iptables.settings = { - enabled = true; - filter = "hass"; - action = ''iptables-multiport[name=HTTP, port="http,https"]''; - logpath = "${config.services.home-assistant.configDir}/*.log"; - backend = "auto"; - findtime = 600; - bantime = 600; - maxretry = 5; + config = lib.mkIf config.services.home-assistant.fail2ban.enable { + environment.etc = { + "fail2ban/filter.d/hass.local".text = ( + pkgs.lib.mkDefault (pkgs.lib.mkAfter '' + [INCLUDES] + before = common.conf + + [Definition] + failregex = ^%(__prefix_line)s.*Login attempt or request with invalid authentication from .*$ + + ignoreregex = + + [Init] + datepattern = ^%%Y-%%m-%%d %%H:%%M:%%S + '') + ); + }; + + services.fail2ban = { + jails = { + home-assistant-iptables.settings = { + enabled = true; + filter = "hass"; + action = ''iptables-multiport[name=HTTP, port="http,https"]''; + logpath = "${config.services.home-assistant.configDir}/*.log"; + backend = "auto"; + findtime = 600; + bantime = 600; + maxretry = 5; + }; }; }; }; diff --git a/modules/nixos-modules/server/immich/fail2ban.nix b/modules/nixos-modules/server/immich/fail2ban.nix index c9ec87b..21593e7 100644 --- a/modules/nixos-modules/server/immich/fail2ban.nix +++ b/modules/nixos-modules/server/immich/fail2ban.nix @@ -4,7 +4,16 @@ pkgs, ... }: { - config = lib.mkIf (config.services.fail2ban.enable && config.services.immich.enable) { + options.services.immich = { + fail2ban = { + enable = lib.mkOption { + type = lib.types.bool; + default = config.services.fail2ban.enable && config.services.immich.enable; + }; + }; + }; + + config = lib.mkIf config.services.immich.fail2ban.enable { environment.etc = { "fail2ban/filter.d/immich.local".text = pkgs.lib.mkDefault (pkgs.lib.mkAfter '' [Definition] From 89793fca6aa221fa1b105f737b082320a8b0e001 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sat, 25 Oct 2025 02:41:00 -0500 Subject: [PATCH 17/61] feat: added per service enable options for impermanence configs --- modules/nixos-modules/server/actual/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/bazarr/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/crab-hole/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/fail2ban/impermanence.nix | 9 ++++++++- .../nixos-modules/server/flaresolverr/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/forgejo/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/immich/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/jackett/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/jellyfin/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/lidarr/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/panoramax/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/paperless/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/qbittorent/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/radarr/impermanence.nix | 9 ++++++++- modules/nixos-modules/server/sonarr/impermanence.nix | 9 ++++++++- 15 files changed, 120 insertions(+), 15 deletions(-) diff --git a/modules/nixos-modules/server/actual/impermanence.nix b/modules/nixos-modules/server/actual/impermanence.nix index 5eee95a..5a2bb6c 100644 --- a/modules/nixos-modules/server/actual/impermanence.nix +++ b/modules/nixos-modules/server/actual/impermanence.nix @@ -6,7 +6,14 @@ const = import ./const.nix; dataDirectory = const.dataDirectory; in { - config = lib.mkIf (config.services.actual.enable && config.host.impermanence.enable) { + options.services.actual = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.actual.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.actual.impermanence.enable { assertions = [ { assertion = config.services.actual.settings.ACTUAL_DATA_DIR == dataDirectory; diff --git a/modules/nixos-modules/server/bazarr/impermanence.nix b/modules/nixos-modules/server/bazarr/impermanence.nix index 22fb0e6..70a45d1 100644 --- a/modules/nixos-modules/server/bazarr/impermanence.nix +++ b/modules/nixos-modules/server/bazarr/impermanence.nix @@ -5,7 +5,14 @@ }: let bazarr_data_directory = "/var/lib/bazarr"; in { - config = lib.mkIf (config.services.bazarr.enable && config.host.impermanence.enable) { + options.services.bazarr = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.bazarr.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.bazarr.impermanence.enable { assertions = [ { assertion = config.services.bazarr.dataDir == bazarr_data_directory; diff --git a/modules/nixos-modules/server/crab-hole/impermanence.nix b/modules/nixos-modules/server/crab-hole/impermanence.nix index 8e1182c..51efc0c 100644 --- a/modules/nixos-modules/server/crab-hole/impermanence.nix +++ b/modules/nixos-modules/server/crab-hole/impermanence.nix @@ -5,7 +5,14 @@ }: let workingDirectory = "/var/lib/private/crab-hole"; in { - config = lib.mkIf (config.services.crab-hole.enable && config.host.impermanence.enable) { + options.services.crab-hole = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.crab-hole.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.crab-hole.impermanence.enable { assertions = [ { assertion = diff --git a/modules/nixos-modules/server/fail2ban/impermanence.nix b/modules/nixos-modules/server/fail2ban/impermanence.nix index 5bc4673..6e214b3 100644 --- a/modules/nixos-modules/server/fail2ban/impermanence.nix +++ b/modules/nixos-modules/server/fail2ban/impermanence.nix @@ -6,7 +6,14 @@ dataFolder = "/var/lib/fail2ban"; dataFile = "fail2ban.sqlite3"; in { - config = lib.mkIf (config.services.fail2ban.enable && config.host.impermanence.enable) { + options.services.fail2ban = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.fail2ban.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.fail2ban.impermanence.enable { assertions = [ { assertion = config.services.fail2ban.daemonSettings.Definition.dbfile == "${dataFolder}/${dataFile}"; diff --git a/modules/nixos-modules/server/flaresolverr/impermanence.nix b/modules/nixos-modules/server/flaresolverr/impermanence.nix index b568a56..4544e75 100644 --- a/modules/nixos-modules/server/flaresolverr/impermanence.nix +++ b/modules/nixos-modules/server/flaresolverr/impermanence.nix @@ -3,7 +3,14 @@ config, ... }: { - config = lib.mkIf (config.services.flaresolverr.enable && config.host.impermanence.enable) { + options.services.flaresolverr = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.flaresolverr.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.flaresolverr.impermanence.enable { # FlareSolverr typically doesn't need persistent storage as it's a proxy service # but we'll add basic structure in case it's needed for logs or configuration environment.persistence."/persist/system/root" = { diff --git a/modules/nixos-modules/server/forgejo/impermanence.nix b/modules/nixos-modules/server/forgejo/impermanence.nix index 04f21a5..6fe3de8 100644 --- a/modules/nixos-modules/server/forgejo/impermanence.nix +++ b/modules/nixos-modules/server/forgejo/impermanence.nix @@ -5,7 +5,14 @@ }: let stateDir = "/var/lib/forgejo"; in { - config = lib.mkIf (config.services.forgejo.enable && config.host.impermanence.enable) { + options.services.forgejo = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.forgejo.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.forgejo.impermanence.enable { assertions = [ { assertion = config.services.forgejo.stateDir == stateDir; diff --git a/modules/nixos-modules/server/immich/impermanence.nix b/modules/nixos-modules/server/immich/impermanence.nix index f63d178..56e51d0 100644 --- a/modules/nixos-modules/server/immich/impermanence.nix +++ b/modules/nixos-modules/server/immich/impermanence.nix @@ -5,7 +5,14 @@ }: let mediaLocation = "/var/lib/immich"; in { - config = lib.mkIf (config.services.immich.enable && config.host.impermanence.enable) { + options.services.immich = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.immich.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.immich.impermanence.enable { assertions = [ { assertion = config.services.immich.mediaLocation == mediaLocation; diff --git a/modules/nixos-modules/server/jackett/impermanence.nix b/modules/nixos-modules/server/jackett/impermanence.nix index 5826a54..24fc5e6 100644 --- a/modules/nixos-modules/server/jackett/impermanence.nix +++ b/modules/nixos-modules/server/jackett/impermanence.nix @@ -5,7 +5,14 @@ }: let jackett_data_directory = "/var/lib/jackett/.config/Jackett"; in { - config = lib.mkIf (config.services.jackett.enable && config.host.impermanence.enable) { + options.services.jackett = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.jackett.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.jackett.impermanence.enable { assertions = [ { assertion = config.services.jackett.dataDir == jackett_data_directory; diff --git a/modules/nixos-modules/server/jellyfin/impermanence.nix b/modules/nixos-modules/server/jellyfin/impermanence.nix index e0b3b5d..cbcb54f 100644 --- a/modules/nixos-modules/server/jellyfin/impermanence.nix +++ b/modules/nixos-modules/server/jellyfin/impermanence.nix @@ -6,7 +6,14 @@ jellyfin_data_directory = "/var/lib/jellyfin"; jellyfin_cache_directory = "/var/cache/jellyfin"; in { - config = lib.mkIf (config.services.jellyfin.enable && config.host.impermanence.enable) { + options.services.jellyfin = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.jellyfin.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.jellyfin.impermanence.enable { fileSystems."/persist/system/jellyfin".neededForBoot = true; host.storage.pool.extraDatasets = { diff --git a/modules/nixos-modules/server/lidarr/impermanence.nix b/modules/nixos-modules/server/lidarr/impermanence.nix index 689b924..5d3aa3f 100644 --- a/modules/nixos-modules/server/lidarr/impermanence.nix +++ b/modules/nixos-modules/server/lidarr/impermanence.nix @@ -5,7 +5,14 @@ }: let lidarr_data_directory = "/var/lib/lidarr/.config/Lidarr"; in { - config = lib.mkIf (config.services.lidarr.enable && config.host.impermanence.enable) { + options.services.lidarr = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.lidarr.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.lidarr.impermanence.enable { assertions = [ { assertion = config.services.lidarr.dataDir == lidarr_data_directory; diff --git a/modules/nixos-modules/server/panoramax/impermanence.nix b/modules/nixos-modules/server/panoramax/impermanence.nix index 41b1401..e25ef92 100644 --- a/modules/nixos-modules/server/panoramax/impermanence.nix +++ b/modules/nixos-modules/server/panoramax/impermanence.nix @@ -3,7 +3,14 @@ config, ... }: { - config = lib.mkIf (config.services.panoramax.enable && config.host.impermanence.enable) { + options.services.panoramax = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.panoramax.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.panoramax.impermanence.enable { # TODO: configure impermanence for panoramax data # This would typically include directories like: # - /var/lib/panoramax diff --git a/modules/nixos-modules/server/paperless/impermanence.nix b/modules/nixos-modules/server/paperless/impermanence.nix index d9e17bd..fc87ea7 100644 --- a/modules/nixos-modules/server/paperless/impermanence.nix +++ b/modules/nixos-modules/server/paperless/impermanence.nix @@ -5,7 +5,14 @@ }: let dataDir = "/var/lib/paperless"; in { - config = lib.mkIf (config.services.paperless.enable && config.host.impermanence.enable) { + options.services.paperless = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.paperless.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.paperless.impermanence.enable { assertions = [ { assertion = config.services.paperless.dataDir == dataDir; diff --git a/modules/nixos-modules/server/qbittorent/impermanence.nix b/modules/nixos-modules/server/qbittorent/impermanence.nix index da47d1a..1489e7d 100644 --- a/modules/nixos-modules/server/qbittorent/impermanence.nix +++ b/modules/nixos-modules/server/qbittorent/impermanence.nix @@ -5,7 +5,14 @@ }: let qbittorent_profile_directory = "/var/lib/qBittorrent/"; in { - config = lib.mkIf (config.services.qbittorrent.enable && config.host.impermanence.enable) { + options.services.qbittorrent = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.qbittorrent.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.qbittorrent.impermanence.enable { fileSystems."/persist/system/qbittorrent".neededForBoot = true; host.storage.pool.extraDatasets = { diff --git a/modules/nixos-modules/server/radarr/impermanence.nix b/modules/nixos-modules/server/radarr/impermanence.nix index 4a3242c..c948e3a 100644 --- a/modules/nixos-modules/server/radarr/impermanence.nix +++ b/modules/nixos-modules/server/radarr/impermanence.nix @@ -5,7 +5,14 @@ }: let radarr_data_directory = "/var/lib/radarr/.config/Radarr"; in { - config = lib.mkIf (config.services.radarr.enable && config.host.impermanence.enable) { + options.services.radarr = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.radarr.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.radarr.impermanence.enable { assertions = [ { assertion = config.services.radarr.dataDir == radarr_data_directory; diff --git a/modules/nixos-modules/server/sonarr/impermanence.nix b/modules/nixos-modules/server/sonarr/impermanence.nix index abc843c..5b90ee9 100644 --- a/modules/nixos-modules/server/sonarr/impermanence.nix +++ b/modules/nixos-modules/server/sonarr/impermanence.nix @@ -5,7 +5,14 @@ }: let sonarr_data_directory = "/var/lib/sonarr/.config/NzbDrone"; in { - config = lib.mkIf (config.services.sonarr.enable && config.host.impermanence.enable) { + options.services.sonarr = { + impermanence.enable = lib.mkOption { + type = lib.types.bool; + default = config.services.sonarr.enable && config.host.impermanence.enable; + }; + }; + + config = lib.mkIf config.services.sonarr.impermanence.enable { assertions = [ { assertion = config.services.sonarr.dataDir == sonarr_data_directory; From 30a042d709f0e12eca50c001cbdbf5d7fa3855e7 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sat, 25 Oct 2025 02:56:07 -0500 Subject: [PATCH 18/61] refactor: moved server module configs out of default.nix files --- .../nixos-modules/server/actual/actual.nix | 20 ++++ .../nixos-modules/server/actual/default.nix | 20 +--- .../nixos-modules/server/forgejo/default.nix | 46 +------- .../nixos-modules/server/forgejo/forgejo.nix | 46 ++++++++ .../server/home-assistant/default.nix | 104 +----------------- .../server/home-assistant/home-assistant.nix | 104 ++++++++++++++++++ .../nixos-modules/server/jellyfin/default.nix | 32 +----- .../server/jellyfin/jellyfin.nix | 32 ++++++ .../server/network_storage/default.nix | 86 +-------------- .../network_storage/network_storage.nix | 86 +++++++++++++++ .../server/paperless/default.nix | 27 +---- .../server/paperless/paperless.nix | 27 +++++ .../nixos-modules/server/searx/default.nix | 59 +--------- modules/nixos-modules/server/searx/searx.nix | 59 ++++++++++ 14 files changed, 381 insertions(+), 367 deletions(-) create mode 100644 modules/nixos-modules/server/actual/actual.nix create mode 100644 modules/nixos-modules/server/forgejo/forgejo.nix create mode 100644 modules/nixos-modules/server/home-assistant/home-assistant.nix create mode 100644 modules/nixos-modules/server/jellyfin/jellyfin.nix create mode 100644 modules/nixos-modules/server/network_storage/network_storage.nix create mode 100644 modules/nixos-modules/server/paperless/paperless.nix create mode 100644 modules/nixos-modules/server/searx/searx.nix diff --git a/modules/nixos-modules/server/actual/actual.nix b/modules/nixos-modules/server/actual/actual.nix new file mode 100644 index 0000000..96ea586 --- /dev/null +++ b/modules/nixos-modules/server/actual/actual.nix @@ -0,0 +1,20 @@ +{ + lib, + config, + ... +}: let + const = import ./const.nix; + dataDirectory = const.dataDirectory; +in { + config = lib.mkIf config.services.actual.enable { + systemd.tmpfiles.rules = [ + "d ${dataDirectory} 2770 actual actual" + ]; + + services.actual = { + settings = { + ACTUAL_DATA_DIR = dataDirectory; + }; + }; + }; +} diff --git a/modules/nixos-modules/server/actual/default.nix b/modules/nixos-modules/server/actual/default.nix index 546240e..b59517b 100644 --- a/modules/nixos-modules/server/actual/default.nix +++ b/modules/nixos-modules/server/actual/default.nix @@ -1,26 +1,8 @@ { - lib, - config, - ... -}: let - const = import ./const.nix; - dataDirectory = const.dataDirectory; -in { imports = [ + ./actual.nix ./proxy.nix ./fail2ban.nix ./impermanence.nix ]; - - config = lib.mkIf config.services.actual.enable { - systemd.tmpfiles.rules = [ - "d ${dataDirectory} 2770 actual actual" - ]; - - services.actual = { - settings = { - ACTUAL_DATA_DIR = dataDirectory; - }; - }; - }; } diff --git a/modules/nixos-modules/server/forgejo/default.nix b/modules/nixos-modules/server/forgejo/default.nix index 5d0e7ad..4333f69 100644 --- a/modules/nixos-modules/server/forgejo/default.nix +++ b/modules/nixos-modules/server/forgejo/default.nix @@ -1,53 +1,9 @@ { - lib, - config, - ... -}: let - const = import ./const.nix; - httpPort = const.httpPort; - sshPort = const.sshPort; - db_user = "forgejo"; -in { imports = [ + ./forgejo.nix ./proxy.nix ./database.nix ./fail2ban.nix ./impermanence.nix ]; - - config = lib.mkIf config.services.forgejo.enable { - assertions = [ - { - assertion = config.services.forgejo.settings.server.BUILTIN_SSH_SERVER_USER == config.users.users.git.name; - message = "Forgejo BUILTIN_SSH_SERVER_USER hardcoded value does not match expected git user name"; - } - ]; - - services.forgejo = { - database = { - type = "postgres"; - socket = "/run/postgresql"; - }; - lfs.enable = true; - settings = { - server = { - DOMAIN = config.services.forgejo.reverseProxy.domain; - HTTP_PORT = httpPort; - START_SSH_SERVER = true; - SSH_LISTEN_PORT = sshPort; - SSH_PORT = 22; - BUILTIN_SSH_SERVER_USER = "git"; - ROOT_URL = "https://git.jan-leila.com"; - }; - service = { - DISABLE_REGISTRATION = true; - }; - database = { - DB_TYPE = "postgres"; - NAME = db_user; - USER = db_user; - }; - }; - }; - }; } diff --git a/modules/nixos-modules/server/forgejo/forgejo.nix b/modules/nixos-modules/server/forgejo/forgejo.nix new file mode 100644 index 0000000..70d3087 --- /dev/null +++ b/modules/nixos-modules/server/forgejo/forgejo.nix @@ -0,0 +1,46 @@ +{ + lib, + config, + ... +}: let + const = import ./const.nix; + httpPort = const.httpPort; + sshPort = const.sshPort; + db_user = "forgejo"; +in { + config = lib.mkIf config.services.forgejo.enable { + assertions = [ + { + assertion = config.services.forgejo.settings.server.BUILTIN_SSH_SERVER_USER == config.users.users.git.name; + message = "Forgejo BUILTIN_SSH_SERVER_USER hardcoded value does not match expected git user name"; + } + ]; + + services.forgejo = { + database = { + type = "postgres"; + socket = "/run/postgresql"; + }; + lfs.enable = true; + settings = { + server = { + DOMAIN = config.services.forgejo.reverseProxy.domain; + HTTP_PORT = httpPort; + START_SSH_SERVER = true; + SSH_LISTEN_PORT = sshPort; + SSH_PORT = 22; + BUILTIN_SSH_SERVER_USER = "git"; + ROOT_URL = "https://git.jan-leila.com"; + }; + service = { + DISABLE_REGISTRATION = true; + }; + database = { + DB_TYPE = "postgres"; + NAME = db_user; + USER = db_user; + }; + }; + }; + }; +} diff --git a/modules/nixos-modules/server/home-assistant/default.nix b/modules/nixos-modules/server/home-assistant/default.nix index 4b1846b..b6f9356 100644 --- a/modules/nixos-modules/server/home-assistant/default.nix +++ b/modules/nixos-modules/server/home-assistant/default.nix @@ -1,112 +1,10 @@ { - lib, - config, - ... -}: { imports = [ + ./home-assistant.nix ./proxy.nix ./database.nix ./fail2ban.nix ./impermanence.nix ./extensions ]; - - options.services.home-assistant = { - database = lib.mkOption { - type = lib.types.enum [ - "builtin" - "postgres" - ]; - description = "what database do we want to use"; - default = "builtin"; - }; - - extensions = { - sonos = { - enable = lib.mkEnableOption "enable the sonos plugin"; - port = lib.mkOption { - type = lib.types.int; - default = 1400; - description = "what port to use for sonos discovery"; - }; - }; - jellyfin = { - enable = lib.mkEnableOption "enable the jellyfin plugin"; - }; - wyoming = { - enable = lib.mkEnableOption "enable wyoming"; - }; - }; - }; - - config = lib.mkIf config.services.home-assistant.enable (lib.mkMerge [ - { - services.home-assistant = { - configDir = "/var/lib/hass"; - extraComponents = [ - "default_config" - "esphome" - "met" - "radio_browser" - "isal" - "zha" - "webostv" - "tailscale" - "syncthing" - "analytics_insights" - "unifi" - "openweathermap" - "ollama" - "mobile_app" - "logbook" - "ssdp" - "usb" - "webhook" - "bluetooth" - "dhcp" - "energy" - "history" - "backup" - "assist_pipeline" - "conversation" - "sun" - "zeroconf" - "cpuspeed" - ]; - config = { - http = { - server_port = 8123; - use_x_forwarded_for = true; - trusted_proxies = ["127.0.0.1" "::1"]; - ip_ban_enabled = true; - login_attempts_threshold = 10; - }; - homeassistant = { - external_url = "https://${config.services.home-assistant.domain}"; - # internal_url = "http://192.168.1.2:8123"; - }; - recorder.db_url = "postgresql://@/${config.services.home-assistant.configDir}"; - "automation manual" = []; - "automation ui" = "!include automations.yaml"; - mobile_app = {}; - }; - extraPackages = python3Packages: - with python3Packages; [ - hassil - numpy - gtts - ]; - }; - - # TODO: configure /var/lib/hass/secrets.yaml via sops - - networking.firewall.allowedUDPPorts = [ - 1900 - ]; - - systemd.tmpfiles.rules = [ - "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" - ]; - } - ]); } diff --git a/modules/nixos-modules/server/home-assistant/home-assistant.nix b/modules/nixos-modules/server/home-assistant/home-assistant.nix new file mode 100644 index 0000000..fa58d5e --- /dev/null +++ b/modules/nixos-modules/server/home-assistant/home-assistant.nix @@ -0,0 +1,104 @@ +{ + lib, + config, + ... +}: { + options.services.home-assistant = { + database = lib.mkOption { + type = lib.types.enum [ + "builtin" + "postgres" + ]; + description = "what database do we want to use"; + default = "builtin"; + }; + + extensions = { + sonos = { + enable = lib.mkEnableOption "enable the sonos plugin"; + port = lib.mkOption { + type = lib.types.int; + default = 1400; + description = "what port to use for sonos discovery"; + }; + }; + jellyfin = { + enable = lib.mkEnableOption "enable the jellyfin plugin"; + }; + wyoming = { + enable = lib.mkEnableOption "enable wyoming"; + }; + }; + }; + + config = lib.mkIf config.services.home-assistant.enable (lib.mkMerge [ + { + services.home-assistant = { + configDir = "/var/lib/hass"; + extraComponents = [ + "default_config" + "esphome" + "met" + "radio_browser" + "isal" + "zha" + "webostv" + "tailscale" + "syncthing" + "analytics_insights" + "unifi" + "openweathermap" + "ollama" + "mobile_app" + "logbook" + "ssdp" + "usb" + "webhook" + "bluetooth" + "dhcp" + "energy" + "history" + "backup" + "assist_pipeline" + "conversation" + "sun" + "zeroconf" + "cpuspeed" + ]; + config = { + http = { + server_port = 8123; + use_x_forwarded_for = true; + trusted_proxies = ["127.0.0.1" "::1"]; + ip_ban_enabled = true; + login_attempts_threshold = 10; + }; + homeassistant = { + external_url = "https://${config.services.home-assistant.domain}"; + # internal_url = "http://192.168.1.2:8123"; + }; + recorder.db_url = "postgresql://@/${config.services.home-assistant.configDir}"; + "automation manual" = []; + "automation ui" = "!include automations.yaml"; + mobile_app = {}; + }; + extraPackages = python3Packages: + with python3Packages; [ + hassil + numpy + gtts + ]; + }; + + # TODO: configure /var/lib/hass/secrets.yaml via sops + + networking.firewall.allowedUDPPorts = [ + 1900 + ]; + + systemd.tmpfiles.rules = [ + "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" + ]; + } + ]); +} diff --git a/modules/nixos-modules/server/jellyfin/default.nix b/modules/nixos-modules/server/jellyfin/default.nix index 0d88481..2dbdcfd 100644 --- a/modules/nixos-modules/server/jellyfin/default.nix +++ b/modules/nixos-modules/server/jellyfin/default.nix @@ -1,38 +1,8 @@ { - lib, - pkgs, - config, - ... -}: let - jellyfinPort = 8096; - dlanPort = 1900; -in { imports = [ + ./jellyfin.nix ./proxy.nix ./fail2ban.nix ./impermanence.nix ]; - - options.services.jellyfin = { - media_directory = lib.mkOption { - type = lib.types.str; - description = "directory jellyfin media will be hosted at"; - default = "/srv/jellyfin/media"; - }; - }; - - config = lib.mkIf config.services.jellyfin.enable { - environment.systemPackages = [ - pkgs.jellyfin - pkgs.jellyfin-web - pkgs.jellyfin-ffmpeg - ]; - - networking.firewall.allowedTCPPorts = [jellyfinPort dlanPort]; - - systemd.tmpfiles.rules = [ - "d ${config.services.jellyfin.media_directory} 2770 jellyfin jellyfin_media" - "A ${config.services.jellyfin.media_directory} - - - - u:jellyfin:rwX,g:jellyfin_media:rwX,o::-" - ]; - }; } diff --git a/modules/nixos-modules/server/jellyfin/jellyfin.nix b/modules/nixos-modules/server/jellyfin/jellyfin.nix new file mode 100644 index 0000000..9bfa921 --- /dev/null +++ b/modules/nixos-modules/server/jellyfin/jellyfin.nix @@ -0,0 +1,32 @@ +{ + lib, + pkgs, + config, + ... +}: let + jellyfinPort = 8096; + dlanPort = 1900; +in { + options.services.jellyfin = { + media_directory = lib.mkOption { + type = lib.types.str; + description = "directory jellyfin media will be hosted at"; + default = "/srv/jellyfin/media"; + }; + }; + + config = lib.mkIf config.services.jellyfin.enable { + environment.systemPackages = [ + pkgs.jellyfin + pkgs.jellyfin-web + pkgs.jellyfin-ffmpeg + ]; + + networking.firewall.allowedTCPPorts = [jellyfinPort dlanPort]; + + systemd.tmpfiles.rules = [ + "d ${config.services.jellyfin.media_directory} 2770 jellyfin jellyfin_media" + "A ${config.services.jellyfin.media_directory} - - - - u:jellyfin:rwX,g:jellyfin_media:rwX,o::-" + ]; + }; +} diff --git a/modules/nixos-modules/server/network_storage/default.nix b/modules/nixos-modules/server/network_storage/default.nix index eaac7fe..cd100ab 100644 --- a/modules/nixos-modules/server/network_storage/default.nix +++ b/modules/nixos-modules/server/network_storage/default.nix @@ -1,90 +1,6 @@ { - config, - lib, - ... -}: let - export_directory = config.host.network_storage.export_directory; -in { imports = [ + ./network_storage.nix ./nfs.nix ]; - - options = { - host.network_storage = { - enable = lib.mkEnableOption "is this machine going to export network storage"; - export_directory = lib.mkOption { - type = lib.types.path; - description = "what are exports going to be stored in"; - default = "/exports"; - }; - directories = lib.mkOption { - type = lib.types.listOf (lib.types.submodule ({config, ...}: { - options = { - folder = lib.mkOption { - type = lib.types.str; - description = "what is the name of this export directory"; - }; - bind = lib.mkOption { - type = lib.types.nullOr lib.types.path; - description = "is this directory bound to anywhere"; - default = null; - }; - user = lib.mkOption { - type = lib.types.str; - description = "what user owns this directory"; - default = "nouser"; - }; - group = lib.mkOption { - type = lib.types.str; - description = "what group owns this directory"; - default = "nogroup"; - }; - _directory = lib.mkOption { - internal = true; - readOnly = true; - type = lib.types.path; - default = "${export_directory}/${config.folder}"; - }; - }; - })); - description = "list of directory names to export"; - }; - }; - }; - - config = lib.mkIf config.host.network_storage.enable (lib.mkMerge [ - { - # create any folders that we need to have for our exports - systemd.tmpfiles.rules = - [ - "d ${config.host.network_storage.export_directory} 2775 nobody nogroup -" - ] - ++ ( - builtins.map ( - directory: "d ${directory._directory} 2770 ${directory.user} ${directory.group}" - ) - config.host.network_storage.directories - ); - - # set up any bind mounts that we need for our exports - fileSystems = builtins.listToAttrs ( - builtins.map (directory: - lib.attrsets.nameValuePair directory._directory { - device = directory.bind; - options = ["bind"]; - }) ( - builtins.filter (directory: directory.bind != null) config.host.network_storage.directories - ) - ); - } - # (lib.mkIf config.host.impermanence.enable { - # environment.persistence."/persist/system/root" = { - # enable = true; - # hideMounts = true; - # directories = [ - # config.host.network_storage.export_directory - # ]; - # }; - # }) - ]); } diff --git a/modules/nixos-modules/server/network_storage/network_storage.nix b/modules/nixos-modules/server/network_storage/network_storage.nix new file mode 100644 index 0000000..ebc3bee --- /dev/null +++ b/modules/nixos-modules/server/network_storage/network_storage.nix @@ -0,0 +1,86 @@ +{ + config, + lib, + ... +}: let + export_directory = config.host.network_storage.export_directory; +in { + options = { + host.network_storage = { + enable = lib.mkEnableOption "is this machine going to export network storage"; + export_directory = lib.mkOption { + type = lib.types.path; + description = "what are exports going to be stored in"; + default = "/exports"; + }; + directories = lib.mkOption { + type = lib.types.listOf (lib.types.submodule ({config, ...}: { + options = { + folder = lib.mkOption { + type = lib.types.str; + description = "what is the name of this export directory"; + }; + bind = lib.mkOption { + type = lib.types.nullOr lib.types.path; + description = "is this directory bound to anywhere"; + default = null; + }; + user = lib.mkOption { + type = lib.types.str; + description = "what user owns this directory"; + default = "nouser"; + }; + group = lib.mkOption { + type = lib.types.str; + description = "what group owns this directory"; + default = "nogroup"; + }; + _directory = lib.mkOption { + internal = true; + readOnly = true; + type = lib.types.path; + default = "${export_directory}/${config.folder}"; + }; + }; + })); + description = "list of directory names to export"; + }; + }; + }; + + config = lib.mkIf config.host.network_storage.enable (lib.mkMerge [ + { + # create any folders that we need to have for our exports + systemd.tmpfiles.rules = + [ + "d ${config.host.network_storage.export_directory} 2775 nobody nogroup -" + ] + ++ ( + builtins.map ( + directory: "d ${directory._directory} 2770 ${directory.user} ${directory.group}" + ) + config.host.network_storage.directories + ); + + # set up any bind mounts that we need for our exports + fileSystems = builtins.listToAttrs ( + builtins.map (directory: + lib.attrsets.nameValuePair directory._directory { + device = directory.bind; + options = ["bind"]; + }) ( + builtins.filter (directory: directory.bind != null) config.host.network_storage.directories + ) + ); + } + # (lib.mkIf config.host.impermanence.enable { + # environment.persistence."/persist/system/root" = { + # enable = true; + # hideMounts = true; + # directories = [ + # config.host.network_storage.export_directory + # ]; + # }; + # }) + ]); +} diff --git a/modules/nixos-modules/server/paperless/default.nix b/modules/nixos-modules/server/paperless/default.nix index d2bc930..7e5e16b 100644 --- a/modules/nixos-modules/server/paperless/default.nix +++ b/modules/nixos-modules/server/paperless/default.nix @@ -1,34 +1,9 @@ { - config, - lib, - ... -}: { imports = [ + ./paperless.nix ./proxy.nix ./database.nix ./fail2ban.nix ./impermanence.nix ]; - - options.services.paperless = { - database = { - user = lib.mkOption { - type = lib.types.str; - description = "what is the user and database that we are going to use for paperless"; - default = "paperless"; - }; - }; - }; - - config = lib.mkIf config.services.paperless.enable { - services.paperless = { - configureTika = true; - settings = { - PAPERLESS_DBENGINE = "postgresql"; - PAPERLESS_DBHOST = "/run/postgresql"; - PAPERLESS_DBNAME = config.services.paperless.database.user; - PAPERLESS_DBUSER = config.services.paperless.database.user; - }; - }; - }; } diff --git a/modules/nixos-modules/server/paperless/paperless.nix b/modules/nixos-modules/server/paperless/paperless.nix new file mode 100644 index 0000000..5bcbfed --- /dev/null +++ b/modules/nixos-modules/server/paperless/paperless.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + ... +}: { + options.services.paperless = { + database = { + user = lib.mkOption { + type = lib.types.str; + description = "what is the user and database that we are going to use for paperless"; + default = "paperless"; + }; + }; + }; + + config = lib.mkIf config.services.paperless.enable { + services.paperless = { + configureTika = true; + settings = { + PAPERLESS_DBENGINE = "postgresql"; + PAPERLESS_DBHOST = "/run/postgresql"; + PAPERLESS_DBNAME = config.services.paperless.database.user; + PAPERLESS_DBUSER = config.services.paperless.database.user; + }; + }; + }; +} diff --git a/modules/nixos-modules/server/searx/default.nix b/modules/nixos-modules/server/searx/default.nix index ac84c1d..5426380 100644 --- a/modules/nixos-modules/server/searx/default.nix +++ b/modules/nixos-modules/server/searx/default.nix @@ -1,63 +1,6 @@ { - config, - lib, - inputs, - ... -}: { imports = [ + ./searx.nix ./proxy.nix ]; - - config = lib.mkIf config.services.searx.enable { - sops.secrets = { - "services/searx" = { - sopsFile = "${inputs.secrets}/defiant-services.yaml"; - }; - }; - - services.searx = { - environmentFile = config.sops.secrets."services/searx".path; - - # Rate limiting - limiterSettings = { - real_ip = { - x_for = 1; - ipv4_prefix = 32; - ipv6_prefix = 56; - }; - - botdetection = { - ip_limit = { - filter_link_local = true; - link_token = true; - }; - }; - }; - - settings = { - server = { - port = 8083; - secret_key = "@SEARXNG_SECRET@"; - }; - - # Search engine settings - search = { - safe_search = 2; - autocomplete_min = 2; - autocomplete = "duckduckgo"; - }; - - # Enabled plugins - enabled_plugins = [ - "Basic Calculator" - "Hash plugin" - "Tor check plugin" - "Open Access DOI rewrite" - "Hostnames plugin" - "Unit converter plugin" - "Tracker URL remover" - ]; - }; - }; - }; } diff --git a/modules/nixos-modules/server/searx/searx.nix b/modules/nixos-modules/server/searx/searx.nix new file mode 100644 index 0000000..d4d4012 --- /dev/null +++ b/modules/nixos-modules/server/searx/searx.nix @@ -0,0 +1,59 @@ +{ + config, + lib, + inputs, + ... +}: { + config = lib.mkIf config.services.searx.enable { + sops.secrets = { + "services/searx" = { + sopsFile = "${inputs.secrets}/defiant-services.yaml"; + }; + }; + + services.searx = { + environmentFile = config.sops.secrets."services/searx".path; + + # Rate limiting + limiterSettings = { + real_ip = { + x_for = 1; + ipv4_prefix = 32; + ipv6_prefix = 56; + }; + + botdetection = { + ip_limit = { + filter_link_local = true; + link_token = true; + }; + }; + }; + + settings = { + server = { + port = 8083; + secret_key = "@SEARXNG_SECRET@"; + }; + + # Search engine settings + search = { + safe_search = 2; + autocomplete_min = 2; + autocomplete = "duckduckgo"; + }; + + # Enabled plugins + enabled_plugins = [ + "Basic Calculator" + "Hash plugin" + "Tor check plugin" + "Open Access DOI rewrite" + "Hostnames plugin" + "Unit converter plugin" + "Tracker URL remover" + ]; + }; + }; + }; +} From 5114f52607aae5462eb391c2d13edee52beb0b70 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sat, 25 Oct 2025 15:11:25 -0500 Subject: [PATCH 19/61] feat: added rust-analyzer vscode package --- .../leyla/packages/vscode/default.nix | 3 +++ .../programs/vscode/default.nix | 1 + .../programs/vscode/rustAnalyzer.nix | 27 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 modules/home-manager-modules/programs/vscode/rustAnalyzer.nix diff --git a/configurations/home-manager/leyla/packages/vscode/default.nix b/configurations/home-manager/leyla/packages/vscode/default.nix index fd72006..36168b2 100644 --- a/configurations/home-manager/leyla/packages/vscode/default.nix +++ b/configurations/home-manager/leyla/packages/vscode/default.nix @@ -69,6 +69,9 @@ in { # go development go.enable = true; + # rust development + rustAnalyzer.enable = true; + # claude development claudeDev = lib.mkIf ai-tooling-enabled { enable = true; diff --git a/modules/home-manager-modules/programs/vscode/default.nix b/modules/home-manager-modules/programs/vscode/default.nix index 8f366fe..f9d83dc 100644 --- a/modules/home-manager-modules/programs/vscode/default.nix +++ b/modules/home-manager-modules/programs/vscode/default.nix @@ -16,6 +16,7 @@ ./go.nix ./evenBetterToml.nix ./openRemoteSsh.nix + ./rustAnalyzer.nix ./astroVscode.nix ./vscodeMdx.nix ./claudeDev.nix diff --git a/modules/home-manager-modules/programs/vscode/rustAnalyzer.nix b/modules/home-manager-modules/programs/vscode/rustAnalyzer.nix new file mode 100644 index 0000000..66e9ebe --- /dev/null +++ b/modules/home-manager-modules/programs/vscode/rustAnalyzer.nix @@ -0,0 +1,27 @@ +{ + lib, + pkgs, + config, + ... +}: let + pkgsRepositories = pkgs.nix-vscode-extensions.forVSCodeVersion config.programs.vscode.package.version; + pkgsRepository = pkgsRepositories.open-vsx; +in { + options.programs.vscode.profiles = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({config, ...}: { + options = { + extraExtensions.rustAnalyzer = { + enable = lib.mkEnableOption "should the rust-analyzer extension for vscode be enabled"; + extension = lib.mkPackageOption pkgsRepository "rust-analyzer" { + default = ["rust-lang" "rust-analyzer"]; + }; + }; + }; + config = lib.mkIf config.extraExtensions.rustAnalyzer.enable { + extensions = [ + config.extraExtensions.rustAnalyzer.extension + ]; + }; + })); + }; +} From c97d43957df6413ab524c608169c77e58b464e3b Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sun, 26 Oct 2025 13:06:08 -0500 Subject: [PATCH 20/61] feat: enabled actual --- configurations/nixos/defiant/configuration.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index ae897ce..62ab1de 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -319,7 +319,7 @@ }; actual = { - enable = false; + enable = true; domain = "budget.jan-leila.com"; }; From 7ad6a83dfa1bc7f1d1335636e976035e1abf425f Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sun, 26 Oct 2025 13:17:48 -0500 Subject: [PATCH 21/61] feat: broke leyla firefox config into submodules --- .../home-manager/leyla/packages/default.nix | 2 +- .../home-manager/leyla/packages/firefox.nix | 344 ------------------ .../leyla/packages/firefox/bookmarks.nix | 149 ++++++++ .../leyla/packages/firefox/default.nix | 18 + .../leyla/packages/firefox/firefox.nix | 221 +++++++++++ .../leyla/packages/firefox/harden.nix | 50 +++ 6 files changed, 439 insertions(+), 345 deletions(-) delete mode 100644 configurations/home-manager/leyla/packages/firefox.nix create mode 100644 configurations/home-manager/leyla/packages/firefox/bookmarks.nix create mode 100644 configurations/home-manager/leyla/packages/firefox/default.nix create mode 100644 configurations/home-manager/leyla/packages/firefox/firefox.nix create mode 100644 configurations/home-manager/leyla/packages/firefox/harden.nix diff --git a/configurations/home-manager/leyla/packages/default.nix b/configurations/home-manager/leyla/packages/default.nix index 5bccad3..50cc175 100644 --- a/configurations/home-manager/leyla/packages/default.nix +++ b/configurations/home-manager/leyla/packages/default.nix @@ -9,7 +9,7 @@ in { imports = [ ./vscode - ./firefox.nix + ./firefox ./direnv.nix ./openssh.nix ./git.nix diff --git a/configurations/home-manager/leyla/packages/firefox.nix b/configurations/home-manager/leyla/packages/firefox.nix deleted file mode 100644 index d166eb4..0000000 --- a/configurations/home-manager/leyla/packages/firefox.nix +++ /dev/null @@ -1,344 +0,0 @@ -{ - lib, - pkgs, - inputs, - ... -}: { - config = { - programs.firefox = { - profiles.leyla = { - settings = { - "browser.search.defaultenginename" = "Searx"; - "browser.search.order.1" = "Searx"; - }; - - search = { - force = true; - default = "Searx"; - engines = { - "Nix Packages" = { - urls = [ - { - template = "https://search.nixos.org/packages"; - params = [ - { - name = "type"; - value = "packages"; - } - { - name = "query"; - value = "{searchTerms}"; - } - ]; - } - ]; - icon = "''${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@np"]; - }; - "NixOS Wiki" = { - urls = [{template = "https://nixos.wiki/index.php?search={searchTerms}";}]; - icon = "https://nixos.wiki/favicon.png"; - updateInterval = 24 * 60 * 60 * 1000; # every day - definedAliases = ["@nw"]; - }; - "Searx" = { - urls = [{template = "https://search.jan-leila.com/?q={searchTerms}";}]; - icon = "https://nixos.wiki/favicon.png"; - updateInterval = 24 * 60 * 60 * 1000; # every day - definedAliases = ["@searx"]; - }; - }; - }; - - extensions.packages = with inputs.firefox-addons.packages.${pkgs.system}; [ - bitwarden - terms-of-service-didnt-read - multi-account-containers - shinigami-eyes - - ublock-origin - sponsorblock - dearrow - df-youtube - return-youtube-dislikes - - privacy-badger - decentraleyes - clearurls - localcdn - - snowflake - - deutsch-de-language-pack - dictionary-german - - tab-session-manager - - # ( - # buildFirefoxXpiAddon rec { - # pname = "italiano-it-language-pack"; - # version = "132.0.20241110.231641"; - # addonId = "langpack-it@firefox.mozilla.org"; - # url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi"; - # sha256 = ""; - # meta = with lib; - # { - # description = "Firefox Language Pack for Italiano (it) – Italian"; - # license = licenses.mpl20; - # mozPermissions = []; - # platforms = platforms.all; - # }; - # } - # ) - # ( - # buildFirefoxXpiAddon rec { - # pname = "dizionario-italiano"; - # version = "5.1"; - # addonId = "it-IT@dictionaries.addons.mozilla.org"; - # url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi"; - # sha256 = ""; - # meta = with lib; - # { - # description = "Add support for Italian to spellchecking"; - # license = licenses.gpl3; - # mozPermissions = []; - # platforms = platforms.all; - # }; - # } - # ) - ]; - - settings = { - # Disable irritating first-run stuff - "browser.disableResetPrompt" = true; - "browser.download.panel.shown" = true; - "browser.feeds.showFirstRunUI" = false; - "browser.messaging-system.whatsNewPanel.enabled" = false; - "browser.rights.3.shown" = true; - "browser.shell.checkDefaultBrowser" = false; - "browser.shell.defaultBrowserCheckCount" = 1; - "browser.startup.homepage_override.mstone" = "ignore"; - "browser.uitour.enabled" = false; - "startup.homepage_override_url" = ""; - "trailhead.firstrun.didSeeAboutWelcome" = true; - "browser.bookmarks.restore_default_bookmarks" = false; - "browser.bookmarks.addedImportButton" = true; - "browser.newtabpage.activity-stream.feeds.section.topstories" = false; - - # Usage Experience - "browser.startup.homepage" = "about:home"; - "browser.download.useDownloadDir" = false; - "browser.uiCustomization.state" = builtins.toJSON { - "currentVersion" = 20; - "newElementCount" = 6; - "dirtyAreaCache" = [ - "nav-bar" - "PersonalToolbar" - "toolbar-menubar" - "TabsToolbar" - "unified-extensions-area" - "vertical-tabs" - ]; - "placements" = { - "widget-overflow-fixed-list" = []; - "unified-extensions-area" = [ - # bitwarden - "_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action" - "ublock0_raymondhill_net-browser-action" - "sponsorblocker_ajay_app-browser-action" - "dearrow_ajay_app-browser-action" - "jid1-mnnxcxisbpnsxq_jetpack-browser-action" - "_testpilot-containers-browser-action" - "addon_simplelogin-browser-action" - "_74145f27-f039-47ce-a470-a662b129930a_-browser-action" - "jid1-bofifl9vbdl2zq_jetpack-browser-action" - "dfyoutube_example_com-browser-action" - "_b86e4813-687a-43e6-ab65-0bde4ab75758_-browser-action" - "_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action" - "_b11bea1f-a888-4332-8d8a-cec2be7d24b9_-browse-action" - "jid0-3guet1r69sqnsrca5p8kx9ezc3u_jetpack-browser-action" - ]; - "nav-bar" = [ - "back-button" - "forward-button" - "stop-reload-button" - "urlbar-container" - "downloads-button" - "unified-extensions-button" - "reset-pbm-toolbar-button" - ]; - "toolbar-menubar" = [ - "menubar-items" - ]; - "TabsToolbar" = [ - "firefox-view-button" - "tabbrowser-tabs" - "new-tab-button" - "alltabs-button" - ]; - "vertical-tabs" = []; - "PersonalToolbar" = [ - "import-button" - "personal-bookmarks" - ]; - }; - "seen" = [ - "save-to-pocket-button" - "developer-button" - "privacy_privacy_com-browser-action" - "sponsorblocker_ajay_app-browser-action" - "ublock0_raymondhill_net-browser-action" - "addon_simplelogin-browser-action" - "dearrow_ajay_app-browser-action" - "_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action" - "_74145f27-f039-47ce-a470-a662b129930a_-browser-action" - "jid1-bofifl9vbdl2zq_jetpack-browser-action" - "dfyoutube_example_com-browser-action" - "_testpilot-containers-browser-action" - "_b86e4813-687a-43e6-ab65-0bde4ab75758_-browser-action" - "jid1-mnnxcxisbpnsxq_jetpack-browser-action" - "_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action" - "_b11bea1f-a888-4332-8d8a-cec2be7d24b9_-browser-action" - "jid0-3guet1r69sqnsrca5p8kx9ezc3u_jetpack-browser-action" - ]; - }; - "browser.newtabpage.activity-stream.feeds.topsites" = false; - "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; - "browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts" = false; - "browser.newtabpage.blocked" = lib.genAttrs [ - # Facebook - "4gPpjkxgZzXPVtuEoAL9Ig==" - # Reddit - "gLv0ja2RYVgxKdp0I5qwvA==" - # Amazon - "K00ILysCaEq8+bEqV/3nuw==" - # Twitter - "T9nJot5PurhJSy8n038xGA==" - ] (_: 1); - "identity.fxaccounts.enabled" = false; - - # Security - "privacy.trackingprotection.enabled" = true; - "dom.security.https_only_mode" = true; - - "extensions.formautofill.addresses.enabled" = false; - "extensions.formautofill.creditCards.enabled" = false; - "signon.rememberSignons" = false; - "privacy.sanitize.sanitizeOnShutdown" = true; - "privacy.clearOnShutdown_v2.cache" = true; - "privacy.clearOnShutdown_v2.cookiesAndStorage" = true; - "privacy.clearOnShutdown_v2.historyFormDataAndDownloads" = true; - "urlclassifier.trackingSkipURLs" = ""; - "urlclassifier.features.socialtracking.skipURLs" = ""; - "dom.security.https_only_mode_pbm" = true; - "dom.security.https_only_mode_error_page_user_suggestions" = true; - - # Disable telemetry - "app.shield.optoutstudies.enabled" = false; - "browser.discovery.enabled" = false; - "browser.newtabpage.activity-stream.feeds.telemetry" = false; - "browser.newtabpage.activity-stream.telemetry" = false; - "browser.ping-centre.telemetry" = false; - "datareporting.healthreport.service.enabled" = false; - "datareporting.healthreport.uploadEnabled" = false; - "datareporting.policy.dataSubmissionEnabled" = false; - "datareporting.sessions.current.clean" = true; - "devtools.onboarding.telemetry.logged" = false; - "toolkit.telemetry.archive.enabled" = false; - "toolkit.telemetry.bhrPing.enabled" = false; - "toolkit.telemetry.enabled" = false; - "toolkit.telemetry.firstShutdownPing.enabled" = false; - "toolkit.telemetry.hybridContent.enabled" = false; - "toolkit.telemetry.newProfilePing.enabled" = false; - "toolkit.telemetry.prompted" = 2; - "toolkit.telemetry.rejected" = true; - "toolkit.telemetry.reportingpolicy.firstRun" = false; - "toolkit.telemetry.server" = ""; - "toolkit.telemetry.shutdownPingSender.enabled" = false; - "toolkit.telemetry.unified" = false; - "toolkit.telemetry.unifiedIsOptIn" = false; - "toolkit.telemetry.updatePing.enabled" = false; - }; - - bookmarks = { - force = true; - settings = [ - { - name = "Media"; - url = "https://media.jan-leila.com/"; - keyword = ""; - tags = [""]; - } - { - name = "Photos"; - url = "https://photos.jan-leila.com"; - keyword = ""; - tags = [""]; - } - { - name = "Git"; - url = "https://git.jan-leila.com/"; - keyword = ""; - tags = [""]; - } - { - name = "Home Automation"; - url = "https://home.jan-leila.com/"; - keyword = ""; - tags = [""]; - } - { - name = "Mail"; - url = "https://mail.protonmail.com"; - keyword = ""; - tags = [""]; - } - { - name = "Open Street Map"; - url = "https://www.openstreetmap.org/"; - keyword = ""; - tags = [""]; - } - { - name = "Password Manager"; - url = "https://vault.bitwarden.com/"; - keyword = ""; - tags = [""]; - } - { - name = "Mastodon"; - url = "https://mspsocial.net"; - keyword = ""; - tags = [""]; - } - { - name = "Linked In"; - url = "https://www.linkedin.com/"; - keyword = ""; - tags = [""]; - } - { - name = "Job Search"; - url = "https://www.jobsinnetwork.com/?state=cleaned_history&language%5B%5D=en&query=react&locations.countryCode%5B%5D=IT&locations.countryCode%5B%5D=DE&locations.countryCode%5B%5D=NL&experience%5B%5D=medior&experience%5B%5D=junior&page=1"; - keyword = ""; - tags = [""]; - } - { - name = "React Docs"; - url = "https://react.dev/"; - keyword = ""; - tags = [""]; - } - # Template - # { - # name = ""; - # url = ""; - # keyword = ""; - # tags = [""]; - # } - ]; - }; - }; - }; - }; -} diff --git a/configurations/home-manager/leyla/packages/firefox/bookmarks.nix b/configurations/home-manager/leyla/packages/firefox/bookmarks.nix new file mode 100644 index 0000000..8435d45 --- /dev/null +++ b/configurations/home-manager/leyla/packages/firefox/bookmarks.nix @@ -0,0 +1,149 @@ +{...}: { + programs.firefox = { + profiles.leyla = { + bookmarks = { + force = true; + settings = [ + # Personal Services + { + name = "Media"; + url = "https://media.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Photos"; + url = "https://photos.jan-leila.com"; + keyword = ""; + tags = [""]; + } + { + name = "Git"; + url = "https://git.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Home Automation"; + url = "https://home.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Search"; + url = "https://search.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Budget"; + url = "https://budget.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Documents"; + url = "https://documents.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + + # Defiant Server Services + { + name = "QBittorrent"; + url = "http://defiant:8084"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Sonarr"; + url = "http://defiant:8989"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Radarr"; + url = "http://defiant:7878"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Bazarr"; + url = "http://defiant:6767"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Lidarr"; + url = "http://defiant:8686"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Jackett"; + url = "http://defiant:9117"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Crab-hole DNS"; + url = "http://defiant:8085"; + keyword = ""; + tags = ["defiant"]; + } + + # External Services + { + name = "Mail"; + url = "https://mail.protonmail.com"; + keyword = ""; + tags = [""]; + } + { + name = "Open Street Map"; + url = "https://www.openstreetmap.org/"; + keyword = ""; + tags = [""]; + } + { + name = "Password Manager"; + url = "https://vault.bitwarden.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Mastodon"; + url = "https://mspsocial.net"; + keyword = ""; + tags = [""]; + } + { + name = "Linked In"; + url = "https://www.linkedin.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Job Search"; + url = "https://www.jobsinnetwork.com/?state=cleaned_history&language%5B%5D=en&query=react&locations.countryCode%5B%5D=IT&locations.countryCode%5B%5D=DE&locations.countryCode%5B%5D=NL&experience%5B%5D=medior&experience%5B%5D=junior&page=1"; + keyword = ""; + tags = [""]; + } + { + name = "React Docs"; + url = "https://react.dev/"; + keyword = ""; + tags = [""]; + } + # Template + # { + # name = ""; + # url = ""; + # keyword = ""; + # tags = [""]; + # } + ]; + }; + }; + }; +} diff --git a/configurations/home-manager/leyla/packages/firefox/default.nix b/configurations/home-manager/leyla/packages/firefox/default.nix new file mode 100644 index 0000000..4246c68 --- /dev/null +++ b/configurations/home-manager/leyla/packages/firefox/default.nix @@ -0,0 +1,18 @@ +{ + lib, + pkgs, + inputs, + ... +}: { + imports = [ + ./firefox.nix + ./bookmarks.nix + ./harden.nix + ]; + + config = { + programs.firefox = { + enable = true; + }; + }; +} diff --git a/configurations/home-manager/leyla/packages/firefox/firefox.nix b/configurations/home-manager/leyla/packages/firefox/firefox.nix new file mode 100644 index 0000000..1678353 --- /dev/null +++ b/configurations/home-manager/leyla/packages/firefox/firefox.nix @@ -0,0 +1,221 @@ +{ + lib, + pkgs, + inputs, + ... +}: { + programs.firefox = { + profiles.leyla = { + settings = { + "browser.search.defaultenginename" = "Searx"; + "browser.search.order.1" = "Searx"; + }; + + search = { + force = true; + default = "Searx"; + engines = { + "Nix Packages" = { + urls = [ + { + template = "https://search.nixos.org/packages"; + params = [ + { + name = "type"; + value = "packages"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + } + ]; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = ["@np"]; + }; + "NixOS Wiki" = { + urls = [{template = "https://nixos.wiki/index.php?search={searchTerms}";}]; + icon = "https://nixos.wiki/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@nw"]; + }; + "Searx" = { + urls = [{template = "https://search.jan-leila.com/?q={searchTerms}";}]; + icon = "https://nixos.wiki/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@searx"]; + }; + }; + }; + + extensions.packages = with inputs.firefox-addons.packages.${pkgs.system}; [ + bitwarden + terms-of-service-didnt-read + multi-account-containers + shinigami-eyes + + ublock-origin + sponsorblock + dearrow + df-youtube + return-youtube-dislikes + + privacy-badger + decentraleyes + clearurls + localcdn + + snowflake + + deutsch-de-language-pack + dictionary-german + + tab-session-manager + + # (\ + # buildFirefoxXpiAddon rec {\ + # pname = "italiano-it-language-pack";\ + # version = "132.0.20241110.231641";\ + # addonId = "langpack-it@firefox.mozilla.org";\ + # url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi";\ + # sha256 = "";\ + # meta = with lib;\ + # {\ + # description = "Firefox Language Pack for Italiano (it) – Italian";\ + # license = licenses.mpl20;\ + # mozPermissions = [];\ + # platforms = platforms.all;\ + # };\ + # }\ + # )\ + # (\ + # buildFirefoxXpiAddon rec {\ + # pname = "dizionario-italiano";\ + # version = "5.1";\ + # addonId = "it-IT@dictionaries.addons.mozilla.org";\ + # url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi";\ + # sha256 = "";\ + # meta = with lib;\ + # {\ + # description = "Add support for Italian to spellchecking";\ + # license = licenses.gpl3;\ + # mozPermissions = [];\ + # platforms = platforms.all;\ + # };\ + # }\ + # )\ + ]; + + settings = { + # Disable irritating first-run stuff + "browser.disableResetPrompt" = true; + "browser.download.panel.shown" = true; + "browser.feeds.showFirstRunUI" = false; + "browser.messaging-system.whatsNewPanel.enabled" = false; + "browser.rights.3.shown" = true; + "browser.shell.checkDefaultBrowser" = false; + "browser.shell.defaultBrowserCheckCount" = 1; + "browser.startup.homepage_override.mstone" = "ignore"; + "browser.uitour.enabled" = false; + "startup.homepage_override_url" = ""; + "trailhead.firstrun.didSeeAboutWelcome" = true; + "browser.bookmarks.restore_default_bookmarks" = false; + "browser.bookmarks.addedImportButton" = true; + "browser.newtabpage.activity-stream.feeds.section.topstories" = false; + + # Usage Experience + "browser.startup.homepage" = "about:home"; + "browser.download.useDownloadDir" = false; + "browser.uiCustomization.state" = builtins.toJSON { + "currentVersion" = 20; + "newElementCount" = 6; + "dirtyAreaCache" = [ + "nav-bar" + "PersonalToolbar" + "toolbar-menubar" + "TabsToolbar" + "unified-extensions-area" + "vertical-tabs" + ]; + "placements" = { + "widget-overflow-fixed-list" = []; + "unified-extensions-area" = [ + # bitwarden + "_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action" + "ublock0_raymondhill_net-browser-action" + "sponsorblocker_ajay_app-browser-action" + "dearrow_ajay_app-browser-action" + "jid1-mnnxcxisbpnsxq_jetpack-browser-action" + "_testpilot-containers-browser-action" + "addon_simplelogin-browser-action" + "_74145f27-f039-47ce-a470-a662b129930a_-browser-action" + "jid1-bofifl9vbdl2zq_jetpack-browser-action" + "dfyoutube_example_com-browser-action" + "_b86e4813-687a-43e6-ab65-0bde4ab75758_-browser-action" + "_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action" + "_b11bea1f-a888-4332-8d8a-cec2be7d24b9_-browse-action" + "jid0-3guet1r69sqnsrca5p8kx9ezc3u_jetpack-browser-action" + ]; + "nav-bar" = [ + "back-button" + "forward-button" + "stop-reload-button" + "urlbar-container" + "downloads-button" + "unified-extensions-button" + "reset-pbm-toolbar-button" + ]; + "toolbar-menubar" = [ + "menubar-items" + ]; + "TabsToolbar" = [ + "firefox-view-button" + "tabbrowser-tabs" + "new-tab-button" + "alltabs-button" + ]; + "vertical-tabs" = []; + "PersonalToolbar" = [ + "import-button" + "personal-bookmarks" + ]; + }; + "seen" = [ + "save-to-pocket-button" + "developer-button" + "privacy_privacy_com-browser-action" + "sponsorblocker_ajay_app-browser-action" + "ublock0_raymondhill_net-browser-action" + "addon_simplelogin-browser-action" + "dearrow_ajay_app-browser-action" + "_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action" + "_74145f27-f039-47ce-a470-a662b129930a_-browser-action" + "jid1-bofifl9vbdl2zq_jetpack-browser-action" + "dfyoutube_example_com-browser-action" + "_testpilot-containers-browser-action" + "_b86e4813-687a-43e6-ab65-0bde4ab75758_-browser-action" + "jid1-mnnxcxisbpnsxq_jetpack-browser-action" + "_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action" + "_b11bea1f-a888-4332-8d8a-cec2be7d24b9_-browser-action" + "jid0-3guet1r69sqnsrca5p8kx9ezc3u_jetpack-browser-action" + ]; + }; + "browser.newtabpage.activity-stream.feeds.topsites" = false; + "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; + "browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts" = false; + "browser.newtabpage.blocked" = lib.genAttrs [ + # Facebook + "4gPpjkxgZzXPVtuEoAL9Ig==" + # Reddit + "gLv0ja2RYVgxKdp0I5qwvA==" + # Amazon + "K00ILysCaEq8+bEqV/3nuw==" + # Twitter + "T9nJot5PurhJSy8n038xGA==" + ] (_: 1); + "identity.fxaccounts.enabled" = false; + }; + }; + }; +} diff --git a/configurations/home-manager/leyla/packages/firefox/harden.nix b/configurations/home-manager/leyla/packages/firefox/harden.nix new file mode 100644 index 0000000..66310c2 --- /dev/null +++ b/configurations/home-manager/leyla/packages/firefox/harden.nix @@ -0,0 +1,50 @@ +{...}: { + programs.firefox = { + profiles.leyla = { + settings = { + # Security + "privacy.trackingprotection.enabled" = true; + "dom.security.https_only_mode" = true; + "dom.security.https_only_mode_pbm" = true; + "dom.security.https_only_mode_error_page_user_suggestions" = true; + + # Privacy & Data Protection + "extensions.formautofill.addresses.enabled" = false; + "extensions.formautofill.creditCards.enabled" = false; + "signon.rememberSignons" = false; + "privacy.sanitize.sanitizeOnShutdown" = true; + "privacy.clearOnShutdown_v2.cache" = true; + "privacy.clearOnShutdown_v2.cookiesAndStorage" = true; + "privacy.clearOnShutdown_v2.historyFormDataAndDownloads" = true; + "urlclassifier.trackingSkipURLs" = ""; + "urlclassifier.features.socialtracking.skipURLs" = ""; + + # Disable telemetry and data collection + "app.shield.optoutstudies.enabled" = false; + "browser.discovery.enabled" = false; + "browser.newtabpage.activity-stream.feeds.telemetry" = false; + "browser.newtabpage.activity-stream.telemetry" = false; + "browser.ping-centre.telemetry" = false; + "datareporting.healthreport.service.enabled" = false; + "datareporting.healthreport.uploadEnabled" = false; + "datareporting.policy.dataSubmissionEnabled" = false; + "datareporting.sessions.current.clean" = true; + "devtools.onboarding.telemetry.logged" = false; + "toolkit.telemetry.archive.enabled" = false; + "toolkit.telemetry.bhrPing.enabled" = false; + "toolkit.telemetry.enabled" = false; + "toolkit.telemetry.firstShutdownPing.enabled" = false; + "toolkit.telemetry.hybridContent.enabled" = false; + "toolkit.telemetry.newProfilePing.enabled" = false; + "toolkit.telemetry.prompted" = 2; + "toolkit.telemetry.rejected" = true; + "toolkit.telemetry.reportingpolicy.firstRun" = false; + "toolkit.telemetry.server" = ""; + "toolkit.telemetry.shutdownPingSender.enabled" = false; + "toolkit.telemetry.unified" = false; + "toolkit.telemetry.unifiedIsOptIn" = false; + "toolkit.telemetry.updatePing.enabled" = false; + }; + }; + }; +} From f72a6da0132b370a6d84db2c91e53e3a8857cc37 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sun, 26 Oct 2025 14:24:18 -0500 Subject: [PATCH 22/61] feat: fixed actual install --- modules/nixos-modules/server/actual/actual.nix | 14 +++++++++----- modules/nixos-modules/server/actual/const.nix | 2 +- .../nixos-modules/server/actual/impermanence.nix | 10 ++++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/modules/nixos-modules/server/actual/actual.nix b/modules/nixos-modules/server/actual/actual.nix index 96ea586..4cca449 100644 --- a/modules/nixos-modules/server/actual/actual.nix +++ b/modules/nixos-modules/server/actual/actual.nix @@ -6,14 +6,18 @@ const = import ./const.nix; dataDirectory = const.dataDirectory; in { + options.services.actual = { + port = lib.mkOption { + type = lib.types.port; + description = "The port to listen on"; + default = 5006; + }; + }; config = lib.mkIf config.services.actual.enable { - systemd.tmpfiles.rules = [ - "d ${dataDirectory} 2770 actual actual" - ]; - services.actual = { settings = { - ACTUAL_DATA_DIR = dataDirectory; + port = config.services.actual.port; + dataDir = dataDirectory; }; }; }; diff --git a/modules/nixos-modules/server/actual/const.nix b/modules/nixos-modules/server/actual/const.nix index 13b068e..14b715e 100644 --- a/modules/nixos-modules/server/actual/const.nix +++ b/modules/nixos-modules/server/actual/const.nix @@ -1,3 +1,3 @@ { - dataDirectory = "/var/lib/actual/"; + dataDirectory = "/var/lib/private/actual"; } diff --git a/modules/nixos-modules/server/actual/impermanence.nix b/modules/nixos-modules/server/actual/impermanence.nix index 5a2bb6c..f203178 100644 --- a/modules/nixos-modules/server/actual/impermanence.nix +++ b/modules/nixos-modules/server/actual/impermanence.nix @@ -5,6 +5,8 @@ }: let const = import ./const.nix; dataDirectory = const.dataDirectory; + # Strip /private from dataDirectory for assertion check (systemd DynamicUser adds /private automatically) + configDataDirectory = lib.strings.replaceStrings ["/var/lib/private"] ["/var/lib"] dataDirectory; in { options.services.actual = { impermanence.enable = lib.mkOption { @@ -16,8 +18,12 @@ in { config = lib.mkIf config.services.actual.impermanence.enable { assertions = [ { - assertion = config.services.actual.settings.ACTUAL_DATA_DIR == dataDirectory; - message = "actual data location does not match persistence"; + assertion = config.services.actual.settings.dataDir == dataDirectory; + message = "actual data location does not match persistence\nconfig directory: ${config.services.actual.settings.dataDir}\npersistence directory: ${dataDirectory}"; + } + { + assertion = config.systemd.services.actual.serviceConfig.DynamicUser or false; + message = "actual systemd service must have DynamicUser enabled to use private directory"; } ]; environment.persistence."/persist/system/root" = { From 758cbd17f72a738658e7d8554b9d3560a01fbb06 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sun, 26 Oct 2025 14:43:50 -0500 Subject: [PATCH 23/61] refactor: removed unused var --- modules/nixos-modules/server/actual/impermanence.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/nixos-modules/server/actual/impermanence.nix b/modules/nixos-modules/server/actual/impermanence.nix index f203178..d870789 100644 --- a/modules/nixos-modules/server/actual/impermanence.nix +++ b/modules/nixos-modules/server/actual/impermanence.nix @@ -5,8 +5,6 @@ }: let const = import ./const.nix; dataDirectory = const.dataDirectory; - # Strip /private from dataDirectory for assertion check (systemd DynamicUser adds /private automatically) - configDataDirectory = lib.strings.replaceStrings ["/var/lib/private"] ["/var/lib"] dataDirectory; in { options.services.actual = { impermanence.enable = lib.mkOption { From 81a65885374148fc60e0335624b8e7102cfbbdab Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sun, 26 Oct 2025 23:35:54 -0500 Subject: [PATCH 24/61] feat: updated flack lock --- flake.lock | 30 ++++++++++++------------ modules/nixos-modules/server/wyoming.nix | 6 ++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/flake.lock b/flake.lock index 09349a6..11fb672 100644 --- a/flake.lock +++ b/flake.lock @@ -46,11 +46,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1761019419, - "narHash": "sha256-lOzy4BGZtPxxNOzDEwfy3lcb7enl53f1wYP/JVWwSHg=", + "lastModified": 1761478231, + "narHash": "sha256-a6ROM73M0TSrooI+8/UMj5KWKOdaDFTycVeo8XJ3dk4=", "owner": "rycee", "repo": "nur-expressions", - "rev": "727c8a012382db77e14d72ce1fe4e19be3206ce6", + "rev": "ae968708476302f8781fb5e245d53f112ed04111", "type": "gitlab" }, "original": { @@ -133,11 +133,11 @@ ] }, "locked": { - "lastModified": 1761081701, - "narHash": "sha256-IwpfaKg5c/WWQiy8b5QGaVPMvoEQ2J6kpwRFdpVpBNQ=", + "lastModified": 1761530345, + "narHash": "sha256-+9+YCK9Lh6GThkXu/8JTxMFUnImIdZpb8ElUh6/F5Y8=", "owner": "nix-community", "repo": "home-manager", - "rev": "9b4a2a7c4fbd75b422f00794af02d6edb4d9d315", + "rev": "bbaeb9f1c29e79bb1653b32c3d73244cdf4bd888", "type": "github" }, "original": { @@ -227,11 +227,11 @@ ] }, "locked": { - "lastModified": 1760721282, - "narHash": "sha256-aAHphQbU9t/b2RRy2Eb8oMv+I08isXv2KUGFAFn7nCo=", + "lastModified": 1761339987, + "narHash": "sha256-IUaawVwItZKi64IA6kF6wQCLCzpXbk2R46dHn8sHkig=", "owner": "LnL7", "repo": "nix-darwin", - "rev": "c3211fcd0c56c11ff110d346d4487b18f7365168", + "rev": "7cd9aac79ee2924a85c211d21fafd394b06a38de", "type": "github" }, "original": { @@ -268,11 +268,11 @@ ] }, "locked": { - "lastModified": 1761011896, - "narHash": "sha256-p6oWYhpJGIV76tJExGUFRkir29yCTUYLsnKmnhzW2C0=", + "lastModified": 1761530505, + "narHash": "sha256-SbuUyC5pfTcMa9JUqSxFyGJpCqoUsB74tboS22+lByY=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "0a74c6a180110ac18584780eeff31e302b0bf8a4", + "rev": "5a5496a7d21265e0ce7641452daf6c560f0eb7a9", "type": "github" }, "original": { @@ -315,11 +315,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1760878510, - "narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=", + "lastModified": 1761373498, + "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=", "owner": "nixos", "repo": "nixpkgs", - "rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67", + "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce", "type": "github" }, "original": { diff --git a/modules/nixos-modules/server/wyoming.nix b/modules/nixos-modules/server/wyoming.nix index 4894dd4..c9a1474 100644 --- a/modules/nixos-modules/server/wyoming.nix +++ b/modules/nixos-modules/server/wyoming.nix @@ -37,9 +37,9 @@ openwakeword = { enable = true; uri = "tcp://0.0.0.0:10400"; - preloadModels = [ - "ok_nabu" - ]; + # preloadModels = [ + # "ok_nabu" + # ]; # TODO: custom models }; }; From bb5c94ec2c8c4955a3fd21bd1c460601889d749d Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 27 Oct 2025 00:53:59 -0500 Subject: [PATCH 25/61] feat: added catch all route to reverse proxy that blocks connections on non specified hosts --- .../server/reverseProxy/reverseProxy.nix | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/nixos-modules/server/reverseProxy/reverseProxy.nix b/modules/nixos-modules/server/reverseProxy/reverseProxy.nix index 5b8357f..eecc9bf 100644 --- a/modules/nixos-modules/server/reverseProxy/reverseProxy.nix +++ b/modules/nixos-modules/server/reverseProxy/reverseProxy.nix @@ -6,6 +6,11 @@ options.services.reverseProxy = { enable = lib.mkEnableOption "turn on the reverse proxy"; openFirewall = lib.mkEnableOption "open the firewall"; + refuseUnmatchedDomains = lib.mkOption { + type = lib.types.bool; + description = "refuse connections for domains that don't match any configured virtual hosts"; + default = true; + }; ports = { http = lib.mkOption { type = lib.types.port; @@ -96,7 +101,20 @@ services.nginx = { enable = true; virtualHosts = lib.mkMerge ( - lib.lists.flatten ( + (lib.optionals config.services.reverseProxy.refuseUnmatchedDomains [ + { + "_" = { + default = true; + serverName = "_"; + locations."/" = { + extraConfig = '' + return 444; + ''; + }; + }; + } + ]) + ++ lib.lists.flatten ( lib.attrsets.mapAttrsToList ( name: service: let hostConfig = { From ec802a2462571c069485b1eeaac6d3c476e332d0 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 27 Oct 2025 00:56:56 -0500 Subject: [PATCH 26/61] chore: updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 23a4966..a251dad 100644 --- a/README.md +++ b/README.md @@ -43,12 +43,12 @@ nix multi user, multi system, configuration with `sops` secret management, `home - Look into this for auto rotating sops keys `https://technotim.live/posts/rotate-sops-encryption-keys/` - Look into this for npins https://jade.fyi/blog/pinning-nixos-with-npins/ - https://nixos-and-flakes.thiscute.world/ +- proton mail now has an smtp server we could use that for our zfs and SMART test emails # Tasks: ## Chores: - [ ] test out crab hole service -- [ ] learn how to use actual ## Tech Debt - [ ] monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/) From f91f20be7c68920c1c52378aba82dba2a8ec472d Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 27 Oct 2025 01:13:42 -0500 Subject: [PATCH 27/61] chore: added more tasks to README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a251dad..b253091 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] rotate sops encryption keys periodically (and somehow sync between devices?) - [ ] Secure Boot - https://github.com/nix-community/lanzaboote - [ ] auto turn off on power loss - nut +- [ ] secondary server with data sync ## Data Access - [ ] nfs export should be backed by the same values for server and client @@ -76,6 +77,8 @@ nix multi user, multi system, configuration with `sops` secret management, `home ## Services - [ ] vikunja service for project management +- [ ] Penpot services (need to make this custom) +- [ ] minecraft server with old world file - [ ] Create Tor guard/relay server - [ ] mastodon instance - [ ] screeps server @@ -98,4 +101,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] postgres db load - [ ] nginx queries - [ ] ntfy.sh for push notifications -- [ ] kuma for uptime visualization \ No newline at end of file +- [ ] kuma for uptime visualization + +## Packages +- [ ] Custom private fork of MultiMC \ No newline at end of file From df663e5438753d2cde51bed048217a2dd99c3058 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 27 Oct 2025 02:34:53 -0500 Subject: [PATCH 28/61] chore: added task to README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b253091..883e143 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] rotate sops encryption keys periodically (and somehow sync between devices?) - [ ] Secure Boot - https://github.com/nix-community/lanzaboote - [ ] auto turn off on power loss - nut -- [ ] secondary server with data sync +- [ ] secondary server with data sync. Maybe a Pi with a usb hdd enclosure and use rtcwake to only turn on once a week to sync data over tailscale with connection initiated from pi's side. We could probably put this at LZ. Hoping for it to draw only like $1 of power a month. Initial sync should probably be done here before we move it over because that will take a while. Data should be encrypted so that devices doesn't have access to it. Project will prob cost like $1800 ## Data Access - [ ] nfs export should be backed by the same values for server and client From e57c1df6e5a6537b4ca8f4fc315fcbdcfd69f2a1 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 27 Oct 2025 02:52:56 -0500 Subject: [PATCH 29/61] chore:added task for qbittorent directory --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 883e143..d3a2121 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home ## Chores: - [ ] test out crab hole service +- [ ] qbittorent should be downloading to `rpool/persist/system/qbittorrent` or maybe even `rpool/persist/system/jellyfin` but right now its downloading to `rpool/persist/system/root` this should be fixed ## Tech Debt - [ ] monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/) From f9c27c82b67930a90db943587543abfe46fda406 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 27 Oct 2025 03:55:09 -0500 Subject: [PATCH 30/61] feat: refactored database configuration --- .../nixos/defiant/configuration.nix | 15 ++- .../nixos-modules/server/forgejo/database.nix | 59 ++++------ .../server/home-assistant/database.nix | 91 +++++++-------- .../nixos-modules/server/immich/database.nix | 44 +++---- .../server/panoramax/database.nix | 64 +++++++---- .../server/paperless/database.nix | 50 ++++---- .../server/postgres/impermanence.nix | 2 +- .../server/postgres/postgres.nix | 108 +++++++++++------- 8 files changed, 229 insertions(+), 204 deletions(-) diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index 62ab1de..e2f9401 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -102,13 +102,6 @@ directories = ["leyla_documents" "eve_documents" "users_documents" "media"]; }; }; - postgres = { - extraUsers = { - leyla = { - isAdmin = true; - }; - }; - }; }; systemd.network = { @@ -220,6 +213,12 @@ }; services = { + # PostgreSQL database server + postgresql = { + enable = true; + adminUsers = ["leyla"]; + }; + # temp enable desktop environment for setup # Enable the X11 windowing system. xserver.enable = true; @@ -327,7 +326,7 @@ enable = true; domain = "home.jan-leila.com"; openFirewall = true; - database = "postgres"; + postgres.enable = true; extensions = { sonos.enable = true; diff --git a/modules/nixos-modules/server/forgejo/database.nix b/modules/nixos-modules/server/forgejo/database.nix index 0417aab..bb8781c 100644 --- a/modules/nixos-modules/server/forgejo/database.nix +++ b/modules/nixos-modules/server/forgejo/database.nix @@ -2,40 +2,31 @@ lib, config, ... -}: { - config = lib.mkIf config.services.forgejo.enable ( - lib.mkMerge [ +}: let + usingPostgres = config.services.forgejo.database.type == "postgres"; +in { + config = lib.mkIf config.services.forgejo.enable { + assertions = [ { - host = { - postgres = { - enable = true; - }; - }; - - assertions = [ - { - assertion = config.services.forgejo.settings.database.DB_TYPE == "postgres"; - message = "Forgejo database type must be postgres"; - } - ]; + assertion = !usingPostgres || config.services.postgresql.enable; + message = "PostgreSQL must be enabled when Forgejo database type is postgres"; } - (lib.mkIf config.host.postgres.enable { - host = { - postgres = { - extraUsers = { - forgejo = { - isClient = true; - createUser = true; - }; - }; - extraDatabases = { - forgejo = { - name = "forgejo"; - }; - }; - }; - }; - }) - ] - ); + { + assertion = !(usingPostgres && config.services.forgejo.database.createDatabase) || (builtins.any (db: db == "forgejo") config.services.postgresql.ensureDatabases); + message = "Forgejo built-in database creation failed - expected 'forgejo' in ensureDatabases but got: ${builtins.toString config.services.postgresql.ensureDatabases}"; + } + { + assertion = !(usingPostgres && config.services.forgejo.database.createDatabase) || (builtins.any (user: user.name == "forgejo") config.services.postgresql.ensureUsers); + message = "Forgejo built-in user creation failed - expected user 'forgejo' in ensureUsers but got: ${builtins.toString (builtins.map (u: u.name) config.services.postgresql.ensureUsers)}"; + } + ]; + + services.forgejo.database.createDatabase = lib.mkDefault usingPostgres; + + systemd.services.forgejo = lib.mkIf usingPostgres { + requires = [ + config.systemd.services.postgresql.name + ]; + }; + }; } diff --git a/modules/nixos-modules/server/home-assistant/database.nix b/modules/nixos-modules/server/home-assistant/database.nix index 0ac8002..f1927ed 100644 --- a/modules/nixos-modules/server/home-assistant/database.nix +++ b/modules/nixos-modules/server/home-assistant/database.nix @@ -2,55 +2,52 @@ lib, config, ... -}: let - dbUser = "hass"; -in { - config = lib.mkIf config.services.home-assistant.enable ( - lib.mkMerge [ +}: { + options.services.home-assistant = { + postgres = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Use PostgreSQL instead of SQLite"; + }; + user = lib.mkOption { + type = lib.types.str; + default = "hass"; + description = "Database user name"; + }; + database = lib.mkOption { + type = lib.types.str; + default = "hass"; + description = "Database name"; + }; + }; + }; + + config = lib.mkIf config.services.home-assistant.enable { + assertions = [ { - host = { - postgres = { - enable = true; - }; - }; - - assertions = [ - { - assertion = config.services.home-assistant.database == "postgres"; - message = "Home Assistant database type must be postgres"; - } - ]; + assertion = !config.services.home-assistant.postgres.enable || config.services.postgresql.enable; + message = "PostgreSQL must be enabled when using postgres database for Home Assistant"; } - (lib.mkIf config.host.postgres.enable { - host = { - postgres = { - extraUsers = { - ${dbUser} = { - isClient = true; - createUser = true; - }; - }; - extraDatabases = { - ${dbUser} = { - name = dbUser; - }; - }; - }; - }; + ]; - services.home-assistant = { - extraPackages = python3Packages: - with python3Packages; [ - psycopg2 - ]; - }; + services.postgresql.databases.home-assistant = lib.mkIf config.services.home-assistant.postgres.enable { + enable = true; + user = config.services.home-assistant.postgres.user; + database = config.services.home-assistant.postgres.database; + }; - systemd.services.home-assistant = { - requires = [ - config.systemd.services.postgresql.name - ]; - }; - }) - ] - ); + services.home-assistant = lib.mkIf config.services.home-assistant.postgres.enable { + extraPackages = python3Packages: + with python3Packages; [ + psycopg2 + ]; + }; + + systemd.services.home-assistant = lib.mkIf config.services.home-assistant.postgres.enable { + requires = [ + config.systemd.services.postgresql.name + ]; + }; + }; } diff --git a/modules/nixos-modules/server/immich/database.nix b/modules/nixos-modules/server/immich/database.nix index 74b1aaa..52af51e 100644 --- a/modules/nixos-modules/server/immich/database.nix +++ b/modules/nixos-modules/server/immich/database.nix @@ -3,24 +3,28 @@ config, ... }: { - config = lib.mkIf config.services.immich.enable (lib.mkMerge [ - { - host = { - postgres = { - enable = true; - }; - }; - } - (lib.mkIf config.host.postgres.enable { - host = { - postgres = { - extraUsers = { - ${config.services.immich.database.user} = { - isClient = true; - }; - }; - }; - }; - }) - ]); + config = lib.mkIf config.services.immich.enable { + assertions = [ + { + assertion = !config.services.immich.database.enable || config.services.postgresql.enable; + message = "PostgreSQL must be enabled when using postgres database for Immich"; + } + { + assertion = !(config.services.immich.database.enable && config.services.immich.database.createDB) || (builtins.any (db: db == "immich") config.services.postgresql.ensureDatabases); + message = "Immich built-in database creation failed - expected 'immich' in ensureDatabases but got: ${builtins.toString config.services.postgresql.ensureDatabases}"; + } + { + assertion = !(config.services.immich.database.enable && config.services.immich.database.createDB) || (builtins.any (user: user.name == "immich") config.services.postgresql.ensureUsers); + message = "Immich built-in user creation failed - expected user 'immich' in ensureUsers but got: ${builtins.toString (builtins.map (u: u.name) config.services.postgresql.ensureUsers)}"; + } + ]; + + # Note: Immich has built-in database creation via services.immich.database.createDB we only add the systemd dependency + + systemd.services.immich-server = lib.mkIf config.services.immich.database.enable { + requires = [ + config.systemd.services.postgresql.name + ]; + }; + }; } diff --git a/modules/nixos-modules/server/panoramax/database.nix b/modules/nixos-modules/server/panoramax/database.nix index 8679f9a..1721726 100644 --- a/modules/nixos-modules/server/panoramax/database.nix +++ b/modules/nixos-modules/server/panoramax/database.nix @@ -3,32 +3,46 @@ config, ... }: { - config = lib.mkIf config.services.panoramax.enable (lib.mkMerge [ - { - host = { - postgres = { - enable = true; + options.services.panoramax = { + database = { + postgres = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Use PostgreSQL instead of SQLite"; + }; + user = lib.mkOption { + type = lib.types.str; + default = "panoramax"; + description = "Database user name"; + }; + database = lib.mkOption { + type = lib.types.str; + default = "panoramax"; + description = "Database name"; }; }; - } - ( - lib.mkIf config.host.postgres.enable { - host = { - postgres = { - extraUsers = { - ${config.services.panoramax.database.user} = { - isClient = true; - createUser = true; - }; - }; - extraDatabases = { - ${config.services.panoramax.database.name} = { - name = config.services.panoramax.database.user; - }; - }; - }; - }; + }; + }; + + config = lib.mkIf config.services.panoramax.enable { + assertions = [ + { + assertion = !config.services.panoramax.database.postgres.enable || config.services.postgresql.enable; + message = "PostgreSQL must be enabled when using postgres database for Panoramax"; } - ) - ]); + ]; + + services.postgresql.databases.panoramax = lib.mkIf config.services.panoramax.database.postgres.enable { + enable = true; + user = config.services.panoramax.database.postgres.user; + database = config.services.panoramax.database.postgres.database; + }; + + systemd.services.panoramax = lib.mkIf config.services.panoramax.database.postgres.enable { + requires = [ + config.systemd.services.postgresql.name + ]; + }; + }; } diff --git a/modules/nixos-modules/server/paperless/database.nix b/modules/nixos-modules/server/paperless/database.nix index 6f4ce51..c63e59d 100644 --- a/modules/nixos-modules/server/paperless/database.nix +++ b/modules/nixos-modules/server/paperless/database.nix @@ -3,32 +3,28 @@ lib, ... }: { - config = lib.mkIf config.services.paperless.enable (lib.mkMerge [ - { - host = { - postgres = { - enable = true; - }; - }; - } - ( - lib.mkIf config.host.postgres.enable { - host = { - postgres = { - extraUsers = { - ${config.services.paperless.database.user} = { - isClient = true; - createUser = true; - }; - }; - extraDatabases = { - ${config.services.paperless.database.user} = { - name = config.services.paperless.database.user; - }; - }; - }; - }; + config = lib.mkIf config.services.paperless.enable { + assertions = [ + { + assertion = !config.services.paperless.database.createLocally || config.services.postgresql.enable; + message = "PostgreSQL must be enabled when using local postgres database for Paperless"; } - ) - ]); + { + assertion = !config.services.paperless.database.createLocally || (builtins.any (db: db == "paperless") config.services.postgresql.ensureDatabases); + message = "Paperless built-in database creation failed - expected 'paperless' in ensureDatabases but got: ${builtins.toString config.services.postgresql.ensureDatabases}"; + } + { + assertion = !config.services.paperless.database.createLocally || (builtins.any (user: user.name == "paperless") config.services.postgresql.ensureUsers); + message = "Paperless built-in user creation failed - expected user 'paperless' in ensureUsers but got: ${builtins.toString (builtins.map (u: u.name) config.services.postgresql.ensureUsers)}"; + } + ]; + + services.paperless.database.createLocally = lib.mkDefault true; + + systemd.services.paperless-scheduler = lib.mkIf config.services.paperless.database.createLocally { + requires = [ + config.systemd.services.postgresql.name + ]; + }; + }; } diff --git a/modules/nixos-modules/server/postgres/impermanence.nix b/modules/nixos-modules/server/postgres/impermanence.nix index 6c2d295..a67fb1a 100644 --- a/modules/nixos-modules/server/postgres/impermanence.nix +++ b/modules/nixos-modules/server/postgres/impermanence.nix @@ -5,7 +5,7 @@ }: let dataDir = "/var/lib/postgresql/16"; in { - config = lib.mkIf (config.host.postgres.enable && config.host.impermanence.enable) { + config = lib.mkIf (config.services.postgresql.enable && config.host.impermanence.enable) { assertions = [ { assertion = config.services.postgresql.dataDir == dataDir; diff --git a/modules/nixos-modules/server/postgres/postgres.nix b/modules/nixos-modules/server/postgres/postgres.nix index e76857c..af7d1b4 100644 --- a/modules/nixos-modules/server/postgres/postgres.nix +++ b/modules/nixos-modules/server/postgres/postgres.nix @@ -4,70 +4,94 @@ pkgs, ... }: let - adminUsers = lib.lists.filter (user: user.isAdmin) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); - clientUsers = lib.lists.filter (user: user.isClient) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); - createUsers = lib.lists.filter (user: user.createUser) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers); - createDatabases = lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraDatabases; + enabledDatabases = lib.filterAttrs (_: db: db.enable) config.services.postgresql.databases; + extraDatabasesList = config.services.postgresql.extraDatabases; + + serviceDatabaseUsers = lib.mapAttrsToList (_: db: { + name = db.user; + ensureDBOwnership = true; + }) (lib.filterAttrs (_: db: db.ensureUser) enabledDatabases); + + extraDatabaseUsers = + builtins.map (dbName: { + name = dbName; + ensureDBOwnership = true; + }) + extraDatabasesList; + + serviceDatabases = lib.mapAttrsToList (_: db: db.database) enabledDatabases; + extraDatabaseNames = extraDatabasesList; + + serviceUserMappings = lib.mapAttrsToList (_: db: "user_map ${db.user} ${db.user}") enabledDatabases; + extraUserMappings = builtins.map (dbName: "user_map ${dbName} ${dbName}") extraDatabasesList; + + builtinServiceMappings = let + forgejoMapping = lib.optional (config.services.forgejo.enable && config.services.forgejo.database.type == "postgres") "user_map forgejo forgejo"; + immichMapping = lib.optional (config.services.immich.enable && config.services.immich.database.enable) "user_map immich immich"; + paperlessMapping = lib.optional (config.services.paperless.enable && config.services.paperless.database.createLocally) "user_map paperless paperless"; + in + forgejoMapping ++ immichMapping ++ paperlessMapping; in { options = { - host.postgres = { - enable = lib.mkEnableOption "enable postgres"; - extraUsers = lib.mkOption { + services.postgresql = { + databases = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { options = { - name = lib.mkOption { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Whether to create this database and user"; + }; + user = lib.mkOption { type = lib.types.str; default = name; + description = "Database user name"; }; - isAdmin = lib.mkOption { - type = lib.types.bool; - default = false; + database = lib.mkOption { + type = lib.types.str; + default = name; + description = "Database name"; }; - isClient = lib.mkOption { + ensureUser = lib.mkOption { type = lib.types.bool; - default = false; - }; - createUser = lib.mkOption { - type = lib.types.bool; - default = false; + default = true; + description = "Whether to ensure the user exists"; }; }; })); default = {}; + description = "Databases to create for services"; }; + extraDatabases = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { - options = { - name = lib.mkOption { - type = lib.types.str; - default = name; - }; - }; - })); - default = {}; + type = lib.types.listOf lib.types.str; + default = []; + description = "Additional databases to create (user name will match database name)"; + example = ["custom_db" "test_db"]; + }; + + adminUsers = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + description = "System users who should have PostgreSQL superuser access"; + example = ["leyla" "admin"]; }; }; }; - config = lib.mkIf config.host.postgres.enable { + config = lib.mkIf config.services.postgresql.enable { services = { postgresql = { - enable = true; package = pkgs.postgresql_16; + ensureUsers = [ - { - name = "postgres"; - } + {name = "postgres";} ] - ++ ( - builtins.map (user: { - name = user.name; - ensureDBOwnership = true; - }) - createUsers - ); - ensureDatabases = builtins.map (database: database.name) createDatabases; + ++ serviceDatabaseUsers ++ extraDatabaseUsers; + + ensureDatabases = serviceDatabases ++ extraDatabaseNames; + identMap = '' # ArbitraryMapName systemUser DBUser @@ -77,16 +101,16 @@ in { superuser_map postgres postgres '' + ( - lib.strings.concatLines (builtins.map (user: "superuser_map ${user.name} postgres") adminUsers) + lib.strings.concatLines (builtins.map (user: "superuser_map ${user} postgres") config.services.postgresql.adminUsers) ) + '' # Client Users '' + ( - lib.strings.concatLines (builtins.map (user: "user_map ${user.name} ${user.name}") clientUsers) + lib.strings.concatLines (serviceUserMappings ++ extraUserMappings ++ builtinServiceMappings) ); - # configuration here lets users access the db that matches their name and lets user postgres access everything + authentication = pkgs.lib.mkOverride 10 '' # type database DBuser origin-address auth-method optional_ident_map local all postgres peer map=superuser_map From 69ccbffd86992895196013fbf737ead6a8adfe7c Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 27 Oct 2025 11:02:42 -0500 Subject: [PATCH 31/61] chore: removed incorrect task --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index d3a2121..883e143 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,6 @@ nix multi user, multi system, configuration with `sops` secret management, `home ## Chores: - [ ] test out crab hole service -- [ ] qbittorent should be downloading to `rpool/persist/system/qbittorrent` or maybe even `rpool/persist/system/jellyfin` but right now its downloading to `rpool/persist/system/root` this should be fixed ## Tech Debt - [ ] monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/) From c0e2e7ba4a6294033a45685d758f31bd2651d2b6 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Thu, 30 Oct 2025 17:43:52 -0500 Subject: [PATCH 32/61] feat: updated flake.lock --- flake.lock | 36 +++++++++---------- .../common-modules/pkgs/polycule/default.nix | 4 +-- .../programs/bitwarden.nix | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/flake.lock b/flake.lock index 11fb672..ae03c48 100644 --- a/flake.lock +++ b/flake.lock @@ -46,11 +46,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1761478231, - "narHash": "sha256-a6ROM73M0TSrooI+8/UMj5KWKOdaDFTycVeo8XJ3dk4=", + "lastModified": 1761797037, + "narHash": "sha256-OqwAGit+3cdsG02K6+8WJniA2q0rqUVc6zbT5N9C1us=", "owner": "rycee", "repo": "nur-expressions", - "rev": "ae968708476302f8781fb5e245d53f112ed04111", + "rev": "3d9f4de0988bcfa57e45e16e1ef9326c56bdf891", "type": "gitlab" }, "original": { @@ -62,11 +62,11 @@ }, "flake-compat": { "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "lastModified": 1761588595, + "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", "owner": "edolstra", "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", "type": "github" }, "original": { @@ -133,11 +133,11 @@ ] }, "locked": { - "lastModified": 1761530345, - "narHash": "sha256-+9+YCK9Lh6GThkXu/8JTxMFUnImIdZpb8ElUh6/F5Y8=", + "lastModified": 1761845621, + "narHash": "sha256-d+R4MHsGmdebvSMsYUFWONsZSlUbOo8Zq/wjMdMiIac=", "owner": "nix-community", "repo": "home-manager", - "rev": "bbaeb9f1c29e79bb1653b32c3d73244cdf4bd888", + "rev": "97e3022a8d2c09313fa49847f6da4d76abcfc72d", "type": "github" }, "original": { @@ -268,11 +268,11 @@ ] }, "locked": { - "lastModified": 1761530505, - "narHash": "sha256-SbuUyC5pfTcMa9JUqSxFyGJpCqoUsB74tboS22+lByY=", + "lastModified": 1761789484, + "narHash": "sha256-17gDUWloFXQlavqHRey/urQe6sQ3yP5hsQyYmcNOZyU=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "5a5496a7d21265e0ce7641452daf6c560f0eb7a9", + "rev": "c47e683d236fa6e4c27dbda2af3468cb9aceb813", "type": "github" }, "original": { @@ -283,11 +283,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1760958188, - "narHash": "sha256-2m1S4jl+GEDtlt2QqeHil8Ny456dcGSKJAM7q3j/BFU=", + "lastModified": 1761827175, + "narHash": "sha256-XdPVSYyIBK4/ruoqujaQmmSGg3J2/EenexV9IEXhr6o=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "d6645c340ef7d821602fd2cd199e8d1eed10afbc", + "rev": "43ffe9ac82567512abb83187cb673de1091bdfa8", "type": "github" }, "original": { @@ -315,11 +315,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1761373498, - "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=", + "lastModified": 1761672384, + "narHash": "sha256-o9KF3DJL7g7iYMZq9SWgfS1BFlNbsm6xplRjVlOCkXI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce", + "rev": "08dacfca559e1d7da38f3cf05f1f45ee9bfd213c", "type": "github" }, "original": { diff --git a/modules/common-modules/pkgs/polycule/default.nix b/modules/common-modules/pkgs/polycule/default.nix index b463cc5..e9841fe 100644 --- a/modules/common-modules/pkgs/polycule/default.nix +++ b/modules/common-modules/pkgs/polycule/default.nix @@ -3,7 +3,7 @@ flutter332, fetchFromGitLab, pkg-config, - wrapGAppsHook, + wrapGAppsHook3, gtk3, glib, glib-networking, @@ -65,7 +65,7 @@ flutter332.buildFlutterApplication rec { nativeBuildInputs = [ pkg-config - wrapGAppsHook + wrapGAppsHook3 ]; buildInputs = [ diff --git a/modules/home-manager-modules/programs/bitwarden.nix b/modules/home-manager-modules/programs/bitwarden.nix index 5c14068..e305b6c 100644 --- a/modules/home-manager-modules/programs/bitwarden.nix +++ b/modules/home-manager-modules/programs/bitwarden.nix @@ -11,7 +11,7 @@ config = lib.mkIf config.programs.bitwarden.enable (lib.mkMerge [ { home.packages = with pkgs; [ - bitwarden + bitwarden-desktop ]; } ( From e1a5ddde95472de74219a40592dd746c9efa704d Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Thu, 30 Oct 2025 22:28:02 -0500 Subject: [PATCH 33/61] feat: added storj to README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 883e143..dc12d35 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] Create Tor guard/relay server - [ ] mastodon instance - [ ] screeps server +- [ ] storj server ## DevOps - [ ] wake on LAN for updates From bfe774b74ccf604029f9e2b9870b7eee096069b5 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 31 Oct 2025 17:08:28 -0500 Subject: [PATCH 34/61] added --vm flag to rebuild --- .gitignore | 3 ++- rebuild.sh | 68 ++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index ce2538f..2810727 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ result .direnv .vscode/* -!.vscode/settings.json \ No newline at end of file +!.vscode/settings.json +nixos.qcow2 diff --git a/rebuild.sh b/rebuild.sh index 6750450..48746d9 100755 --- a/rebuild.sh +++ b/rebuild.sh @@ -18,6 +18,7 @@ else fi show_trace=false +clean_vm=false while [ $# -gt 0 ]; do case "$1" in @@ -50,6 +51,9 @@ while [ $# -gt 0 ]; do --show-trace) show_trace=true ;; + --clean-vm) + clean_vm=true + ;; --help|-h) echo "--help -h: print this message" echo "--target -t: defaults to the current system" @@ -58,6 +62,8 @@ while [ $# -gt 0 ]; do echo " currently: ${target:-$default_target}" echo "--mode -m: defaults to 'switch', but 'test' on non-main branches" echo " currently would be: $default_mode" + echo " Available modes: switch, test, build, boot, vm" + echo " 'vm' mode builds and starts a virtual machine" echo "--user -u: defaults to the current user" echo " currently: $default_user" echo "--host: defaults to building on the current machine" @@ -65,6 +71,7 @@ while [ $# -gt 0 ]; do echo "--preserve-result: do not remove the generated result folder after building" echo "--no-preserve-result: remove any result folder after building" echo "--show-trace: show trace on builds" + echo "--clean-vm: remove existing VM disk (nixos.qcow2) before building" echo "" echo "Branch-aware behavior:" echo " - On non-main branches: defaults to test mode with warning" @@ -90,6 +97,20 @@ flake=${flake:-$target} mode=${mode:-$default_mode} user=${user:-$default_user} +# Validate mode +valid_modes="switch test build boot vm" +if [[ ! " $valid_modes " =~ " $mode " ]]; then + echo "Error: Invalid mode '$mode'" + echo "Valid modes are: $valid_modes" + exit 1 +fi + +# Clean VM disk if requested +if [[ "$clean_vm" = true ]] && [[ -f "nixos.qcow2" ]]; then + echo "Removing existing VM disk: nixos.qcow2" + rm nixos.qcow2 +fi + # Branch-aware warnings and behavior if [[ "$current_branch" != "main" ]] && [[ "$mode" == "test" ]]; then echo "⚠️ WARNING: You are on branch '$current_branch' (not main)" @@ -101,26 +122,39 @@ elif [[ "$current_branch" == "main" ]] && [[ -n "$git_status" ]] && [[ "$mode" ! echo " git checkout -b feature/your-feature-name" fi -command="nixos-rebuild $mode --sudo --ask-sudo-password --flake .#$flake" +if [[ "$mode" == "vm" ]]; then + command="nix build .#nixosConfigurations.$flake.config.system.build.vm" + + if [[ "$show_trace" = true ]]; then + command="$command --show-trace" + fi + + echo $command + $command + + if [[ $? -eq 0 ]] && [[ -d "result" ]]; then + echo "Starting VM..." + QEMU_KERNEL_PARAMS=console=ttyS0 ./result/bin/run-nixos-vm -nographic; reset + fi +else + command="nixos-rebuild $mode --sudo --ask-sudo-password --flake .#$flake" + + if [[ $host ]]; then + command="$command --build-host $host" + fi -if [[ $host ]]; -then - command="$command --build-host $host" + if [[ "$target" != "$(hostname)" ]]; then + command="$command --target-host $user@$target" + fi + + if [[ "$show_trace" = true ]]; then + command="$command --show-trace" + fi + + echo $command + $command fi -if [[ "$target" != "$(hostname)" ]]; -then - command="$command --target-host $user@$target" -fi - -if [[ "$show_trace" = true ]]; -then - command="$command --show-trace" -fi - -echo $command -$command - if [ -d "result" ]; then if [[ "$preserve_result" == "false" ]]; From dfeac5585f95fd4f07a164e9002cca3b5527f3be Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 31 Oct 2025 17:29:34 -0500 Subject: [PATCH 35/61] chore: added task to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index dc12d35..ba6bfc2 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home ## Tech Debt - [ ] monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/) - [ ] migrate away from flakes and move to npins +- [ ] `host.users` should be redone so that we just extend the base `users.users` object. Right now we cant quite do this because we have weird circular dependencies with disko/impermanence (not sure which one) and home manger enabling/disabling users per devices ## Broken things - [ ] figure out steam vr things? @@ -65,6 +66,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] rotate sops encryption keys periodically (and somehow sync between devices?) - [ ] Secure Boot - https://github.com/nix-community/lanzaboote - [ ] auto turn off on power loss - nut +- [ ] every service needs to have its own data pool - [ ] secondary server with data sync. Maybe a Pi with a usb hdd enclosure and use rtcwake to only turn on once a week to sync data over tailscale with connection initiated from pi's side. We could probably put this at LZ. Hoping for it to draw only like $1 of power a month. Initial sync should probably be done here before we move it over because that will take a while. Data should be encrypted so that devices doesn't have access to it. Project will prob cost like $1800 ## Data Access From c6b129726d772900d459824979697d7d5eb19e99 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 31 Oct 2025 17:45:26 -0500 Subject: [PATCH 36/61] chore: added task to README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ba6bfc2..08c689f 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] figure out why syncthing and jellyfins permissions don't propagate downwards - [ ] make radarr, sonarr, and bazarr accessible over vpn - [ ] move searx, home-assistant, actual, vikunja, jellyfin, paperless, and immich to only be accessible via vpn +- [ ] FreeIPA/SSSD/LDAP/Kerberos to manage uid and gid's ## Services - [ ] vikunja service for project management From 34e8cf44058080b3a8532005ab05f026917fc598 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 31 Oct 2025 19:37:59 -0500 Subject: [PATCH 37/61] chore: reorganized some tasks in TODO --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 08c689f..2a53e24 100644 --- a/README.md +++ b/README.md @@ -82,10 +82,10 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] vikunja service for project management - [ ] Penpot services (need to make this custom) - [ ] minecraft server with old world file -- [ ] Create Tor guard/relay server -- [ ] mastodon instance -- [ ] screeps server - [ ] storj server +- [ ] Create Tor guard/relay server +- [ ] screeps server +- [ ] mastodon instance ## DevOps - [ ] wake on LAN for updates From 353ae4b87498c2f2b8a406d9c89992427e63edb8 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 31 Oct 2025 19:49:10 -0500 Subject: [PATCH 38/61] chore: added more description to task in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a53e24..f1b559c 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] samba mounts - [ ] offline access for nfs mounts (overlay with rsync might be a good option here? https://www.spinics.net/lists/linux-unionfs/msg07105.html note about nfs4 and overlay fs) - [ ] figure out why syncthing and jellyfins permissions don't propagate downwards -- [ ] make radarr, sonarr, and bazarr accessible over vpn +- [ ] make radarr, sonarr, and bazarr accessible over vpn with fully qualified names via reverse proxy - [ ] move searx, home-assistant, actual, vikunja, jellyfin, paperless, and immich to only be accessible via vpn - [ ] FreeIPA/SSSD/LDAP/Kerberos to manage uid and gid's From 4f16a0cf996c9bd5874450db38ec74a1bced548a Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 31 Oct 2025 21:47:30 -0500 Subject: [PATCH 39/61] chore: created nodes for impermanence module --- modules/nixos-modules/impermanence.nix | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/modules/nixos-modules/impermanence.nix b/modules/nixos-modules/impermanence.nix index 7735e97..60011cb 100644 --- a/modules/nixos-modules/impermanence.nix +++ b/modules/nixos-modules/impermanence.nix @@ -3,6 +3,39 @@ lib, ... }: { + # options.storage = { + # zfs = { + # # TODO: enable option + # # when this option is enabled we need to configure and enable disko things + + # # TODO: we need some way of managing notifications + + # # TODO: we need options to configure zfs pools + # # we should have warnings when the configured pool is missing drives + + # # TODO: dataset option that is a submodule that adds datasets to the system + # # warnings for when a dataset was created in the past on a system but it is now missing some of the options defined for it + + # # TODO: pools and datasets need to be passed to disko + # }; + + # impermanence = { + # # TODO: enable option + + # # TODO: datasets option that is a submodule that will be used to define what datasets to add to the storage system + # # We should by default create the `local`, `local/system/nix`, `local/system/root`, `persist` `persist/system/root`, and `persist/system/var/log` datasets + # # Then we should make a dataset for user folders local and persist + # # We should also create datasets for systemd modules that have have impermanence enabled for them + # # we need to figure out what options a dataset can have in zfs + # }; + + # # TODO: we should have an impermanence module for home manager that proxies its values namespaced to the user down here that matches the same interface + + # # TODO: we should have a way of enabling impermanence for a systemd config + # # these should have an option to put their folder into their own dataset (this needs to support private vs non private) + # # options for features that can be added to the dataset + # }; + options.host.impermanence.enable = lib.mkEnableOption "are we going to use impermanence on this device"; config = lib.mkMerge [ @@ -93,6 +126,7 @@ ]; }; + # TODO: this should live in leylas home manager configuration security.sudo.extraConfig = "Defaults lecture=never"; } ) From 0d6f82f29e7341122bff2d44bf51109b4c14d458 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Mon, 3 Nov 2025 20:04:36 -0600 Subject: [PATCH 40/61] build: updated flake.lock --- flake.lock | 58 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/flake.lock b/flake.lock index ae03c48..6a4736b 100644 --- a/flake.lock +++ b/flake.lock @@ -25,11 +25,11 @@ ] }, "locked": { - "lastModified": 1760701190, - "narHash": "sha256-y7UhnWlER8r776JsySqsbTUh2Txf7K30smfHlqdaIQw=", + "lastModified": 1761899396, + "narHash": "sha256-XOpKBp6HLzzMCbzW50TEuXN35zN5WGQREC7n34DcNMM=", "owner": "nix-community", "repo": "disko", - "rev": "3a9450b26e69dcb6f8de6e2b07b3fc1c288d85f5", + "rev": "6f4cf5abbe318e4cd1e879506f6eeafd83f7b998", "type": "github" }, "original": { @@ -46,11 +46,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1761797037, - "narHash": "sha256-OqwAGit+3cdsG02K6+8WJniA2q0rqUVc6zbT5N9C1us=", + "lastModified": 1762162438, + "narHash": "sha256-GPnRGcVck+TPiQl6Rqj0i57c8hAa34RsQWVqQAW0OVY=", "owner": "rycee", "repo": "nur-expressions", - "rev": "3d9f4de0988bcfa57e45e16e1ef9326c56bdf891", + "rev": "2cf91d46e558b29f9f9bbdd23408f62e8423aa00", "type": "gitlab" }, "original": { @@ -133,11 +133,11 @@ ] }, "locked": { - "lastModified": 1761845621, - "narHash": "sha256-d+R4MHsGmdebvSMsYUFWONsZSlUbOo8Zq/wjMdMiIac=", + "lastModified": 1762183399, + "narHash": "sha256-vr2aL1QLfERYTfYBgK8cW3T9eSdSEThH462wKaGlmEU=", "owner": "nix-community", "repo": "home-manager", - "rev": "97e3022a8d2c09313fa49847f6da4d76abcfc72d", + "rev": "a5fee077929ae2f2800c3087dce5e1abb4edfbc6", "type": "github" }, "original": { @@ -164,11 +164,11 @@ "lix": { "flake": false, "locked": { - "lastModified": 1755787066, - "narHash": "sha256-X2UwkUEban08GRSPXRr+kz8fckHqebr3P77qSvjoeOw=", - "rev": "ac9721a92e8138d29707824dbedb484c76948493", + "lastModified": 1761937274, + "narHash": "sha256-KlELhsSq3XbemrGyQhmGurFu7m8wOEBw+8M04L7hn7A=", + "rev": "91867941fa73afea7869b7c71ede82e5ef8927da", "type": "tarball", - "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/ac9721a92e8138d29707824dbedb484c76948493.tar.gz?rev=ac9721a92e8138d29707824dbedb484c76948493" + "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/91867941fa73afea7869b7c71ede82e5ef8927da.tar.gz?rev=91867941fa73afea7869b7c71ede82e5ef8927da" }, "original": { "type": "tarball", @@ -185,11 +185,11 @@ ] }, "locked": { - "lastModified": 1759851320, - "narHash": "sha256-n5dRAIC3/78drQtFxmQRrBLd6TKfotUnX7GWu0mAcSg=", + "lastModified": 1761960361, + "narHash": "sha256-FvuAw56NIVJpS3Kr8Wv9PpU4eehZMcdIVkxjStuYmqc=", "ref": "refs/heads/main", - "rev": "7c31a18259b8358ac196cf803a26967c0fa1d3e4", - "revCount": 163, + "rev": "c47f62187601ea2991b79a9bacdbfdf76cd29fbe", + "revCount": 167, "type": "git", "url": "https://git.lix.systems/lix-project/nixos-module.git" }, @@ -227,11 +227,11 @@ ] }, "locked": { - "lastModified": 1761339987, - "narHash": "sha256-IUaawVwItZKi64IA6kF6wQCLCzpXbk2R46dHn8sHkig=", + "lastModified": 1762186368, + "narHash": "sha256-dzLBZKccS0jMefj+WAYwsk7gKDluqavC7I4KfFwVh8k=", "owner": "LnL7", "repo": "nix-darwin", - "rev": "7cd9aac79ee2924a85c211d21fafd394b06a38de", + "rev": "69921864a70b58787abf5ba189095566c3f0ffd3", "type": "github" }, "original": { @@ -268,11 +268,11 @@ ] }, "locked": { - "lastModified": 1761789484, - "narHash": "sha256-17gDUWloFXQlavqHRey/urQe6sQ3yP5hsQyYmcNOZyU=", + "lastModified": 1762135163, + "narHash": "sha256-gP8SCvsYSfi4olYZcrZ4P1IGMzYJSFe1FuO8RL3xpEc=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "c47e683d236fa6e4c27dbda2af3468cb9aceb813", + "rev": "5d6525e4d5372973da1777b9ebdb01f033db1395", "type": "github" }, "original": { @@ -283,11 +283,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1761827175, - "narHash": "sha256-XdPVSYyIBK4/ruoqujaQmmSGg3J2/EenexV9IEXhr6o=", + "lastModified": 1762179181, + "narHash": "sha256-T4+TNfXlF/gHbcNCC2HY7sMGBKgqNzyYeMBWmcbH7/o=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "43ffe9ac82567512abb83187cb673de1091bdfa8", + "rev": "256770618502d2eda892af3ae91da5e386ce9586", "type": "github" }, "original": { @@ -315,11 +315,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1761672384, - "narHash": "sha256-o9KF3DJL7g7iYMZq9SWgfS1BFlNbsm6xplRjVlOCkXI=", + "lastModified": 1762111121, + "narHash": "sha256-4vhDuZ7OZaZmKKrnDpxLZZpGIJvAeMtK6FKLJYUtAdw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "08dacfca559e1d7da38f3cf05f1f45ee9bfd213c", + "rev": "b3d51a0365f6695e7dd5cdf3e180604530ed33b4", "type": "github" }, "original": { From f5b026bb15dd12b52611bf322f589d843210de91 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Tue, 4 Nov 2025 18:05:31 -0600 Subject: [PATCH 41/61] chore: added task to README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f1b559c..2d6911b 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] FreeIPA/SSSD/LDAP/Kerberos to manage uid and gid's ## Services +- [ ] ntfy service for unified push - [ ] vikunja service for project management - [ ] Penpot services (need to make this custom) - [ ] minecraft server with old world file From 1b4d0596335f140e252b6f0d6130e4e4d2a894a0 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Wed, 5 Nov 2025 18:37:26 -0600 Subject: [PATCH 42/61] feat: removed polycule application --- .../home-manager/leyla/packages/default.nix | 2 - modules/common-modules/pkgs/default.nix | 3 - .../common-modules/pkgs/polycule/default.nix | 149 - .../pkgs/polycule/polycule-pubspec.lock.json | 2459 ----------------- .../home-manager-modules/programs/default.nix | 1 - .../programs/polycule.nix | 31 - 6 files changed, 2645 deletions(-) delete mode 100644 modules/common-modules/pkgs/polycule/default.nix delete mode 100644 modules/common-modules/pkgs/polycule/polycule-pubspec.lock.json delete mode 100644 modules/home-manager-modules/programs/polycule.nix diff --git a/configurations/home-manager/leyla/packages/default.nix b/configurations/home-manager/leyla/packages/default.nix index 50cc175..d065739 100644 --- a/configurations/home-manager/leyla/packages/default.nix +++ b/configurations/home-manager/leyla/packages/default.nix @@ -70,8 +70,6 @@ in { noisetorch.enable = true; tor-browser.enable = true; gdx-liftoff.enable = true; - # polycule package is now working with Flutter 3.29 - polycule.enable = true; }) ]; } diff --git a/modules/common-modules/pkgs/default.nix b/modules/common-modules/pkgs/default.nix index a2f61b1..c97f97c 100644 --- a/modules/common-modules/pkgs/default.nix +++ b/modules/common-modules/pkgs/default.nix @@ -38,8 +38,5 @@ # Override h3 C library to version 4.3.0 h3 = pkgs.callPackage ./h3-c-lib.nix {}; }) - (final: prev: { - polycule = pkgs.callPackage ./polycule {}; - }) ]; } diff --git a/modules/common-modules/pkgs/polycule/default.nix b/modules/common-modules/pkgs/polycule/default.nix deleted file mode 100644 index e9841fe..0000000 --- a/modules/common-modules/pkgs/polycule/default.nix +++ /dev/null @@ -1,149 +0,0 @@ -{ - lib, - flutter332, - fetchFromGitLab, - pkg-config, - wrapGAppsHook3, - gtk3, - glib, - glib-networking, - webkitgtk_4_1, - libsecret, - libnotify, - dbus, - sqlcipher, - openssl, - mpv, - alsa-lib, - libass, - ffmpeg-full, - libplacebo, - libunwind, - shaderc, - vulkan-headers, - vulkan-loader, - lcms2, - libdovi, - libdvdnav, - libdvdread, - mujs, - libbluray, - lua, - rubberband, - libuchardet, - zimg, - openal, - pipewire, - libpulseaudio, - libcaca, - libdrm, - libdisplay-info, - libgbm, - xorg, - nv-codec-headers-11, - libva, - libvdpau, -}: -flutter332.buildFlutterApplication rec { - pname = "polycule"; - version = "0.3.4"; - - src = fetchFromGitLab { - owner = "polycule_client"; - repo = "polycule"; - rev = "v${version}"; - hash = "sha256-RUu8DKuX2NUU5Ce5WLHtDaORkn7CSrgTj3KhM/z+yHc="; - }; - - pubspecLock = lib.importJSON ./polycule-pubspec.lock.json; - - gitHashes = { - matrix = "sha256-w/QB5nYJ9Lh77TcYKEN/DnNQjWfp+9NX0dwQ9GOzWE8="; - media_kit = "sha256-1sVX+aHFLFJBtrNZrR6tWkb80vFELW2N9EejyQKlBPg="; - media_kit_libs_android_video = "sha256-N6QoktM8u9NYF8MAXLsxM9RlV8nICM4NbnmABHTRkZg="; - }; - - nativeBuildInputs = [ - pkg-config - wrapGAppsHook3 - ]; - - buildInputs = [ - gtk3 - glib - glib-networking - webkitgtk_4_1 - libsecret - libnotify - dbus - sqlcipher - openssl - mpv - alsa-lib - libass - ffmpeg-full - libplacebo - libunwind - shaderc - vulkan-headers - vulkan-loader - lcms2 - libdovi - libdvdnav - libdvdread - mujs - libbluray - lua - rubberband - libuchardet - zimg - openal - pipewire - libpulseaudio - libcaca - libdrm - libdisplay-info - libgbm - xorg.libXScrnSaver - xorg.libXpresent - nv-codec-headers-11 - libva - libvdpau - ]; - - flutterBuildFlags = [ - "--release" - "--target" - "lib/main.dart" - "--dart-define=POLYCULE_VERSION=v${version}" - "--dart-define=POLYCULE_IS_STABLE=true" - "--no-tree-shake-icons" - ]; - - postInstall = '' - # Install desktop files and icons from the source - install -Dm644 linux/business.braid.polycule.desktop $out/share/applications/polycule.desktop - install -Dm644 assets/logo/logo-circle.png $out/share/pixmaps/polycule.png - - # Update desktop file to use correct executable name - substituteInPlace $out/share/applications/polycule.desktop \ - --replace 'Exec=business.braid.polycule' 'Exec=polycule' - - # Create a symlink with the expected name - ln -sf $out/bin/polycule $out/bin/business.braid.polycule - ''; - - meta = with lib; { - description = "A geeky and efficient [matrix] client for power users"; - longDescription = '' - Polycule is a modern Matrix client built with Flutter, designed for power users - who want a fast, efficient, and feature-rich Matrix experience. - ''; - homepage = "https://polycule.im/"; - license = licenses.eupl12; - maintainers = []; - platforms = ["x86_64-linux" "aarch64-linux"]; - sourceProvenance = with sourceTypes; [fromSource]; - mainProgram = "polycule"; - }; -} diff --git a/modules/common-modules/pkgs/polycule/polycule-pubspec.lock.json b/modules/common-modules/pkgs/polycule/polycule-pubspec.lock.json deleted file mode 100644 index e119fa2..0000000 --- a/modules/common-modules/pkgs/polycule/polycule-pubspec.lock.json +++ /dev/null @@ -1,2459 +0,0 @@ -{ - "packages": { - "_fe_analyzer_shared": { - "dependency": "transitive", - "description": { - "name": "_fe_analyzer_shared", - "sha256": "da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "85.0.0" - }, - "analyzer": { - "dependency": "transitive", - "description": { - "name": "analyzer", - "sha256": "974859dc0ff5f37bc4313244b3218c791810d03ab3470a579580279ba971a48d", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "7.7.1" - }, - "animations": { - "dependency": "direct main", - "description": { - "name": "animations", - "sha256": "d3d6dcfb218225bbe68e87ccf6378bbb2e32a94900722c5f81611dad089911cb", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.11" - }, - "app_links": { - "dependency": "direct main", - "description": { - "name": "app_links", - "sha256": "85ed8fc1d25a76475914fff28cc994653bd900bc2c26e4b57a49e097febb54ba", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.4.0" - }, - "app_links_linux": { - "dependency": "transitive", - "description": { - "name": "app_links_linux", - "sha256": "f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.3" - }, - "app_links_platform_interface": { - "dependency": "transitive", - "description": { - "name": "app_links_platform_interface", - "sha256": "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.2" - }, - "app_links_web": { - "dependency": "transitive", - "description": { - "name": "app_links_web", - "sha256": "af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.4" - }, - "archive": { - "dependency": "transitive", - "description": { - "name": "archive", - "sha256": "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.0.7" - }, - "args": { - "dependency": "transitive", - "description": { - "name": "args", - "sha256": "d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.7.0" - }, - "async": { - "dependency": "direct main", - "description": { - "name": "async", - "sha256": "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.13.0" - }, - "audio_session": { - "dependency": "transitive", - "description": { - "name": "audio_session", - "sha256": "8f96a7fecbb718cb093070f868b4cdcb8a9b1053dce342ff8ab2fde10eb9afb7", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.2" - }, - "barcode": { - "dependency": "transitive", - "description": { - "name": "barcode", - "sha256": "7b6729c37e3b7f34233e2318d866e8c48ddb46c1f7ad01ff7bb2a8de1da2b9f4", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.2.9" - }, - "barcode_widget": { - "dependency": "direct main", - "description": { - "name": "barcode_widget", - "sha256": "6f2c5b08659b1a5f4d88d183e6007133ea2f96e50e7b8bb628f03266c3931427", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.4" - }, - "base58check": { - "dependency": "transitive", - "description": { - "name": "base58check", - "sha256": "6c300dfc33e598d2fe26319e13f6243fea81eaf8204cb4c6b69ef20a625319a5", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.0" - }, - "blurhash_dart": { - "dependency": "direct main", - "description": { - "name": "blurhash_dart", - "sha256": "43955b6c2e30a7d440028d1af0fa185852f3534b795cc6eb81fbf397b464409f", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.2.1" - }, - "boolean_selector": { - "dependency": "transitive", - "description": { - "name": "boolean_selector", - "sha256": "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.2" - }, - "build_cli_annotations": { - "dependency": "transitive", - "description": { - "name": "build_cli_annotations", - "sha256": "b59d2769769efd6c9ff6d4c4cede0be115a566afc591705c2040b707534b1172", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.0" - }, - "camera": { - "dependency": "transitive", - "description": { - "name": "camera", - "sha256": "d6ec2cbdbe2fa8f5e0d07d8c06368fe4effa985a4a5ddade9cc58a8cd849557d", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.11.2" - }, - "camera_android_camerax": { - "dependency": "transitive", - "description": { - "name": "camera_android_camerax", - "sha256": "58b8fe843a3c83fd1273c00cb35f5a8ae507f6cc9b2029bcf7e2abba499e28d8", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.6.19+1" - }, - "camera_avfoundation": { - "dependency": "transitive", - "description": { - "name": "camera_avfoundation", - "sha256": "e4aca5bccaf897b70cac87e5fdd789393310985202442837922fd40325e2733b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.9.21+1" - }, - "camera_platform_interface": { - "dependency": "transitive", - "description": { - "name": "camera_platform_interface", - "sha256": "2f757024a48696ff4814a789b0bd90f5660c0fb25f393ab4564fb483327930e2", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.10.0" - }, - "camera_web": { - "dependency": "transitive", - "description": { - "name": "camera_web", - "sha256": "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.3.5" - }, - "canonical_json": { - "dependency": "transitive", - "description": { - "name": "canonical_json", - "sha256": "d6be1dd66b420c6ac9f42e3693e09edf4ff6edfee26cb4c28c1c019fdb8c0c15", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.2" - }, - "characters": { - "dependency": "transitive", - "description": { - "name": "characters", - "sha256": "f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.4.0" - }, - "checked_yaml": { - "dependency": "transitive", - "description": { - "name": "checked_yaml", - "sha256": "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.4" - }, - "cli_config": { - "dependency": "transitive", - "description": { - "name": "cli_config", - "sha256": "ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.0" - }, - "cli_util": { - "dependency": "transitive", - "description": { - "name": "cli_util", - "sha256": "ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.4.2" - }, - "clock": { - "dependency": "transitive", - "description": { - "name": "clock", - "sha256": "fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.2" - }, - "collection": { - "dependency": "direct main", - "description": { - "name": "collection", - "sha256": "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.19.1" - }, - "convert": { - "dependency": "transitive", - "description": { - "name": "convert", - "sha256": "b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.1.2" - }, - "coverage": { - "dependency": "transitive", - "description": { - "name": "coverage", - "sha256": "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.15.0" - }, - "cross_file": { - "dependency": "direct main", - "description": { - "name": "cross_file", - "sha256": "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.3.4+2" - }, - "crypto": { - "dependency": "transitive", - "description": { - "name": "crypto", - "sha256": "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.6" - }, - "csslib": { - "dependency": "direct main", - "description": { - "name": "csslib", - "sha256": "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.2" - }, - "cupertino_http": { - "dependency": "direct main", - "description": { - "name": "cupertino_http", - "sha256": "72187f715837290a63479a5b0ae709f4fedad0ed6bd0441c275eceaa02d5abae", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.3.0" - }, - "cupertino_icons": { - "dependency": "direct main", - "description": { - "name": "cupertino_icons", - "sha256": "ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.8" - }, - "dart_animated_emoji": { - "dependency": "direct main", - "description": { - "name": "dart_animated_emoji", - "sha256": "0e0865f1b56e2f2979e8caa09a7d693e30133050c5c677de301e6ca4d8da945e", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.1.2" - }, - "dbus": { - "dependency": "direct main", - "description": { - "name": "dbus", - "sha256": "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.7.11" - }, - "diacritic": { - "dependency": "direct main", - "description": { - "name": "diacritic", - "sha256": "12981945ec38931748836cd76f2b38773118d0baef3c68404bdfde9566147876", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.1.6" - }, - "diffutil_dart": { - "dependency": "direct main", - "description": { - "name": "diffutil_dart", - "sha256": "5e74883aedf87f3b703cb85e815bdc1ed9208b33501556e4a8a5572af9845c81", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.0.1" - }, - "dynamic_color": { - "dependency": "direct main", - "description": { - "name": "dynamic_color", - "sha256": "43a5a6679649a7731ab860334a5812f2067c2d9ce6452cf069c5e0c25336c17c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.8.1" - }, - "emoji_extension": { - "dependency": "direct main", - "description": { - "name": "emoji_extension", - "sha256": "7678a3e3fca4f2dfbce02cf8d439a81e130ce303fdc1ad90f484f57fd5ce4ba1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.2.0" - }, - "enhanced_enum": { - "dependency": "transitive", - "description": { - "name": "enhanced_enum", - "sha256": "074c5a8b9664799ca91e1e8b68003b8694cb19998671cbafd9c7779c13fcdecf", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.4" - }, - "equatable": { - "dependency": "transitive", - "description": { - "name": "equatable", - "sha256": "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.7" - }, - "fake_async": { - "dependency": "transitive", - "description": { - "name": "fake_async", - "sha256": "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.3.3" - }, - "fetch_api": { - "dependency": "transitive", - "description": { - "name": "fetch_api", - "sha256": "24cbd5616f3d4008c335c197bb90bfa0eb43b9e55c6de5c60d1f805092636034", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.3.1" - }, - "fetch_client": { - "dependency": "direct main", - "description": { - "name": "fetch_client", - "sha256": "375253f4efe64303c793fb17fe90771c591320b2ae11fb29cb5b406cc8533c00", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.4" - }, - "ffi": { - "dependency": "transitive", - "description": { - "name": "ffi", - "sha256": "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.4" - }, - "file": { - "dependency": "transitive", - "description": { - "name": "file", - "sha256": "a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "7.0.1" - }, - "file_selector": { - "dependency": "direct main", - "description": { - "name": "file_selector", - "sha256": "5019692b593455127794d5718304ff1ae15447dea286cdda9f0db2a796a1b828", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.3" - }, - "file_selector_android": { - "dependency": "transitive", - "description": { - "name": "file_selector_android", - "sha256": "3015702ab73987000e7ff2df5ddc99666d2bcd65cdb243f59da35729d3be6cff", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.5.1+15" - }, - "file_selector_ios": { - "dependency": "transitive", - "description": { - "name": "file_selector_ios", - "sha256": "94b98ad950b8d40d96fee8fa88640c2e4bd8afcdd4817993bd04e20310f45420", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.5.3+1" - }, - "file_selector_linux": { - "dependency": "transitive", - "description": { - "name": "file_selector_linux", - "sha256": "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.9.3+2" - }, - "file_selector_macos": { - "dependency": "transitive", - "description": { - "name": "file_selector_macos", - "sha256": "8c9250b2bd2d8d4268e39c82543bacbaca0fda7d29e0728c3c4bbb7c820fd711", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.9.4+3" - }, - "file_selector_platform_interface": { - "dependency": "transitive", - "description": { - "name": "file_selector_platform_interface", - "sha256": "a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.6.2" - }, - "file_selector_web": { - "dependency": "transitive", - "description": { - "name": "file_selector_web", - "sha256": "c4c0ea4224d97a60a7067eca0c8fd419e708ff830e0c83b11a48faf566cec3e7", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.9.4+2" - }, - "file_selector_windows": { - "dependency": "transitive", - "description": { - "name": "file_selector_windows", - "sha256": "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.9.3+4" - }, - "fixnum": { - "dependency": "transitive", - "description": { - "name": "fixnum", - "sha256": "b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.1" - }, - "flutter": { - "dependency": "direct main", - "description": "flutter", - "source": "sdk", - "version": "0.0.0" - }, - "flutter_adaptive_scaffold": { - "dependency": "direct main", - "description": { - "name": "flutter_adaptive_scaffold", - "sha256": "5eb1d1d174304a4e67c4bb402ed38cb4a5ebdac95ce54099e91460accb33d295", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.3.3+1" - }, - "flutter_confetti": { - "dependency": "direct main", - "description": { - "name": "flutter_confetti", - "sha256": "7e46b82ea0adc456afc91037652bbfbd52a951804fde0708822fad5d68be6398", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.5.1" - }, - "flutter_driver": { - "dependency": "direct dev", - "description": "flutter", - "source": "sdk", - "version": "0.0.0" - }, - "flutter_highlighting": { - "dependency": "direct main", - "description": { - "name": "flutter_highlighting", - "sha256": "426770b1453e8302f8cc58455ebcaad33e3049e73ca18f9d3c83554552bf3baf", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.9.0+11.8.0" - }, - "flutter_html": { - "dependency": "direct main", - "description": { - "name": "flutter_html", - "sha256": "38a2fd702ffdf3243fb7441ab58aa1bc7e6922d95a50db76534de8260638558d", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.0" - }, - "flutter_html_svg": { - "dependency": "direct main", - "description": { - "name": "flutter_html_svg", - "sha256": "76f59c238571333d95271817c3d94688b3c4dca2735552e481e49039d3efdb13", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.0" - }, - "flutter_html_table": { - "dependency": "direct main", - "description": { - "name": "flutter_html_table", - "sha256": "de15300b1f6d8014e1702e7edfdf3411f362c8fb753e89bac4c99215ea94a4d8", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.0" - }, - "flutter_keyboard_visibility": { - "dependency": "direct main", - "description": { - "name": "flutter_keyboard_visibility", - "sha256": "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.0.0" - }, - "flutter_keyboard_visibility_linux": { - "dependency": "transitive", - "description": { - "name": "flutter_keyboard_visibility_linux", - "sha256": "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.0" - }, - "flutter_keyboard_visibility_macos": { - "dependency": "transitive", - "description": { - "name": "flutter_keyboard_visibility_macos", - "sha256": "c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.0" - }, - "flutter_keyboard_visibility_platform_interface": { - "dependency": "transitive", - "description": { - "name": "flutter_keyboard_visibility_platform_interface", - "sha256": "e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.0" - }, - "flutter_keyboard_visibility_web": { - "dependency": "transitive", - "description": { - "name": "flutter_keyboard_visibility_web", - "sha256": "d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.0" - }, - "flutter_keyboard_visibility_windows": { - "dependency": "transitive", - "description": { - "name": "flutter_keyboard_visibility_windows", - "sha256": "fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.0" - }, - "flutter_launcher_icons": { - "dependency": "direct dev", - "description": { - "name": "flutter_launcher_icons", - "sha256": "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.14.4" - }, - "flutter_layout_grid": { - "dependency": "transitive", - "description": { - "name": "flutter_layout_grid", - "sha256": "739e568db97af031d528dfd8a80d333df0e5a310a126e087690fa42cd61dfb5f", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.8" - }, - "flutter_lints": { - "dependency": "direct dev", - "description": { - "name": "flutter_lints", - "sha256": "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.0.0" - }, - "flutter_local_notifications": { - "dependency": "direct main", - "description": { - "name": "flutter_local_notifications", - "sha256": "20ca0a9c82ce0c855ac62a2e580ab867f3fbea82680a90647f7953832d0850ae", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "19.4.0" - }, - "flutter_local_notifications_linux": { - "dependency": "transitive", - "description": { - "name": "flutter_local_notifications_linux", - "sha256": "e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.0.0" - }, - "flutter_local_notifications_platform_interface": { - "dependency": "transitive", - "description": { - "name": "flutter_local_notifications_platform_interface", - "sha256": "277d25d960c15674ce78ca97f57d0bae2ee401c844b6ac80fcd972a9c99d09fe", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "9.1.0" - }, - "flutter_local_notifications_windows": { - "dependency": "transitive", - "description": { - "name": "flutter_local_notifications_windows", - "sha256": "ed46d7ae4ec9d19e4c8fa2badac5fe27ba87a3fe387343ce726f927af074ec98", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.2" - }, - "flutter_localizations": { - "dependency": "direct main", - "description": "flutter", - "source": "sdk", - "version": "0.0.0" - }, - "flutter_openssl_crypto": { - "dependency": "direct main", - "description": { - "name": "flutter_openssl_crypto", - "sha256": "293b4fcda13ab0710645a16e82f3d5b7de19bfc0ab2d06bcdb87637222eda5e1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.5.0" - }, - "flutter_plugin_android_lifecycle": { - "dependency": "transitive", - "description": { - "name": "flutter_plugin_android_lifecycle", - "sha256": "6382ce712ff69b0f719640ce957559dde459e55ecd433c767e06d139ddf16cab", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.29" - }, - "flutter_rust_bridge": { - "dependency": "transitive", - "description": { - "name": "flutter_rust_bridge", - "sha256": "b416ff56002789e636244fb4cc449f587656eff995e5a7169457eb0593fcaddb", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.10.0" - }, - "flutter_secure_storage": { - "dependency": "direct main", - "description": { - "name": "flutter_secure_storage", - "sha256": "f7eceb0bc6f4fd0441e29d43cab9ac2a1c5ffd7ea7b64075136b718c46954874", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "10.0.0-beta.4" - }, - "flutter_secure_storage_darwin": { - "dependency": "transitive", - "description": { - "name": "flutter_secure_storage_darwin", - "sha256": "f226f2a572bed96bc6542198ebaec227150786e34311d455a7e2d3d06d951845", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.1.0" - }, - "flutter_secure_storage_linux": { - "dependency": "transitive", - "description": { - "name": "flutter_secure_storage_linux", - "sha256": "9b4b73127e857cd3117d43a70fa3dddadb6e0b253be62e6a6ab85caa0742182c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.1" - }, - "flutter_secure_storage_platform_interface": { - "dependency": "transitive", - "description": { - "name": "flutter_secure_storage_platform_interface", - "sha256": "8ceea1223bee3c6ac1a22dabd8feefc550e4729b3675de4b5900f55afcb435d6", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.1" - }, - "flutter_secure_storage_web": { - "dependency": "transitive", - "description": { - "name": "flutter_secure_storage_web", - "sha256": "4c3f233e739545c6cb09286eeec1cc4744138372b985113acc904f7263bef517", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.0" - }, - "flutter_secure_storage_windows": { - "dependency": "transitive", - "description": { - "name": "flutter_secure_storage_windows", - "sha256": "ff32af20f70a8d0e59b2938fc92de35b54a74671041c814275afd80e27df9f21", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.0.0" - }, - "flutter_svg": { - "dependency": "direct main", - "description": { - "name": "flutter_svg", - "sha256": "cd57f7969b4679317c17af6fd16ee233c1e60a82ed209d8a475c54fd6fd6f845", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.2.0" - }, - "flutter_test": { - "dependency": "direct dev", - "description": "flutter", - "source": "sdk", - "version": "0.0.0" - }, - "flutter_typeahead": { - "dependency": "direct main", - "description": { - "name": "flutter_typeahead", - "sha256": "d64712c65db240b1057559b952398ebb6e498077baeebf9b0731dade62438a6d", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "5.2.0" - }, - "flutter_vodozemac": { - "dependency": "direct main", - "description": { - "name": "flutter_vodozemac", - "sha256": "2405ca121b84d1cd83200a14021022e1691b123a23bcefc36adc7740cefbc1f9", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.2" - }, - "flutter_web_plugins": { - "dependency": "transitive", - "description": "flutter", - "source": "sdk", - "version": "0.0.0" - }, - "flutter_zxing": { - "dependency": "direct main", - "description": { - "name": "flutter_zxing", - "sha256": "dbcd89da2c9aa84f48d7d7e1ba436825f8656a69b142abb7bcdb7c2d9c22d48c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.2.1" - }, - "frontend_server_client": { - "dependency": "transitive", - "description": { - "name": "frontend_server_client", - "sha256": "f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.0.0" - }, - "fuchsia_remote_debug_protocol": { - "dependency": "transitive", - "description": "flutter", - "source": "sdk", - "version": "0.0.0" - }, - "glob": { - "dependency": "transitive", - "description": { - "name": "glob", - "sha256": "c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.3" - }, - "go_router": { - "dependency": "direct main", - "description": { - "name": "go_router", - "sha256": "8b1f37dfaf6e958c6b872322db06f946509433bec3de753c3491a42ae9ec2b48", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "16.1.0" - }, - "gtk": { - "dependency": "transitive", - "description": { - "name": "gtk", - "sha256": "e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.0" - }, - "highlighting": { - "dependency": "direct main", - "description": { - "name": "highlighting", - "sha256": "196005ed9c98ee559939fcecd466fa941b9e99b3a93394691b86780ad4da50f3", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.9.0+11.8.0" - }, - "html": { - "dependency": "direct main", - "description": { - "name": "html", - "sha256": "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.15.6" - }, - "html_unescape": { - "dependency": "transitive", - "description": { - "name": "html_unescape", - "sha256": "15362d7a18f19d7b742ef8dcb811f5fd2a2df98db9f80ea393c075189e0b61e3", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.0" - }, - "http": { - "dependency": "direct main", - "description": { - "name": "http", - "sha256": "bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.5.0" - }, - "http_parser": { - "dependency": "transitive", - "description": { - "name": "http_parser", - "sha256": "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.1.2" - }, - "http_profile": { - "dependency": "transitive", - "description": { - "name": "http_profile", - "sha256": "7e679e355b09aaee2ab5010915c932cce3f2d1c11c3b2dc177891687014ffa78", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.1.0" - }, - "image": { - "dependency": "direct main", - "description": { - "name": "image", - "sha256": "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.5.4" - }, - "image_picker": { - "dependency": "direct main", - "description": { - "name": "image_picker", - "sha256": "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.2" - }, - "image_picker_android": { - "dependency": "transitive", - "description": { - "name": "image_picker_android", - "sha256": "b08e9a04d0f8d91f4a6e767a745b9871bfbc585410205c311d0492de20a7ccd6", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.8.12+25" - }, - "image_picker_for_web": { - "dependency": "transitive", - "description": { - "name": "image_picker_for_web", - "sha256": "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.6" - }, - "image_picker_ios": { - "dependency": "transitive", - "description": { - "name": "image_picker_ios", - "sha256": "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.8.12+2" - }, - "image_picker_linux": { - "dependency": "transitive", - "description": { - "name": "image_picker_linux", - "sha256": "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.1+2" - }, - "image_picker_macos": { - "dependency": "transitive", - "description": { - "name": "image_picker_macos", - "sha256": "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.1+2" - }, - "image_picker_platform_interface": { - "dependency": "transitive", - "description": { - "name": "image_picker_platform_interface", - "sha256": "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.10.1" - }, - "image_picker_windows": { - "dependency": "transitive", - "description": { - "name": "image_picker_windows", - "sha256": "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.1+1" - }, - "import_sorter": { - "dependency": "direct main", - "description": { - "name": "import_sorter", - "sha256": "eb15738ccead84e62c31e0208ea4e3104415efcd4972b86906ca64a1187d0836", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.6.0" - }, - "integration_test": { - "dependency": "direct dev", - "description": "flutter", - "source": "sdk", - "version": "0.0.0" - }, - "intl": { - "dependency": "direct main", - "description": { - "name": "intl", - "sha256": "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.20.2" - }, - "io": { - "dependency": "transitive", - "description": { - "name": "io", - "sha256": "dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.5" - }, - "js": { - "dependency": "transitive", - "description": { - "name": "js", - "sha256": "f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.6.7" - }, - "json_annotation": { - "dependency": "transitive", - "description": { - "name": "json_annotation", - "sha256": "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.9.0" - }, - "just_audio": { - "dependency": "direct main", - "description": { - "name": "just_audio", - "sha256": "679637a3ec5b6e00f36472f5a3663667df00ee4822cbf5dafca0f568c710960a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.10.4" - }, - "just_audio_media_kit": { - "dependency": "direct main", - "description": { - "name": "just_audio_media_kit", - "sha256": "f3cf04c3a50339709e87e90b4e841eef4364ab4be2bdbac0c54cc48679f84d23", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.0" - }, - "just_audio_platform_interface": { - "dependency": "transitive", - "description": { - "name": "just_audio_platform_interface", - "sha256": "2532c8d6702528824445921c5ff10548b518b13f808c2e34c2fd54793b999a6a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.6.0" - }, - "just_audio_web": { - "dependency": "transitive", - "description": { - "name": "just_audio_web", - "sha256": "6ba8a2a7e87d57d32f0f7b42856ade3d6a9fbe0f1a11fabae0a4f00bb73f0663", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.4.16" - }, - "just_waveform": { - "dependency": "direct main", - "description": { - "name": "just_waveform", - "sha256": "8c65acd24f13b866e3377f07f8869e823f3f2d8b734938f4e6688075af40b4f2", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.0.7" - }, - "leak_tracker": { - "dependency": "transitive", - "description": { - "name": "leak_tracker", - "sha256": "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "10.0.9" - }, - "leak_tracker_flutter_testing": { - "dependency": "transitive", - "description": { - "name": "leak_tracker_flutter_testing", - "sha256": "f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.9" - }, - "leak_tracker_testing": { - "dependency": "transitive", - "description": { - "name": "leak_tracker_testing", - "sha256": "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.1" - }, - "linkify": { - "dependency": "direct main", - "description": { - "name": "linkify", - "sha256": "4139ea77f4651ab9c315b577da2dd108d9aa0bd84b5d03d33323f1970c645832", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "5.0.0" - }, - "lints": { - "dependency": "transitive", - "description": { - "name": "lints", - "sha256": "a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.0.0" - }, - "list_counter": { - "dependency": "transitive", - "description": { - "name": "list_counter", - "sha256": "c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.2" - }, - "locale_names": { - "dependency": "direct main", - "description": { - "name": "locale_names", - "sha256": "7a89ca54072f4f13d0f5df5a9ba69337554bf2fd057d1dd2a238898f3f159374", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.1" - }, - "logging": { - "dependency": "transitive", - "description": { - "name": "logging", - "sha256": "c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.3.0" - }, - "lottie": { - "dependency": "direct main", - "description": { - "name": "lottie", - "sha256": "c5fa04a80a620066c15cf19cc44773e19e9b38e989ff23ea32e5903ef1015950", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.3.1" - }, - "markdown": { - "dependency": "transitive", - "description": { - "name": "markdown", - "sha256": "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "7.3.0" - }, - "matcher": { - "dependency": "transitive", - "description": { - "name": "matcher", - "sha256": "dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.12.17" - }, - "material_color_utilities": { - "dependency": "transitive", - "description": { - "name": "material_color_utilities", - "sha256": "f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.11.1" - }, - "matrix": { - "dependency": "direct main", - "description": { - "path": ".", - "ref": "braid/msc3861-native-oidc", - "resolved-ref": "82ad90573e0e5e1ccb2cf1e669a5861bd6db351c", - "url": "https://github.com/TheOneWithTheBraid/matrix-dart-sdk.git" - }, - "source": "git", - "version": "1.1.0" - }, - "matrix_homeserver_recommendations": { - "dependency": "direct main", - "description": { - "name": "matrix_homeserver_recommendations", - "sha256": "48cd67146dd80b925c1cce1604da4712e7963b490d31801bad70b51ff8e30cd2", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.4.1" - }, - "media_kit": { - "dependency": "direct main", - "description": { - "path": "media_kit", - "ref": "braid/stub-template", - "resolved-ref": "215972e56ceb6036b51d1dc8803d5e0ab489bfe1", - "url": "https://github.com/TheOneWithTheBraid/media-kit.git" - }, - "source": "git", - "version": "1.2.0" - }, - "media_kit_libs_android_video": { - "dependency": "direct overridden", - "description": { - "path": "libs/android/media_kit_libs_android_video", - "ref": "main", - "resolved-ref": "ad84c59faa2b871926cb31516bdeec65d7676884", - "url": "https://github.com/Predidit/media-kit.git" - }, - "source": "git", - "version": "1.3.6" - }, - "media_kit_libs_ios_video": { - "dependency": "transitive", - "description": { - "name": "media_kit_libs_ios_video", - "sha256": "b5382994eb37a4564c368386c154ad70ba0cc78dacdd3fb0cd9f30db6d837991", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.4" - }, - "media_kit_libs_linux": { - "dependency": "transitive", - "description": { - "name": "media_kit_libs_linux", - "sha256": "2b473399a49ec94452c4d4ae51cfc0f6585074398d74216092bf3d54aac37ecf", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.2.1" - }, - "media_kit_libs_macos_video": { - "dependency": "transitive", - "description": { - "name": "media_kit_libs_macos_video", - "sha256": "f26aa1452b665df288e360393758f84b911f70ffb3878032e1aabba23aa1032d", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.4" - }, - "media_kit_libs_video": { - "dependency": "direct main", - "description": { - "name": "media_kit_libs_video", - "sha256": "958cc55e7065d9d01f52a2842dab2a0812a92add18489f1006d864fb5e42a3ef", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.6" - }, - "media_kit_libs_windows_video": { - "dependency": "transitive", - "description": { - "name": "media_kit_libs_windows_video", - "sha256": "dff76da2778729ab650229e6b4ec6ec111eb5151431002cbd7ea304ff1f112ab", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.11" - }, - "media_kit_video": { - "dependency": "direct main", - "description": { - "name": "media_kit_video", - "sha256": "a656a9463298c1adc64c57f2d012874f7f2900f0c614d9545a3e7b8bb9e2137b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.3.0" - }, - "media_store_plus": { - "dependency": "direct main", - "description": { - "name": "media_store_plus", - "sha256": "4b4971365e00a4ed9fde14abf40d7c27475b66b8bba9bf43478ae2ecb449df20", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.1.3" - }, - "meta": { - "dependency": "transitive", - "description": { - "name": "meta", - "sha256": "e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.16.0" - }, - "mime": { - "dependency": "direct main", - "description": { - "name": "mime", - "sha256": "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.0" - }, - "objective_c": { - "dependency": "transitive", - "description": { - "name": "objective_c", - "sha256": "9f034ba1eeca53ddb339bc8f4813cb07336a849cd735559b60cdc068ecce2dc7", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "7.1.0" - }, - "package_config": { - "dependency": "transitive", - "description": { - "name": "package_config", - "sha256": "f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.2.0" - }, - "package_info_plus": { - "dependency": "transitive", - "description": { - "name": "package_info_plus", - "sha256": "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "8.3.1" - }, - "package_info_plus_platform_interface": { - "dependency": "transitive", - "description": { - "name": "package_info_plus_platform_interface", - "sha256": "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.2.1" - }, - "path": { - "dependency": "transitive", - "description": { - "name": "path", - "sha256": "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.9.1" - }, - "path_parsing": { - "dependency": "transitive", - "description": { - "name": "path_parsing", - "sha256": "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.0" - }, - "path_provider": { - "dependency": "direct main", - "description": { - "name": "path_provider", - "sha256": "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.5" - }, - "path_provider_android": { - "dependency": "transitive", - "description": { - "name": "path_provider_android", - "sha256": "d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.2.17" - }, - "path_provider_foundation": { - "dependency": "transitive", - "description": { - "name": "path_provider_foundation", - "sha256": "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.4.1" - }, - "path_provider_linux": { - "dependency": "transitive", - "description": { - "name": "path_provider_linux", - "sha256": "f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.2.1" - }, - "path_provider_platform_interface": { - "dependency": "transitive", - "description": { - "name": "path_provider_platform_interface", - "sha256": "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.2" - }, - "path_provider_windows": { - "dependency": "transitive", - "description": { - "name": "path_provider_windows", - "sha256": "bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.3.0" - }, - "petitparser": { - "dependency": "transitive", - "description": { - "name": "petitparser", - "sha256": "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.1.0" - }, - "platform": { - "dependency": "transitive", - "description": { - "name": "platform", - "sha256": "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.1.6" - }, - "plugin_platform_interface": { - "dependency": "transitive", - "description": { - "name": "plugin_platform_interface", - "sha256": "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.8" - }, - "pointer_interceptor": { - "dependency": "transitive", - "description": { - "name": "pointer_interceptor", - "sha256": "57210410680379aea8b1b7ed6ae0c3ad349bfd56fe845b8ea934a53344b9d523", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.10.1+2" - }, - "pointer_interceptor_ios": { - "dependency": "transitive", - "description": { - "name": "pointer_interceptor_ios", - "sha256": "a6906772b3205b42c44614fcea28f818b1e5fdad73a4ca742a7bd49818d9c917", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.10.1" - }, - "pointer_interceptor_platform_interface": { - "dependency": "transitive", - "description": { - "name": "pointer_interceptor_platform_interface", - "sha256": "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.10.0+1" - }, - "pointer_interceptor_web": { - "dependency": "transitive", - "description": { - "name": "pointer_interceptor_web", - "sha256": "460b600e71de6fcea2b3d5f662c92293c049c4319e27f0829310e5a953b3ee2a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.10.3" - }, - "pool": { - "dependency": "transitive", - "description": { - "name": "pool", - "sha256": "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.5.1" - }, - "posix": { - "dependency": "transitive", - "description": { - "name": "posix", - "sha256": "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.0.3" - }, - "process": { - "dependency": "transitive", - "description": { - "name": "process", - "sha256": "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "5.0.3" - }, - "pub_semver": { - "dependency": "transitive", - "description": { - "name": "pub_semver", - "sha256": "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.2.0" - }, - "qr": { - "dependency": "transitive", - "description": { - "name": "qr", - "sha256": "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.2" - }, - "quiver": { - "dependency": "transitive", - "description": { - "name": "quiver", - "sha256": "ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.2.2" - }, - "random_string": { - "dependency": "transitive", - "description": { - "name": "random_string", - "sha256": "03b52435aae8cbdd1056cf91bfc5bf845e9706724dd35ae2e99fa14a1ef79d02", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.3.1" - }, - "receive_sharing_intent": { - "dependency": "direct main", - "description": { - "name": "receive_sharing_intent", - "sha256": "ec76056e4d258ad708e76d85591d933678625318e411564dcb9059048ca3a593", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.8.1" - }, - "rxdart": { - "dependency": "transitive", - "description": { - "name": "rxdart", - "sha256": "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.28.0" - }, - "safe_local_storage": { - "dependency": "transitive", - "description": { - "name": "safe_local_storage", - "sha256": "e9a21b6fec7a8aa62cc2585ff4c1b127df42f3185adbd2aca66b47abe2e80236", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.1" - }, - "screen_brightness_android": { - "dependency": "transitive", - "description": { - "name": "screen_brightness_android", - "sha256": "fb5fa43cb89d0c9b8534556c427db1e97e46594ac5d66ebdcf16063b773d54ed", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.2" - }, - "screen_brightness_platform_interface": { - "dependency": "transitive", - "description": { - "name": "screen_brightness_platform_interface", - "sha256": "737bd47b57746bc4291cab1b8a5843ee881af499514881b0247ec77447ee769c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.0" - }, - "sdp_transform": { - "dependency": "transitive", - "description": { - "name": "sdp_transform", - "sha256": "73e412a5279a5c2de74001535208e20fff88f225c9a4571af0f7146202755e45", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.3.2" - }, - "sentry": { - "dependency": "direct main", - "description": { - "name": "sentry", - "sha256": "d9f3dcf1ecdd600cf9ce134f622383adde5423ecfdaf0ca9b20fbc1c44849337", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "9.6.0" - }, - "share_plus": { - "dependency": "direct main", - "description": { - "name": "share_plus", - "sha256": "d7dc0630a923883c6328ca31b89aa682bacbf2f8304162d29f7c6aaff03a27a1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "11.1.0" - }, - "share_plus_platform_interface": { - "dependency": "transitive", - "description": { - "name": "share_plus_platform_interface", - "sha256": "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.1.0" - }, - "sky_engine": { - "dependency": "transitive", - "description": "flutter", - "source": "sdk", - "version": "0.0.0" - }, - "slugify": { - "dependency": "transitive", - "description": { - "name": "slugify", - "sha256": "b272501565cb28050cac2d96b7bf28a2d24c8dae359280361d124f3093d337c3", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.0" - }, - "source_map_stack_trace": { - "dependency": "transitive", - "description": { - "name": "source_map_stack_trace", - "sha256": "c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.2" - }, - "source_maps": { - "dependency": "transitive", - "description": { - "name": "source_maps", - "sha256": "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.10.13" - }, - "source_span": { - "dependency": "transitive", - "description": { - "name": "source_span", - "sha256": "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.10.1" - }, - "sprintf": { - "dependency": "transitive", - "description": { - "name": "sprintf", - "sha256": "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "7.0.0" - }, - "sqflite": { - "dependency": "direct main", - "description": { - "name": "sqflite", - "sha256": "e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.4.2" - }, - "sqflite_android": { - "dependency": "transitive", - "description": { - "name": "sqflite_android", - "sha256": "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.4.1" - }, - "sqflite_common": { - "dependency": "transitive", - "description": { - "name": "sqflite_common", - "sha256": "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.5.6" - }, - "sqflite_common_ffi": { - "dependency": "direct main", - "description": { - "name": "sqflite_common_ffi", - "sha256": "9faa2fedc5385ef238ce772589f7718c24cdddd27419b609bb9c6f703ea27988", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.3.6" - }, - "sqflite_darwin": { - "dependency": "transitive", - "description": { - "name": "sqflite_darwin", - "sha256": "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.4.2" - }, - "sqflite_platform_interface": { - "dependency": "transitive", - "description": { - "name": "sqflite_platform_interface", - "sha256": "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.4.0" - }, - "sqlcipher_flutter_libs": { - "dependency": "direct main", - "description": { - "name": "sqlcipher_flutter_libs", - "sha256": "dd1fcc74d5baf3c36ad53e2652b2d06c9f8747494a3ccde0076e88b159dfe622", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.6.8" - }, - "sqlite3": { - "dependency": "transitive", - "description": { - "name": "sqlite3", - "sha256": "f393d92c71bdcc118d6203d07c991b9be0f84b1a6f89dd4f7eed348131329924", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.9.0" - }, - "stack_trace": { - "dependency": "transitive", - "description": { - "name": "stack_trace", - "sha256": "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.12.1" - }, - "stream_channel": { - "dependency": "transitive", - "description": { - "name": "stream_channel", - "sha256": "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.4" - }, - "stream_transform": { - "dependency": "transitive", - "description": { - "name": "stream_transform", - "sha256": "ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.1" - }, - "string_scanner": { - "dependency": "transitive", - "description": { - "name": "string_scanner", - "sha256": "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.4.1" - }, - "sync_http": { - "dependency": "transitive", - "description": { - "name": "sync_http", - "sha256": "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.3.1" - }, - "synchronized": { - "dependency": "transitive", - "description": { - "name": "synchronized", - "sha256": "c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.4.0" - }, - "term_glyph": { - "dependency": "transitive", - "description": { - "name": "term_glyph", - "sha256": "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.2.2" - }, - "test_api": { - "dependency": "transitive", - "description": { - "name": "test_api", - "sha256": "fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.7.4" - }, - "test_core": { - "dependency": "transitive", - "description": { - "name": "test_core", - "sha256": "84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.6.8" - }, - "timezone": { - "dependency": "transitive", - "description": { - "name": "timezone", - "sha256": "dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.10.1" - }, - "tint": { - "dependency": "transitive", - "description": { - "name": "tint", - "sha256": "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.1" - }, - "tuple": { - "dependency": "transitive", - "description": { - "name": "tuple", - "sha256": "a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.0.2" - }, - "typed_data": { - "dependency": "transitive", - "description": { - "name": "typed_data", - "sha256": "f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.4.0" - }, - "unifiedpush": { - "dependency": "direct main", - "description": { - "name": "unifiedpush", - "sha256": "1418375efb580af9640de4eaf4209cb6481f9a48792648ced3051f30e67d9568", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.0.2" - }, - "unifiedpush_android": { - "dependency": "transitive", - "description": { - "name": "unifiedpush_android", - "sha256": "2f25db8eb2fc3183bf2e43db89fff20b2587adc1c361e1d1e06b223a0d45b50a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.1.1" - }, - "unifiedpush_platform_interface": { - "dependency": "transitive", - "description": { - "name": "unifiedpush_platform_interface", - "sha256": "bb49d2748211520e35e0374ab816faa8a2c635267e71909d334ad868d532eba5", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.1" - }, - "universal_platform": { - "dependency": "transitive", - "description": { - "name": "universal_platform", - "sha256": "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.0" - }, - "unorm_dart": { - "dependency": "direct main", - "description": { - "name": "unorm_dart", - "sha256": "5b35bff83fce4d76467641438f9e867dc9bcfdb8c1694854f230579d68cd8f4b", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.0" - }, - "uri_parser": { - "dependency": "transitive", - "description": { - "name": "uri_parser", - "sha256": "ff4d2c720aca3f4f7d5445e23b11b2d15ef8af5ddce5164643f38ff962dcb270", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.0.0" - }, - "url_launcher": { - "dependency": "direct main", - "description": { - "name": "url_launcher", - "sha256": "f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.3.2" - }, - "url_launcher_android": { - "dependency": "transitive", - "description": { - "name": "url_launcher_android", - "sha256": "0aedad096a85b49df2e4725fa32118f9fa580f3b14af7a2d2221896a02cd5656", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.3.17" - }, - "url_launcher_ios": { - "dependency": "transitive", - "description": { - "name": "url_launcher_ios", - "sha256": "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.3.3" - }, - "url_launcher_linux": { - "dependency": "transitive", - "description": { - "name": "url_launcher_linux", - "sha256": "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.2.1" - }, - "url_launcher_macos": { - "dependency": "transitive", - "description": { - "name": "url_launcher_macos", - "sha256": "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.2.2" - }, - "url_launcher_platform_interface": { - "dependency": "transitive", - "description": { - "name": "url_launcher_platform_interface", - "sha256": "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.3.2" - }, - "url_launcher_web": { - "dependency": "transitive", - "description": { - "name": "url_launcher_web", - "sha256": "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.4.1" - }, - "url_launcher_windows": { - "dependency": "transitive", - "description": { - "name": "url_launcher_windows", - "sha256": "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.1.4" - }, - "uuid": { - "dependency": "transitive", - "description": { - "name": "uuid", - "sha256": "a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "4.5.1" - }, - "vector_graphics": { - "dependency": "transitive", - "description": { - "name": "vector_graphics", - "sha256": "a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.19" - }, - "vector_graphics_codec": { - "dependency": "transitive", - "description": { - "name": "vector_graphics_codec", - "sha256": "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.13" - }, - "vector_graphics_compiler": { - "dependency": "transitive", - "description": { - "name": "vector_graphics_compiler", - "sha256": "557a315b7d2a6dbb0aaaff84d857967ce6bdc96a63dc6ee2a57ce5a6ee5d3331", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.17" - }, - "vector_math": { - "dependency": "transitive", - "description": { - "name": "vector_math", - "sha256": "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "2.1.4" - }, - "visibility_detector": { - "dependency": "direct main", - "description": { - "name": "visibility_detector", - "sha256": "dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.4.0+2" - }, - "vm_service": { - "dependency": "transitive", - "description": { - "name": "vm_service", - "sha256": "ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "15.0.0" - }, - "vodozemac": { - "dependency": "direct main", - "description": { - "name": "vodozemac", - "sha256": "dba14017e042748fb22d270e8ab1d3e46965b89788dd3857dba938ec07571968", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.2.0" - }, - "volume_controller": { - "dependency": "transitive", - "description": { - "name": "volume_controller", - "sha256": "d75039e69c0d90e7810bfd47e3eedf29ff8543ea7a10392792e81f9bded7edf5", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.4.0" - }, - "wakelock_plus": { - "dependency": "transitive", - "description": { - "name": "wakelock_plus", - "sha256": "a474e314c3e8fb5adef1f9ae2d247e57467ad557fa7483a2b895bc1b421c5678", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.3.2" - }, - "wakelock_plus_platform_interface": { - "dependency": "transitive", - "description": { - "name": "wakelock_plus_platform_interface", - "sha256": "e10444072e50dbc4999d7316fd303f7ea53d31c824aa5eb05d7ccbdd98985207", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.2.3" - }, - "watcher": { - "dependency": "transitive", - "description": { - "name": "watcher", - "sha256": "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.2" - }, - "web": { - "dependency": "direct main", - "description": { - "name": "web", - "sha256": "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.1" - }, - "web_multiple_tab_detector": { - "dependency": "direct main", - "description": { - "name": "web_multiple_tab_detector", - "sha256": "a40d485720ea88b4e25311421d435906ba202ac33e35435403dc1c49c5ed7c4e", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "0.3.0" - }, - "web_socket": { - "dependency": "transitive", - "description": { - "name": "web_socket", - "sha256": "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.0.1" - }, - "webdriver": { - "dependency": "transitive", - "description": { - "name": "webdriver", - "sha256": "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.1.0" - }, - "webrtc_interface": { - "dependency": "transitive", - "description": { - "name": "webrtc_interface", - "sha256": "86fe3afc81a08481dfb25cf14a5a94e27062ecef25544783f352c914e0bbc1ca", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.2.2+hotfix.2" - }, - "win32": { - "dependency": "transitive", - "description": { - "name": "win32", - "sha256": "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "5.14.0" - }, - "xdg_directories": { - "dependency": "transitive", - "description": { - "name": "xdg_directories", - "sha256": "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "1.1.0" - }, - "xml": { - "dependency": "transitive", - "description": { - "name": "xml", - "sha256": "b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "6.5.0" - }, - "yaml": { - "dependency": "transitive", - "description": { - "name": "yaml", - "sha256": "b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce", - "url": "https://pub.dev" - }, - "source": "hosted", - "version": "3.1.3" - } - }, - "sdks": { - "dart": ">=3.8.0 <4.0.0", - "flutter": ">=3.29.0" - } -} diff --git a/modules/home-manager-modules/programs/default.nix b/modules/home-manager-modules/programs/default.nix index 3fff489..c164c44 100644 --- a/modules/home-manager-modules/programs/default.nix +++ b/modules/home-manager-modules/programs/default.nix @@ -43,7 +43,6 @@ ./davinci-resolve.nix ./gdx-liftoff.nix ./tor-browser.nix - ./polycule.nix ./vmware-workstation.nix ]; } diff --git a/modules/home-manager-modules/programs/polycule.nix b/modules/home-manager-modules/programs/polycule.nix deleted file mode 100644 index d0aea2a..0000000 --- a/modules/home-manager-modules/programs/polycule.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - lib, - pkgs, - config, - ... -}: { - options.programs.polycule = { - enable = lib.mkEnableOption "enable polycule matrix client"; - package = lib.mkPackageOption pkgs "polycule" {}; - }; - - config = lib.mkIf config.programs.polycule.enable (lib.mkMerge [ - { - home.packages = [ - config.programs.polycule.package - ]; - } - ( - lib.mkIf config.impermanence.enable { - home.persistence."/persist${config.home.homeDirectory}" = { - # TODO: check that these are actually the correct folders - # directories = [ - # "${config.xdg.configHome}/polycule" - # "${config.xdg.dataHome}/polycule" - # "${config.xdg.cacheHome}/polycule" - # ]; - }; - } - ) - ]); -} From 1ed8a2b8abec16fc41f5c72e28027fe4a0384759 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Thu, 6 Nov 2025 14:21:09 -0600 Subject: [PATCH 43/61] feat: added cyberia matrix to leyla's bookmarks --- .../home-manager/leyla/packages/firefox/bookmarks.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configurations/home-manager/leyla/packages/firefox/bookmarks.nix b/configurations/home-manager/leyla/packages/firefox/bookmarks.nix index 8435d45..4210d1e 100644 --- a/configurations/home-manager/leyla/packages/firefox/bookmarks.nix +++ b/configurations/home-manager/leyla/packages/firefox/bookmarks.nix @@ -135,6 +135,12 @@ keyword = ""; tags = [""]; } + { + name = "Cyberia Matrix"; + url = "https://chat.cyberia.club"; + keyword = ""; + tags = [""]; + } # Template # { # name = ""; From e0ad443188af8b8c4450a74b344ece65663afb9b Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 7 Nov 2025 11:44:45 -0600 Subject: [PATCH 44/61] refactor: fixed deprecation warning for pkgs.system --- configurations/home-manager/leyla/packages/firefox/firefox.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configurations/home-manager/leyla/packages/firefox/firefox.nix b/configurations/home-manager/leyla/packages/firefox/firefox.nix index 1678353..6b58768 100644 --- a/configurations/home-manager/leyla/packages/firefox/firefox.nix +++ b/configurations/home-manager/leyla/packages/firefox/firefox.nix @@ -49,7 +49,7 @@ }; }; - extensions.packages = with inputs.firefox-addons.packages.${pkgs.system}; [ + extensions.packages = with inputs.firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; [ bitwarden terms-of-service-didnt-read multi-account-containers From e3a8ddbf32f761a4b93563d3b0c642975394a18d Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 7 Nov 2025 11:53:12 -0600 Subject: [PATCH 45/61] feat: fixed install of firefox language pack --- .../leyla/packages/firefox/firefox.nix | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/configurations/home-manager/leyla/packages/firefox/firefox.nix b/configurations/home-manager/leyla/packages/firefox/firefox.nix index 6b58768..f1097a1 100644 --- a/configurations/home-manager/leyla/packages/firefox/firefox.nix +++ b/configurations/home-manager/leyla/packages/firefox/firefox.nix @@ -49,7 +49,9 @@ }; }; - extensions.packages = with inputs.firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; [ + extensions.packages = with inputs.firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; let + inherit (inputs.firefox-addons.lib.${pkgs.stdenv.hostPlatform.system}) buildFirefoxXpiAddon; + in [ bitwarden terms-of-service-didnt-read multi-account-containers @@ -73,38 +75,36 @@ tab-session-manager - # (\ - # buildFirefoxXpiAddon rec {\ - # pname = "italiano-it-language-pack";\ - # version = "132.0.20241110.231641";\ - # addonId = "langpack-it@firefox.mozilla.org";\ - # url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi";\ - # sha256 = "";\ - # meta = with lib;\ - # {\ - # description = "Firefox Language Pack for Italiano (it) – Italian";\ - # license = licenses.mpl20;\ - # mozPermissions = [];\ - # platforms = platforms.all;\ - # };\ - # }\ - # )\ - # (\ - # buildFirefoxXpiAddon rec {\ - # pname = "dizionario-italiano";\ - # version = "5.1";\ - # addonId = "it-IT@dictionaries.addons.mozilla.org";\ - # url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi";\ - # sha256 = "";\ - # meta = with lib;\ - # {\ - # description = "Add support for Italian to spellchecking";\ - # license = licenses.gpl3;\ - # mozPermissions = [];\ - # platforms = platforms.all;\ - # };\ - # }\ - # )\ + ( + buildFirefoxXpiAddon rec { + pname = "italiano-it-language-pack"; + version = "132.0.20241110.231641"; + addonId = "langpack-it@firefox.mozilla.org"; + url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi"; + sha256 = "2b4764045daa62b00de8773fdfb03b5bbc1cd62c42f8fa27ef70c412d549dbe6"; + meta = with lib; { + description = "Firefox Language Pack for Italiano (it) – Italian"; + license = licenses.mpl20; + mozPermissions = []; + platforms = platforms.all; + }; + } + ) + ( + buildFirefoxXpiAddon rec { + pname = "dizionario-italiano"; + version = "5.1"; + addonId = "it-IT@dictionaries.addons.mozilla.org"; + url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi"; + sha256 = "ae75847ce65e7744ba44d5f7d98a18b81f61770a0fdfc6d06bae8b7239535ee0"; + meta = with lib; { + description = "Add support for Italian to spellchecking"; + license = licenses.gpl3; + mozPermissions = []; + platforms = platforms.all; + }; + } + ) ]; settings = { From c33121e3480823f63bc6fae461de5cbcde227739 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 7 Nov 2025 12:06:11 -0600 Subject: [PATCH 46/61] refactor: moved firefox configs to the common modules packages folder --- .../leyla/packages/firefox/firefox.nix | 36 ++----------------- modules/common-modules/pkgs/default.nix | 11 +++++- .../pkgs/firefox-extensions/default.nix | 14 ++++++++ .../dizionario-italiano.nix | 18 ++++++++++ .../italiano-it-language-pack.nix | 18 ++++++++++ 5 files changed, 63 insertions(+), 34 deletions(-) create mode 100644 modules/common-modules/pkgs/firefox-extensions/default.nix create mode 100644 modules/common-modules/pkgs/firefox-extensions/dizionario-italiano.nix create mode 100644 modules/common-modules/pkgs/firefox-extensions/italiano-it-language-pack.nix diff --git a/configurations/home-manager/leyla/packages/firefox/firefox.nix b/configurations/home-manager/leyla/packages/firefox/firefox.nix index f1097a1..fecb038 100644 --- a/configurations/home-manager/leyla/packages/firefox/firefox.nix +++ b/configurations/home-manager/leyla/packages/firefox/firefox.nix @@ -49,9 +49,7 @@ }; }; - extensions.packages = with inputs.firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; let - inherit (inputs.firefox-addons.lib.${pkgs.stdenv.hostPlatform.system}) buildFirefoxXpiAddon; - in [ + extensions.packages = with inputs.firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; [ bitwarden terms-of-service-didnt-read multi-account-containers @@ -75,36 +73,8 @@ tab-session-manager - ( - buildFirefoxXpiAddon rec { - pname = "italiano-it-language-pack"; - version = "132.0.20241110.231641"; - addonId = "langpack-it@firefox.mozilla.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi"; - sha256 = "2b4764045daa62b00de8773fdfb03b5bbc1cd62c42f8fa27ef70c412d549dbe6"; - meta = with lib; { - description = "Firefox Language Pack for Italiano (it) – Italian"; - license = licenses.mpl20; - mozPermissions = []; - platforms = platforms.all; - }; - } - ) - ( - buildFirefoxXpiAddon rec { - pname = "dizionario-italiano"; - version = "5.1"; - addonId = "it-IT@dictionaries.addons.mozilla.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi"; - sha256 = "ae75847ce65e7744ba44d5f7d98a18b81f61770a0fdfc6d06bae8b7239535ee0"; - meta = with lib; { - description = "Add support for Italian to spellchecking"; - license = licenses.gpl3; - mozPermissions = []; - platforms = platforms.all; - }; - } - ) + pkgs.firefox-extensions.italiano-it-language-pack + pkgs.firefox-extensions.dizionario-italiano ]; settings = { diff --git a/modules/common-modules/pkgs/default.nix b/modules/common-modules/pkgs/default.nix index c97f97c..612dd08 100644 --- a/modules/common-modules/pkgs/default.nix +++ b/modules/common-modules/pkgs/default.nix @@ -1,4 +1,8 @@ -{pkgs, ...}: { +{ + pkgs, + inputs, + ... +}: { imports = [ ./python ]; @@ -25,6 +29,11 @@ (final: prev: { codium-extensions = pkgs.callPackage ./codium-extensions {}; }) + (final: prev: { + firefox-extensions = pkgs.callPackage ./firefox-extensions { + inherit inputs; + }; + }) (final: prev: { mapillary-uploader = pkgs.callPackage ./mapillary-uploader.nix {}; }) diff --git a/modules/common-modules/pkgs/firefox-extensions/default.nix b/modules/common-modules/pkgs/firefox-extensions/default.nix new file mode 100644 index 0000000..5e3e70c --- /dev/null +++ b/modules/common-modules/pkgs/firefox-extensions/default.nix @@ -0,0 +1,14 @@ +{ + pkgs, + inputs, + ... +}: let + inherit (inputs.firefox-addons.lib.${pkgs.stdenv.hostPlatform.system}) buildFirefoxXpiAddon; +in { + italiano-it-language-pack = pkgs.callPackage ./italiano-it-language-pack.nix { + inherit buildFirefoxXpiAddon; + }; + dizionario-italiano = pkgs.callPackage ./dizionario-italiano.nix { + inherit buildFirefoxXpiAddon; + }; +} diff --git a/modules/common-modules/pkgs/firefox-extensions/dizionario-italiano.nix b/modules/common-modules/pkgs/firefox-extensions/dizionario-italiano.nix new file mode 100644 index 0000000..6fb793c --- /dev/null +++ b/modules/common-modules/pkgs/firefox-extensions/dizionario-italiano.nix @@ -0,0 +1,18 @@ +{ + lib, + buildFirefoxXpiAddon, + ... +}: +buildFirefoxXpiAddon rec { + pname = "dizionario-italiano"; + version = "5.1"; + addonId = "it-IT@dictionaries.addons.mozilla.org"; + url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi"; + sha256 = "ae75847ce65e7744ba44d5f7d98a18b81f61770a0fdfc6d06bae8b7239535ee0"; + meta = with lib; { + description = "Add support for Italian to spellchecking"; + license = licenses.gpl3; + mozPermissions = []; + platforms = platforms.all; + }; +} diff --git a/modules/common-modules/pkgs/firefox-extensions/italiano-it-language-pack.nix b/modules/common-modules/pkgs/firefox-extensions/italiano-it-language-pack.nix new file mode 100644 index 0000000..765368c --- /dev/null +++ b/modules/common-modules/pkgs/firefox-extensions/italiano-it-language-pack.nix @@ -0,0 +1,18 @@ +{ + lib, + buildFirefoxXpiAddon, + ... +}: +buildFirefoxXpiAddon rec { + pname = "italiano-it-language-pack"; + version = "132.0.20241110.231641"; + addonId = "langpack-it@firefox.mozilla.org"; + url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi"; + sha256 = "2b4764045daa62b00de8773fdfb03b5bbc1cd62c42f8fa27ef70c412d549dbe6"; + meta = with lib; { + description = "Firefox Language Pack for Italiano (it) – Italian"; + license = licenses.mpl20; + mozPermissions = []; + platforms = platforms.all; + }; +} From f031a20d11d0f3a5281fbae0f567376153175a55 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 7 Nov 2025 12:57:05 -0600 Subject: [PATCH 47/61] build: updated firefox language extension versions --- .../leyla/packages/firefox/firefox.nix | 2 +- .../pkgs/firefox-extensions/default.nix | 3 +++ .../deutsch-de-language-pack.nix | 18 ++++++++++++++++++ .../firefox-extensions/dizionario-italiano.nix | 4 ++-- .../italiano-it-language-pack.nix | 6 +++--- 5 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 modules/common-modules/pkgs/firefox-extensions/deutsch-de-language-pack.nix diff --git a/configurations/home-manager/leyla/packages/firefox/firefox.nix b/configurations/home-manager/leyla/packages/firefox/firefox.nix index fecb038..ef6d202 100644 --- a/configurations/home-manager/leyla/packages/firefox/firefox.nix +++ b/configurations/home-manager/leyla/packages/firefox/firefox.nix @@ -68,7 +68,7 @@ snowflake - deutsch-de-language-pack + pkgs.firefox-extensions.deutsch-de-language-pack dictionary-german tab-session-manager diff --git a/modules/common-modules/pkgs/firefox-extensions/default.nix b/modules/common-modules/pkgs/firefox-extensions/default.nix index 5e3e70c..922dfc7 100644 --- a/modules/common-modules/pkgs/firefox-extensions/default.nix +++ b/modules/common-modules/pkgs/firefox-extensions/default.nix @@ -11,4 +11,7 @@ in { dizionario-italiano = pkgs.callPackage ./dizionario-italiano.nix { inherit buildFirefoxXpiAddon; }; + deutsch-de-language-pack = pkgs.callPackage ./deutsch-de-language-pack.nix { + inherit buildFirefoxXpiAddon; + }; } diff --git a/modules/common-modules/pkgs/firefox-extensions/deutsch-de-language-pack.nix b/modules/common-modules/pkgs/firefox-extensions/deutsch-de-language-pack.nix new file mode 100644 index 0000000..b769bfd --- /dev/null +++ b/modules/common-modules/pkgs/firefox-extensions/deutsch-de-language-pack.nix @@ -0,0 +1,18 @@ +{ + lib, + buildFirefoxXpiAddon, + ... +}: +buildFirefoxXpiAddon rec { + pname = "deutsch-de-language-pack"; + version = "145.0.20251106.194447"; + addonId = "langpack-de@firefox.mozilla.org"; + url = "https://addons.mozilla.org/firefox/downloads/file/4614311/deutsch_de_language_pack-${version}.xpi"; + sha256 = "aaaa95c29984fb3802a5e7edb6b7e5020c391d81f389b8a8133c163959ea4299"; + meta = with lib; { + description = "Firefox Language Pack for Deutsch (de) – German"; + license = licenses.mpl20; + mozPermissions = []; + platforms = platforms.all; + }; +} diff --git a/modules/common-modules/pkgs/firefox-extensions/dizionario-italiano.nix b/modules/common-modules/pkgs/firefox-extensions/dizionario-italiano.nix index 6fb793c..4bfca14 100644 --- a/modules/common-modules/pkgs/firefox-extensions/dizionario-italiano.nix +++ b/modules/common-modules/pkgs/firefox-extensions/dizionario-italiano.nix @@ -7,8 +7,8 @@ buildFirefoxXpiAddon rec { pname = "dizionario-italiano"; version = "5.1"; addonId = "it-IT@dictionaries.addons.mozilla.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi"; - sha256 = "ae75847ce65e7744ba44d5f7d98a18b81f61770a0fdfc6d06bae8b7239535ee0"; + url = "https://addons.mozilla.org/firefox/downloads/file/3693497/dizionario_italiano-${version}.xpi"; + sha256 = "90b173ffdde34a77108152a5ff51879767b1dd84e0aa0dfb7b2bab94cd2e7f53"; meta = with lib; { description = "Add support for Italian to spellchecking"; license = licenses.gpl3; diff --git a/modules/common-modules/pkgs/firefox-extensions/italiano-it-language-pack.nix b/modules/common-modules/pkgs/firefox-extensions/italiano-it-language-pack.nix index 765368c..35f4243 100644 --- a/modules/common-modules/pkgs/firefox-extensions/italiano-it-language-pack.nix +++ b/modules/common-modules/pkgs/firefox-extensions/italiano-it-language-pack.nix @@ -5,10 +5,10 @@ }: buildFirefoxXpiAddon rec { pname = "italiano-it-language-pack"; - version = "132.0.20241110.231641"; + version = "145.0.20251106.194447"; addonId = "langpack-it@firefox.mozilla.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi"; - sha256 = "2b4764045daa62b00de8773fdfb03b5bbc1cd62c42f8fa27ef70c412d549dbe6"; + url = "https://addons.mozilla.org/firefox/downloads/file/4614309/italiano_it_language_pack-${version}.xpi"; + sha256 = "1eb271cedbf326543e222ba1b9a1da62fceef9d3c523ac02a098df296f155038"; meta = with lib; { description = "Firefox Language Pack for Italiano (it) – Italian"; license = licenses.mpl20; From 0e5ebb37f1ce8f93dd7316156567094f1aba788b Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 7 Nov 2025 16:53:05 -0600 Subject: [PATCH 48/61] build: update flake.lock --- flake.lock | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/flake.lock b/flake.lock index 6a4736b..3c1f2ad 100644 --- a/flake.lock +++ b/flake.lock @@ -25,11 +25,11 @@ ] }, "locked": { - "lastModified": 1761899396, - "narHash": "sha256-XOpKBp6HLzzMCbzW50TEuXN35zN5WGQREC7n34DcNMM=", + "lastModified": 1762276996, + "narHash": "sha256-TtcPgPmp2f0FAnc+DMEw4ardEgv1SGNR3/WFGH0N19M=", "owner": "nix-community", "repo": "disko", - "rev": "6f4cf5abbe318e4cd1e879506f6eeafd83f7b998", + "rev": "af087d076d3860760b3323f6b583f4d828c1ac17", "type": "github" }, "original": { @@ -46,11 +46,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1762162438, - "narHash": "sha256-GPnRGcVck+TPiQl6Rqj0i57c8hAa34RsQWVqQAW0OVY=", + "lastModified": 1762488230, + "narHash": "sha256-b7FFUa+bQ8m5din6ylspTTeQvhTf7NNDwC3fPOwCkx4=", "owner": "rycee", "repo": "nur-expressions", - "rev": "2cf91d46e558b29f9f9bbdd23408f62e8423aa00", + "rev": "05e744e2e2d174b2fd445e51ad38fb8356001a18", "type": "gitlab" }, "original": { @@ -133,11 +133,11 @@ ] }, "locked": { - "lastModified": 1762183399, - "narHash": "sha256-vr2aL1QLfERYTfYBgK8cW3T9eSdSEThH462wKaGlmEU=", + "lastModified": 1762463325, + "narHash": "sha256-33YUsWpPyeBZEWrKQ2a1gkRZ7i0XCC/2MYpU6BVeQSU=", "owner": "nix-community", "repo": "home-manager", - "rev": "a5fee077929ae2f2800c3087dce5e1abb4edfbc6", + "rev": "0562fef070a1027325dd4ea10813d64d2c967b39", "type": "github" }, "original": { @@ -227,11 +227,11 @@ ] }, "locked": { - "lastModified": 1762186368, - "narHash": "sha256-dzLBZKccS0jMefj+WAYwsk7gKDluqavC7I4KfFwVh8k=", + "lastModified": 1762501326, + "narHash": "sha256-QbhsksHaIN6qU3oXhwUFbYycKX1GRxObpQSWAM5fhRY=", "owner": "LnL7", "repo": "nix-darwin", - "rev": "69921864a70b58787abf5ba189095566c3f0ffd3", + "rev": "e2b82ebd0f990a5d1b68fcc761b3d6383c86ccfd", "type": "github" }, "original": { @@ -268,11 +268,11 @@ ] }, "locked": { - "lastModified": 1762135163, - "narHash": "sha256-gP8SCvsYSfi4olYZcrZ4P1IGMzYJSFe1FuO8RL3xpEc=", + "lastModified": 1762480525, + "narHash": "sha256-7akzuLV8uKP3ym67TJoSIT5hTeC5FG8H745Y/7/7J+8=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "5d6525e4d5372973da1777b9ebdb01f033db1395", + "rev": "b8b0b207dc13cb7b004f9d0c1d2b76a85e9494c8", "type": "github" }, "original": { @@ -283,11 +283,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1762179181, - "narHash": "sha256-T4+TNfXlF/gHbcNCC2HY7sMGBKgqNzyYeMBWmcbH7/o=", + "lastModified": 1762463231, + "narHash": "sha256-hv1mG5j5PTbnWbtHHomzTus77pIxsc4x8VrMjc7+/YE=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "256770618502d2eda892af3ae91da5e386ce9586", + "rev": "52113c4f5cfd1e823001310e56d9c8d0699a6226", "type": "github" }, "original": { @@ -315,11 +315,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1762111121, - "narHash": "sha256-4vhDuZ7OZaZmKKrnDpxLZZpGIJvAeMtK6FKLJYUtAdw=", + "lastModified": 1762363567, + "narHash": "sha256-YRqMDEtSMbitIMj+JLpheSz0pwEr0Rmy5mC7myl17xs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b3d51a0365f6695e7dd5cdf3e180604530ed33b4", + "rev": "ae814fd3904b621d8ab97418f1d0f2eb0d3716f4", "type": "github" }, "original": { From 761246a4a486a9f94a4e8cac64a7022737625ccf Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 7 Nov 2025 17:01:21 -0600 Subject: [PATCH 49/61] chore: removed installerConfigurations --- flake.nix | 7 ------- util/default.nix | 10 ---------- 2 files changed, 17 deletions(-) diff --git a/flake.nix b/flake.nix index ddf92ce..ee41728 100644 --- a/flake.nix +++ b/flake.nix @@ -91,16 +91,11 @@ util = import ./util {inherit inputs;}; forEachPkgs = util.forEachPkgs; - mkNixosInstaller = util.mkNixosInstaller; mkNixosSystem = util.mkNixosSystem; mkDarwinSystem = util.mkDarwinSystem; mkHome = util.mkHome; syncthingConfiguration = util.syncthingConfiguration; - installerSystems = { - basic = mkNixosInstaller "basic" []; - }; - nixosSystems = { horizon = mkNixosSystem "horizon"; twilight = mkNixosSystem "twilight"; @@ -170,8 +165,6 @@ }; }); - installerConfigurations = installerSystems; - nixosConfigurations = nixosSystems; darwinConfigurations = darwinSystems; diff --git a/util/default.nix b/util/default.nix index fb2f83d..1b89169 100644 --- a/util/default.nix +++ b/util/default.nix @@ -62,16 +62,6 @@ in { (lib.mkUnless condition no) ]; - mkNixosInstaller = host: userKeys: - nixpkgs.lib.nixosSystem { - modules = [ - { - # TODO: authorized keys for all users and hosts - } - ../configurations/nixos/${host} - ]; - }; - mkNixosSystem = host: nixpkgs.lib.nixosSystem { specialArgs = {inherit inputs outputs util;}; From d613dee36414595ce3f49c72a0d546d086a7e027 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 7 Nov 2025 17:11:41 -0600 Subject: [PATCH 50/61] refactor: move syncthing configs out of flake file --- flake.nix | 3 --- modules/nixos-modules/sync.nix | 4 ++-- util/default.nix | 14 +++++++------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/flake.nix b/flake.nix index ee41728..6f85fa3 100644 --- a/flake.nix +++ b/flake.nix @@ -94,7 +94,6 @@ mkNixosSystem = util.mkNixosSystem; mkDarwinSystem = util.mkDarwinSystem; mkHome = util.mkHome; - syncthingConfiguration = util.syncthingConfiguration; nixosSystems = { horizon = mkNixosSystem "horizon"; @@ -170,7 +169,5 @@ darwinConfigurations = darwinSystems; homeConfigurations = homeConfigurations; - - syncthingConfiguration = syncthingConfiguration; }; } diff --git a/modules/nixos-modules/sync.nix b/modules/nixos-modules/sync.nix index bf43041..96f54d5 100644 --- a/modules/nixos-modules/sync.nix +++ b/modules/nixos-modules/sync.nix @@ -1,7 +1,7 @@ { config, lib, - outputs, + syncthingConfiguration, ... }: let mountDir = "/mnt/sync"; @@ -27,7 +27,7 @@ in { configDir = configDir; overrideDevices = true; overrideFolders = true; - configuration = outputs.syncthingConfiguration; + configuration = syncthingConfiguration; deviceName = config.networking.hostName; }; } diff --git a/util/default.nix b/util/default.nix index 1b89169..97bfa49 100644 --- a/util/default.nix +++ b/util/default.nix @@ -52,6 +52,12 @@ home-manager-config ../modules/system-modules ]; + + syncthingConfiguration = nix-syncthing.lib.syncthingConfiguration { + modules = [ + (import ../configurations/syncthing) + ]; + }; in { forEachPkgs = lambda: forEachSystem (system: lambda system (pkgsFor system)); @@ -64,7 +70,7 @@ in { mkNixosSystem = host: nixpkgs.lib.nixosSystem { - specialArgs = {inherit inputs outputs util;}; + specialArgs = {inherit inputs outputs util syncthingConfiguration;}; modules = system-modules ++ [ @@ -109,10 +115,4 @@ in { ../configurations/home-manager/${user} ]; }; - - syncthingConfiguration = nix-syncthing.lib.syncthingConfiguration { - modules = [ - (import ../configurations/syncthing) - ]; - }; } From 5dedf4f314911d7c834c531fa98be05f61f1587b Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sat, 8 Nov 2025 11:39:17 -0600 Subject: [PATCH 51/61] chore: service to list of services that need to be added --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2d6911b..7f49aa8 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home ## Services - [ ] ntfy service for unified push +- [ ] signal socket server - [ ] vikunja service for project management - [ ] Penpot services (need to make this custom) - [ ] minecraft server with old world file From 81a9ed31548c9842f4f051b6c19656c4cd032382 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sun, 9 Nov 2025 02:21:08 -0600 Subject: [PATCH 52/61] doc: added documentation tasks to README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 2d6911b..e16fe0e 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,20 @@ nix multi user, multi system, configuration with `sops` secret management, `home # Tasks: +## Documentation +- [ ] project layout +- [ ] users file structure +- [ ] reverse proxy design + - public service compatibility + - vpn based services compatibility +- [ ] the choice of impermanence +- [ ] storage module design + - base impermanence compatibility and structure reason + - plans for home manager datasets + - plans for auto systemd service datasets +- [ ] plans to migrate to some kind of acl structure for user management +- [ ] plans to migrate from flakes to npins + ## Chores: - [ ] test out crab hole service From 46cd54e9bac9c0fd975f0ecbcf6a2dd90d648e3a Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sun, 9 Nov 2025 02:27:00 -0600 Subject: [PATCH 53/61] feat: added option for prompt footer in conventional commit plugin --- .../programs/vscode/conventionalCommits.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/home-manager-modules/programs/vscode/conventionalCommits.nix b/modules/home-manager-modules/programs/vscode/conventionalCommits.nix index 5bc8124..b667c27 100644 --- a/modules/home-manager-modules/programs/vscode/conventionalCommits.nix +++ b/modules/home-manager-modules/programs/vscode/conventionalCommits.nix @@ -19,6 +19,10 @@ in { gitmoji = lib.mkEnableOption "should emoji be prompted for as a part of the commit message./"; promptScopes = lib.mkEnableOption "prompting for scopes in conventional commits"; + + promptFooter = lib.mkEnableOption "prompting for footer in conventional commits"; + + showNewVersionNotes = lib.mkEnableOption "showing new version notes for conventional commits"; }; }; config = lib.mkIf config.extraExtensions.conventionalCommits.enable { @@ -27,6 +31,8 @@ in { userSettings = { "conventionalCommits.gitmoji" = config.extraExtensions.conventionalCommits.gitmoji; "conventionalCommits.promptScopes" = config.extraExtensions.conventionalCommits.promptScopes; + "conventionalCommits.promptFooter" = config.extraExtensions.conventionalCommits.promptFooter; + "conventionalCommits.showNewVersionNotes" = config.extraExtensions.conventionalCommits.showNewVersionNotes; }; }; })); From 8ddaa1c9dd45c62dd810597aa6d0abe6c7770169 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sun, 9 Nov 2025 02:39:43 -0600 Subject: [PATCH 54/61] doc: added more notes to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7d13298..a50813e 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ nix multi user, multi system, configuration with `sops` secret management, `home - [ ] the choice of impermanence - [ ] storage module design - base impermanence compatibility and structure reason + - what does local vs persist mean in pool names (do we need a second layer? ephemeral, local, and persist? local exist only on this machine and is not backed up, persist is backed up to other machines (I think we need to redo the sops and torrent/media folders?)) + - plans to possibly support btrfs in the future - plans for home manager datasets - plans for auto systemd service datasets - [ ] plans to migrate to some kind of acl structure for user management From eb379816adc758207c4decdead031a56508002ab Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Wed, 12 Nov 2025 22:15:22 -0600 Subject: [PATCH 55/61] chore: added research note to README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a50813e..d29ba58 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ nix multi user, multi system, configuration with `sops` secret management, `home - Look into this for npins https://jade.fyi/blog/pinning-nixos-with-npins/ - https://nixos-and-flakes.thiscute.world/ - proton mail now has an smtp server we could use that for our zfs and SMART test emails +- VR https://lvra.gitlab.io/docs/distros/nixos/ # Tasks: From 69a60155885b267619346be662f9181b2c6a2f6f Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 14 Nov 2025 22:36:31 -0600 Subject: [PATCH 56/61] feat: added friture package to eve --- configurations/home-manager/eve/packages.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/configurations/home-manager/eve/packages.nix b/configurations/home-manager/eve/packages.nix index fb8d8a4..f650a70 100644 --- a/configurations/home-manager/eve/packages.nix +++ b/configurations/home-manager/eve/packages.nix @@ -19,6 +19,7 @@ in { with pkgs; [ gnomeExtensions.dash-to-panel claude-code + friture ] ); From c501b1688ea9c7ac955cbf24cf109a620b2f0ecf Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Fri, 21 Nov 2025 18:15:13 -0600 Subject: [PATCH 57/61] build: updated flake.lock --- flake.lock | 56 +++++++++---------- .../home-manager-modules/programs/discord.nix | 10 ---- util/default.nix | 2 +- 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/flake.lock b/flake.lock index 3c1f2ad..e9d259b 100644 --- a/flake.lock +++ b/flake.lock @@ -25,11 +25,11 @@ ] }, "locked": { - "lastModified": 1762276996, - "narHash": "sha256-TtcPgPmp2f0FAnc+DMEw4ardEgv1SGNR3/WFGH0N19M=", + "lastModified": 1763651264, + "narHash": "sha256-8vvwZbw0s7YvBMJeyPVpWke6lg6ROgtts5N2/SMCcv4=", "owner": "nix-community", "repo": "disko", - "rev": "af087d076d3860760b3323f6b583f4d828c1ac17", + "rev": "e86a89079587497174ccab6d0d142a65811a4fd9", "type": "github" }, "original": { @@ -46,11 +46,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1762488230, - "narHash": "sha256-b7FFUa+bQ8m5din6ylspTTeQvhTf7NNDwC3fPOwCkx4=", + "lastModified": 1763697825, + "narHash": "sha256-AgCCcVPOi1tuzuW5/StlwqBjRWSX62oL97qWuxrq5UA=", "owner": "rycee", "repo": "nur-expressions", - "rev": "05e744e2e2d174b2fd445e51ad38fb8356001a18", + "rev": "cefce78793603231be226fa77e7ad58e0e4899b8", "type": "gitlab" }, "original": { @@ -133,11 +133,11 @@ ] }, "locked": { - "lastModified": 1762463325, - "narHash": "sha256-33YUsWpPyeBZEWrKQ2a1gkRZ7i0XCC/2MYpU6BVeQSU=", + "lastModified": 1763748372, + "narHash": "sha256-AUc78Qv3sWir0hvbmfXoZ7Jzq9VVL97l+sP9Jgms+JU=", "owner": "nix-community", "repo": "home-manager", - "rev": "0562fef070a1027325dd4ea10813d64d2c967b39", + "rev": "d10a9b16b2a3ee28433f3d1c603f4e9f1fecb8e1", "type": "github" }, "original": { @@ -185,11 +185,11 @@ ] }, "locked": { - "lastModified": 1761960361, - "narHash": "sha256-FvuAw56NIVJpS3Kr8Wv9PpU4eehZMcdIVkxjStuYmqc=", + "lastModified": 1763435414, + "narHash": "sha256-i2467FddWfd19q5Qoj+1/BAeg6LZmM5m4mYGRSQn/as=", "ref": "refs/heads/main", - "rev": "c47f62187601ea2991b79a9bacdbfdf76cd29fbe", - "revCount": 167, + "rev": "192c92b603731fbc1bade6c1b18c8d8a0086f703", + "revCount": 169, "type": "git", "url": "https://git.lix.systems/lix-project/nixos-module.git" }, @@ -227,11 +227,11 @@ ] }, "locked": { - "lastModified": 1762501326, - "narHash": "sha256-QbhsksHaIN6qU3oXhwUFbYycKX1GRxObpQSWAM5fhRY=", + "lastModified": 1763505477, + "narHash": "sha256-nJRd4LY2kT3OELfHqdgWjvToNZ4w+zKCMzS2R6z4sXE=", "owner": "LnL7", "repo": "nix-darwin", - "rev": "e2b82ebd0f990a5d1b68fcc761b3d6383c86ccfd", + "rev": "3bda9f6b14161becbd07b3c56411f1670e19b9b5", "type": "github" }, "original": { @@ -268,11 +268,11 @@ ] }, "locked": { - "lastModified": 1762480525, - "narHash": "sha256-7akzuLV8uKP3ym67TJoSIT5hTeC5FG8H745Y/7/7J+8=", + "lastModified": 1763690163, + "narHash": "sha256-MMl9P8f17unCvlk2IAinnMq/P72f51UUHVRIYnojT7w=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "b8b0b207dc13cb7b004f9d0c1d2b76a85e9494c8", + "rev": "590349d9faeb398a037205c2927ffbaede980539", "type": "github" }, "original": { @@ -283,11 +283,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1762463231, - "narHash": "sha256-hv1mG5j5PTbnWbtHHomzTus77pIxsc4x8VrMjc7+/YE=", + "lastModified": 1762847253, + "narHash": "sha256-BWWnUUT01lPwCWUvS0p6Px5UOBFeXJ8jR+ZdLX8IbrU=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "52113c4f5cfd1e823001310e56d9c8d0699a6226", + "rev": "899dc449bc6428b9ee6b3b8f771ca2b0ef945ab9", "type": "github" }, "original": { @@ -315,11 +315,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1762363567, - "narHash": "sha256-YRqMDEtSMbitIMj+JLpheSz0pwEr0Rmy5mC7myl17xs=", + "lastModified": 1763421233, + "narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ae814fd3904b621d8ab97418f1d0f2eb0d3716f4", + "rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648", "type": "github" }, "original": { @@ -370,11 +370,11 @@ ] }, "locked": { - "lastModified": 1760998189, - "narHash": "sha256-ee2e1/AeGL5X8oy/HXsZQvZnae6XfEVdstGopKucYLY=", + "lastModified": 1763607916, + "narHash": "sha256-VefBA1JWRXM929mBAFohFUtQJLUnEwZ2vmYUNkFnSjE=", "owner": "Mic92", "repo": "sops-nix", - "rev": "5a7d18b5c55642df5c432aadb757140edfeb70b3", + "rev": "877bb495a6f8faf0d89fc10bd142c4b7ed2bcc0b", "type": "github" }, "original": { diff --git a/modules/home-manager-modules/programs/discord.nix b/modules/home-manager-modules/programs/discord.nix index d5d7192..71b09b2 100644 --- a/modules/home-manager-modules/programs/discord.nix +++ b/modules/home-manager-modules/programs/discord.nix @@ -1,19 +1,9 @@ { lib, - pkgs, config, ... }: { - options.programs.discord = { - enable = lib.mkEnableOption "enable discord"; - }; - config = lib.mkIf config.programs.discord.enable (lib.mkMerge [ - { - home.packages = with pkgs; [ - discord - ]; - } ( lib.mkIf config.impermanence.enable { home.persistence."/persist${config.home.homeDirectory}" = { diff --git a/util/default.nix b/util/default.nix index 97bfa49..66e300b 100644 --- a/util/default.nix +++ b/util/default.nix @@ -79,7 +79,7 @@ in { impermanence.nixosModules.impermanence home-manager.nixosModules.home-manager disko.nixosModules.disko - lix-module.nixosModules.default + # lix-module.nixosModules.default ../modules/nixos-modules ../configurations/nixos/${host} ]; From f660b601e2d7c039509595533e5721736498e19c Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Wed, 26 Nov 2025 21:42:02 -0600 Subject: [PATCH 58/61] feat: installed noita entangled worlds on horizon --- .../nixos/horizon/configuration.nix | 1 + flake.lock | 75 +++++++++++++++++++ flake.nix | 6 ++ modules/common-modules/overlays/default.nix | 4 + modules/common-modules/pkgs/default.nix | 3 - .../pkgs/noita-entangled-worlds.nix | 46 ------------ 6 files changed, 86 insertions(+), 49 deletions(-) delete mode 100644 modules/common-modules/pkgs/noita-entangled-worlds.nix diff --git a/configurations/nixos/horizon/configuration.nix b/configurations/nixos/horizon/configuration.nix index 0e86fe7..0245253 100644 --- a/configurations/nixos/horizon/configuration.nix +++ b/configurations/nixos/horizon/configuration.nix @@ -88,6 +88,7 @@ environment.systemPackages = with pkgs; [ cachefilesd webtoon-dl + noita_entangled_worlds ]; services.cachefilesd.enable = true; diff --git a/flake.lock b/flake.lock index e9d259b..a3c552f 100644 --- a/flake.lock +++ b/flake.lock @@ -329,6 +329,43 @@ "type": "github" } }, + "nixpkgs_3": { + "locked": { + "lastModified": 1759070547, + "narHash": "sha256-JVZl8NaVRYb0+381nl7LvPE+A774/dRpif01FKLrYFQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "647e5c14cbd5067f44ac86b74f014962df460840", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "noita-entangled-worlds": { + "inputs": { + "nixpkgs": "nixpkgs_3", + "rust-overlay": "rust-overlay", + "systems": "systems_3" + }, + "locked": { + "lastModified": 1764204484, + "narHash": "sha256-S45ghD/YjcKDy8Mz3DYklLMaA/z6f6mTbx0i7pAktYk=", + "owner": "IntQuant", + "repo": "noita_entangled_worlds", + "rev": "ab2c2162157140ab519fa19f6737c044e1ed0e3b", + "type": "github" + }, + "original": { + "owner": "IntQuant", + "ref": "master", + "repo": "noita_entangled_worlds", + "type": "github" + } + }, "root": { "inputs": { "disko": "disko", @@ -343,10 +380,32 @@ "nix-vscode-extensions": "nix-vscode-extensions", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs_2", + "noita-entangled-worlds": "noita-entangled-worlds", "secrets": "secrets", "sops-nix": "sops-nix" } }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "noita-entangled-worlds", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1759199574, + "narHash": "sha256-w24RYly3VSVKp98rVfCI1nFYfQ0VoWmShtKPCbXgK6A=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "381776b12d0d125edd7c1930c2041a1471e586c0", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "secrets": { "flake": false, "locked": { @@ -412,6 +471,22 @@ "repo": "default", "type": "github" } + }, + "systems_3": { + "flake": false, + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 6f85fa3..e935688 100644 --- a/flake.nix +++ b/flake.nix @@ -77,6 +77,12 @@ url = "github:utensils/mcp-nixos"; inputs.nixpkgs.follows = "nixpkgs"; }; + + # Noita Entangled Worlds package + # Not following our nixpkgs so it can use its own rust-overlay configuration + noita-entangled-worlds = { + url = "github:IntQuant/noita_entangled_worlds/master"; + }; }; outputs = { diff --git a/modules/common-modules/overlays/default.nix b/modules/common-modules/overlays/default.nix index 2c0f712..f658e8a 100644 --- a/modules/common-modules/overlays/default.nix +++ b/modules/common-modules/overlays/default.nix @@ -2,5 +2,9 @@ {inputs, ...}: { nixpkgs.overlays = [ inputs.nix-vscode-extensions.overlays.default + # Add noita_entangled_worlds from upstream flake to pkgs + (final: prev: { + noita_entangled_worlds = inputs.noita-entangled-worlds.packages.${prev.system}.noita-proxy; + }) ]; } diff --git a/modules/common-modules/pkgs/default.nix b/modules/common-modules/pkgs/default.nix index 612dd08..2afc9f2 100644 --- a/modules/common-modules/pkgs/default.nix +++ b/modules/common-modules/pkgs/default.nix @@ -20,9 +20,6 @@ ./prostudiomasters.nix {}; }) - (final: prev: { - noita_entangled_worlds = pkgs.callPackage ./noita-entangled-worlds.nix {}; - }) (final: prev: { gdx-liftoff = pkgs.callPackage ./gdx-liftoff.nix {}; }) diff --git a/modules/common-modules/pkgs/noita-entangled-worlds.nix b/modules/common-modules/pkgs/noita-entangled-worlds.nix deleted file mode 100644 index 322ce41..0000000 --- a/modules/common-modules/pkgs/noita-entangled-worlds.nix +++ /dev/null @@ -1,46 +0,0 @@ -# not working yet -{ - pkgs, - rustPlatform, - fetchFromGitHub, - ... -}: let - version = "1.5.3"; - repo = fetchFromGitHub { - owner = "IntQuant"; - repo = "noita_entangled_worlds"; - rev = "v${version}"; - hash = "sha256-frrpD0aWTeDbZYtp15R+quUUAZf7OvHlbSLtGJJtAqk="; - }; -in - rustPlatform.buildRustPackage { - name = "noita-proxy-${version}"; - src = repo + "/noita-proxy"; - prePatch = '' - substituteInPlace Cargo.toml \ - --replace "path = \"../shared\"" "path = \"${repo + "/shared"}\"" - ''; - nativeBuildInputs = with pkgs; [ - pkg-config - python3 - cmake - ]; - buildInputs = with pkgs; [ - openssl - openssl.dev - libpulseaudio - libjack2 - alsa-lib - xorg.libxcb - xorg.libxcb.dev - libopus - ]; - propagatedBuildInputs = with pkgs; [ - steamworks-sdk-redist - ]; - runtimeDependencies = with pkgs; [ - steamworks-sdk-redist - ]; - doCheck = false; - cargoHash = "sha256-TzUS6d6PopgGf2i1yVaXaXdzNrvfSz+Gv67BAtxYmb4="; - } From 1d5bb9e945b5bf6e49bc54db57d41e903903ade2 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Wed, 26 Nov 2025 21:52:17 -0600 Subject: [PATCH 59/61] feat: installed noita proxy for eve and leyla users --- configurations/home-manager/eve/packages.nix | 1 + .../home-manager/leyla/packages/default.nix | 1 + configurations/nixos/horizon/configuration.nix | 1 - .../home-manager-modules/programs/default.nix | 1 + .../programs/noita-entangled-worlds.nix | 18 ++++++++++++++++++ 5 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 modules/home-manager-modules/programs/noita-entangled-worlds.nix diff --git a/configurations/home-manager/eve/packages.nix b/configurations/home-manager/eve/packages.nix index f650a70..6b3c2e2 100644 --- a/configurations/home-manager/eve/packages.nix +++ b/configurations/home-manager/eve/packages.nix @@ -73,6 +73,7 @@ in { tor-browser.enable = true; olympus.enable = true; libreoffice.enable = true; + noita-entangled-worlds.enable = true; claude-code.enable = osConfig.host.ai.enable; diff --git a/configurations/home-manager/leyla/packages/default.nix b/configurations/home-manager/leyla/packages/default.nix index d065739..bc41350 100644 --- a/configurations/home-manager/leyla/packages/default.nix +++ b/configurations/home-manager/leyla/packages/default.nix @@ -68,6 +68,7 @@ in { qflipper.enable = true; openvpn.enable = true; noisetorch.enable = true; + noita-entangled-worlds.enable = true; tor-browser.enable = true; gdx-liftoff.enable = true; }) diff --git a/configurations/nixos/horizon/configuration.nix b/configurations/nixos/horizon/configuration.nix index 0245253..0e86fe7 100644 --- a/configurations/nixos/horizon/configuration.nix +++ b/configurations/nixos/horizon/configuration.nix @@ -88,7 +88,6 @@ environment.systemPackages = with pkgs; [ cachefilesd webtoon-dl - noita_entangled_worlds ]; services.cachefilesd.enable = true; diff --git a/modules/home-manager-modules/programs/default.nix b/modules/home-manager-modules/programs/default.nix index c164c44..e70cfc8 100644 --- a/modules/home-manager-modules/programs/default.nix +++ b/modules/home-manager-modules/programs/default.nix @@ -31,6 +31,7 @@ ./freecad.nix ./onionshare.nix ./mfoc.nix + ./noita-entangled-worlds.nix ./pdfarranger.nix ./picard.nix ./qflipper.nix diff --git a/modules/home-manager-modules/programs/noita-entangled-worlds.nix b/modules/home-manager-modules/programs/noita-entangled-worlds.nix new file mode 100644 index 0000000..3f3af64 --- /dev/null +++ b/modules/home-manager-modules/programs/noita-entangled-worlds.nix @@ -0,0 +1,18 @@ +{ + lib, + pkgs, + config, + ... +}: { + options = { + programs.noita-entangled-worlds = { + enable = lib.mkEnableOption "Noita Entangled Worlds multiplayer mod"; + }; + }; + + config = lib.mkIf config.programs.noita-entangled-worlds.enable { + home.packages = with pkgs; [ + noita_entangled_worlds + ]; + }; +} From 5776640b5d431d9520b8c42d7442ef4b798e4e91 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Thu, 27 Nov 2025 14:26:33 -0600 Subject: [PATCH 60/61] feat: only allow post quantum crypto --- modules/nixos-modules/ssh.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/nixos-modules/ssh.nix b/modules/nixos-modules/ssh.nix index 6f5fac1..0a82116 100644 --- a/modules/nixos-modules/ssh.nix +++ b/modules/nixos-modules/ssh.nix @@ -16,6 +16,8 @@ }; }; }; + + programs.ssh.kexAlgorithms = config.services.openssh.settings.KexAlgorithms; } (lib.mkIf config.host.impermanence.enable { environment.persistence."/persist/system/root" = { From b9251029d57b808af7af130d166a6dd2b282b69a Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Thu, 27 Nov 2025 14:33:11 -0600 Subject: [PATCH 61/61] feat: fixed deprecation warning --- modules/common-modules/overlays/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/common-modules/overlays/default.nix b/modules/common-modules/overlays/default.nix index f658e8a..3def9e9 100644 --- a/modules/common-modules/overlays/default.nix +++ b/modules/common-modules/overlays/default.nix @@ -4,7 +4,7 @@ inputs.nix-vscode-extensions.overlays.default # Add noita_entangled_worlds from upstream flake to pkgs (final: prev: { - noita_entangled_worlds = inputs.noita-entangled-worlds.packages.${prev.system}.noita-proxy; + noita_entangled_worlds = inputs.noita-entangled-worlds.packages.${prev.stdenv.hostPlatform.system}.noita-proxy; }) ]; }