diff --git a/checks/default.nix b/checks/default.nix index 03e5b6b..737313d 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -1,82 +1,47 @@ -{ self, ... }: +{ flake-inputs }: +let + inherit (flake-inputs.nixpkgs) lib; + pkgs = flake-inputs.nixpkgs.legacyPackages.x86_64-linux; + checkLib = pkgs.callPackage ./lib.nix { }; +in { - perSystem = + x86_64-linux = lib.mergeAttrsList [ + flake-inputs.self.nixosConfigurations.hetzner-1.config.serviceTests + { - inputs', - lib, - pkgs, - ... - }: - let - mkLint = - { - name, - fileset, - checkInputs ? [ ], - script, - }: - pkgs.stdenvNoCC.mkDerivation { - inherit name; + nix = checkLib.mkLint { + name = "nix-lints"; + fileset = lib.fileset.fileFilter (file: file.hasExt "nix") ../.; - src = lib.fileset.toSource { - root = ../.; - fileset = lib.fileset.difference fileset ( - lib.fileset.fileFilter ( - file: file.type != "regular" || file.name == "hardware-configuration.nix" - ) ../. - ); - }; + checkInputs = lib.attrValues { + inherit (pkgs) deadnix nixfmt-rfc-style; - checkInputs = [ pkgs.nushell ] ++ checkInputs; - - checkPhase = '' - nu -c '${script}' | tee $out - ''; - - dontPatch = true; - dontConfigure = true; - dontBuild = true; - dontInstall = true; - dontFixup = true; - doCheck = true; - }; - in - { - checks = { - nix = mkLint { - name = "nix-lints"; - fileset = lib.fileset.fileFilter (file: file.hasExt "nix") ../.; - - checkInputs = lib.attrValues { - inherit (pkgs) deadnix nixfmt-rfc-style; - - statix = pkgs.statix.overrideAttrs (old: { - patches = old.patches ++ [ - (pkgs.fetchpatch { - url = "https://github.com/oppiliappan/statix/commit/925dec39bb705acbbe77178b4d658fe1b752abbb.patch"; - hash = "sha256-0wacO6wuYJ4ufN9PGucRVJucFdFFNF+NoHYIrLXsCWs="; - }) - ]; - }); - }; - - script = /* bash */ '' - statix check **/*.nix - deadnix --fail **/*.nix - nixfmt --check --strict **/*.nix - ''; + statix = pkgs.statix.overrideAttrs (old: { + patches = old.patches ++ [ + (pkgs.fetchpatch { + url = "https://github.com/oppiliappan/statix/commit/925dec39bb705acbbe77178b4d658fe1b752abbb.patch"; + hash = "sha256-0wacO6wuYJ4ufN9PGucRVJucFdFFNF+NoHYIrLXsCWs="; + }) + ]; + }); }; - lockfile = mkLint { - name = "nix-lockfile"; - fileset = ../flake.lock; - checkInputs = lib.attrValues { inherit (inputs'.flint.packages) flint; }; + script = '' + statix check **/*.nix + deadnix --fail **/*.nix + nixfmt --check --strict **/*.nix + ''; + }; - script = /* bash */ '' - flint --fail-if-multiple-versions - ''; - }; - } - // self.nixosConfigurations.hetzner-1.config.serviceTests; - }; + lockfile = checkLib.mkLint { + name = "nix-lockfile"; + fileset = ../flake.lock; + checkInputs = lib.attrValues { inherit (flake-inputs.flint.packages.x86_64-linux) flint; }; + + script = '' + flint --fail-if-multiple-versions + ''; + }; + } + ]; } diff --git a/checks/lib.nix b/checks/lib.nix new file mode 100644 index 0000000..d38cd21 --- /dev/null +++ b/checks/lib.nix @@ -0,0 +1,35 @@ +{ pkgs, lib, ... }: +{ + mkLint = + { + name, + fileset, + checkInputs ? [ ], + script, + }: + pkgs.stdenvNoCC.mkDerivation { + inherit name; + + src = lib.fileset.toSource { + root = ../.; + fileset = lib.fileset.difference fileset ( + lib.fileset.fileFilter ( + file: file.type != "regular" || file.name == "hardware-configuration.nix" + ) ../. + ); + }; + + checkInputs = [ pkgs.nushell ] ++ checkInputs; + + checkPhase = '' + nu -c '${script}' | tee $out + ''; + + dontPatch = true; + dontConfigure = true; + dontBuild = true; + dontInstall = true; + dontFixup = true; + doCheck = true; + }; +} diff --git a/configuration/default.nix b/configuration/default.nix index ef68727..456d12d 100644 --- a/configuration/default.nix +++ b/configuration/default.nix @@ -1,5 +1,4 @@ { - pkgs, lib, modulesPath, flake-inputs, @@ -54,19 +53,6 @@ }; logrotate.enable = true; - - postgresql = { - package = pkgs.postgresql_14; - enable = true; - - # Only enable connections via the unix socket, and check with the - # OS to make sure the user matches the database name. - # - # See https://www.postgresql.org/docs/current/auth-pg-hba-conf.html - authentication = '' - local sameuser all peer - ''; - }; }; security = { diff --git a/configuration/hardware-specific/hetzner/default.nix b/configuration/hardware-specific/hetzner/default.nix index 3b60011..4d0408c 100644 --- a/configuration/hardware-specific/hetzner/default.nix +++ b/configuration/hardware-specific/hetzner/default.nix @@ -2,7 +2,6 @@ imports = [ ./hardware-configuration.nix ./disko.nix - ./vm.nix ]; # Intel's special encrypted memory<->CPU feature. Hetzner's BIOS diff --git a/configuration/hardware-specific/hetzner/disko.nix b/configuration/hardware-specific/hetzner/disko.nix index 6b769d2..7e1acd7 100644 --- a/configuration/hardware-specific/hetzner/disko.nix +++ b/configuration/hardware-specific/hetzner/disko.nix @@ -80,7 +80,7 @@ inherit mountOptions; mountpoint = "/var"; }; - "/volume/var/lib/private/continuwuity" = { + "/volume/var/lib/private/matrix-conduit" = { mountOptions = [ # Explicitly don't compress here, since # conduwuit's database does compression by @@ -89,7 +89,7 @@ # if btrfs compresses it) "noatime" ]; - mountpoint = "/var/lib/private/continuwuity"; + mountpoint = "/var/lib/private/matrix-conduit"; }; "/volume/nix-store" = { inherit mountOptions; diff --git a/configuration/hardware-specific/hetzner/vm.nix b/configuration/hardware-specific/hetzner/vm.nix deleted file mode 100644 index 7ecf8f8..0000000 --- a/configuration/hardware-specific/hetzner/vm.nix +++ /dev/null @@ -1,70 +0,0 @@ -{ lib, ... }: -{ - virtualisation.vmVariant = { - users.users.tlater.password = "insecure"; - - # Disable graphical tty so -curses works - boot.kernelParams = [ "nomodeset" ]; - - networking.hostName = lib.mkForce "testvm"; - - services = { - # Sets the base domain for nginx to a local domain so that we can - # easily test locally with the VM. - nginx.domain = lib.mkForce "dev.local"; - - # Don't run this - batteryManager.enable = lib.mkForce false; - btrfs.autoScrub.enable = lib.mkForce false; - - openssh.hostKeys = lib.mkForce [ - { - type = "rsa"; - bits = 4096; - path = "/etc/staging.key"; - } - ]; - }; - - # Use the staging secrets - sops.defaultSopsFile = lib.mkOverride 99 ../../../keys/staging.yaml; - - systemd.network.networks."10-eth0" = { - matchConfig.Name = "eth0"; - gateway = [ "192.168.9.1" ]; - networkConfig = { - Address = "192.168.9.2/24"; - }; - }; - - # Both so we have a predictable key for the staging env, as well as - # to have a static key for decrypting the sops secrets for the - # staging env. - environment.etc."staging.key" = { - mode = "0400"; - source = ../../../keys/hosts/staging.key; - }; - - # Pretend the acme renew succeeds. - # - # TODO(tlater): Set up pebble to retrieve certs "properly" - # instead - systemd.services."acme-order-renew-tlater.net".script = '' - touch out/acme-success - ''; - - virtualisation = { - memorySize = 3941; - cores = 2; - graphics = false; - diskSize = 1024 * 20; - - qemu = { - networkingOptions = lib.mkForce [ - "-device virtio-net,netdev=n1" - "-netdev bridge,id=n1,br=br0,helper=$(which qemu-bridge-helper)" - ]; - }; - }; - }; -} diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix new file mode 100644 index 0000000..7696439 --- /dev/null +++ b/configuration/hardware-specific/vm.nix @@ -0,0 +1,63 @@ +{ lib, ... }: +{ + users.users.tlater.password = "insecure"; + + # Disable graphical tty so -curses works + boot.kernelParams = [ "nomodeset" ]; + + networking.hostName = "testvm"; + + systemd.services.matrix-hookshot.enable = lib.mkForce false; + + services = { + # Sets the base domain for nginx to a local domain so that we can + # easily test locally with the VM. + nginx.domain = "dev.local"; + + # Don't run this + batteryManager.enable = lib.mkForce false; + + openssh.hostKeys = lib.mkForce [ + { + type = "rsa"; + bits = 4096; + path = "/etc/staging.key"; + } + ]; + }; + + # Use the staging secrets + sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml; + + systemd.network.networks."10-eth0" = { + matchConfig.Name = "eth0"; + gateway = [ "192.168.9.1" ]; + networkConfig = { + Address = "192.168.9.2/24"; + }; + }; + + # Both so we have a predictable key for the staging env, as well as + # to have a static key for decrypting the sops secrets for the + # staging env. + environment.etc."staging.key" = { + mode = "0400"; + source = ../../keys/hosts/staging.key; + }; + + virtualisation.vmVariant = { + virtualisation = { + memorySize = 3941; + cores = 2; + graphics = false; + diskSize = 1024 * 20; + }; + + virtualisation.qemu = { + networkingOptions = lib.mkForce [ + "-device virtio-net,netdev=n1" + "-netdev bridge,id=n1,br=br0,helper=$(which qemu-bridge-helper)" + ]; + }; + }; +} diff --git a/configuration/nginx/ssl.nix b/configuration/nginx/ssl.nix index f3fac13..56bfa78 100644 --- a/configuration/nginx/ssl.nix +++ b/configuration/nginx/ssl.nix @@ -51,9 +51,20 @@ paths = [ "/var/lib/acme/tlater.net" ]; }; - systemd.services.nginx.serviceConfig.SupplementaryGroups = [ - config.security.acme.certs."tlater.net".group - ]; + systemd.services = { + nginx.serviceConfig.SupplementaryGroups = [ config.security.acme.certs."tlater.net".group ]; + + # Don't attempt to retrieve a certificate if the domain name + # doesn't *actually* match the cert name + # + # TODO(tlater): Set up pebble to retrieve certs "properly" + # instead + "acme-tlater.net".serviceConfig.ExecCondition = + let + confirm = ''[[ "tlater.net" = "${config.services.nginx.domain}" ]]''; + in + ''${pkgs.runtimeShell} -c '${confirm}' ''; + }; sops.secrets = { "porkbun/api-key".owner = "acme"; @@ -74,18 +85,10 @@ security.acme.certs."tlater.net".extraDomainNames = [ config.services.nginx.domain ]; - # Pretend the acme renew succeeds. - # - # TODO(tlater): Set up pebble to retrieve certs "properly" - # instead - systemd.services."acme-order-renew-tlater.net".script = '' - touch out/acme-success - ''; - services.nginx = { - domain = "testHost.test"; + domain = "testHost"; - virtualHosts."${config.services.nginx.domain}.local" = { + virtualHosts."${config.services.nginx.domain}" = { useACMEHost = "tlater.net"; onlySSL = true; enableHSTS = true; @@ -106,7 +109,6 @@ { pkgs, ... }: { environment.systemPackages = [ pkgs.curl ]; - networking.hosts."192.168.1.2" = [ "testHost.test" ]; }; }; @@ -123,7 +125,7 @@ "--silent", "--dump-header -", "--cacert /certs/tlater.net/fullchain.pem", - "https://testHost.test", + "https://testHost", "-o /dev/null" ])) diff --git a/configuration/services/conduit/default.nix b/configuration/services/conduit/default.nix index e1a5f60..b6f8f27 100644 --- a/configuration/services/conduit/default.nix +++ b/configuration/services/conduit/default.nix @@ -7,12 +7,15 @@ let inherit (lib.strings) concatMapStringsSep; - cfg = config.services.matrix-continuwuity; + cfg = config.services.matrix-conduit; domain = "matrix.${config.services.nginx.domain}"; turn-realm = "turn.${config.services.nginx.domain}"; in { - imports = [ ./heisenbridge.nix ]; + imports = [ + ./heisenbridge.nix + ./matrix-hookshot.nix + ]; networking.firewall = { allowedTCPPorts = [ @@ -45,14 +48,14 @@ in }; services = { - matrix-continuwuity = { + matrix-conduit = { enable = true; package = pkgs.matrix-continuwuity; settings.global = { - address = [ "127.0.0.1" ]; + address = "127.0.0.1"; server_name = domain; new_user_displayname_suffix = "🦆"; - turn_secret_file = "/run/credentials/continuwuity.service/turn-secret"; + allow_check_for_updates = true; # Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended # This is primarily to make sliding sync work @@ -173,30 +176,35 @@ in locations = { "/_matrix" = { - proxyPass = "http://${lib.head cfg.settings.global.address}:${toString cfg.settings.global.port}"; + proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}"; # Recommended by conduit extraConfig = '' proxy_buffering off; ''; }; "/.well-known/matrix" = { - proxyPass = "http://${lib.head cfg.settings.global.address}:${toString cfg.settings.global.port}"; + proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}"; }; }; }; backups.conduit = { user = "root"; - paths = [ "/var/lib/private/matrix-continuwuity/" ]; + paths = [ "/var/lib/private/matrix-conduit/" ]; # Other services store their data in conduit, so no other services # need to be shut down currently. - pauseServices = [ "continuwuity.service" ]; + pauseServices = [ "conduit.service" ]; }; }; - systemd.services.continuwuity.serviceConfig.LoadCredential = "turn-secret:${ - config.sops.secrets."turn/env".path - }"; + systemd.services.conduit.serviceConfig = { + ExecStart = lib.mkForce "${config.services.matrix-conduit.package}/bin/conduwuit"; + # Pass in the TURN secret via EnvironmentFile, not supported by + # upstream module currently. + # + # See also https://gitlab.com/famedly/conduit/-/issues/314 + EnvironmentFile = config.sops.secrets."turn/env".path; + }; systemd.services.coturn.serviceConfig.SupplementaryGroups = [ config.security.acme.certs."tlater.net".group diff --git a/configuration/services/conduit/heisenbridge.nix b/configuration/services/conduit/heisenbridge.nix index 0fe6bc5..5441639 100644 --- a/configuration/services/conduit/heisenbridge.nix +++ b/configuration/services/conduit/heisenbridge.nix @@ -5,7 +5,7 @@ ... }: let - conduitCfg = config.services.matrix-continuwuity; + conduitCfg = config.services.matrix-conduit; matrixLib = pkgs.callPackage ./lib.nix { }; in { @@ -36,7 +36,7 @@ in { description = "Matrix<->IRC bridge"; wantedBy = [ "multi-user.target" ]; - after = [ "continuwuity.service" ]; + after = [ "conduit.service" ]; serviceConfig = { Type = "exec"; diff --git a/configuration/services/conduit/matrix-hookshot.nix b/configuration/services/conduit/matrix-hookshot.nix new file mode 100644 index 0000000..c1fec82 --- /dev/null +++ b/configuration/services/conduit/matrix-hookshot.nix @@ -0,0 +1,172 @@ +{ + pkgs, + lib, + config, + ... +}: +let + matrixLib = pkgs.callPackage ./lib.nix { }; + + cfg = config.services.matrix-hookshot; + conduitCfg = config.services.matrix-conduit; + + domain = conduitCfg.settings.global.server_name; + + registration = matrixLib.writeRegistrationScript { + id = "matrix-hookshot"; + url = "http://127.0.0.1:9993"; + sender_localpart = "hookshot"; + + namespaces = { + aliases = [ ]; + rooms = [ ]; + users = [ + { + regex = "@${cfg.settings.generic.userIdPrefix}.*:${domain}"; + exclusive = true; + } + ]; + }; + + # Encryption support + # TODO(tlater): Enable when + # https://github.com/matrix-org/matrix-hookshot/issues/1060 is + # fixed + # extraSettings = { + # "de.sorunome.msc2409.push_ephemeral" = true; + # push_ephemeral = true; + # "org.matrix.msc3202" = true; + # }; + + runtimeRegistration = "${cfg.registrationFile}"; + }; +in +{ + # users = { + # users.matrix-hookshot = { + # home = "/run/matrix-hookshot"; + # group = "matrix-hookshot"; + # isSystemUser = true; + # }; + + # groups.matrix-hookshot = { }; + # }; + + systemd.services.matrix-hookshot = { + serviceConfig = { + Type = lib.mkForce "exec"; + + LoadCredential = "matrix-hookshot:/run/secrets/matrix-hookshot"; + inherit (registration) ExecStartPre; + + # Some library in matrix-hookshot wants a home directory + Environment = [ "HOME=/run/matrix-hookshot" ]; + + # User = "matrix-hookshot"; + DynamicUser = true; + StateDirectory = "matrix-hookshot"; + RuntimeDirectory = "matrix-hookshot"; + RuntimeDirectoryMode = "0700"; + + RestrictNamespaces = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ + # "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; + LockPersonality = true; + RestrictRealtime = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + UMask = 77; + }; + }; + + # services.redis.servers.matrix-hookshot = { + # enable = true; + # user = "matrix-hookshot"; + # }; + + services.matrix-hookshot = { + enable = true; + + serviceDependencies = [ "conduit.service" ]; + + registrationFile = "/run/matrix-hookshot/registration.yaml"; + + settings = { + bridge = { + inherit domain; + url = "http://localhost:${toString conduitCfg.settings.global.port}"; + mediaUrl = conduitCfg.settings.global.well_known.client; + port = 9993; + bindAddress = "127.0.0.1"; + }; + + bot.displayname = "Hookshot"; + + # cache.redisUri = "redis://${config.services.redis.servers.matrix-hookshot.unixSocket}"; + + generic = { + enabled = true; + outbound = false; + # Only allow webhooks from localhost for the moment + urlPrefix = "http://127.0.0.1:9000/webhook"; + userIdPrefix = "_webhooks_"; + allowJsTransformationFunctions = true; + }; + + # TODO(tlater): Enable when + # https://github.com/matrix-org/matrix-hookshot/issues/1060 is + # fixed + # encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore"; + + permissions = [ + { + actor = "matrix.tlater.net"; + services = [ + { + service = "*"; + level = "notifications"; + } + ]; + } + { + actor = "@tlater:matrix.tlater.net"; + services = [ + { + service = "*"; + level = "admin"; + } + ]; + } + ]; + + listeners = [ + { + port = 9000; + resources = [ "webhooks" ]; + } + { + port = 9001; + resources = [ "metrics" ]; + } + ]; + + metrics.enabled = true; + }; + }; + + sops.secrets = { + # Accessed via systemd cred through /run/secrets/matrix-hookshot + "matrix-hookshot/as-token" = { }; + "matrix-hookshot/hs-token" = { }; + }; +} diff --git a/configuration/services/configs/starbound.json b/configuration/services/configs/starbound.json new file mode 100644 index 0000000..d995fdf --- /dev/null +++ b/configuration/services/configs/starbound.json @@ -0,0 +1,50 @@ +{ + "allowAdminCommands" : true, + "allowAdminCommandsFromAnyone" : false, + "allowAnonymousConnections" : true, + "allowAssetsMismatch" : true, + "anonymousConnectionsAreAdmin" : false, + "bannedIPs" : [], + "bannedUuids" : [], + "checkAssetsDigest" : false, + "clearPlayerFiles" : false, + "clearUniverseFiles" : false, + "clientIPJoinable" : false, + "clientP2PJoinable" : true, + "configurationVersion" : { + "basic" : 2, + "server" : 4 + }, + "crafting" : { + "filterHaveMaterials" : false + }, + "gameServerBind" : "::", + "gameServerPort" : 21025, + "interactiveHighlight" : true, + "inventory" : { + "pickupToActionBar" : true + }, + "maxPlayers" : 8, + "maxTeamSize" : 4, + "monochromeLighting" : false, + "playerBackupFileCount" : 3, + "queryServerBind" : "::", + "queryServerPort" : 21025, + "rconServerBind" : "::", + "rconServerPassword" : "", + "rconServerPort" : 21026, + "rconServerTimeout" : 1000, + "runQueryServer" : false, + "runRconServer" : false, + "safeScripts" : true, + "scriptInstructionLimit" : 10000000, + "scriptInstructionMeasureInterval" : 10000, + "scriptProfilingEnabled" : false, + "scriptRecursionLimit" : 100, + "serverFidelity" : "automatic", + "serverName" : "tlater.net", + "serverOverrideAssetsDigest" : null, + "serverUsers" : { + }, + "tutorialMessages" : true +} diff --git a/configuration/services/crowdsec.nix b/configuration/services/crowdsec.nix index 99eaa11..174115b 100644 --- a/configuration/services/crowdsec.nix +++ b/configuration/services/crowdsec.nix @@ -1,80 +1,45 @@ -{ config, lib, ... }: { - services = { - crowdsec = { - enable = true; - autoUpdateService = true; + pkgs, + config, + lib, + ... +}: +{ + security.crowdsec = { + enable = true; - settings = { - general.api.server = { - enable = true; - online_client.sharing = false; - }; + parserWhitelist = [ "10.45.249.2" ]; - lapi.credentialsFile = "/var/lib/crowdsec/state/local_credentials.yaml"; - }; + extraGroups = [ + "systemd-journal" + "nginx" + ]; - hub = { - collections = [ - "crowdsecurity/base-http-scenarios" - "crowdsecurity/http-cve" - "crowdsecurity/linux" - "crowdsecurity/nextcloud" - "crowdsecurity/nginx" - "crowdsecurity/sshd" - ]; - }; + acquisitions = [ + { + source = "journalctl"; + labels.type = "syslog"; + journalctl_filter = [ "SYSLOG_IDENTIFIER=Nextcloud" ]; + } - localConfig = { - acquisitions = [ - { - labels.type = "syslog"; - journalctl_filter = [ - "SYSLOG_IDENTIFIER=Nextcloud" - "SYSLOG_IDENTIFIER=sshd-session" - ]; - source = "journalctl"; - } + { + source = "journalctl"; + labels.type = "syslog"; + journalctl_filter = [ "SYSLOG_IDENTIFIER=sshd-session" ]; + } - { - labels.type = "nginx"; - filenames = [ - "/var/log/nginx/*.log" - ] - ++ lib.mapAttrsToList ( - vHost: _: "/var/log/nginx/${vHost}/access.log" - ) config.services.nginx.virtualHosts; - } - ]; + { + labels.type = "nginx"; + filenames = [ + "/var/log/nginx/*.log" + ] + ++ lib.mapAttrsToList ( + vHost: _: "/var/log/nginx/${vHost}/access.log" + ) config.services.nginx.virtualHosts; + } + ]; - parsers.s02Enrich = [ - { - name = "nixos/parser-whitelist"; - description = "Parser whitelist generated by the crowdsec NixOS module"; - whitelist = { - reason = "Filtered by NixOS whitelist"; - ip = [ "10.45.249.2" ]; - }; - } - ]; - - postOverflows.s01Whitelist = [ - { - description = "custom matrix whitelist"; - name = "tetsumaki/matrix"; - whitelist = { - reason = "whitelist false positive for matrix"; - expression = [ - "evt.Overflow.Alert.Events[0].GetMeta('target_fqdn') == '${config.services.matrix-continuwuity.settings.global.server_name}'" - "evt.Overflow.Alert.GetScenario() in ['crowdsecurity/http-probing', 'crowdsecurity/http-crawl-non_statics']" - ]; - }; - } - ]; - }; - }; - - crowdsec-firewall-bouncer = { + remediationComponents.firewallBouncer = { enable = true; settings.prometheus = { enabled = true; @@ -82,23 +47,37 @@ listen_port = "60601"; }; }; - - victoriametrics.scrapeConfigs = { - crowdsec.targets = - let - cfg = config.services.crowdsec.settings.general; - address = cfg.prometheus.listen_addr; - port = cfg.prometheus.listen_port; - in - [ "${address}:${toString port}" ]; - - csFirewallBouncer.targets = - let - cfg = config.services.crowdsec-firewall-bouncer.settings; - address = cfg.prometheus.listen_addr; - port = cfg.prometheus.listen_port; - in - [ "${address}:${toString port}" ]; - }; }; + + # Add whitelists for matrix + systemd.tmpfiles.settings."10-matrix" = + let + stateDir = config.security.crowdsec.stateDirectory; + in + { + "${stateDir}/config/postoverflows".d = { + user = "crowdsec"; + group = "crowdsec"; + mode = "0700"; + }; + + "${stateDir}/config/postoverflows/s01-whitelist".d = { + user = "crowdsec"; + group = "crowdsec"; + mode = "0700"; + }; + + "${stateDir}/config/postoverflows/s01-whitelist/matrix-whitelist.yaml"."L+".argument = + ((pkgs.formats.yaml { }).generate "crowdsec-matrix-whitelist.yaml" { + name = "tetsumaki/matrix"; + description = "custom matrix whitelist"; + whitelist = { + reason = "whitelist false positive for matrix"; + expression = [ + "evt.Overflow.Alert.Events[0].GetMeta('target_fqdn') == '${config.services.matrix-conduit.settings.global.server_name}'" + "evt.Overflow.Alert.GetScenario() in ['crowdsecurity/http-probing', 'crowdsecurity/http-crawl-non_statics']" + ]; + }; + }).outPath; + }; } diff --git a/configuration/services/default.nix b/configuration/services/default.nix index bee8f44..1624653 100644 --- a/configuration/services/default.nix +++ b/configuration/services/default.nix @@ -11,6 +11,8 @@ ./ntfy-sh ./minecraft.nix ./nextcloud.nix + ./postgres.nix + # ./starbound.nix -- Not currently used ./webserver.nix ./wireguard.nix ]; diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix index d7b9d02..5c8a21f 100644 --- a/configuration/services/foundryvtt.nix +++ b/configuration/services/foundryvtt.nix @@ -23,7 +23,7 @@ in minifyStaticFiles = true; proxySSL = true; proxyPort = 443; - package = flake-inputs.foundryvtt.packages.${pkgs.stdenv.hostPlatform.system}.foundryvtt_13; + package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_13; }; nginx.virtualHosts."${domain}" = diff --git a/configuration/services/immich.nix b/configuration/services/immich.nix index 1255490..39673d0 100644 --- a/configuration/services/immich.nix +++ b/configuration/services/immich.nix @@ -18,9 +18,6 @@ in enable = true; settings.server.externalDomain = "https://${hostName}"; - # We're using vectorchord now - database.enableVectors = false; - environment.IMMICH_TELEMETRY_INCLUDE = "all"; }; diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix index 3b757df..078f27c 100644 --- a/configuration/services/metrics/grafana.nix +++ b/configuration/services/metrics/grafana.nix @@ -8,93 +8,80 @@ in 443 ]; - services = { - grafana = { - enable = true; - settings = { - server = { - http_port = 3001; # Default overlaps with gitea - root_url = "https://metrics.tlater.net"; - }; - - security = { - admin_user = "tlater"; - admin_password = "$__file{${config.sops.secrets."grafana/adminPassword".path}}"; - secret_key = "$__file{${config.sops.secrets."grafana/secretKey".path}}"; - cookie_secure = true; - cookie_samesite = "strict"; - content_security_policy = true; - }; - - database = { - user = "grafana"; - name = "grafana"; - type = "postgres"; - host = "/run/postgresql"; - }; + services.grafana = { + enable = true; + settings = { + server = { + http_port = 3001; # Default overlaps with gitea + root_url = "https://metrics.tlater.net"; }; - declarativePlugins = [ - pkgs.grafanaPlugins.victoriametrics-metrics-datasource - pkgs.grafanaPlugins.victoriametrics-logs-datasource - ]; + security = { + admin_user = "tlater"; + admin_password = "$__file{${config.sops.secrets."grafana/adminPassword".path}}"; + secret_key = "$__file{${config.sops.secrets."grafana/secretKey".path}}"; + cookie_secure = true; + cookie_samesite = "strict"; + content_security_policy = true; + }; - provision = { - enable = true; - - datasources.settings.datasources = [ - { - name = "Victoriametrics - tlater.net"; - url = "http://localhost:8428"; - type = "victoriametrics-metrics-datasource"; - access = "proxy"; - isDefault = true; - } - - { - name = "Victorialogs - tlater.net"; - url = "http://${config.services.victorialogs.bindAddress}"; - type = "victoriametrics-logs-datasource"; - access = "proxy"; - } - ]; - - alerting.contactPoints.settings.contactPoints = [ - { - name = "ntfy"; - receivers = [ - { - uid = "ntfy"; - type = "webhook"; - settings.url = "http://${config.services.ntfy-sh.settings.listen-http}/local-alerts?template=grafana"; - } - ]; - } - ]; + database = { + user = "grafana"; + name = "grafana"; + type = "postgres"; + host = "/run/postgresql"; }; }; - postgresql = { - ensureUsers = [ + declarativePlugins = [ + pkgs.grafanaPlugins.victoriametrics-metrics-datasource + pkgs.grafanaPlugins.victoriametrics-logs-datasource + ]; + + provision = { + enable = true; + + datasources.settings.datasources = [ { - name = "grafana"; - ensureDBOwnership = true; + name = "Victoriametrics - tlater.net"; + url = "http://localhost:8428"; + type = "victoriametrics-metrics-datasource"; + access = "proxy"; + isDefault = true; + } + + { + name = "Victorialogs - tlater.net"; + url = "http://${config.services.victorialogs.bindAddress}"; + type = "victoriametrics-logs-datasource"; + access = "proxy"; } ]; - ensureDatabases = [ "grafana" ]; + alerting.contactPoints.settings.contactPoints = [ + { + name = "ntfy"; + receivers = [ + { + uid = "ntfy"; + type = "webhook"; + settings.url = "http://${config.services.ntfy-sh.settings.listen-http}/local-alerts?template=grafana"; + } + ]; + } + ]; }; + }; - nginx.virtualHosts."${domain}" = { - forceSSL = true; - useACMEHost = "tlater.net"; - enableHSTS = true; - locations = { - "/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; - "/api/live" = { - proxyWebsockets = true; - proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; - }; + services.nginx.virtualHosts."${domain}" = { + forceSSL = true; + useACMEHost = "tlater.net"; + enableHSTS = true; + locations = { + "/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; + "/api/live" = { + proxyWebsockets = true; + proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; }; }; }; diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix index 3befec0..96e09e5 100644 --- a/configuration/services/metrics/victoriametrics.nix +++ b/configuration/services/metrics/victoriametrics.nix @@ -68,11 +68,31 @@ in coturn.targets = [ "127.0.0.1:9641" ]; + crowdsec.targets = + let + address = config.security.crowdsec.settings.prometheus.listen_addr; + port = config.security.crowdsec.settings.prometheus.listen_port; + in + [ "${address}:${toString port}" ]; + + csFirewallBouncer.targets = + let + address = + config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_addr; + port = + config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_port; + in + [ "${address}:${toString port}" ]; + immich.targets = [ "127.0.0.1:8081" "127.0.0.1:8082" ]; + # Configured in the hookshot listeners, but it's hard to filter + # the correct values out of that config. + matrixHookshot.targets = [ "127.0.0.1:9001" ]; + victorialogs.targets = [ config.services.victorialogs.bindAddress ]; }; }; diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix index 6628d07..77cfa4c 100644 --- a/configuration/services/nextcloud.nix +++ b/configuration/services/nextcloud.nix @@ -5,7 +5,7 @@ ... }: let - nextcloud = pkgs.nextcloud32; + nextcloud = pkgs.nextcloud31; hostName = "nextcloud.${config.services.nginx.domain}"; in { @@ -103,19 +103,8 @@ in }; }; - services.postgresql = { - ensureUsers = [ - { - name = "nextcloud"; - ensureDBOwnership = true; - } - ]; - - ensureDatabases = [ "nextcloud" ]; - }; - # Ensure that this service doesn't start before postgres is ready - systemd.services.nextcloud-setup.after = [ "postgresql.target" ]; + systemd.services.nextcloud-setup.after = [ "postgresql.service" ]; sops.secrets."nextcloud/tlater" = { owner = "nextcloud"; diff --git a/configuration/services/ntfy-sh/default.nix b/configuration/services/ntfy-sh/default.nix index 9cca567..aacec91 100644 --- a/configuration/services/ntfy-sh/default.nix +++ b/configuration/services/ntfy-sh/default.nix @@ -17,6 +17,7 @@ in services.ntfy-sh = { enable = true; + package = flake-inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.ntfy-sh; environmentFile = config.sops.secrets."ntfy/users".path; @@ -137,17 +138,17 @@ in "curl", "--silent", "--show-error", - f"--max-time {2 + timeout}", + f"--max-time {timeout}", "-u tlater:insecure", f"http://ntfy.testHost/{topic}/json", - "-o messages" + "> messages" ] client.succeed(f'{" ".join(systemd_invocation)} "{" ".join(curl)}"') # Give some slack so the host doesn't send messages before # we're listening - time.sleep(2) + time.sleep(1) yield diff --git a/configuration/services/postgres.nix b/configuration/services/postgres.nix new file mode 100644 index 0000000..85a6843 --- /dev/null +++ b/configuration/services/postgres.nix @@ -0,0 +1,35 @@ +{ pkgs, ... }: +{ + services.postgresql = { + package = pkgs.postgresql_14; + enable = true; + + # Only enable connections via the unix socket, and check with the + # OS to make sure the user matches the database name. + # + # See https://www.postgresql.org/docs/current/auth-pg-hba-conf.html + authentication = '' + local sameuser all peer + ''; + + # Note: The following options with ensure.* are set-only; i.e., + # when permissions/users/databases are removed from these lists, + # that operation needs to be performed manually on the system as + # well. + ensureUsers = [ + { + name = "grafana"; + ensureDBOwnership = true; + } + { + name = "nextcloud"; + ensureDBOwnership = true; + } + ]; + + ensureDatabases = [ + "grafana" + "nextcloud" + ]; + }; +} diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix new file mode 100644 index 0000000..6b97471 --- /dev/null +++ b/configuration/services/starbound.nix @@ -0,0 +1,129 @@ +{ + flake-inputs, + pkgs, + lib, + ... +}: +let + inherit (lib) concatStringsSep; +in +{ + networking.firewall.allowedTCPPorts = [ 21025 ]; + + # Sadly, steam-run requires some X libs + environment.noXlibs = false; + + systemd.services.starbound = { + description = "Starbound"; + after = [ "network.target" ]; + + serviceConfig = { + ExecStart = "${ + flake-inputs.self.packages.${pkgs.system}.starbound + }/bin/launch-starbound ${./configs/starbound.json}"; + + Type = "simple"; + + # Credential loading for steam auth (if necessary; prefer + # anonymous login wherever possible). + LoadCredential = "steam:/run/secrets/steam/tlater"; + + # Security settings + DynamicUser = true; + + # This is where the StateDirectory ends up + WorkingDirectory = "/var/lib/starbound"; + # Creates /var/lib/starbound (or rather, a symlink there to + # /var/lib/private/starbound), and sets it up to be writeable to + # by the dynamic user. + StateDirectory = "starbound"; + + # Note some settings below are basically tautologous with + # `NoNewPrivileges`, but they all work slightly differently so + # add additional layers in case of bugs. + + ## THESE SETTINGS ARE A GOOD IDEA BUT THE STEAM CLIENT IS + ## REALLY, REALLY BAD, AND FOR SOME REASON I NEED TO USE IT TO + ## DOWNLOAD GAME SERVERS AS WELL: + ## + # To guarantee the above (only permits 64-bit syscalls, 32-bit + # syscalls can circumvent the above restrictions). + # + # Obviously, if running a 32 bit game server, change this. + # SystemCallArchitectures = "native"; + # Game servers shouldn't need to create new namespaces ever. + # + # TODO: Since steam uses namespaces for things *entirely + # unrelated* to installing game servers, we need to allow + # namespace access. Ideally I'd instead do this in an + # ExecStartPre, but alas, this isn't possible because of + # https://github.com/systemd/systemd/issues/19604. + # + # RestrictNamespaces = true; + + # Don't need to let the game server see other user accounts + PrivateUsers = true; + # *Probably* not harmful for game servers, which probably don't update dynamically + ProtectHostname = true; + # Yeah, if a game server tries to edit the hardware clock something's fishy + ProtectClock = true; + # Don't let game servers modify kernel settings, duh + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + # Game servers shouldn't use cgroups themselves either + ProtectControlGroups = true; + # Most game servers will never need other socket types + RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ]; + # Also a no-brainer, no game server should ever need this + LockPersonality = true; + # Some game servers will probably try to set this, but they + # don't need it. It's only required for audio processing and + # such, which the server end doesn't need to do. + RestrictRealtime = true; + # Don't allow a variety of syscalls that gameservers have no + # business using anyway + SystemCallFilter = + "~" + + (concatStringsSep " " [ + "@clock" + "@cpu-emulation" + "@debug" + "@keyring" + "@memlock" + "@module" + # "@mount" TODO: Consider adding when steamcmd is run in ExecStartPre + "@obsolete" + "@raw-io" + "@reboot" + # "@resources" TODO: Ditto + "@setuid" + "@swap" + ]); + # Normally only "read-only", but steamcmd will puke if there is + # no home directory to write to (though the nix package will + # implicitly symlink to the path that we set in its override, so + # no actual files are created, besides a symlink). + ProtectHome = "tmpfs"; + + # Implied by DynamicUser anyway, but it doesn't hurt to add + # these explicitly, at least for reference. + RemoveIPC = true; + PrivateTmp = true; + PrivateDevices = true; + NoNewPrivileges = true; + RestrictSUIDSGID = true; + ProtectSystem = "strict"; + # ProtectHome = "read-only"; # See further up + }; + }; + + services.backups.starbound = { + user = "root"; + paths = [ "/var/lib/private/starbound/storage/universe/" ]; + pauseServices = [ "starbound.service" ]; + }; + + # Accessed via systemd cred through /run/secrets/steam + sops.secrets."steam/tlater" = { }; +} diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix index ffe7480..e8daeaf 100644 --- a/configuration/services/webserver.nix +++ b/configuration/services/webserver.nix @@ -20,7 +20,7 @@ in after = [ "network.target" ]; script = '' - ${lib.getExe flake-inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.webserver} + ${lib.getExe flake-inputs.self.packages.${pkgs.system}.webserver} ''; environment = { diff --git a/dev-utils.nix b/dev-utils.nix deleted file mode 100644 index bfa0d17..0000000 --- a/dev-utils.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ self, ... }: -{ - # Systems on which to make dev utilities runnable; anything - # NixOS-related encodes its own system. - systems = [ "x86_64-linux" ]; - - perSystem = - { - inputs', - self', - pkgs, - lib, - ... - }: - { - apps = { - default = self'.apps.runVm; - - runVm = { - type = "app"; - program = lib.getExe self.nixosConfigurations.hetzner-1.config.system.build.vm; - meta.description = "Run the test VM"; - }; - }; - - devShells = { - default = pkgs.mkShell { - sopsPGPKeyDirs = [ - "./keys/hosts/" - "./keys/users/" - ]; - - packages = lib.attrValues { - inherit (inputs'.sops-nix.packages) sops-import-keys-hook sops-init-gpg-key; - inherit (pkgs) deploy-rs; - }; - }; - - minecraft = pkgs.mkShell { packages = lib.attrValues { inherit (pkgs) packwiz; }; }; - webserver = self'.packages.webserver.devShell; - }; - }; -} diff --git a/flake.lock b/flake.lock index 3094d19..3c65247 100644 --- a/flake.lock +++ b/flake.lock @@ -46,9 +46,7 @@ "deploy-rs", "flake-compat" ], - "flake-parts": [ - "flake-parts" - ], + "flake-parts": "flake-parts", "nix-test-runner": "nix-test-runner", "nixpkgs": [ "sonnenshift", @@ -79,11 +77,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1770019181, - "narHash": "sha256-hwsYgDnby50JNVpTRYlF3UR/Rrpt01OrxVuryF40CFY=", + "lastModified": 1762286984, + "narHash": "sha256-9I2H9x5We6Pl+DBYHjR1s3UT8wgwcpAH03kn9CqtdQc=", "owner": "serokell", "repo": "deploy-rs", - "rev": "77c906c0ba56aabdbc72041bf9111b565cdd6171", + "rev": "9c870f63e28ec1e83305f7f6cb73c941e699f74f", "type": "github" }, "original": { @@ -125,11 +123,11 @@ ] }, "locked": { - "lastModified": 1771355198, - "narHash": "sha256-89m5VKxIs8QNiIvLsxHu5NpyhDsoXTtoN801IAurnW4=", + "lastModified": 1762276996, + "narHash": "sha256-TtcPgPmp2f0FAnc+DMEw4ardEgv1SGNR3/WFGH0N19M=", "owner": "nix-community", "repo": "disko", - "rev": "92fceb111901a6f13e81199be4fab95fce86a5c9", + "rev": "af087d076d3860760b3323f6b583f4d828c1ac17", "type": "github" }, "original": { @@ -156,14 +154,18 @@ }, "flake-parts": { "inputs": { - "nixpkgs-lib": "nixpkgs-lib" + "nixpkgs-lib": [ + "sonnenshift", + "crate2nix", + "nixpkgs" + ] }, "locked": { - "lastModified": 1769996383, - "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", "type": "github" }, "original": { @@ -179,11 +181,11 @@ ] }, "locked": { - "lastModified": 1767431140, - "narHash": "sha256-ug37Jt6r8LP3161suTh6IW+fkx0a7kiSAhAPsVcPrkA=", + "lastModified": 1762437643, + "narHash": "sha256-nQ2ItqrkvOYEjJr1HcXkIEFS4SEy5q1ax0Y1CTuKhHs=", "owner": "NotAShelf", "repo": "flint", - "rev": "7832a5b5f5ef1243818f8f5e357ad1ee2d35d2b7", + "rev": "36c565edd971166718d21ae973c792b194ca737d", "type": "github" }, "original": { @@ -199,11 +201,11 @@ ] }, "locked": { - "lastModified": 1767491610, - "narHash": "sha256-/Nldo9ILD7T5aQKuyeUccNPXjhNBrovGXEoi5k7m9Bo=", + "lastModified": 1761916399, + "narHash": "sha256-wLZ8km5ftKlIDdHJrFiDQivXc5b+7DRxmBp2347H5g8=", "owner": "reckenrode", "repo": "nix-foundryvtt", - "rev": "35e789ba383fbfaa9039005b9b24669c5be6b8ab", + "rev": "8cceb7af3dfbe465b5108db5c098b097edf85790", "type": "github" }, "original": { @@ -253,30 +255,28 @@ }, "nixpkgs": { "locked": { - "lastModified": 1771208521, - "narHash": "sha256-G2qGwj2t77kM0hZatRrTp2+50obn4ssSXoLCrJKZtgQ=", - "rev": "fa56d7d6de78f5a7f997b0ea2bc6efd5868ad9e8", + "lastModified": 1763509821, + "narHash": "sha256-ibZr0ONEUA1W2WAdTzgm9/6jBE+tM20j1YW2FK4RZ/k=", + "rev": "659aa6fa27619d04de231b4cc0c938905dfa01e9", "type": "tarball", - "url": "https://releases.nixos.org/nixos/25.11/nixos-25.11.6074.fa56d7d6de78/nixexprs.tar.xz" + "url": "https://releases.nixos.org/nixos/25.05-small/nixos-25.05.812929.659aa6fa2761/nixexprs.tar.xz?lastModified=1763509821&rev=659aa6fa27619d04de231b4cc0c938905dfa01e9" }, "original": { "type": "tarball", - "url": "https://channels.nixos.org/nixos-25.11/nixexprs.tar.xz" + "url": "https://channels.nixos.org/nixos-25.05-small/nixexprs.tar.xz" } }, - "nixpkgs-lib": { + "nixpkgs-unstable": { "locked": { - "lastModified": 1769909678, - "narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "72716169fe93074c333e8d0173151350670b824c", - "type": "github" + "lastModified": 1763835633, + "narHash": "sha256-nzRnw0UkYQpDm0o20AKvG/5oHCXy5qEGOsFAVhB5NmA=", + "rev": "050e09e091117c3d7328c7b2b7b577492c43c134", + "type": "tarball", + "url": "https://releases.nixos.org/nixos/unstable/nixos-25.11pre900642.050e09e09111/nixexprs.tar.xz?lastModified=1763835633&rev=050e09e091117c3d7328c7b2b7b577492c43c134" }, "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" + "type": "tarball", + "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" } }, "pre-commit-hooks": { @@ -322,10 +322,10 @@ "inputs": { "deploy-rs": "deploy-rs", "disko": "disko", - "flake-parts": "flake-parts", "flint": "flint", "foundryvtt": "foundryvtt", "nixpkgs": "nixpkgs", + "nixpkgs-unstable": "nixpkgs-unstable", "sonnenshift": "sonnenshift", "sops-nix": "sops-nix" } @@ -338,11 +338,11 @@ ] }, "locked": { - "lastModified": 1764578400, - "narHash": "sha256-8V0SpIcYyjpP+nAHfYJDof7CofLTwVVDo5QLZ0epjOQ=", + "lastModified": 1763619077, + "narHash": "sha256-dlfamaoIzFEgwgtzPJuw5Tl5SqjbWcV8CsbP2hVBeuI=", "ref": "refs/heads/main", - "rev": "bf17617899692c9c2bfebfce87320a4174e6dc28", - "revCount": 27, + "rev": "64a2c8a3743ea6897ecac6692fba8aebc3389fca", + "revCount": 26, "type": "git", "url": "ssh://git@github.com/sonnenshift/battery-manager" }, @@ -358,11 +358,11 @@ ] }, "locked": { - "lastModified": 1771166946, - "narHash": "sha256-UFc4lfGBr+wJmwgDGJDn1cVD6DTr0/8TdronNUiyXlU=", + "lastModified": 1763607916, + "narHash": "sha256-VefBA1JWRXM929mBAFohFUtQJLUnEwZ2vmYUNkFnSjE=", "owner": "Mic92", "repo": "sops-nix", - "rev": "2d0cf89b4404529778bc82de7e42b5754e0fe4fa", + "rev": "877bb495a6f8faf0d89fc10bd142c4b7ed2bcc0b", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 8680b59..951eef5 100644 --- a/flake.nix +++ b/flake.nix @@ -1,7 +1,9 @@ { + description = "tlater.net host configuration"; + inputs = { - nixpkgs.url = "https://channels.nixos.org/nixos-25.11/nixexprs.tar.xz"; - flake-parts.url = "github:hercules-ci/flake-parts"; + nixpkgs.url = "https://channels.nixos.org/nixos-25.05-small/nixexprs.tar.xz"; + nixpkgs-unstable.url = "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"; ## Nix/OS utilities @@ -41,49 +43,142 @@ crate2nix.inputs = { flake-compat.follows = "deploy-rs/flake-compat"; devshell.inputs.flake-utils.follows = "deploy-rs/utils"; - flake-parts.follows = "flake-parts"; }; }; }; }; outputs = - { flake-parts, ... }@inputs: - flake-parts.lib.mkFlake { inherit inputs; } ( - { self, ... }@args: - { - imports = [ - (flake-parts.lib.importApply ./flakeModules/deploy-rs.nix args) - ./checks - ./dev-utils.nix - ./pkgs - ]; + { + self, + nixpkgs, + sops-nix, + ... + }@inputs: + let + system = "x86_64-linux"; - flake.nixosConfigurations.hetzner-1 = inputs.nixpkgs.lib.nixosSystem { + vm = nixpkgs.lib.nixosSystem { + inherit system; + specialArgs.flake-inputs = inputs; + + modules = [ + ./configuration + ./configuration/hardware-specific/vm.nix + ]; + }; + + # deploy-rs unfortunately uses an `import nixpkgs`, and its + # library functions depend on an instantiated nixpkgs, so we + # can't get around multi-nixpkgs-eval. + inherit + (import nixpkgs { + inherit system; + overlays = [ + inputs.deploy-rs.overlays.default + (_: prev: { + deploy-rs = { + inherit (nixpkgs.legacyPackages.${system}) deploy-rs; + inherit (prev.deploy-rs) lib; + }; + }) + ]; + }) + deploy-rs + ; + in + { + ################## + # Configurations # + ################## + nixosConfigurations = { + # The actual system definition + hetzner-1 = nixpkgs.lib.nixosSystem { + inherit system; specialArgs.flake-inputs = inputs; + modules = [ ./configuration ./configuration/hardware-specific/hetzner ]; }; + }; - deploy.nodes.hetzner-1 = { + ############################ + # Deployment configuration # + ############################ + deploy.nodes = { + hetzner-1 = { hostname = "116.202.158.55"; profiles.system = { user = "root"; - activation = "nixos"; - closure = self.nixosConfigurations.hetzner-1; + path = deploy-rs.lib.activate.nixos self.nixosConfigurations.hetzner-1; + }; - sshUser = "tlater"; - sshOpts = [ - "-p" - "2222" - "-o" - "ForwardAgent=yes" - ]; + sshUser = "tlater"; + sshOpts = [ + "-p" + "2222" + "-o" + "ForwardAgent=yes" + ]; + }; + }; + + ######### + # Tests # + ######### + checks = import ./checks { flake-inputs = inputs; }; + + ########################### + # Garbage collection root # + ########################### + + packages.${system} = { + default = vm.config.system.build.vm; + } + // import ./pkgs { + pkgs = nixpkgs.legacyPackages.${system}; + flake-inputs = inputs; + }; + + ################### + # Utility scripts # + ################### + apps.${system} = { + default = self.apps.${system}.run-vm; + + run-vm = { + type = "app"; + program = + (nixpkgs.legacyPackages.${system}.writeShellScript "" '' + ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm + '').outPath; + }; + }; + + ########################### + # Development environment # + ########################### + devShells.${system} = { + default = nixpkgs.legacyPackages.${system}.mkShell { + sopsPGPKeyDirs = [ + "./keys/hosts/" + "./keys/users/" + ]; + + packages = nixpkgs.lib.attrValues { + inherit (sops-nix.packages.${system}) sops-import-keys-hook sops-init-gpg-key; + inherit (deploy-rs) deploy-rs; }; }; - } - ); + + minecraft = nixpkgs.legacyPackages.${system}.mkShell { + packages = nixpkgs.lib.attrValues { inherit (nixpkgs.legacyPackages.${system}) packwiz; }; + }; + + webserver = self.packages.${system}.webserver.devShell; + }; + }; } diff --git a/flakeModules/deploy-rs.nix b/flakeModules/deploy-rs.nix deleted file mode 100644 index abee5a8..0000000 --- a/flakeModules/deploy-rs.nix +++ /dev/null @@ -1,136 +0,0 @@ -{ lib, ... }@exportingFlake: -let - inherit (lib) mkOption types; - - deploy-rs-for-system = - system: - (import exportingFlake.inputs.nixpkgs { - inherit system; - overlays = [ - exportingFlake.inputs.deploy-rs.overlays.default - (_final: prev: { - deploy-rs = { - inherit (exportingFlake.inputs.nixpkgs.legacyPackages.${system}) deploy-rs; - inherit (prev.deploy-rs) lib; - }; - }) - ]; - }).deploy-rs; -in -{ config, ... }: -let - cfg = config.deploy; -in -{ - options.deploy = - let - genericOptions = - let - mkGenericOption = - type: - mkOption { - type = types.nullOr type; - default = null; - }; - in - { - options = { - sshUser = mkGenericOption types.str; - user = mkGenericOption types.str; - sshOpts = mkGenericOption (types.listOf types.str); - fastConnection = mkGenericOption types.bool; - autoRollback = mkGenericOption types.bool; - magicRollback = mkGenericOption types.bool; - confirmTimeout = mkGenericOption types.int; - activationTimeout = mkGenericOption types.int; - tempPath = mkGenericOption types.str; - interactiveSudo = mkGenericOption types.bool; - }; - }; - - profileModule = - { config, ... }: - { - imports = [ genericOptions ]; - - options = { - activation = mkOption { - type = types.oneOf [ - (types.enum [ - "nixos" - "home-manager" - "darwin" - "noop" - ]) - ]; - }; - - closure = mkOption { type = types.raw; }; - - profilePath = mkOption { - type = types.nullOr types.str; - default = null; - }; - - path = mkOption { - type = types.raw; - internal = true; - }; - }; - - config = - let - inherit (config.closure.config.nixpkgs.hostPlatform) system; - deploy-rs = deploy-rs-for-system system; - in - lib.mkMerge [ - (lib.mkIf (lib.elem config.activation [ - "nixos" - "home-manager" - "darwin" - "noop" - ]) { path = deploy-rs.lib.activate.${config.activation} config.closure; }) - ]; - }; - - nodeModule = { - imports = [ genericOptions ]; - - options = { - hostname = mkOption { type = types.str; }; - - profilesOrder = mkOption { - type = types.listOf types.str; - default = [ ]; - }; - - profiles = mkOption { - type = types.attrsOf (types.submoduleWith { modules = [ profileModule ]; }); - - apply = lib.mapAttrs ( - _: profile: - lib.filterAttrs ( - name: val: - !(lib.elem name [ - "activation" - "closure" - ]) - && val != null - ) profile - ); - - default = { }; - }; - }; - }; - in - { - nodes = mkOption { - default = { }; - type = types.attrsOf (types.submoduleWith { modules = [ nodeModule ]; }); - apply = lib.mapAttrs (_: node: lib.filterAttrs (_: val: val != null) node); - }; - }; - - config = lib.mkIf (cfg.nodes != { }) { flake.deploy.nodes = cfg.nodes; }; -} diff --git a/keys/production.yaml b/keys/production.yaml index 6a60c40..ccbee64 100644 --- a/keys/production.yaml +++ b/keys/production.yaml @@ -20,6 +20,9 @@ steam: heisenbridge: as-token: ENC[AES256_GCM,data:+2yo6T18j34622H8ZWblAFB2phLw1q0k0vUQEZ5sFj7dQaRnkEiAMi0R3p17Zq0pOtGEC0RRZuPLYkcZ1oKP0w==,iv:lGwrQYp//FufpmJocrLIVyy9RK7lEEVcpAi0wmkjr34=,tag:yV06UbhAYJQz36O2XdhY+A==,type:str] hs-token: ENC[AES256_GCM,data:u52WpkQFd/J7JFoE/rfNluebyZQLOokvkVdL7+AEAvrhJhrkJli1ztkD79lbC+6tGUH4tT3T+nX9wvGKnrRUQg==,iv:as+9fVuvMg2IoE2WIKD9mHi+znhNcWRh5Zq+yr0xcDQ=,tag:mZ7fh7U0MfgI8hyq/28Bcg==,type:str] +matrix-hookshot: + as-token: ENC[AES256_GCM,data:nXTanPhDyDF7R3AllLqpM5dzljBrHwlh1KJnTGIi5PhbDY2lPj4+uXkMEwvm1u+hQjPyM7vKZPfK+0/dms6Y7A==,iv:fSakJN+yai0gfOJKFxxaxgyUtk0pNmIeqVgrdq92/24=,tag:Qc7+SUnm5/Nq5+QIScR9kQ==,type:str] + hs-token: ENC[AES256_GCM,data:Bwyj0JTTN0NNnwOs1zA8CqbtZSNcvlINeT7QVc2eJiHda92J6vQk7bSxy6KuqCN9DxlUsK13ggYjNORY2vic5w==,iv:Npnp8arYQ3Yb6CXrnKgE03hD7ZjGINPa/DwFI8D+5tA=,tag:FqNE6yI0nF4puEUw9MGAjQ==,type:str] wireguard: server-key: ENC[AES256_GCM,data:mXb7ZznJHf5CgV8rI4uzPBATMRbmd7LimgtCkQM9kAjbIaGwUBqJZBN3fXs=,iv:3Po1Orinzov9rnEm9cLzgJY1PeD+5Jl9115MriABHh8=,tag:E/2CjDO1JCvJzxCnqKcNyw==,type:str] restic: @@ -29,8 +32,8 @@ turn: env: ENC[AES256_GCM,data:kt5nhVo9pb/ZbPUEcqSYXxN9YMgQKnFb5VRfFFS/qoIaJ73uD2fuJKqcxAyVRrdLqnSAWSQBgTgunBzdP7xqLAK2qt8DYAQWHkIe9uxFbSXZpdmw,iv:9lq6SFwTFN4GGm6gPiJpUMasMdnHVF6XLGYrsyG3kjU=,tag:428Qf9DOiiHt/Wjb188b8g==,type:str] secret: ENC[AES256_GCM,data:si7ee6Xfhdgdyzbp6aQpF7pz3TmTBb7iQ82lRPVXNDg9JfHI+lbmgAsSnRLX5qMCA6P9R045sSMosqidL8QwRg==,iv:SrhpZKK8D45yxCEfDb9P3TwtA14+qEI+wcRqcN/a6pw=,tag:PiwV+mOL9xHJgJft6sc61g==,type:str] sops: - lastmodified: "2025-12-01T11:39:17Z" - mac: ENC[AES256_GCM,data:TwhGOW/V9/IoBifzh1MSwy/ff7ONTnxEmwERD8Yl2E27WG/6dTVz0/nIlZ8KsEKLC6vB2m+sJT+14Q9KCj4Cn/bWV1PmhytktGPxLQpgF55+pZlSK1aLUPLq0hwE93b4MAeOvzoOXtCQguh1dsB2RkinabFoMeZ2xJ7Kc+jHlfA=,iv:Ri8aEA4tssGDv2UuKeza8vs94IovM9GARLIEapb9Ya0=,tag:MDgAffj7ndmMwpw7mBXNRg==,type:str] + lastmodified: "2025-11-29T14:52:24Z" + mac: ENC[AES256_GCM,data:RC18s48jxRFQMtbmu74P7G4uhm2yHk9TB0wN7z4g8SNE3nfkYMvHAJqPr3A3dO+T33zkTFcSRm7fhWItUahTCW3fO10u6kDvWbnyjlSuAy86Tkz2iqeW4iSOzKswDptAgb/B+juAHhEMxDnkG5vpPlIcD0SVP89NlflXftogOqw=,iv:2vN2TJvzePzBJfUeBxvGXwGmRsB5sopqyWm9uUv/rzA=,tag:C6UOWrUxVsRMFncL1y1eTQ==,type:str] pgp: - created_at: "2025-10-03T21:38:48Z" enc: |- diff --git a/keys/staging.yaml b/keys/staging.yaml index b5c8533..20ee3db 100644 --- a/keys/staging.yaml +++ b/keys/staging.yaml @@ -21,6 +21,9 @@ steam: heisenbridge: as-token: ENC[AES256_GCM,data:tXbOeo7nv8I=,iv:wJAKcOXX9nGIw4n38ThOoj29u7dUWhsxSQG/p79JlEw=,tag:rTVaGS2UuWcea1uBa8YX2g==,type:str] hs-token: ENC[AES256_GCM,data:VBwvwomv0Xg=,iv:q6INtJ+rg+QiXj8uBdBzQYQZUBBXp+9odxDHwvu8Jxc=,tag:XKhm8nxygAkKaiVPJ2Fcdg==,type:str] +matrix-hookshot: + as-token: ENC[AES256_GCM,data:uSUOo4f2KqA=,iv:Xb9G8Ecv6m59m51kDw2bOfq3SMJt4g9/6/EdH74R+KM=,tag:K9MSfO2c2Y4rlf0eYrmTnw==,type:str] + hs-token: ENC[AES256_GCM,data:0KsyA06InL4=,iv:zAR0Y1fk8SyodcSLBHlQ8I+BAmttz9Hkd8Q3OREFqs4=,tag:t1Et8N/3seq95DeGoUd7Sw==,type:str] wireguard: server-key: ENC[AES256_GCM,data:FvY897XdKoa/mckE8JQLCkklsnYD6Wz1wpsu5t3uhEnW3iarnDQxF9msuYU=,iv:jqGXfekM+Vs+J9b5nlZ5Skd1ZKHajoUo2Dc4tMYPm1w=,tag:EehikjI/FCU8wqtpvJRamQ==,type:str] restic: @@ -30,8 +33,8 @@ turn: env: ENC[AES256_GCM,data:xjIz/AY109lyiL5N01p5T3HcYco/rM5CJSRTtg==,iv:16bW6OpyOK/QL0QPGQp/Baa9xyT8E3ZsYkwqmjuofk0=,tag:J5re3uKxIykw3YunvQWBgg==,type:str] secret: ENC[AES256_GCM,data:eQ7dAocoZtg=,iv:fgzjTPv30WqTKlLy+yMn5MsKQgjhPnwlGFFwYEg3gWs=,tag:1ze33U1NBkgMX/9SiaBNQg==,type:str] sops: - lastmodified: "2025-12-01T11:39:26Z" - mac: ENC[AES256_GCM,data:11VQAYk8Am0k8OO6BtU17qpuEhcJ8ylRhJWQNHVAsmi5BCFjD1zU3NkWhtSstPrBcqHMenG+9XuEzpNnbccHI2ru0qlILsQvNj5OKo96FnvYtzApYlApoAzOetCx08Lfxa4RGLN/XCUSuccjBIU2PZRWEK+z+Cm1wHUFeqc1xPc=,iv:6y9j55Cld+GoOVGWAqsEgURRna6dHA2mGZwHVA+ZOE8=,tag:bSZi3nYmYrn3nFT2+RBPUQ==,type:str] + lastmodified: "2025-11-29T11:54:33Z" + mac: ENC[AES256_GCM,data:SaTvwxfARVou/ZjrWfdC8J6je8l89Zuumdz7PkmY2Tl2CQVxZmEt4AyV4bWiCtWhJmfH1Qa8m4Q+DyqimjapgYT5cUB1yxlknp233bB/+5C5k3KozU2hmh80KYgR496FtQvI74p0qw/lw00CGCR3WHNcIc0dbTiDzC90HlOpafg=,iv:vxMCAjpgyWvxk18LalmFhwOb5b2ThCDq1KTaX2OPvpM=,tag:QMA+tC4hs/FBnuVDye38Vg==,type:str] pgp: - created_at: "2025-10-03T21:38:26Z" enc: |- diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix new file mode 100644 index 0000000..44e6bc5 --- /dev/null +++ b/modules/crowdsec/default.nix @@ -0,0 +1,383 @@ +{ + pkgs, + lib, + config, + ... +}: +let + cfg = config.security.crowdsec; + settingsFormat = pkgs.formats.yaml { }; + + hub = pkgs.fetchFromGitHub { + owner = "crowdsecurity"; + repo = "hub"; + rev = "7a3b4753f4577257c0cbeb8f8f90c7f17d2ae008"; + hash = "sha256-HB4jHyhiO8gjBkLmpo6bDbwhfm5m5nAtNlKhDkZjt2I="; + }; + + cscli = pkgs.writeShellScriptBin "cscli" '' + export PATH="$PATH:${cfg.package}/bin/" + + sudo=exec + if [ "$USER" != "crowdsec" ]; then + sudo='exec /run/wrappers/bin/sudo -u crowdsec' + fi + + $sudo ${cfg.package}/bin/cscli "$@" + ''; + + acquisitions = '' + --- + ${lib.concatMapStringsSep "\n---\n" builtins.toJSON cfg.acquisitions} + --- + ''; +in +{ + imports = [ ./remediations ]; + + options.security.crowdsec = + let + inherit (lib.types) + nullOr + listOf + package + path + str + ; + in + { + enable = lib.mkEnableOption "crowdsec"; + + package = lib.mkOption { + type = package; + default = pkgs.crowdsec; + }; + + stateDirectory = lib.mkOption { + type = path; + readOnly = true; + + description = '' + The state directory of the crowdsec instance. Cannot be + changed, but is exposed for downstream use. + ''; + }; + + settings = lib.mkOption { + inherit (settingsFormat) type; + default = { }; + + description = '' + The crowdsec configuration. Refer to + + for details on supported values. + ''; + }; + + parserWhitelist = lib.mkOption { + type = listOf str; + default = [ ]; + description = '' + Set of IP addresses to add to a parser-based whitelist. + + Addresses can be specified either as plain IP addresses or + in CIDR notation. + ''; + }; + + acquisitions = lib.mkOption { + type = listOf settingsFormat.type; + default = [ ]; + description = '' + Log acquisitions. + ''; + }; + + extraGroups = lib.mkOption { + type = listOf str; + default = [ ]; + description = '' + Additional groups to make the service part of. + + Required to permit reading from various log sources. + ''; + }; + + hubConfigurations = { + collections = lib.mkOption { + type = listOf str; + description = '' + List of pre-made crowdsec collections to install. + ''; + }; + + scenarios = lib.mkOption { + type = listOf str; + description = '' + List of pre-made crowdsec scenarios to install. + ''; + }; + + parsers = lib.mkOption { + type = listOf str; + description = '' + List of pre-made crowdsec parsers to install. + ''; + }; + + postoverflows = lib.mkOption { + type = listOf str; + description = '' + List of pre-made crowdsec postoverflows to install. + ''; + }; + + appsecConfigs = lib.mkOption { + type = listOf str; + description = '' + List of pre-made crowdsec appsec configurations to install. + ''; + }; + + appsecRules = lib.mkOption { + type = listOf str; + description = '' + List of pre-made crowdsec appsec rules to install. + ''; + }; + }; + + centralApiCredentials = lib.mkOption { + type = nullOr path; + default = null; + + description = '' + The API key to access crowdsec's central API - this is + required to access any of the shared blocklists. + + Use of this feature is optional, entering no API key (the + default) turns all sharing or receiving of blocked IPs off. + + Note that adding the API key by itself does not enable + sharing of blocked IPs with the central API. This limits the + types of blocklists this instance can access. + + To also turn sharing blocked IPs on, set + `api.server.online_client.sharing = true;`. + ''; + }; + + ctiApiKey = lib.mkOption { + type = nullOr path; + default = null; + + description = '' + The API key for crowdsec's CTI offering. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + # Set up default settings; anything that *shouldn't* be changed is + # set to the default priority so that users need to use + # `lib.mkForce`. + security.crowdsec = { + stateDirectory = "/var/lib/crowdsec"; + + settings = { + common = { + daemonize = true; + # The default logs to files, which isn't the preferred way + # on NixOS + log_media = "stdout"; + }; + + config_paths = { + config_dir = "${cfg.stateDirectory}/config/"; + data_dir = "${cfg.stateDirectory}/data/"; + # This "config" file is intended to be written to using the + # cscli tool, so you can temporarily make it so rules don't + # do anything but log what they *would* do for + # experimentation. + simulation_path = "${cfg.stateDirectory}/config/simulation.yaml"; + + pattern_dir = lib.mkDefault "${cfg.package}/share/crowdsec/config/patterns"; + + hub_dir = hub; + index_path = "${hub}/.index.json"; + + # Integrations aren't supported for now + notification_dir = lib.mkDefault "/var/empty/"; + plugin_dir = lib.mkDefault "/var/empty/"; + }; + + crowdsec_service.acquisition_path = + # Using an if/else here because `mkMerge` does not work in + # YAML-type options + if cfg.acquisitions == [ ] then + "${cfg.package}/share/crowdsec/config/acquis.yaml" + else + pkgs.writeText "acquis.yaml" acquisitions; + + cscli = { + prometheus_uri = lib.mkDefault "127.0.0.1:6060"; + }; + + db_config = { + type = lib.mkDefault "sqlite"; + db_path = lib.mkDefault "${cfg.stateDirectory}/data/crowdsec.db"; + use_wal = lib.mkDefault true; + flush = { + max_items = lib.mkDefault 5000; + max_age = lib.mkDefault "7d"; + }; + }; + + api = { + cti = { + enabled = cfg.ctiApiKey != null; + key = cfg.ctiApiKey; + }; + client.credentials_path = "${cfg.stateDirectory}/local_credentials.yaml"; + server = { + listen_uri = lib.mkDefault "127.0.0.1:8080"; + profiles_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/profiles.yaml"; + console_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/console.yaml"; + + online_client = { + # By default, we don't let crowdsec phone home, since + # this is usually within NixOS users' concerns. + sharing = lib.mkDefault false; + credentials_path = cfg.centralApiCredentials; + }; + }; + }; + + # We enable prometheus by default, since cscli relies on it + # for metrics + prometheus = { + enabled = lib.mkDefault true; + level = lib.mkDefault "full"; + listen_addr = lib.mkDefault "127.0.0.1"; + listen_port = lib.mkDefault 6060; + }; + }; + }; + + systemd.packages = [ cfg.package ]; + + environment = { + systemPackages = [ + # To add completions; sadly need to hand-roll this since + # neither `symlinkJoin` nor `buildEnv` have collision + # handling. + (pkgs.runCommandNoCCLocal "cscli" { } '' + mkdir -p $out + ln -s ${cscli}/bin $out/bin + ln -s ${cfg.package}/share $out/share + '') + ]; + + etc."crowdsec/config.yaml".source = settingsFormat.generate "crowdsec-settings.yaml" cfg.settings; + }; + + systemd = { + tmpfiles.settings."10-crowdsec" = { + "${cfg.stateDirectory}".d = { + user = "crowdsec"; + group = "crowdsec"; + mode = "0700"; + }; + + # This must be created for the setup service to work + "${cfg.stateDirectory}/config".d = { + user = "crowdsec"; + group = "crowdsec"; + mode = "0700"; + }; + + "${cfg.stateDirectory}/config/parsers".d = lib.mkIf (cfg.parserWhitelist != [ ]) { + user = "crowdsec"; + group = "crowdsec"; + mode = "0700"; + }; + + "${cfg.stateDirectory}/config/parsers/s02-enrich".d = lib.mkIf (cfg.parserWhitelist != [ ]) { + user = "crowdsec"; + group = "crowdsec"; + mode = "0700"; + }; + + "${cfg.stateDirectory}/config/parsers/s02-enrich/nixos-whitelist.yaml" = + lib.mkIf (cfg.parserWhitelist != [ ]) + { + "L+".argument = + (settingsFormat.generate "crowdsec-nixos-whitelist.yaml" { + name = "nixos/parser-whitelist"; + description = "Parser whitelist generated by the crowdsec NixOS module"; + whitelist = { + reason = "Filtered by NixOS whitelist"; + ip = lib.lists.filter (ip: !(lib.hasInfix "/" ip)) cfg.parserWhitelist; + cidr = lib.lists.filter (ip: lib.hasInfix "/" ip) cfg.parserWhitelist; + }; + }).outPath; + }; + }; + + services = { + crowdsec-setup = { + # TODO(tlater): Depend on tmpfiles path for + # /var/lib/crowdsec/config + description = "Crowdsec database and config preparation"; + + script = '' + if [ ! -e '${cfg.settings.config_paths.simulation_path}' ]; then + cp '${cfg.package}/share/crowdsec/config/simulation.yaml' '${cfg.settings.config_paths.simulation_path}' + fi + + if [ ! -e '${cfg.settings.api.client.credentials_path}' ]; then + ${cfg.package}/bin/cscli machines add --auto --file '${cfg.settings.api.client.credentials_path}' + fi + ''; + + serviceConfig = { + User = "crowdsec"; + Group = "crowdsec"; + StateDirectory = "crowdsec"; + + Type = "oneshot"; + RemainAfterExit = true; + }; + }; + + # Note that the service basics are already defined upstream + crowdsec = { + enable = true; + + after = [ "crowdsec-setup.service" ]; + bindsTo = [ "crowdsec-setup.service" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + User = "crowdsec"; + Group = "crowdsec"; + SupplementaryGroups = cfg.extraGroups; + + StateDirectory = "crowdsec"; + }; + }; + }; + }; + + users = { + users.crowdsec = { + isSystemUser = true; + home = cfg.stateDirectory; + group = "crowdsec"; + }; + groups = { + crowdsec = { }; + }; + }; + }; +} diff --git a/modules/crowdsec/remediations/cs-firewall-bouncer.nix b/modules/crowdsec/remediations/cs-firewall-bouncer.nix new file mode 100644 index 0000000..42accc6 --- /dev/null +++ b/modules/crowdsec/remediations/cs-firewall-bouncer.nix @@ -0,0 +1,87 @@ +{ + flake-inputs, + pkgs, + lib, + config, + ... +}: +let + inherit (flake-inputs.self.packages.${pkgs.system}) crowdsec-firewall-bouncer; + + crowdsecCfg = config.security.crowdsec; + cfg = crowdsecCfg.remediationComponents.firewallBouncer; + settingsFormat = pkgs.formats.yaml { }; +in +{ + options.security.crowdsec.remediationComponents.firewallBouncer = { + enable = lib.mkEnableOption "cs-firewall-bouncer"; + + settings = lib.mkOption { + inherit (settingsFormat) type; + default = { }; + + description = '' + The bouncer configuration. Refer to + for details + on supported values. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + security.crowdsec.remediationComponents.firewallBouncer.settings = { + mode = lib.mkDefault "${if config.networking.nftables.enable then "nftables" else "iptables"}"; + log_mode = "stdout"; + iptables_chains = [ "nixos-fw" ]; + + # Don't let users easily override this; unfortunately we need to + # set up this key through substitution at runtime. + api_key = lib.mkForce "\${API_KEY}"; + api_url = lib.mkDefault "http://${crowdsecCfg.settings.api.server.listen_uri}"; + }; + + systemd = { + packages = [ crowdsec-firewall-bouncer ]; + + services = { + crowdsec-firewall-bouncer-setup = { + description = "Crowdsec firewall bouncer config preparation"; + script = '' + if [ ! -e '${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml' ]; then + ${crowdsecCfg.package}/bin/cscli -oraw bouncers add "cs-firewall-bouncer-$(${pkgs.coreutils}/bin/date +%s)" > \ + ${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml + fi + + # Stdout redirection is deliberately used to forcibly + # overwrite the file if it exists + API_KEY="$(<${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml)" \ + ${lib.getExe pkgs.envsubst} \ + -i ${settingsFormat.generate "crowdsec-firewall-bouncer.yaml" cfg.settings} \ + > /var/lib/crowdsec/config/crowdsec-firewall-bouncer.yaml + ''; + + serviceConfig = { + User = "crowdsec"; + Group = "crowdsec"; + + Type = "oneshot"; + RemainAfterExit = true; + }; + }; + + crowdsec-firewall-bouncer = { + enable = true; + + after = [ "crowdsec-firewall-bouncer-setup.service" ]; + bindsTo = [ "crowdsec-firewall-bouncer-setup.service" ]; + requiredBy = [ "crowdsec.service" ]; + + path = + lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [ pkgs.ipset ] + ++ lib.optional (cfg.settings.mode == "iptables") pkgs.iptables + ++ lib.optional (cfg.settings.mode == "nftables") pkgs.nftables; + }; + }; + }; + }; +} diff --git a/modules/crowdsec/remediations/default.nix b/modules/crowdsec/remediations/default.nix new file mode 100644 index 0000000..c3c0790 --- /dev/null +++ b/modules/crowdsec/remediations/default.nix @@ -0,0 +1 @@ +{ imports = [ ./cs-firewall-bouncer.nix ]; } diff --git a/modules/default.nix b/modules/default.nix index c03a700..1bf5314 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1 +1,6 @@ -{ imports = [ ./serviceTests/stub.nix ]; } +{ + imports = [ + ./crowdsec + ./serviceTests/stub.nix + ]; +} diff --git a/pkgs/default.nix b/pkgs/default.nix index 46a9b61..1ce8cd2 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -1,10 +1,8 @@ -{ - perSystem = - { pkgs, ... }: - { - packages = pkgs.lib.packagesFromDirectoryRecursive { - inherit (pkgs) callPackage; - directory = ./packages; - }; - }; +{ pkgs, flake-inputs }: +let + inherit (flake-inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}) ast-grep; +in +pkgs.lib.packagesFromDirectoryRecursive { + callPackage = pkgs.lib.callPackageWith (pkgs // { inherit ast-grep; }); + directory = ./packages; } diff --git a/pkgs/packages/crowdsec-firewall-bouncer.nix b/pkgs/packages/crowdsec-firewall-bouncer.nix new file mode 100644 index 0000000..41bba86 --- /dev/null +++ b/pkgs/packages/crowdsec-firewall-bouncer.nix @@ -0,0 +1,51 @@ +{ + lib, + fetchFromGitHub, + buildGoModule, + envsubst, + coreutils, + + writers, + nix-update, +}: +let + envsubstBin = lib.getExe envsubst; +in +buildGoModule (drv: { + pname = "crowdsec-firewall-bouncer"; + version = drv.src.rev; + + src = fetchFromGitHub { + owner = "crowdsecurity"; + repo = "cs-firewall-bouncer"; + rev = "0.0.34"; + sha256 = "sha256-lDO9pwPkbI+FDTdXBv03c0p8wbkRUiIDNl1ip3AZo2g="; + }; + + vendorHash = "sha256-SbpclloBgd9vffC0lBduGRqPOqmzQ0J91/KeDHCh0jo="; + + postInstall = '' + mkdir -p $out/lib/systemd/system + + CFG=/var/lib/crowdsec/config BIN=$out/bin/cs-firewall-bouncer ${envsubstBin} \ + -i ./config/crowdsec-firewall-bouncer.service \ + -o $out/lib/systemd/system/crowdsec-firewall-bouncer.service + + substituteInPlace $out/lib/systemd/system/crowdsec-firewall-bouncer.service \ + --replace-fail /bin/sleep ${coreutils}/bin/sleep + ''; + + passthru.updateScript = + writers.writeNuBin "update-crowdsec-firewall-bouncer" + { + makeWrapperArgs = [ + "--prefix" + "PATH" + ":" + (lib.makeBinPath [ nix-update ]) + ]; + } + '' + nix-update --flake --format crowdsec-firewall-bouncer + ''; +}) diff --git a/pkgs/packages/crowdsec-hub.nix b/pkgs/packages/crowdsec-hub.nix new file mode 100644 index 0000000..3d0ad28 --- /dev/null +++ b/pkgs/packages/crowdsec-hub.nix @@ -0,0 +1,38 @@ +{ + lib, + fetchFromGitHub, + stdenvNoCC, + + writers, + nix-update, +}: +# Using `mkDerivation` so nix-update can pick up the version +stdenvNoCC.mkDerivation (drv: { + pname = "crowdsec-hub"; + version = drv.src.rev; + + src = fetchFromGitHub { + owner = "crowdsecurity"; + repo = "hub"; + rev = "b63d9e925cfdd70f818a6a136ea53d5c8ca96d9a"; + hash = "sha256-FMArGnR/pI/QlzsznStp8vzs/LbXooVgLdoTw+eSbec="; + }; + + installPhase = '' + cp -r $src $out + ''; + + passthru.updateScript = + writers.writeNuBin "update-crowdsec-hub" + { + makeWrapperArgs = [ + "--prefix" + "PATH" + ":" + (lib.makeBinPath [ nix-update ]) + ]; + } + '' + nix-update --flake --format --version=branch crowdsec-hub + ''; +}) diff --git a/pkgs/packages/webserver/Cargo.lock b/pkgs/packages/webserver/Cargo.lock index 790783b..a6db6ec 100644 --- a/pkgs/packages/webserver/Cargo.lock +++ b/pkgs/packages/webserver/Cargo.lock @@ -18,34 +18,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1384d3fe1eecb464229fcf6eebb72306591c56bf27b373561489458a7c73027d" dependencies = [ "futures", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "wasm-bindgen-futures", ] [[package]] name = "anyhow" -version = "1.0.101" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "async-lock" -version = "3.4.2" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ "event-listener", "event-listener-strategy", "pin-project-lite", ] -[[package]] -name = "async-once-cell" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a" - [[package]] name = "async-trait" version = "0.1.89" @@ -104,9 +98,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.8" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +checksum = "5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425" dependencies = [ "axum-core", "axum-macros", @@ -142,9 +136,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.6" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" dependencies = [ "bytes", "futures-core", @@ -170,12 +164,6 @@ dependencies = [ "syn", ] -[[package]] -name = "base16" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" - [[package]] name = "base64" version = "0.22.1" @@ -184,9 +172,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "block-buffer" @@ -199,33 +187,33 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "bytes" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "camino" -version = "1.2.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" [[package]] name = "cc" -version = "1.2.56" +version = "1.2.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" dependencies = [ "find-msvc-tools", "shlex", @@ -245,13 +233,13 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "codee" -version = "0.3.5" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dbbdc4b4d349732bc6690de10a9de952bd39ba6a065c586e26600b6b0b91f5" +checksum = "30b61b7a19443f478176473b0c35acf7f9f7e2752c781dea55820343826f366c" dependencies = [ "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -278,7 +266,7 @@ dependencies = [ "convert_case 0.6.0", "pathdiff", "serde_core", - "toml 0.9.12+spec-1.1.0", + "toml 0.9.8", "winnow", ] @@ -342,24 +330,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "convert_case" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "convert_case_extras" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589c70f0faf8aa9d17787557d5eae854d7755cac50f5c3d12c81d3d57661cebb" -dependencies = [ - "convert_case 0.11.0", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -370,16 +340,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -427,9 +387,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "derive-where" @@ -559,9 +519,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "fnv" @@ -569,12 +529,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "foreign-types" version = "0.3.2" @@ -601,9 +555,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -616,9 +570,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -626,32 +580,33 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", "futures-util", + "num_cpus", ] [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -660,21 +615,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -684,6 +639,7 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", + "pin-utils", "slab", ] @@ -699,9 +655,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", @@ -724,19 +680,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", - "wasip3", -] - [[package]] name = "gloo-net" version = "0.6.0" @@ -779,9 +722,9 @@ checksum = "17e2ac29387b1aa07a1e448f7bb4f35b500787971e965b02842b900afa5c8f6f" [[package]] name = "h2" -version = "0.4.13" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", @@ -802,15 +745,6 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - [[package]] name = "hashbrown" version = "0.16.1" @@ -818,10 +752,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] -name = "heck" -version = "0.5.0" +name = "hermit-abi" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "html-escape" @@ -834,11 +768,12 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", + "fnv", "itoa", ] @@ -957,13 +892,14 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.20" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" dependencies = [ "base64", "bytes", "futures-channel", + "futures-core", "futures-util", "http", "http-body", @@ -1028,9 +964,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ "icu_collections", "icu_locale_core", @@ -1042,9 +978,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" @@ -1061,12 +997,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "idna" version = "1.1.0" @@ -1090,14 +1020,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown 0.16.1", - "serde", - "serde_core", ] [[package]] @@ -1129,9 +1057,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" dependencies = [ "memchr", "serde", @@ -1148,9 +1076,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" @@ -1162,17 +1090,11 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "leptos" -version = "0.8.14" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c98f6d751e524ff425ad9d63d53e120ed68311ffbc22bbd9c0b3c4005a421e" +checksum = "6c202a7897aa73c90ac4ce73713512d871f75e79847558d9e88f778659b164dc" dependencies = [ "any_spawner", "base64", @@ -1195,26 +1117,23 @@ dependencies = [ "rustc_version", "send_wrapper", "serde", - "serde_json", "serde_qs", "server_fn", "slotmap", "tachys", - "thiserror 2.0.18", + "thiserror 2.0.17", "throw_error", - "typed-builder 0.22.0", - "typed-builder-macro 0.22.0", + "typed-builder", + "typed-builder-macro", "wasm-bindgen", - "wasm-bindgen-futures", - "wasm_split_helpers", "web-sys", ] [[package]] name = "leptos_axum" -version = "0.8.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0caa95760f87f3067e05025140becefdbdfd36cbc2adac4519f06e1f1edf4af" +checksum = "a84872a7df15ec047f8b27b27e35354752a8cc62ab8b789e3dc9d4ed5613bcea" dependencies = [ "any_spawner", "axum", @@ -1236,22 +1155,22 @@ dependencies = [ [[package]] name = "leptos_config" -version = "0.8.9" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a2ac32008dda0d657f2147cc33336f4e743e091597db10f7a99d668e92a46d" +checksum = "74eec2103dfa808f4b13c149dfbd3842f13a5948489fda3de31cc565fb28dbec" dependencies = [ "config", "regex", "serde", - "thiserror 2.0.18", - "typed-builder 0.23.2", + "thiserror 2.0.17", + "typed-builder", ] [[package]] name = "leptos_dom" -version = "0.8.8" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35742e9ed8f8aaf9e549b454c68a7ac0992536e06856365639b111f72ab07884" +checksum = "25b845379c33884f0dead9abb5aa3d258d7bd507789fc2527a5972f82c0757c7" dependencies = [ "js-sys", "or_poisoned", @@ -1264,14 +1183,14 @@ dependencies = [ [[package]] name = "leptos_hot_reload" -version = "0.8.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2a0f220c8a5ef3c51199dfb9cdd702bc0eb80d52fbe70c7890adfaaae8a4b1" +checksum = "fae732329192df886803f076515d73c883166a4c8cbc5532584d0d1e43539300" dependencies = [ "anyhow", "camino", "indexmap", - "or_poisoned", + "parking_lot", "proc-macro2", "quote", "rstml", @@ -1282,9 +1201,9 @@ dependencies = [ [[package]] name = "leptos_integration_utils" -version = "0.8.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13cccc9305df53757bae61bf15641bfa6a667b5f78456ace4879dfe0591ae0e8" +checksum = "51059fee81537ba299323e2b58c9d721f66fd8a2d42df710a020efbdfb8efae2" dependencies = [ "futures", "hydration_context", @@ -1297,14 +1216,13 @@ dependencies = [ [[package]] name = "leptos_macro" -version = "0.8.15" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712325a77f1d050bf2897061ccaf2b075930aab36954980d658f04452686c474" +checksum = "8e32ae8783d4b64838167e026ef773dbc53399e9e6658e9c2f65e0ce67a5ccec" dependencies = [ "attribute-derive", "cfg-if", - "convert_case 0.11.0", - "convert_case_extras", + "convert_case 0.8.0", "html-escape", "itertools", "leptos_hot_reload", @@ -1321,9 +1239,9 @@ dependencies = [ [[package]] name = "leptos_meta" -version = "0.8.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d489e38d3f541e9e43ecc2e3a815527840345a2afca629b3e23fcc1dd254578" +checksum = "ef0521aeb2e73cbae8e6278287da485020b971e0b2cd471c5de5eb8cbcaa8802" dependencies = [ "futures", "indexmap", @@ -1336,9 +1254,9 @@ dependencies = [ [[package]] name = "leptos_router" -version = "0.8.10" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b824cae28db1551b71f8c2a45eab7bb98d61407f5adcc368cfe7b671e4a71d" +checksum = "e1b6df1b107c301bd39c114768a1196a8dfcbdae869364b3f0247e3f554b503a" dependencies = [ "any_spawner", "either_of", @@ -1353,7 +1271,7 @@ dependencies = [ "rustc_version", "send_wrapper", "tachys", - "thiserror 2.0.18", + "thiserror 2.0.17", "url", "wasm-bindgen", "web-sys", @@ -1361,9 +1279,9 @@ dependencies = [ [[package]] name = "leptos_router_macro" -version = "0.8.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "409c0bd99f986c3cfa1a4db2443c835bc602ded1a12784e22ecb28c3ed5a2ae2" +checksum = "0d35d4bb7922e74546fac3e852b0f3252e9996e04fca12c359aba1e5958cfda8" dependencies = [ "proc-macro-error2", "proc-macro2", @@ -1373,9 +1291,9 @@ dependencies = [ [[package]] name = "leptos_server" -version = "0.8.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf1045af93050bf3388d1c138426393fc131f6d9e46a65519da884c033ed730" +checksum = "26851048e161998b8f9fb3261a833ec64df2a2669ea95f360c54b7f47a1e07cb" dependencies = [ "any_spawner", "base64", @@ -1393,9 +1311,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.182" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "linear-map" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee" [[package]] name = "linux-raw-sys" @@ -1420,9 +1344,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lru-slab" @@ -1455,9 +1379,9 @@ dependencies = [ [[package]] name = "markdown_view_leptos" -version = "0.1.92" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e163223791290ed4ab63635ccd579e251264f3b1421d98591c2b0ea3908e1952" +checksum = "7f75ce57ac1fcfcb0e31a39dd92f2c7f529c9840670b47d2516b4c037fd00689" dependencies = [ "proc-macro2", "pulldown-cmark", @@ -1474,9 +1398,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.8.0" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "mime" @@ -1496,9 +1420,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", "wasi", @@ -1524,9 +1448,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.16" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5d26952a508f321b4d3d2e80e78fc2603eaefcdf0c30783867f19586518bdc" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", @@ -1546,13 +1470,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60993920e071b0c9b66f14e2b32740a4e27ffc82854dcd72035887f336a09a28" [[package]] -name = "oco_ref" -version = "0.2.1" +name = "num_cpus" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0423ff9973dea4d6bd075934fdda86ebb8c05bdf9d6b0507067d4a1226371d" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "oco_ref" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b94982fe39a861561cf67ff17a7849f2cedadbbad960a797634032b7abb998" dependencies = [ "serde", - "thiserror 2.0.18", + "thiserror 1.0.69", ] [[package]] @@ -1589,9 +1523,9 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.2.1" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" @@ -1782,9 +1716,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -1834,7 +1768,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", "web-time", @@ -1855,7 +1789,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror 2.0.17", "tinyvec", "tracing", "web-time", @@ -1877,9 +1811,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -1934,42 +1868,40 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom 0.3.4", ] [[package]] name = "reactive_graph" -version = "0.2.13" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35774620b3da884a07341e9e36612e1509b1eb0553ef3bb76f1547dd1b797417" +checksum = "c79f7561c7c246e2c2feab3b0b63502b213e589d7768032bbfc5ea7b267140b9" dependencies = [ "any_spawner", "async-lock", "futures", "guardian", "hydration_context", - "indexmap", "or_poisoned", - "paste", "pin-project-lite", "rustc-hash", "rustc_version", "send_wrapper", "serde", "slotmap", - "thiserror 2.0.18", + "thiserror 2.0.17", "web-sys", ] [[package]] name = "reactive_stores" -version = "0.3.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35372f05664a62a3dd389503371a15b8feb3396f99f6ec000de651fddb030942" +checksum = "9edd67f166cfec4ffc6abf271bada268c13dac0b0318f4c6a76a877490d0617a" dependencies = [ "dashmap", "guardian", @@ -1984,9 +1916,9 @@ dependencies = [ [[package]] name = "reactive_stores_macro" -version = "0.2.6" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa40919eb2975100283b2a70e68eafce1e8bcf81f0622ff168e4c2b3f8d46bb" +checksum = "2418b703f385f35481737d8f2ccd9ae3de850dd778bce09817f30338f3cb5ca2" dependencies = [ "convert_case 0.8.0", "proc-macro-error2", @@ -2006,9 +1938,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -2018,9 +1950,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -2029,15 +1961,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.28" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64", "bytes", @@ -2087,7 +2019,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.17", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -2105,7 +2037,7 @@ dependencies = [ "quote", "syn", "syn_derive", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -2125,9 +2057,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", @@ -2138,9 +2070,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" dependencies = [ "once_cell", "ring", @@ -2152,9 +2084,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" dependencies = [ "web-time", "zeroize", @@ -2162,9 +2094,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ "ring", "rustls-pki-types", @@ -2179,9 +2111,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.23" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -2209,12 +2141,12 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "3.6.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", - "core-foundation 0.10.1", + "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", @@ -2222,9 +2154,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.16.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -2277,15 +2209,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", + "ryu", "serde", "serde_core", - "zmij", ] [[package]] @@ -2307,7 +2239,7 @@ checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" dependencies = [ "percent-encoding", "serde", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -2321,9 +2253,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" dependencies = [ "serde_core", ] @@ -2342,9 +2274,9 @@ dependencies = [ [[package]] name = "server_fn" -version = "0.8.8" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc30228718f62d80a376964baf990edbcb5e97688fdc71183a8ef3d44cb6c89" +checksum = "9c27fbd25ecc066481e383e2ed62ab2480e708aa3fe46cba36e95f58e61dfd04" dependencies = [ "axum", "base64", @@ -2367,7 +2299,7 @@ dependencies = [ "serde_json", "serde_qs", "server_fn_macro_default", - "thiserror 2.0.18", + "thiserror 2.0.17", "throw_error", "tokio", "tower", @@ -2382,12 +2314,12 @@ dependencies = [ [[package]] name = "server_fn_macro" -version = "0.8.9" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14faf423aab09f8c3eb2d9785bb37f11a255cdf01857d3c6083eacc82269c191" +checksum = "950b8cfc9ff5f39ca879c5a7c5e640de2695a199e18e424c3289d0964cabe642" dependencies = [ "const_format", - "convert_case 0.11.0", + "convert_case 0.8.0", "proc-macro2", "quote", "rustc_version", @@ -2416,17 +2348,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "shlex" version = "1.3.0" @@ -2435,15 +2356,15 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "slab" -version = "0.4.12" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "slotmap" -version = "1.1.1" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ "version_check", ] @@ -2456,9 +2377,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", "windows-sys 0.60.2", @@ -2484,9 +2405,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.116" +version = "2.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" dependencies = [ "proc-macro2", "quote", @@ -2527,12 +2448,12 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.7.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags", - "core-foundation 0.9.4", + "core-foundation", "system-configuration-sys", ] @@ -2548,9 +2469,9 @@ dependencies = [ [[package]] name = "tachys" -version = "0.2.13" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14691ce610071757bd17bd8d572065192c9c93f9f169125390aaea345a4c56b9" +checksum = "9d706b2ab0fa7e14b878d638faee3dafed08a2ab9ff7f116ad2445cce04bfaaa" dependencies = [ "any_spawner", "async-trait", @@ -2563,9 +2484,11 @@ dependencies = [ "indexmap", "itertools", "js-sys", + "linear-map", "next_tuple", "oco_ref", "or_poisoned", + "parking_lot", "paste", "reactive_graph", "reactive_stores", @@ -2580,12 +2503,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.25.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.4.1", + "getrandom 0.3.4", "once_cell", "rustix", "windows-sys 0.61.2", @@ -2602,11 +2525,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.17", ] [[package]] @@ -2622,9 +2545,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -2633,9 +2556,9 @@ dependencies = [ [[package]] name = "throw_error" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0ed6038fcbc0795aca7c92963ddda636573b956679204e044492d2b13c8f64" +checksum = "41e42a6afdde94f3e656fae18f837cb9bbe500a5ac5de325b09f3ec05b9c28e3" dependencies = [ "pin-project-lite", ] @@ -2679,7 +2602,7 @@ dependencies = [ "markdown_view_leptos", "reqwest", "serde", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "url", "wasm-bindgen", @@ -2688,9 +2611,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.49.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ "bytes", "libc", @@ -2746,9 +2669,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -2771,13 +2694,13 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.12+spec-1.1.0" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ "serde_core", - "serde_spanned 1.0.4", - "toml_datetime 0.7.5+spec-1.1.0", + "serde_spanned 1.0.3", + "toml_datetime 0.7.3", "toml_parser", "winnow", ] @@ -2793,9 +2716,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ "serde_core", ] @@ -2816,9 +2739,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ "winnow", ] @@ -2831,9 +2754,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "tower" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", @@ -2847,9 +2770,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "bitflags", "bytes", @@ -2887,9 +2810,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.44" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -2898,9 +2821,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.36" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", ] @@ -2924,44 +2847,24 @@ dependencies = [ "log", "rand", "sha1", - "thiserror 2.0.18", + "thiserror 2.0.17", "utf-8", ] [[package]] name = "typed-builder" -version = "0.22.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "398a3a3c918c96de527dc11e6e846cd549d4508030b8a33e1da12789c856b81a" +checksum = "fef81aec2ca29576f9f6ae8755108640d0a86dd3161b2e8bca6cfa554e98f77d" dependencies = [ - "typed-builder-macro 0.22.0", -] - -[[package]] -name = "typed-builder" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31aa81521b70f94402501d848ccc0ecaa8f93c8eb6999eb9747e72287757ffda" -dependencies = [ - "typed-builder-macro 0.23.2", + "typed-builder-macro", ] [[package]] name = "typed-builder-macro" -version = "0.22.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e48cea23f68d1f78eb7bc092881b6bb88d3d6b5b7e6234f6f9c911da1ffb221" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typed-builder-macro" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" +checksum = "1ecb9ecf7799210407c14a8cfdfe0173365780968dc57973ed082211958e0b18" dependencies = [ "proc-macro2", "quote", @@ -2985,15 +2888,15 @@ dependencies = [ [[package]] name = "unicase" -version = "2.9.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-segmentation" @@ -3015,15 +2918,14 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.8" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", - "serde_derive", ] [[package]] @@ -3034,9 +2936,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8-width" -version = "0.1.8" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" [[package]] name = "utf8_iter" @@ -3046,11 +2948,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.21.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom 0.4.1", + "getrandom 0.3.4", "js-sys", "wasm-bindgen", ] @@ -3094,18 +2996,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] @@ -3181,28 +3074,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" version = "0.4.2" @@ -3216,40 +3087,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasm_split_helpers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a114b3073258dd5de3d812cdd048cca6842342755e828a14dbf15f843f2d1b84" -dependencies = [ - "async-once-cell", - "wasm_split_macros", -] - -[[package]] -name = "wasm_split_macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56481f8ed1a9f9ae97ea7b08a5e2b12e8adf9a7818a6ba952b918e09c7be8bf0" -dependencies = [ - "base16", - "quote", - "sha2", - "syn", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-sys" version = "0.3.77" @@ -3272,9 +3109,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ "rustls-pki-types", ] @@ -3481,100 +3318,18 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -3619,18 +3374,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26" dependencies = [ "proc-macro2", "quote", @@ -3696,9 +3451,3 @@ dependencies = [ "quote", "syn", ] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/pkgs/packages/webserver/Cargo.toml b/pkgs/packages/webserver/Cargo.toml index 107cf18..6b53991 100644 --- a/pkgs/packages/webserver/Cargo.toml +++ b/pkgs/packages/webserver/Cargo.toml @@ -19,7 +19,7 @@ reqwest = "0.12.24" serde = { version = "1.0.228", features = ["derive"] } thiserror = "2.0.17" tokio = { version = "1.48.0", features = ["rt-multi-thread"], optional = true } -url = { version = "2.5.7", features = ["serde"] } +url = "2.5.7" wasm-bindgen = { version = "=0.2.100", optional = true } web-sys = "^0.3.77" diff --git a/pkgs/packages/webserver/package.nix b/pkgs/packages/webserver/package.nix index 9deeb2b..00ebf58 100644 --- a/pkgs/packages/webserver/package.nix +++ b/pkgs/packages/webserver/package.nix @@ -237,11 +237,7 @@ rustPlatform.buildRustPackage (drv: { buildPhase = '' runHook preBuild - - # dart-sass and wasm-pack want a home directory to put cache files - export HOME=$(mktemp -d) cargo leptos build --release - runHook postBuild ''; @@ -292,7 +288,6 @@ rustPlatform.buildRustPackage (drv: { (lib.makeBinPath [ ast-grep nix-prefetch-github - cargo ]) ]; } ./update.nu; diff --git a/pkgs/update.nu b/pkgs/update.nu index 7ae7d26..0ed1bc1 100644 --- a/pkgs/update.nu +++ b/pkgs/update.nu @@ -5,7 +5,7 @@ let packages_with_updatescript = ( | from json | $in.packages.x86_64-linux | columns - | where {|p| nix eval $'.#($p)' --apply 'builtins.hasAttr "updateScript"' | $in == 'true' } + | filter {|p| nix eval $'.#($p)' --apply 'builtins.hasAttr "updateScript"' | $in == 'true' } ) for $package in $packages_with_updatescript {