diff --git a/server/routers/newt/buildConfiguration.ts b/server/routers/newt/buildConfiguration.ts index f87d38450..ce126f9c5 100644 --- a/server/routers/newt/buildConfiguration.ts +++ b/server/routers/newt/buildConfiguration.ts @@ -1,4 +1,6 @@ import { + browserGatewayTarget, + BrowserGatewayTarget, clients, clientSiteResourcesAssociationsCache, clientSitesAssociationsCache, @@ -310,3 +312,12 @@ export async function buildTargetConfigurationForNewtClient( udpTargets }; } + +export async function buildBrowserGatewayTargetConfigurationForNewtClient( + siteId: number +): Promise { + return await db + .select() + .from(browserGatewayTarget) + .where(eq(browserGatewayTarget.siteId, siteId)); +} diff --git a/server/routers/newt/sync.ts b/server/routers/newt/sync.ts index 6fce13ff3..d7ceefde4 100644 --- a/server/routers/newt/sync.ts +++ b/server/routers/newt/sync.ts @@ -3,6 +3,7 @@ import { eq } from "drizzle-orm"; import { sendToClient } from "#dynamic/routers/ws"; import logger from "@server/logger"; import { + buildBrowserGatewayTargetConfigurationForNewtClient, buildClientConfigurationForNewtClient, buildTargetConfigurationForNewtClient } from "./buildConfiguration"; @@ -12,6 +13,9 @@ export async function sendNewtSyncMessage(newt: Newt, site: Site) { const { tcpTargets, udpTargets, validHealthCheckTargets } = await buildTargetConfigurationForNewtClient(site.siteId); + const browserGatewayTargets = + await buildBrowserGatewayTargetConfigurationForNewtClient(site.siteId); + let exitNode: ExitNode | undefined; if (site.exitNodeId) { [exitNode] = await db @@ -36,7 +40,15 @@ export async function sendNewtSyncMessage(newt: Newt, site: Site) { }, healthCheckTargets: validHealthCheckTargets, peers: peers, - clientTargets: targets + clientTargets: targets, + browserGatewayTargets: browserGatewayTargets.map((t) => ({ + id: t.browserGatewayTargetId, + resourceId: t.resourceId, + siteId: t.siteId, + type: t.type, + destination: t.destination, + destinationPort: t.destinationPort + })) } }, { diff --git a/server/routers/newt/targets.ts b/server/routers/newt/targets.ts index ac25fb27d..ca15e50cc 100644 --- a/server/routers/newt/targets.ts +++ b/server/routers/newt/targets.ts @@ -1,4 +1,4 @@ -import { Target, TargetHealthCheck } from "@server/db"; +import { BrowserGatewayTarget, Target, TargetHealthCheck } from "@server/db"; import { sendToClient } from "#dynamic/routers/ws"; import logger from "@server/logger"; import { canCompress } from "@server/lib/clientVersionChecks"; @@ -239,3 +239,48 @@ export async function removeTargets( { incrementConfigVersion: true, compress: canCompress(version, "newt") } ); } + +export async function sendBrowserGatewayTargets( + newtId: string, + targets: BrowserGatewayTarget[], + version?: string | null +) { + if (targets.length === 0) return; + + const payload = targets.map((t) => ({ + id: t.browserGatewayTargetId, + resourceId: t.resourceId, + siteId: t.siteId, + type: t.type, + destination: t.destination, + destinationPort: t.destinationPort + })); + + await sendToClient( + newtId, + { + type: "newt/browsergateway/add", + data: { + targets: payload + } + }, + { incrementConfigVersion: true, compress: canCompress(version, "newt") } + ); +} + +export async function removeBrowserGatewayTarget( + newtId: string, + browserGatewayTargetId: number, + version?: string | null +) { + await sendToClient( + newtId, + { + type: "newt/browsergateway/remove", + data: { + ids: [browserGatewayTargetId] + } + }, + { incrementConfigVersion: true, compress: canCompress(version, "newt") } + ); +}