{ config, lib, pkgs, ... }: let cfg = config.services.download; in { options.services.download = { enable = lib.mkEnableOption "the File Drop private file host"; user = lib.mkOption { type = lib.types.str; description = "System user that runs the service."; }; workingDir = lib.mkOption { type = lib.types.str; default = "/srv/download"; description = "Directory containing the code (src/server.ts)."; }; storageDir = lib.mkOption { type = lib.types.str; default = "/srv/download/storage"; description = "Persistent directory where files and metadata are stored."; }; host = lib.mkOption { type = lib.types.str; default = "127.0.0.1"; description = "Bind address. Use 0.0.0.0 to expose directly."; }; port = lib.mkOption { type = lib.types.port; default = 3000; description = "Listen port."; }; maxFileSize = lib.mkOption { type = lib.types.str; default = "10GB"; description = "Maximum upload size (B/KB/MB/GB/TB)."; }; fileTtlMs = lib.mkOption { type = lib.types.ints.positive; default = 48 * 60 * 60 * 1000; description = "Milliseconds before an uploaded file expires and is deleted (hard-capped at 48 hours)."; }; maxStorageUsage = lib.mkOption { type = lib.types.float; default = 0.5; description = "Maximum fraction (0.0-1.0) of the storage filesystem that may be used; uploads are rejected above this."; }; publicBaseUrl = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Public domain of the site (e.g. https://files.example.com)."; }; trustProxy = lib.mkEnableOption "trust of X-Forwarded-* headers (behind a reverse proxy)"; repoUrl = lib.mkOption { type = lib.types.str; default = "https://github.com/Kisakay/download.git"; description = "Git repository to clone/pull from."; }; deployOnBoot = lib.mkOption { type = lib.types.bool; default = true; description = "Pull the repo at boot (like the nightcord-deploy pattern)."; }; }; config = lib.mkIf cfg.enable { systemd.tmpfiles.rules = [ "d ${cfg.storageDir} 0755 ${cfg.user} ${cfg.user} -" ]; systemd.services.download-deploy = { description = "Update download from git"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; wantedBy = lib.mkIf cfg.deployOnBoot [ "multi-user.target" ]; path = with pkgs; [ git bun ]; serviceConfig = { Type = "oneshot"; User = cfg.user; WorkingDirectory = cfg.workingDir; Environment = [ "HOME=/home/${cfg.user}" ]; ExecStartPost = "+${pkgs.systemd}/bin/systemctl restart download.service"; }; script = '' set -euo pipefail if [ ! -d "${cfg.workingDir}/.git" ]; then git clone ${cfg.repoUrl} ${cfg.workingDir} else git -C ${cfg.workingDir} pull --ff-only fi cd ${cfg.workingDir} bun install ''; }; systemd.services.download = { description = "File Drop private file host"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; path = with pkgs; [ bun ]; serviceConfig = { Type = "simple"; User = cfg.user; Group = cfg.user; WorkingDirectory = cfg.workingDir; Environment = [ "HOME=/home/${cfg.user}" "PORT=${toString cfg.port}" "HOST=${cfg.host}" "STORAGE_DIR=${cfg.storageDir}" "MAX_FILE_SIZE=${cfg.maxFileSize}" "FILE_TTL_MS=${toString cfg.fileTtlMs}" "MAX_STORAGE_USAGE=${toString cfg.maxStorageUsage}" ] ++ lib.optionals (cfg.publicBaseUrl != null) [ "PUBLIC_BASE_URL=${cfg.publicBaseUrl}" ] ++ lib.optionals cfg.trustProxy [ "TRUST_PROXY=1" ]; ExecStart = "${pkgs.bun}/bin/bun src/server.ts"; Restart = "on-failure"; RestartSec = 3; TimeoutStopSec = 30; NoNewPrivileges = true; PrivateTmp = true; ProtectSystem = "full"; ProtectHome = true; ReadWritePaths = [ cfg.storageDir ]; }; }; }; }