{ self, ... }: { flake.nixosModules.default = nixos@{ config, pkgs, lib, utils, ... }: let inherit (lib) mkEnableOption mkPackageOption mkOption mkIf types; format = pkgs.formats.json {}; cfg = config.services.amarth-customer-portal; in { options.services.amarth-customer-portal = { enable = mkEnableOption "Enable Amarth cloud's customer portal."; package = mkPackageOption self.packages.${pkgs.hostPlatform.system} "amarth-customer-portal" {}; openFirewall = mkOption { type = types.bool; default = false; example = "true"; description = '' Open the configured port in the firewall. ''; }; user = lib.mkOption { type = types.str; default = "amarth"; description = '' User account under which FileBrowser runs. ''; }; group = lib.mkOption { type = types.str; default = "amarth"; description = '' Group under which FileBrowser runs. ''; }; settings = mkOption { default = {}; description = '' ''; type = types.submodule { freeformType = format.type; options = { address = mkOption { default = "localhost"; description = '' The address to listen on. ''; type = types.str; }; port = mkOption { type = types.port; default = 8080; description = '' Which port to run the portal on. ''; }; dataDir = lib.mkOption { default = "/var/lib/amarth/customer-portal"; description = '' Directory where the portal persists files. ''; type = types.path; }; }; }; }; }; config = mkIf cfg.enable { environment.systemPackages = with pkgs; [ bun ]; systemd = { services.amarthCustomerPortal = { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; description = "Amarth cloud's customer portal"; serviceConfig = { ExecStart = utils.escapeSystemdExecArgs [ (lib.getExe cfg.package) "--config" (format.generate "config.json" cfg.settings) ]; StateDirectory = "amarth-customer-portal"; CacheDirectory = "amarth-customer-portal"; WorkingDirectory = cfg.settings.dataDir; User = cfg.user; Group = cfg.group; UMask = "0077"; NoNewPrivileges = true; PrivateDevices = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectControlGroups = true; MemoryDenyWriteExecute = true; LockPersonality = true; RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; DevicePolicy = "closed"; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; }; }; tmpfiles.settings.amarth-customer-portal = { "${cfg.settings.dataDir}".d = { inherit (cfg) user group; mode = "0700"; }; }; }; users = { users = mkIf (cfg.user == "amarth") { amarth = { inherit (cfg) group; isSystemUser = true; }; }; groups = mkIf (cfg.group == "amarth") { amarth = {}; }; }; networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.port ]; }; }; }