diff --git a/extra/admin-api/Spacebar.UApi/Program.cs b/extra/admin-api/Spacebar.UApi/Program.cs index 0a2a1b326..326d0a9c8 100644 --- a/extra/admin-api/Spacebar.UApi/Program.cs +++ b/extra/admin-api/Spacebar.UApi/Program.cs @@ -11,8 +11,10 @@ using Spacebar.Models.Db.Contexts; using Spacebar.UApi.Services; var builder = WebApplication.CreateBuilder(args); -if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("APPSETTINGS_PATH"))) +if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("APPSETTINGS_PATH"))) { + Console.WriteLine("Loading appsettings from path: " + Environment.GetEnvironmentVariable("APPSETTINGS_PATH")); builder.Configuration.AddJsonFile(Environment.GetEnvironmentVariable("APPSETTINGS_PATH")!); +} // Add services to the container. @@ -70,9 +72,23 @@ app.UseAuthorization(); app.MapControllers(); StreamingHttpClient.LogRequests = false; app.Use((context, next) => { - context.Response.Headers["Access-Control-Allow-Origin"] = "*"; - context.Response.Headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"; - context.Response.Headers["Access-Control-Allow-Headers"] = "*, Authorization"; + context.Response.Headers["Access-Control-Allow-Origin"] = + string.IsNullOrWhiteSpace(context.Request.Headers.Origin) + ? "*" + : context.Request.Headers.Origin; + + context.Response.Headers["Access-Control-Allow-Methods"] = + string.IsNullOrWhiteSpace(context.Request.Headers.AccessControlRequestMethod) + ? "GET, POST, PUT, DELETE, OPTIONS" + : context.Request.Headers.AccessControlRequestMethod.ToString(); + + context.Response.Headers["Access-Control-Allow-Headers"] = + string.IsNullOrWhiteSpace(context.Request.Headers.AccessControlRequestHeaders) + ? "*, Authorization" + : context.Request.Headers.AccessControlRequestHeaders.ToString(); + + context.Response.Headers.AccessControlAllowCredentials = "true"; + if (context.Request.Method == "OPTIONS") { context.Response.StatusCode = 200; return Task.CompletedTask; diff --git a/extra/admin-api/Utilities/Spacebar.AdminApi.TestClient/Pages/GuildDiscovery.razor b/extra/admin-api/Utilities/Spacebar.AdminApi.TestClient/Pages/GuildDiscovery.razor index 7e388fbc5..ff233731e 100644 --- a/extra/admin-api/Utilities/Spacebar.AdminApi.TestClient/Pages/GuildDiscovery.razor +++ b/extra/admin-api/Utilities/Spacebar.AdminApi.TestClient/Pages/GuildDiscovery.razor @@ -16,8 +16,7 @@
@guild.Description
diff --git a/flake.lock b/flake.lock index 3c3a5a856..abb78335e 100644 Binary files a/flake.lock and b/flake.lock differ diff --git a/flake.nix b/flake.nix index 2ad5e94f0..59bae2440 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,7 @@ description = "Spacebar server, written in Typescript."; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + nixpkgs.url = "github:NixOS/nixpkgs/master"; # temp hack because unstable is frozen flake-utils.url = "github:numtide/flake-utils"; }; @@ -118,4 +118,4 @@ inherit self nixpkgs flake-utils; } ); -} +} \ No newline at end of file diff --git a/nix/modules/default/cs/admin-api.nix b/nix/modules/default/cs/admin-api.nix index 132a746cb..a7b7ca05b 100644 --- a/nix/modules/default/cs/admin-api.nix +++ b/nix/modules/default/cs/admin-api.nix @@ -119,16 +119,7 @@ in in { assertions = [ - { - assertion = - cfg.adminApi.extraConfiguration ? ConnectionStrings - && cfg.adminApi.extraConfiguration.ConnectionStrings ? Spacebar - && cfg.adminApi.extraConfiguration.ConnectionStrings.Spacebar != null; - message = '' - Admin API: Setting a database connection string in extraConfiguration (`extraConfiguration.ConnectionStrings.Spacebar`) is required when using C# services. - Example: Host=127.0.0.1; Username=Spacebar; Password=SuperSecurePassword12; Database=spacebar; Port=5432; Include Error Detail=true; Maximum Pool Size=1000; Command Timeout=6000; Timeout=600; - ''; - } + (import ./assert-has-connection-string.nix "Admin API" cfg.adminApi.extraConfiguration) ]; services.spacebarchat-server.settings.admin = { diff --git a/nix/modules/default/cs/assert-has-connection-string.nix b/nix/modules/default/cs/assert-has-connection-string.nix new file mode 100644 index 000000000..4066c8938 --- /dev/null +++ b/nix/modules/default/cs/assert-has-connection-string.nix @@ -0,0 +1,7 @@ +name: extraConfig: { + assertion = extraConfig ? ConnectionStrings && extraConfig.ConnectionStrings ? Spacebar && extraConfig.ConnectionStrings.Spacebar != null; + message = '' + ${name}: Setting a database connection string in extraConfiguration (`extraConfiguration.ConnectionStrings.Spacebar`) is required when using C# services. + Example: Host=127.0.0.1; Username=Spacebar; Password=SuperSecurePassword12; Database=spacebar; Port=5432; Include Error Detail=true; Maximum Pool Size=1000; Command Timeout=6000; Timeout=600; + ''; +} diff --git a/nix/modules/default/cs/gateway-offload-cs.nix b/nix/modules/default/cs/gateway-offload-cs.nix index 28def43ac..4e56a566f 100644 --- a/nix/modules/default/cs/gateway-offload-cs.nix +++ b/nix/modules/default/cs/gateway-offload-cs.nix @@ -127,16 +127,7 @@ in in { assertions = [ - { - assertion = - cfg.gatewayOffload.extraConfiguration ? ConnectionStrings - && cfg.gatewayOffload.extraConfiguration.ConnectionStrings ? Spacebar - && cfg.gatewayOffload.extraConfiguration.ConnectionStrings.Spacebar != null; - message = '' - Gateway Offload: Setting a database connection string in extraConfiguration (`extraConfiguration.ConnectionStrings.Spacebar`) is required when using C# services. - Example: Host=127.0.0.1; Username=Spacebar; Password=SuperSecurePassword12; Database=spacebar; Port=5432; Include Error Detail=true; Maximum Pool Size=1000; Command Timeout=6000; Timeout=600; - ''; - } + (import ./assert-has-connection-string.nix "Gateway Offload" cfg.gatewayOffload.extraConfiguration) ]; services.spacebarchat-server.settings.offload = { @@ -162,7 +153,9 @@ in CONFIG_READONLY = 1; ASPNETCORE_URLS = "http://0.0.0.0:${toString cfg.gatewayOffload.listenPort}"; STORAGE_LOCATION = cfg.cdnPath; - APPSETTINGS_PATH = jsonFormat.generate "appsettings.spacebar-gateway-offload.json" (lib.recursiveUpdate (import ./default-appsettings-json.nix) cfg.gatewayOffload.extraConfiguration); + APPSETTINGS_PATH = jsonFormat.generate "appsettings.spacebar-gateway-offload.json" ( + lib.recursiveUpdate (import ./default-appsettings-json.nix) cfg.gatewayOffload.extraConfiguration + ); } ); serviceConfig = { diff --git a/nix/modules/default/cs/uapi.nix b/nix/modules/default/cs/uapi.nix index 262ce6baf..1486ef266 100644 --- a/nix/modules/default/cs/uapi.nix +++ b/nix/modules/default/cs/uapi.nix @@ -20,6 +20,11 @@ in type = lib.types.submodule { options = { enable = lib.mkEnableOption "Enable C# API overlay."; + listenPort = lib.mkOption { + type = lib.types.port; + default = 3012; + description = "Port for the gateway offload daemon to listen on."; + }; extraConfiguration = lib.mkOption { type = jsonFormat.type; default = import ./default-appsettings-json.nix; @@ -119,25 +124,11 @@ in in { assertions = [ - { - assertion = - cfg.adminApi.extraConfiguration ? ConnectionStrings - && cfg.adminApi.extraConfiguration.ConnectionStrings ? Spacebar - && cfg.adminApi.extraConfiguration.ConnectionStrings.Spacebar != null; - message = '' - Admin API: Setting a database connection string in extraConfiguration (`extraConfiguration.ConnectionStrings.Spacebar`) is required when using C# services. - Example: Host=127.0.0.1; Username=Spacebar; Password=SuperSecurePassword12; Database=spacebar; Port=5432; Include Error Detail=true; Maximum Pool Size=1000; Command Timeout=6000; Timeout=600; - ''; - } + (import ./assert-has-connection-string.nix "uAPI" cfg.uApi.extraConfiguration) ]; - services.spacebarchat-server.settings.admin = { - endpointPublic = "http${if cfg.adminApiEndpoint.useSsl then "s" else ""}://${cfg.adminApiEndpoint.host}:${toString cfg.adminApiEndpoint.publicPort}"; - endpointPrivate = "http://127.0.0.1:${builtins.toString cfg.adminApiEndpoint.localPort}"; - }; - - systemd.services.spacebar-admin-api = makeServerTsService { - description = "Spacebar Server - Admin API"; + systemd.services.spacebar-uapi = makeServerTsService { + description = "Spacebar Server - C# API overlay"; environment = builtins.mapAttrs (_: val: builtins.toString val) ( { # things we set by default... @@ -149,7 +140,7 @@ in # things we force... # CONFIG_PATH = configFile; CONFIG_READONLY = 1; - ASPNETCORE_URLS = "http://0.0.0.0:${toString cfg.uApi.localPort}"; + ASPNETCORE_URLS = "http://0.0.0.0:${toString cfg.uApi.listenPort}"; STORAGE_LOCATION = cfg.cdnPath; APPSETTINGS_PATH = jsonFormat.generate "appsettings.spacebar-uapi.json" (lib.recursiveUpdate (import ./default-appsettings-json.nix) cfg.uApi.extraConfiguration); } diff --git a/nix/modules/default/default.nix b/nix/modules/default/default.nix index 8306aba6e..07cb7d2ec 100644 --- a/nix/modules/default/default.nix +++ b/nix/modules/default/default.nix @@ -212,6 +212,7 @@ in # message = "You cannot set CONFIG_PATH, CONFIG_READONLY, PORT or STORAGE_LOCATION in extraEnvironment, these are managed by the NixOS module."; # } ]; + services.spacebarchat-server.uApi.extraConfiguration.Spacebar.UApi.FallbackApiEndpoint = "http://127.0.0.1:${toString cfg.apiEndpoint.localPort}"; systemd.services.spacebar-api = makeServerTsService { description = "Spacebar Server - API"; diff --git a/nix/modules/default/integration-nginx.nix b/nix/modules/default/integration-nginx.nix index 718e57286..d80016bf1 100644 --- a/nix/modules/default/integration-nginx.nix +++ b/nix/modules/default/integration-nginx.nix @@ -15,12 +15,13 @@ in config = lib.mkIf (cfg.enable && cfg.nginx.enable) { services.nginx = { + recommendedProxySettings = true; virtualHosts = lib.mkIf cfg.enable { "${cfg.apiEndpoint.host}" = { enableACME = cfg.apiEndpoint.useSsl; forceSSL = cfg.apiEndpoint.useSsl; locations."/" = { - proxyPass = "http://127.0.0.1:${toString cfg.apiEndpoint.localPort}/"; + proxyPass = if cfg.uApi.enable then "http://127.0.0.1:${toString cfg.uApi.listenPort}/" else "http://127.0.0.1:${toString cfg.apiEndpoint.localPort}/"; }; }; "${cfg.gatewayEndpoint.host}" = { diff --git a/nix/testVm/configuration.nix b/nix/testVm/configuration.nix index 71c2451f7..e8de371aa 100644 --- a/nix/testVm/configuration.nix +++ b/nix/testVm/configuration.nix @@ -57,6 +57,10 @@ in enable = true; extraConfiguration.ConnectionStrings.Spacebar = csConnectionString; }; + uApi = { + enable = true; + extraConfiguration.ConnectionStrings.Spacebar = csConnectionString; + }; extraEnvironment = { DATABASE = "postgres://postgres:postgres@127.0.0.1/spacebar"; #WEBRTC_PORT_RANGE=60000-61000; diff --git a/package-lock.json b/package-lock.json index 286a07788..c4869bfa5 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index e3bc55e2b..c86c976a3 100644 --- a/package.json +++ b/package.json @@ -60,14 +60,14 @@ "@types/multer": "^2.0.0", "@types/murmurhash-js": "^1.0.6", "@types/node": "^24.10.13", - "@types/nodemailer": "^7.0.9", + "@types/nodemailer": "^7.0.11", "@types/probe-image-size": "^7.2.5", "@types/sharp": "^0.31.1", "@types/ws": "^8.18.1", - "@typescript-eslint/eslint-plugin": "^8.55.0", - "@typescript-eslint/parser": "^8.55.0", + "@typescript-eslint/eslint-plugin": "^8.56.0", + "@typescript-eslint/parser": "^8.56.0", "@typescript/native-preview": "^7.0.0-dev.20260119.1", - "eslint": "^9.39.2", + "eslint": "^9.39.3", "globals": "^16.5.0", "husky": "^9.1.7", "patch-package": "^8.0.1", @@ -78,9 +78,9 @@ "typescript-json-schema": "^0.65.1" }, "dependencies": { - "@spacebarchat/medooze-webrtc": "^1.0.10", + "@spacebarchat/medooze-webrtc": "^1.0.11", "@toondepauw/node-zstd": "^1.2.0", - "ajv": "^8.17.1", + "ajv": "^8.18.0", "ajv-formats": "^3.0.1", "amqplib": "^0.10.9", "badge-maker": "^5.0.2", @@ -90,15 +90,15 @@ "cheerio": "^1.2.0", "cookie-parser": "^1.4.7", "discord-protos": "^1.2.102", - "dotenv": "^17.2.4", + "dotenv": "^17.3.1", "email-providers": "^2.21.0", "exif-be-gone": "^1.5.1", "express": "^5.2.1", "fast-zlib": "^2.0.1", - "fido2-lib": "^3.5.6", + "fido2-lib": "^3.5.7", "file-type": "^21.3.0", "form-data": "^4.0.5", - "i18next": "^25.8.6", + "i18next": "^25.8.13", "i18next-fs-backend": "^2.6.1", "i18next-http-middleware": "^3.9.2", "image-size": "^2.0.2", diff --git a/src/api/routes/discoverable-guilds.ts b/src/api/routes/discoverable-guilds.ts index 87de37a3b..2df44c16b 100644 --- a/src/api/routes/discoverable-guilds.ts +++ b/src/api/routes/discoverable-guilds.ts @@ -21,6 +21,7 @@ import { Config, Guild, Member } from "@spacebar/util"; import { route } from "@spacebar/api"; import { Request, Response, Router } from "express"; import { In, Like, Not } from "typeorm"; +import { DiscoverableGuildsResponse } from "@spacebar/schemas"; const router = Router({ mergeParams: true }); @@ -64,7 +65,11 @@ router.get( res.send({ total: total, - guilds: guilds, + guilds: guilds.map((g) => ({ + ...g, + discovery_weight: undefined, + discovery_splash: undefined, + })), offset: Number(offset || Config.get().guild.discovery.offset), limit: Number(limit || configLimit), });