# Based off of https://github.com/spacebarchat/server/blob/master/flake.nix { description = "Final assignment for NodeJS"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils, }: (flake-utils.lib.eachSystem flake-utils.lib.allSystems ( system: let pkgs = import nixpkgs { inherit system; config.allowUnfree = true; }; hashesFile = builtins.fromJSON (builtins.readFile ./hashes.json); lib = pkgs.lib; in { packages = { default = pkgs.buildNpmPackage { pname = "SafeNSound"; name = "SafeNSound"; meta = with lib; { description = "Final assignment for NodeJS"; homepage = "https://github.com/VivesMDima/nodejs-ti-a-final-assignment-TheArcaneBrony"; license = licenses.agpl3Plus; platforms = platforms.all; mainProgram = "start"; }; src = ./.; nativeBuildInputs = with pkgs; [ python3 ]; npmDepsHash = hashesFile.npmDepsHash; makeCacheWritable = true; dontNpmBuild = true; postPatch = '' substituteInPlace package.json --replace 'npx patch-package' '${pkgs.nodePackages.patch-package}/bin/patch-package' ''; installPhase = '' runHook preInstall set -x #remove packages not needed for production, or at least try to... npm prune --omit dev --no-save $npmInstallFlags "''${npmInstallFlagsArray[@]}" $npmFlags "''${npmFlagsArray[@]}" find node_modules -maxdepth 1 -type d -empty -delete mkdir -p $out cp -r src node_modules package.json $out/ makeWrapper ${pkgs.nodejs}/bin/node $out/bin/start --prefix NODE_PATH : $out/node_modules --add-flags $out set +x runHook postInstall ''; }; update-nix = pkgs.writeShellApplication { name = "update-nix"; runtimeInputs = with pkgs; [ prefetch-npm-deps nix jq ]; text = '' #nix flake update --extra-experimental-features 'nix-command flakes' DEPS_HASH=$(prefetch-npm-deps package-lock.json) TMPFILE=$(mktemp) jq '.npmDepsHash = "'"$DEPS_HASH"'"' hashes.json > "$TMPFILE" mv -- "$TMPFILE" hashes.json ''; }; }; devShell = pkgs.mkShell { buildInputs = with pkgs; [ mongodb-compass # jetbrains.webstorm # jetbrains.rider # dotnet-sdk_9 nodejs nodePackages.prettier ]; }; } )) // { nixosModules.default = { pkgs, config, lib, ... }: { options.services.safensound = { enable = lib.mkEnableOption "Enable SafeNSound service"; package = lib.mkOption { type = lib.types.package; default = self.packages.${pkgs.stdenv.hostPlatform.system}.default; description = "The SafeNSound service package to run."; }; port = lib.mkOption { type = lib.types.port; default = 3000; description = "The port on which the SafeNSound service will listen."; }; dbCredentialsPath = lib.mkOption { type = lib.types.path; description = "Path to the database credentials file."; }; jwtSecretPath = lib.mkOption { type = lib.types.path; default = "/var/lib/SafeNSound"; description = "Path to the JWT secret directory."; }; logRequests = lib.mkOption { type = lib.types.string; description = "Which requests to log."; default = "-"; }; logQueries = lib.mkEnableOption "Log queries"; logAuth = lib.mkEnableOption "Log authentication"; }; config = lib.mkIf (config.services.safensound.enable) ( let cfg = config.services.safensound; in { systemd.services.safensound = { description = "SafeNSound Service"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" "mongodb.service" ]; requires = [ "mongodb.service" ]; environment = { PORT = toString cfg.port; DATABASE_SECRET_PATH = "/run/credentials/safensound.service/mongodb"; JWT_SECRET_PATH = cfg.jwtSecretPath; LOG_AUTH = lib.boolToString cfg.logAuth; LOG_QUERIES = lib.boolToString cfg.logQueries; LOG_REQUESTS = cfg.logRequests; }; serviceConfig = { Type = "simple"; ExecStart = "${cfg.package}/bin/start"; WorkingDirectory = "/var/lib/SafeNSound"; StateDirectory = "SafeNSound"; StateDirectoryMode = "0700"; ProtectSystem = "strict"; ProtectHome = true; PrivateTmp = true; NoNewPrivileges = true; PrivateDevices = true; DynamicUser = true; Restart = "always"; StartLimitIntervalSec = 60; StartLimitBurst = 5; LoadCredential = [ "mongodb:${cfg.dbCredentialsPath}" ]; }; }; } ); }; }; }