mirror of
https://github.com/fosrl/pangolin.git
synced 2026-10-15 09:09:05 +02:00
Push client identities to newt
This commit is contained in:
@@ -35,6 +35,7 @@ import { LimitId } from "@server/lib/billing";
|
||||
import { usageService } from "@server/lib/billing/usageService";
|
||||
import { build } from "@server/build";
|
||||
import { calculateUserClientsForOrgs } from "@server/lib/calculateUserClientsForOrgs";
|
||||
import { pushClientIdentitiesForUser } from "@server/lib/clientIdentities";
|
||||
import { isSubscribed } from "#dynamic/lib/isSubscribed";
|
||||
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
@@ -642,6 +643,17 @@ export async function validateOidcCallback(
|
||||
);
|
||||
});
|
||||
|
||||
if (existingUser) {
|
||||
// The sync above may have changed the user's name, email or
|
||||
// roles, all of which newt forwards as Remote-* headers.
|
||||
pushClientIdentitiesForUser(userId!).catch((err) => {
|
||||
logger.error(
|
||||
"Error pushing client identities after syncing OIDC user",
|
||||
{ error: err }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
for (const orgCount of orgUserCounts) {
|
||||
await usageService.updateCount(
|
||||
orgCount.orgId,
|
||||
|
||||
@@ -24,6 +24,10 @@ import {
|
||||
generateSubnetProxyTargetV2,
|
||||
SubnetProxyTargetV2
|
||||
} from "@server/lib/ip";
|
||||
import {
|
||||
ClientIdentity,
|
||||
getClientIdentities
|
||||
} from "@server/lib/clientIdentities";
|
||||
|
||||
export async function buildClientConfigurationForNewtClient(
|
||||
site: Site,
|
||||
@@ -166,7 +170,8 @@ export async function buildClientConfigurationForNewtClient(
|
||||
if (allSiteResources.length === 0) {
|
||||
return {
|
||||
peers: validPeers,
|
||||
targets: targetsToSend
|
||||
targets: targetsToSend,
|
||||
clientIdentities: [] as ClientIdentity[]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -234,9 +239,26 @@ export async function buildClientConfigurationForNewtClient(
|
||||
}
|
||||
}
|
||||
|
||||
// Only clients that can reach an HTTP resource ever hit newt's HTTP proxy,
|
||||
// so those are the only identities it needs to set Remote-* headers.
|
||||
const httpClientIds = new Set<number>();
|
||||
for (const resource of allSiteResources) {
|
||||
if (resource.mode !== "http") {
|
||||
continue;
|
||||
}
|
||||
for (const c of clientsByResourceId.get(resource.siteResourceId) ??
|
||||
[]) {
|
||||
httpClientIds.add(c.clientId);
|
||||
}
|
||||
}
|
||||
const clientIdentities = Array.from(
|
||||
(await getClientIdentities(httpClientIds)).values()
|
||||
);
|
||||
|
||||
return {
|
||||
peers: validPeers,
|
||||
targets: targetsToSend
|
||||
targets: targetsToSend,
|
||||
clientIdentities
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -117,10 +117,8 @@ export const handleNewtGetConfigMessage: MessageHandler = async (context) => {
|
||||
}
|
||||
}
|
||||
|
||||
const { peers, targets } = await buildClientConfigurationForNewtClient(
|
||||
site,
|
||||
exitNode
|
||||
);
|
||||
const { peers, targets, clientIdentities } =
|
||||
await buildClientConfigurationForNewtClient(site, exitNode);
|
||||
|
||||
// Older newt clients only understand inline tlsCert/tlsKey on each
|
||||
// target, so only switch to certId references once we know the client
|
||||
@@ -144,6 +142,7 @@ export const handleNewtGetConfigMessage: MessageHandler = async (context) => {
|
||||
peers,
|
||||
targets: targetsToSend,
|
||||
certs,
|
||||
clientIdentities,
|
||||
chainId: chainId
|
||||
}
|
||||
},
|
||||
|
||||
@@ -28,10 +28,8 @@ export async function sendNewtSyncMessage(newt: Newt, site: Site) {
|
||||
.where(eq(exitNodes.exitNodeId, site.exitNodeId))
|
||||
.limit(1);
|
||||
}
|
||||
const { peers, targets } = await buildClientConfigurationForNewtClient(
|
||||
site,
|
||||
exitNode
|
||||
);
|
||||
const { peers, targets, clientIdentities } =
|
||||
await buildClientConfigurationForNewtClient(site, exitNode);
|
||||
|
||||
// Older newt clients only understand inline tlsCert/tlsKey on each
|
||||
// target, so only switch to certId references once we know the client
|
||||
@@ -55,6 +53,7 @@ export async function sendNewtSyncMessage(newt: Newt, site: Site) {
|
||||
peers: peers,
|
||||
clientTargets: clientTargets,
|
||||
certs: certs,
|
||||
clientIdentities: clientIdentities,
|
||||
browserGatewayTargets: browserGatewayTargets,
|
||||
remoteExitNodeSubnets: remoteExitNodeSubnets
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { fromError } from "zod-validation-error";
|
||||
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
import { pushClientIdentitiesForRole } from "@server/lib/clientIdentities";
|
||||
|
||||
const updateRoleParamsSchema = z.strictObject({
|
||||
roleId: z.coerce.number().int().positive()
|
||||
@@ -216,6 +217,16 @@ export async function updateRole(
|
||||
);
|
||||
}
|
||||
|
||||
if (updateData.name !== undefined && updateData.name !== role[0].name) {
|
||||
// Role names are forwarded by newt as the Remote-Role header.
|
||||
pushClientIdentitiesForRole(roleId, orgId).catch((err) => {
|
||||
logger.error(
|
||||
`Error pushing client identities after renaming role ${roleId}`,
|
||||
err
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return response(res, {
|
||||
data: updatedRole,
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user