diff --git a/nix/modules/default/default.nix b/nix/modules/default/default.nix index 3983ef1..aa81975 100644 --- a/nix/modules/default/default.nix +++ b/nix/modules/default/default.nix @@ -79,10 +79,77 @@ gatewayEndpoint = mkEndpointOptions "gateway.sb.localhost" 3003; cdnEndpoint = mkEndpointOptions "cdn.sb.localhost" 3003; cdnPath = lib.mkOption { - type = lib.types.nullOr lib.types.str; + type = lib.types.str; + default = "./files"; description = "Path to store CDN files."; }; + cdnSignaturePath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + legacyJwtSecretPath = libMkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + mailjetApiKeyPath = libMkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + mailjetApiSecretPath = libMkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + smtpPasswordPath = libMkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + gifApiKeyPath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + rabbitmqHost = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + rabbitmqHostPath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + abuseIpDbApiKeyPath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + captchaSecretKeyPath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + captchaSiteKeyPath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + ipdataApiKeyPath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + requestSignaturePath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Path to the secret"; + }; + extraEnvironment = lib.mkOption { default = { }; description = '' @@ -127,7 +194,35 @@ wantedBy = [ "multi-user.target" ]; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; + environment = + { } + // (if cfg.cdnSignaturePath != null then { CDN_SIGNATURE_PATH = "%d/cdnSignature"; } else { }) + // (if cfg.legacyJwtSecretPath != null then { LEGACY_JWT_SECRET_PATH = "%d/legacyJwtSecret"; } else { }) + // (if cfg.mailjetApiKeyPath != null then { MAILJET_API_KEY_PATH = "%d/mailjetApiKey"; } else { }) + // (if cfg.mailjetApiSecretPath != null then { MAILJET_API_SECRET_PATH = "%d/mailjetApiSecret"; } else { }) + // (if cfg.smtpPasswordPath != null then { SMTP_PASSWORD_PATH = "%d/smtpPassword"; } else { }) + // (if cfg.gifApiKeyPath != null then { GIF_API_KEY_PATH = "%d/gifApiKey"; } else { }) + // (if cfg.rabbitmqHostPath != null then { RABBITMQ_HOST_PATH = "%d/rabbitmqHost"; } else { }) + // (if cfg.abuseIpDbApiKeyPath != null then { ABUSE_IP_DB_API_KEY_PATH = "%d/abuseIpDbApiKey"; } else { }) + // (if cfg.captchaSecretKeyPath != null then { CAPTCHA_SECRET_KEY_PATH = "%d/captchaSecretKey"; } else { }) + // (if cfg.captchaSiteKeyPath != null then { CAPTCHA_SITE_KEY_PATH = "%d/captchaSiteKey"; } else { }) + // (if cfg.ipdataApiKeyPath != null then { IPDATA_API_KEY_PATH = "%d/ipdataApiKey"; } else { }) + // (if cfg.requestSignaturePath != null then { REQUEST_SIGNATURE_PATH = "%d/requestSignature"; } else { }); serviceConfig = { + LoadCredential = + [ ] + ++ (if cfg.cdnSignaturePath != null then [ "cdnSignature:${cfg.cdnSignaturePath}" ] else [ ]) + ++ (if cfg.legacyJwtSecretPath != null then [ "legacyJwtSecret:${cfg.legacyJwtSecretPath}" ] else [ ]) + ++ (if cfg.mailjetApiKeyPath != null then [ "mailjetApiKey:${cfg.mailjetApiKeyPath}" ] else [ ]) + ++ (if cfg.mailjetApiSecretPath != null then [ "mailjetApiSecret:${cfg.mailjetApiSecretPath}" ] else [ ]) + ++ (if cfg.smtpPasswordPath != null then [ "smtpPassword:${cfg.smtpPasswordPath}" ] else [ ]) + ++ (if cfg.gifApiKeyPath != null then [ "gifApiKey:${cfg.gifApiKeyPath}" ] else [ ]) + ++ (if cfg.rabbitmqHostPath != null then [ "rabbitmqHost:${cfg.rabbitmqHostPath}" ] else [ ]) + ++ (if cfg.abuseIpDbApiKeyPath != null then [ "abuseIpDbApiKey:${cfg.abuseIpDbApiKeyPath}" ] else [ ]) + ++ (if cfg.captchaSecretKeyPath != null then [ "captchaSecretKey:${cfg.captchaSecretKeyPath}" ] else [ ]) + ++ (if cfg.captchaSiteKeyPath != null then [ "captchaSiteKey:${cfg.captchaSiteKeyPath}" ] else [ ]) + ++ (if cfg.ipdataApiKeyPath != null then [ "ipdataApiKey:${cfg.ipdataApiKeyPath}" ] else [ ]) + ++ (if cfg.requestSignaturePath != null then [ "requestSignature:${cfg.requestSignaturePath}" ] else [ ]); User = "spacebarchat"; Group = "spacebarchat"; DynamicUser = false; @@ -172,14 +267,12 @@ in { assertions = [ - # { - # assertion = !((cfg.extraEnvironment.THREADS > 1) && !config.services.rabbitmq.enable); - # message = "Make sure you've setup RabbitMQ when using more than one thread with Spacebar"; - # } + { + assertion = lib.all (map (key: !(key == "CONFIG_PATH" || key == "CONFIG_READONLY" || key == "PORT" || key == "STORAGE_LOCATION")) (lib.attrNames cfg.extraEnvironment)); + message = "You cannot set CONFIG_PATH, CONFIG_READONLY, PORT or STORAGE_LOCATION in extraEnvironment, these are managed by the NixOS module."; + } ]; - # systemd.tmpfiles.rules = [ "d /run/spacebarchat 0750 spacebar spacebar" ]; - users.users.spacebarchat = { isSystemUser = true; description = "Spacebar service user"; @@ -202,15 +295,8 @@ CONFIG_PATH = configFile; CONFIG_READONLY = 1; PORT = toString cfg.apiEndpoint.localPort; + STORAGE_LOCATION = cfg.cdnPath; } - // ( - if cfg.cdnPath != null then - { - STORAGE_LOCATION = cfg.cdnPath; - } - else - { } - ) ); serviceConfig = { ExecStart = "${cfg.package}/bin/start-api"; @@ -231,15 +317,8 @@ CONFIG_PATH = configFile; CONFIG_READONLY = 1; PORT = toString cfg.gatewayEndpoint.localPort; + STORAGE_LOCATION = cfg.cdnPath; } - // ( - if cfg.cdnPath != null then - { - STORAGE_LOCATION = cfg.cdnPath; - } - else - { } - ) ); serviceConfig = { ExecStart = "${cfg.package}/bin/start-gateway"; @@ -260,15 +339,8 @@ CONFIG_PATH = configFile; CONFIG_READONLY = 1; PORT = toString cfg.cdnEndpoint.localPort; + STORAGE_LOCATION = cfg.cdnPath; } - // ( - if cfg.cdnPath != null then - { - STORAGE_LOCATION = cfg.cdnPath; - } - else - { } - ) ); serviceConfig = { ExecStart = "${cfg.package}/bin/start-cdn"; diff --git a/nix/modules/default/integration-nginx.nix b/nix/modules/default/integration-nginx.nix index fb90fc2..70e4b2e 100644 --- a/nix/modules/default/integration-nginx.nix +++ b/nix/modules/default/integration-nginx.nix @@ -14,7 +14,7 @@ }; config = lib.mkIf (cfg.enable && cfg.nginx.enable) { - services.nginx = lib.trace (cfg.apiEndpoint) { + services.nginx = { virtualHosts = lib.mkIf cfg.enable { "${cfg.apiEndpoint.host}" = { enableACME = cfg.apiEndpoint.useSsl; diff --git a/src/util/util/Config.ts b/src/util/util/Config.ts index bc482d3..1cd24b9 100644 --- a/src/util/util/Config.ts +++ b/src/util/util/Config.ts @@ -53,6 +53,21 @@ config = OrmUtils.mergeDeep({}, { ...new ConfigValue() }, config); + // TODO: factor this out someday + if (process.env.CDN_SIGNATURE_PATH) config.security.cdnSignatureKey = (await fs.readFile(process.env.CDN_SIGNATURE_PATH, "utf-8")).trim(); + if (process.env.LEGACY_JWT_SECRET_PATH) config.security.jwtSecret = (await fs.readFile(process.env.LEGACY_JWT_SECRET_PATH, "utf-8")).trim(); + if (process.env.MAILJET_API_KEY_PATH) config.email.mailjet.apiKey = (await fs.readFile(process.env.MAILJET_API_KEY_PATH, "utf-8")).trim(); + if (process.env.MAILJET_API_SECRET_PATH) config.email.mailjet.apiSecret = (await fs.readFile(process.env.MAILJET_API_SECRET_PATH, "utf-8")).trim(); + if (process.env.SMTP_PASSWORD_PATH) config.email.smtp.password = (await fs.readFile(process.env.SMTP_PASSWORD_PATH, "utf-8")).trim(); + if (process.env.GIF_API_KEY_PATH) config.gif.apiKey = (await fs.readFile(process.env.GIF_API_KEY_PATH, "utf-8")).trim(); + if (process.env.RABBITMQ_HOST) config.rabbitmq.host = process.env.RABBITMQ_HOST.trim(); + if (process.env.RABBITMQ_HOST_PATH) config.rabbitmq.host = (await fs.readFile(process.env.RABBITMQ_HOST_PATH, "utf-8")).trim(); + if (process.env.ABUSEIPDB_API_KEY_PATH) config.security.abuseIpDbApiKey = (await fs.readFile(process.env.ABUSEIPDB_API_KEY_PATH, "utf-8")).trim(); + if (process.env.CAPTCHA_SECRET_KEY_PATH) config.security.captcha.secret = (await fs.readFile(process.env.CAPTCHA_SECRET_KEY_PATH, "utf-8")).trim(); + if (process.env.CAPTCHA_SITE_KEY_PATH) config.security.captcha.sitekey = (await fs.readFile(process.env.CAPTCHA_SITE_KEY_PATH, "utf-8")).trim(); + if (process.env.IPDATA_API_KEY_PATH) config.security.ipdataApiKey = (await fs.readFile(process.env.IPDATA_API_KEY_PATH, "utf-8")).trim(); + if (process.env.REQUEST_SIGNATURE_PATH) config.security.requestSignature = (await fs.readFile(process.env.REQUEST_SIGNATURE_PATH, "utf-8")).trim(); + await this.set(config); validateFinalConfig(config); return config;