mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-04 09:46:40 +00:00
Compare commits
11 Commits
dependabot
...
msg-opt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b01fcc70fe | ||
|
|
35fed74e49 | ||
|
|
64bae5b142 | ||
|
|
6cf1b9b010 | ||
|
|
dae169540b | ||
|
|
19f9dda490 | ||
|
|
280cbb6e22 | ||
|
|
c20babcb53 | ||
|
|
768eebe2cd | ||
|
|
81c1a1da9c | ||
|
|
52f26396ac |
1422
package-lock.json
generated
1422
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@@ -33,7 +33,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@asteasolutions/zod-to-openapi": "8.4.1",
|
||||
"@aws-sdk/client-s3": "3.1001.0",
|
||||
"@aws-sdk/client-s3": "3.989.0",
|
||||
"@faker-js/faker": "10.3.0",
|
||||
"@headlessui/react": "2.2.9",
|
||||
"@hookform/resolvers": "5.2.2",
|
||||
@@ -85,11 +85,11 @@
|
||||
"helmet": "8.1.0",
|
||||
"http-errors": "2.0.1",
|
||||
"input-otp": "1.4.2",
|
||||
"ioredis": "5.10.0",
|
||||
"ioredis": "5.9.3",
|
||||
"jmespath": "0.16.0",
|
||||
"js-yaml": "4.1.1",
|
||||
"jsonwebtoken": "9.0.3",
|
||||
"lucide-react": "0.576.0",
|
||||
"lucide-react": "0.563.0",
|
||||
"maxmind": "5.0.5",
|
||||
"moment": "2.30.1",
|
||||
"next": "15.5.12",
|
||||
@@ -103,17 +103,17 @@
|
||||
"posthog-node": "5.26.0",
|
||||
"qrcode.react": "4.2.0",
|
||||
"react": "19.2.4",
|
||||
"react-day-picker": "9.14.0",
|
||||
"react-day-picker": "9.13.2",
|
||||
"react-dom": "19.2.4",
|
||||
"react-easy-sort": "1.8.0",
|
||||
"react-hook-form": "7.71.2",
|
||||
"react-icons": "5.6.0",
|
||||
"react-icons": "5.5.0",
|
||||
"recharts": "2.15.4",
|
||||
"reodotdev": "1.1.0",
|
||||
"reodotdev": "1.0.0",
|
||||
"resend": "6.9.2",
|
||||
"semver": "7.7.4",
|
||||
"sshpk": "^1.18.0",
|
||||
"stripe": "20.4.0",
|
||||
"stripe": "20.3.1",
|
||||
"swagger-ui-express": "5.0.1",
|
||||
"tailwind-merge": "3.5.0",
|
||||
"topojson-client": "3.1.0",
|
||||
|
||||
@@ -17,7 +17,6 @@ import fs from "fs";
|
||||
import path from "path";
|
||||
import { APP_PATH } from "./lib/consts";
|
||||
import yaml from "js-yaml";
|
||||
import { z } from "zod";
|
||||
|
||||
const dev = process.env.ENVIRONMENT !== "prod";
|
||||
const externalPort = config.getRawConfig().server.integration_port;
|
||||
@@ -39,24 +38,12 @@ export function createIntegrationApiServer() {
|
||||
apiServer.use(cookieParser());
|
||||
apiServer.use(express.json());
|
||||
|
||||
const openApiDocumentation = getOpenApiDocumentation();
|
||||
|
||||
apiServer.use(
|
||||
"/v1/docs",
|
||||
swaggerUi.serve,
|
||||
swaggerUi.setup(openApiDocumentation)
|
||||
swaggerUi.setup(getOpenApiDocumentation())
|
||||
);
|
||||
|
||||
// Unauthenticated OpenAPI spec endpoints
|
||||
apiServer.get("/v1/openapi.json", (_req, res) => {
|
||||
res.json(openApiDocumentation);
|
||||
});
|
||||
|
||||
apiServer.get("/v1/openapi.yaml", (_req, res) => {
|
||||
const yamlOutput = yaml.dump(openApiDocumentation);
|
||||
res.type("application/yaml").send(yamlOutput);
|
||||
});
|
||||
|
||||
// API routes
|
||||
const prefix = `/v1`;
|
||||
apiServer.use(logIncomingMiddleware);
|
||||
@@ -88,6 +75,16 @@ function getOpenApiDocumentation() {
|
||||
}
|
||||
);
|
||||
|
||||
for (const def of registry.definitions) {
|
||||
if (def.type === "route") {
|
||||
def.route.security = [
|
||||
{
|
||||
[bearerAuth.name]: []
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/",
|
||||
@@ -97,74 +94,6 @@ function getOpenApiDocumentation() {
|
||||
responses: {}
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/openapi.json",
|
||||
description: "Get OpenAPI specification as JSON",
|
||||
tags: [],
|
||||
request: {},
|
||||
responses: {
|
||||
"200": {
|
||||
description: "OpenAPI specification as JSON",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: {
|
||||
type: "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/openapi.yaml",
|
||||
description: "Get OpenAPI specification as YAML",
|
||||
tags: [],
|
||||
request: {},
|
||||
responses: {
|
||||
"200": {
|
||||
description: "OpenAPI specification as YAML",
|
||||
content: {
|
||||
"application/yaml": {
|
||||
schema: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (const def of registry.definitions) {
|
||||
if (def.type === "route") {
|
||||
def.route.security = [
|
||||
{
|
||||
[bearerAuth.name]: []
|
||||
}
|
||||
];
|
||||
|
||||
// Ensure every route has a generic JSON response schema so Swagger UI can render responses
|
||||
const existingResponses = def.route.responses;
|
||||
const hasExistingResponses =
|
||||
existingResponses && Object.keys(existingResponses).length > 0;
|
||||
|
||||
if (!hasExistingResponses) {
|
||||
def.route.responses = {
|
||||
"*": {
|
||||
description: "",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const generator = new OpenApiGeneratorV3(registry.definitions);
|
||||
|
||||
const generated = generator.generateDocument({
|
||||
|
||||
123
server/lib/ip.ts
123
server/lib/ip.ts
@@ -571,6 +571,129 @@ export function generateSubnetProxyTargets(
|
||||
return targets;
|
||||
}
|
||||
|
||||
export type SubnetProxyTargetV2 = {
|
||||
sourcePrefixes: string[]; // must be cidrs
|
||||
destPrefix: string; // must be a cidr
|
||||
disableIcmp?: boolean;
|
||||
rewriteTo?: string; // must be a cidr
|
||||
portRange?: {
|
||||
min: number;
|
||||
max: number;
|
||||
protocol: "tcp" | "udp";
|
||||
}[];
|
||||
};
|
||||
|
||||
export function generateSubnetProxyTargetV2(
|
||||
siteResource: SiteResource,
|
||||
clients: {
|
||||
clientId: number;
|
||||
pubKey: string | null;
|
||||
subnet: string | null;
|
||||
}[]
|
||||
): SubnetProxyTargetV2 | undefined {
|
||||
if (clients.length === 0) {
|
||||
logger.debug(
|
||||
`No clients have access to site resource ${siteResource.siteResourceId}, skipping target generation.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let target: SubnetProxyTargetV2 | null = null;
|
||||
|
||||
const portRange = [
|
||||
...parsePortRangeString(siteResource.tcpPortRangeString, "tcp"),
|
||||
...parsePortRangeString(siteResource.udpPortRangeString, "udp")
|
||||
];
|
||||
const disableIcmp = siteResource.disableIcmp ?? false;
|
||||
|
||||
if (siteResource.mode == "host") {
|
||||
let destination = siteResource.destination;
|
||||
// check if this is a valid ip
|
||||
const ipSchema = z.union([z.ipv4(), z.ipv6()]);
|
||||
if (ipSchema.safeParse(destination).success) {
|
||||
destination = `${destination}/32`;
|
||||
|
||||
target = {
|
||||
sourcePrefixes: [],
|
||||
destPrefix: destination,
|
||||
portRange,
|
||||
disableIcmp
|
||||
};
|
||||
}
|
||||
|
||||
if (siteResource.alias && siteResource.aliasAddress) {
|
||||
// also push a match for the alias address
|
||||
target = {
|
||||
sourcePrefixes: [],
|
||||
destPrefix: `${siteResource.aliasAddress}/32`,
|
||||
rewriteTo: destination,
|
||||
portRange,
|
||||
disableIcmp
|
||||
};
|
||||
}
|
||||
} else if (siteResource.mode == "cidr") {
|
||||
target = {
|
||||
sourcePrefixes: [],
|
||||
destPrefix: siteResource.destination,
|
||||
portRange,
|
||||
disableIcmp
|
||||
};
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const clientSite of clients) {
|
||||
if (!clientSite.subnet) {
|
||||
logger.debug(
|
||||
`Client ${clientSite.clientId} has no subnet, skipping for site resource ${siteResource.siteResourceId}.`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const clientPrefix = `${clientSite.subnet.split("/")[0]}/32`;
|
||||
|
||||
// add client prefix to source prefixes
|
||||
target.sourcePrefixes.push(clientPrefix);
|
||||
}
|
||||
|
||||
// print a nice representation of the targets
|
||||
// logger.debug(
|
||||
// `Generated subnet proxy targets for: ${JSON.stringify(targets, null, 2)}`
|
||||
// );
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a SubnetProxyTargetV2 to an array of SubnetProxyTarget (v1)
|
||||
* by expanding each source prefix into its own target entry.
|
||||
* @param targetV2 - The v2 target to convert
|
||||
* @returns Array of v1 SubnetProxyTarget objects
|
||||
*/
|
||||
export function convertSubnetProxyTargetsV2ToV1(
|
||||
targetsV2: SubnetProxyTargetV2[]
|
||||
): SubnetProxyTarget[] {
|
||||
return targetsV2.flatMap((targetV2) =>
|
||||
targetV2.sourcePrefixes.map((sourcePrefix) => ({
|
||||
sourcePrefix,
|
||||
destPrefix: targetV2.destPrefix,
|
||||
...(targetV2.disableIcmp !== undefined && {
|
||||
disableIcmp: targetV2.disableIcmp
|
||||
}),
|
||||
...(targetV2.rewriteTo !== undefined && {
|
||||
rewriteTo: targetV2.rewriteTo
|
||||
}),
|
||||
...(targetV2.portRange !== undefined && {
|
||||
portRange: targetV2.portRange
|
||||
})
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Custom schema for validating port range strings
|
||||
// Format: "80,443,8000-9000" or "*" for all ports, or empty string
|
||||
export const portRangeStringSchema = z
|
||||
|
||||
@@ -302,8 +302,8 @@ export const configSchema = z
|
||||
.optional()
|
||||
.default({
|
||||
block_size: 24,
|
||||
subnet_group: "100.90.128.0/24",
|
||||
utility_subnet_group: "100.96.128.0/24"
|
||||
subnet_group: "100.90.128.0/20",
|
||||
utility_subnet_group: "100.96.128.0/20"
|
||||
}),
|
||||
rate_limits: z
|
||||
.object({
|
||||
|
||||
@@ -32,7 +32,7 @@ import logger from "@server/logger";
|
||||
import {
|
||||
generateAliasConfig,
|
||||
generateRemoteSubnets,
|
||||
generateSubnetProxyTargets,
|
||||
generateSubnetProxyTargetV2,
|
||||
parseEndpoint,
|
||||
formatEndpoint
|
||||
} from "@server/lib/ip";
|
||||
@@ -659,17 +659,14 @@ async function handleSubnetProxyTargetUpdates(
|
||||
);
|
||||
|
||||
if (addedClients.length > 0) {
|
||||
const targetsToAdd = generateSubnetProxyTargets(
|
||||
const targetToAdd = generateSubnetProxyTargetV2(
|
||||
siteResource,
|
||||
addedClients
|
||||
);
|
||||
|
||||
if (targetsToAdd.length > 0) {
|
||||
logger.info(
|
||||
`Adding ${targetsToAdd.length} subnet proxy targets for siteResource ${siteResource.siteResourceId}`
|
||||
);
|
||||
if (targetToAdd) {
|
||||
proxyJobs.push(
|
||||
addSubnetProxyTargets(newt.newtId, targetsToAdd)
|
||||
addSubnetProxyTargets(newt.newtId, [targetToAdd])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -695,17 +692,14 @@ async function handleSubnetProxyTargetUpdates(
|
||||
);
|
||||
|
||||
if (removedClients.length > 0) {
|
||||
const targetsToRemove = generateSubnetProxyTargets(
|
||||
const targetToRemove = generateSubnetProxyTargetV2(
|
||||
siteResource,
|
||||
removedClients
|
||||
);
|
||||
|
||||
if (targetsToRemove.length > 0) {
|
||||
logger.info(
|
||||
`Removing ${targetsToRemove.length} subnet proxy targets for siteResource ${siteResource.siteResourceId}`
|
||||
);
|
||||
if (targetToRemove) {
|
||||
proxyJobs.push(
|
||||
removeSubnetProxyTargets(newt.newtId, targetsToRemove)
|
||||
removeSubnetProxyTargets(newt.newtId, [targetToRemove])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1159,7 +1153,7 @@ async function handleMessagesForClientResources(
|
||||
}
|
||||
|
||||
for (const resource of resources) {
|
||||
const targets = generateSubnetProxyTargets(resource, [
|
||||
const target = generateSubnetProxyTargetV2(resource, [
|
||||
{
|
||||
clientId: client.clientId,
|
||||
pubKey: client.pubKey,
|
||||
@@ -1167,8 +1161,8 @@ async function handleMessagesForClientResources(
|
||||
}
|
||||
]);
|
||||
|
||||
if (targets.length > 0) {
|
||||
proxyJobs.push(addSubnetProxyTargets(newt.newtId, targets));
|
||||
if (target) {
|
||||
proxyJobs.push(addSubnetProxyTargets(newt.newtId, [target]));
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -1230,7 +1224,7 @@ async function handleMessagesForClientResources(
|
||||
}
|
||||
|
||||
for (const resource of resources) {
|
||||
const targets = generateSubnetProxyTargets(resource, [
|
||||
const target = generateSubnetProxyTargetV2(resource, [
|
||||
{
|
||||
clientId: client.clientId,
|
||||
pubKey: client.pubKey,
|
||||
@@ -1238,9 +1232,9 @@ async function handleMessagesForClientResources(
|
||||
}
|
||||
]);
|
||||
|
||||
if (targets.length > 0) {
|
||||
if (target) {
|
||||
proxyJobs.push(
|
||||
removeSubnetProxyTargets(newt.newtId, targets)
|
||||
removeSubnetProxyTargets(newt.newtId, [target])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,20 +5,17 @@ export const registry = new OpenAPIRegistry();
|
||||
export enum OpenAPITags {
|
||||
Site = "Site",
|
||||
Org = "Organization",
|
||||
PublicResource = "Public Resource",
|
||||
PrivateResource = "Private Resource",
|
||||
Resource = "Resource",
|
||||
Role = "Role",
|
||||
User = "User",
|
||||
Invitation = "User Invitation",
|
||||
Target = "Resource Target",
|
||||
Invitation = "Invitation",
|
||||
Target = "Target",
|
||||
Rule = "Rule",
|
||||
AccessToken = "Access Token",
|
||||
GlobalIdp = "Identity Provider (Global)",
|
||||
OrgIdp = "Identity Provider (Organization Only)",
|
||||
Idp = "Identity Provider",
|
||||
Client = "Client",
|
||||
ApiKey = "API Key",
|
||||
Domain = "Domain",
|
||||
Blueprint = "Blueprint",
|
||||
Ssh = "SSH",
|
||||
Logs = "Logs"
|
||||
Ssh = "SSH"
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/logs/access/export",
|
||||
description: "Export the access audit log for an organization as CSV",
|
||||
tags: [OpenAPITags.Logs],
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
query: queryAccessAuditLogsQuery,
|
||||
params: queryAccessAuditLogsParams
|
||||
|
||||
@@ -32,7 +32,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/logs/action/export",
|
||||
description: "Export the action audit log for an organization as CSV",
|
||||
tags: [OpenAPITags.Logs],
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
query: queryActionAuditLogsQuery,
|
||||
params: queryActionAuditLogsParams
|
||||
|
||||
@@ -249,7 +249,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/logs/access",
|
||||
description: "Query the access audit log for an organization",
|
||||
tags: [OpenAPITags.Logs],
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
query: queryAccessAuditLogsQuery,
|
||||
params: queryAccessAuditLogsParams
|
||||
|
||||
@@ -160,7 +160,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/logs/action",
|
||||
description: "Query the action audit log for an organization",
|
||||
tags: [OpenAPITags.Logs],
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
query: queryActionAuditLogsQuery,
|
||||
params: queryActionAuditLogsParams
|
||||
|
||||
@@ -31,16 +31,16 @@ const getOrgSchema = z.strictObject({
|
||||
orgId: z.string()
|
||||
});
|
||||
|
||||
// registry.registerPath({
|
||||
// method: "get",
|
||||
// path: "/org/{orgId}/billing/usage",
|
||||
// description: "Get an organization's billing usage",
|
||||
// tags: [OpenAPITags.Org],
|
||||
// request: {
|
||||
// params: getOrgSchema
|
||||
// },
|
||||
// responses: {}
|
||||
// });
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/billing/usage",
|
||||
description: "Get an organization's billing usage",
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
params: getOrgSchema
|
||||
},
|
||||
responses: {}
|
||||
});
|
||||
|
||||
export async function getOrgUsage(
|
||||
req: Request,
|
||||
|
||||
@@ -52,7 +52,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/idp/oidc",
|
||||
description: "Create an OIDC IdP for a specific organization.",
|
||||
tags: [OpenAPITags.OrgIdp],
|
||||
tags: [OpenAPITags.Idp, OpenAPITags.Org],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
body: {
|
||||
|
||||
@@ -35,7 +35,7 @@ registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/org/{orgId}/idp/{idpId}",
|
||||
description: "Delete IDP for a specific organization.",
|
||||
tags: [OpenAPITags.OrgIdp],
|
||||
tags: [OpenAPITags.Idp, OpenAPITags.Org],
|
||||
request: {
|
||||
params: paramsSchema
|
||||
},
|
||||
|
||||
@@ -50,9 +50,9 @@ async function query(idpId: number, orgId: string) {
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/idp/{idpId}",
|
||||
path: "/org/:orgId/idp/:idpId",
|
||||
description: "Get an IDP by its IDP ID for a specific organization.",
|
||||
tags: [OpenAPITags.OrgIdp],
|
||||
tags: [OpenAPITags.Idp, OpenAPITags.Org],
|
||||
request: {
|
||||
params: paramsSchema
|
||||
},
|
||||
|
||||
@@ -67,7 +67,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/idp",
|
||||
description: "List all IDP for a specific organization.",
|
||||
tags: [OpenAPITags.OrgIdp],
|
||||
tags: [OpenAPITags.Idp, OpenAPITags.Org],
|
||||
request: {
|
||||
query: querySchema,
|
||||
params: paramsSchema
|
||||
|
||||
@@ -59,7 +59,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/org/{orgId}/idp/{idpId}/oidc",
|
||||
description: "Update an OIDC IdP for a specific organization.",
|
||||
tags: [OpenAPITags.OrgIdp],
|
||||
tags: [OpenAPITags.Idp, OpenAPITags.Org],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
body: {
|
||||
|
||||
@@ -52,7 +52,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/maintenance/info",
|
||||
description: "Get maintenance information for a resource by domain.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
query: z.object({
|
||||
fullDomain: z.string()
|
||||
|
||||
@@ -43,7 +43,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}/access-token",
|
||||
description: "Generate a new access token for a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.AccessToken],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.AccessToken],
|
||||
request: {
|
||||
params: generateAccssTokenParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -122,7 +122,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/access-tokens",
|
||||
description: "List all access tokens in an organization.",
|
||||
tags: [OpenAPITags.AccessToken],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.AccessToken],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string()
|
||||
@@ -135,8 +135,8 @@ registry.registerPath({
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/resource/{resourceId}/access-tokens",
|
||||
description: "List all access tokens for a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.AccessToken],
|
||||
description: "List all access tokens in an organization.",
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.AccessToken],
|
||||
request: {
|
||||
params: z.object({
|
||||
resourceId: z.number()
|
||||
|
||||
@@ -37,7 +37,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/api-key",
|
||||
description: "Create a new API key scoped to the organization.",
|
||||
tags: [OpenAPITags.ApiKey],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.ApiKey],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
body: {
|
||||
|
||||
@@ -18,7 +18,7 @@ registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/org/{orgId}/api-key/{apiKeyId}",
|
||||
description: "Delete an API key.",
|
||||
tags: [OpenAPITags.ApiKey],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.ApiKey],
|
||||
request: {
|
||||
params: paramsSchema
|
||||
},
|
||||
|
||||
@@ -48,7 +48,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/api-key/{apiKeyId}/actions",
|
||||
description: "List all actions set for an API key.",
|
||||
tags: [OpenAPITags.ApiKey],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.ApiKey],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
query: querySchema
|
||||
|
||||
@@ -52,7 +52,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/api-keys",
|
||||
description: "List all API keys for an organization",
|
||||
tags: [OpenAPITags.ApiKey],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.ApiKey],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
query: querySchema
|
||||
|
||||
@@ -25,7 +25,7 @@ registry.registerPath({
|
||||
path: "/org/{orgId}/api-key/{apiKeyId}/actions",
|
||||
description:
|
||||
"Set actions for an API key. This will replace any existing actions.",
|
||||
tags: [OpenAPITags.ApiKey],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.ApiKey],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
body: {
|
||||
|
||||
@@ -20,7 +20,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/logs/request",
|
||||
description: "Query the request audit log for an organization",
|
||||
tags: [OpenAPITags.Logs],
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
query: queryAccessAuditLogsQuery.omit({
|
||||
limit: true,
|
||||
|
||||
@@ -151,7 +151,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/logs/analytics",
|
||||
description: "Query the request audit analytics for an organization",
|
||||
tags: [OpenAPITags.Logs],
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
query: queryAccessAuditLogsQuery,
|
||||
params: queryRequestAuditLogsParams
|
||||
|
||||
@@ -182,7 +182,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/logs/request",
|
||||
description: "Query the request audit log for an organization",
|
||||
tags: [OpenAPITags.Logs],
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
query: queryAccessAuditLogsQuery,
|
||||
params: queryRequestAuditLogsParams
|
||||
|
||||
@@ -20,7 +20,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/blueprint",
|
||||
description: "Apply a base64 encoded JSON blueprint to an organization",
|
||||
tags: [OpenAPITags.Blueprint],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Blueprint],
|
||||
request: {
|
||||
params: applyBlueprintParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -43,7 +43,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/blueprint",
|
||||
description: "Create and apply a YAML blueprint to an organization",
|
||||
tags: [OpenAPITags.Blueprint],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Blueprint],
|
||||
request: {
|
||||
params: applyBlueprintParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -53,7 +53,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/blueprint/{blueprintId}",
|
||||
description: "Get a blueprint by its blueprint ID.",
|
||||
tags: [OpenAPITags.Blueprint],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Blueprint],
|
||||
request: {
|
||||
params: getBlueprintSchema
|
||||
},
|
||||
|
||||
@@ -67,7 +67,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/blueprints",
|
||||
description: "List all blueprints for a organization.",
|
||||
tags: [OpenAPITags.Blueprint],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Blueprint],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string()
|
||||
|
||||
@@ -48,7 +48,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/client",
|
||||
description: "Create a new client for an organization.",
|
||||
tags: [OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
params: createClientParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -49,7 +49,7 @@ registry.registerPath({
|
||||
path: "/org/{orgId}/user/{userId}/client",
|
||||
description:
|
||||
"Create a new client for a user and associate it with an existing olm.",
|
||||
tags: [OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org, OpenAPITags.User],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
body: {
|
||||
|
||||
@@ -243,7 +243,7 @@ registry.registerPath({
|
||||
path: "/org/{orgId}/client/{niceId}",
|
||||
description:
|
||||
"Get a client by orgId and niceId. NiceId is a readable ID for the site and unique on a per org basis.",
|
||||
tags: [OpenAPITags.Site],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Site],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string(),
|
||||
|
||||
@@ -237,7 +237,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/clients",
|
||||
description: "List all clients for an organization.",
|
||||
tags: [OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
query: listClientsSchema,
|
||||
params: listClientsParamsSchema
|
||||
|
||||
@@ -256,7 +256,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/user-devices",
|
||||
description: "List all user devices for an organization.",
|
||||
tags: [OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
query: listUserDevicesSchema,
|
||||
params: listUserDevicesParamsSchema
|
||||
|
||||
@@ -23,7 +23,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/pick-client-defaults",
|
||||
description: "Return pre-requisite data for creating a client.",
|
||||
tags: [OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Site],
|
||||
request: {
|
||||
params: pickClientDefaultsSchema
|
||||
},
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import { sendToClient } from "#dynamic/routers/ws";
|
||||
import { db, olms, Transaction } from "@server/db";
|
||||
import { Alias, SubnetProxyTarget } from "@server/lib/ip";
|
||||
import { S } from "@faker-js/faker/dist/airline-Dz1uGqgJ";
|
||||
import { db, newts, olms, Transaction } from "@server/db";
|
||||
import {
|
||||
Alias,
|
||||
convertSubnetProxyTargetsV2ToV1,
|
||||
SubnetProxyTarget,
|
||||
SubnetProxyTargetV2
|
||||
} from "@server/lib/ip";
|
||||
import logger from "@server/logger";
|
||||
import { eq } from "drizzle-orm";
|
||||
import semver from "semver";
|
||||
|
||||
const BATCH_SIZE = 50;
|
||||
const BATCH_DELAY_MS = 50;
|
||||
@@ -19,57 +26,149 @@ function chunkArray<T>(array: T[], size: number): T[][] {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
export async function addTargets(newtId: string, targets: SubnetProxyTarget[]) {
|
||||
const batches = chunkArray(targets, BATCH_SIZE);
|
||||
const NEWT_V2_TARGETS_VERSION = ">=1.11.0";
|
||||
|
||||
export async function convertTargetsIfNessicary(
|
||||
newtId: string,
|
||||
targets: SubnetProxyTarget[] | SubnetProxyTargetV2[]
|
||||
) {
|
||||
// get the newt
|
||||
const [newt] = await db
|
||||
.select()
|
||||
.from(newts)
|
||||
.where(eq(newts.newtId, newtId));
|
||||
if (!newt) {
|
||||
throw new Error(`No newt found for id: ${newtId}`);
|
||||
}
|
||||
|
||||
// check the semver
|
||||
if (
|
||||
newt.version &&
|
||||
!semver.satisfies(newt.version, NEWT_V2_TARGETS_VERSION)
|
||||
) {
|
||||
logger.debug(
|
||||
`addTargets Newt version ${newt.version} does not support targets v2 falling back`
|
||||
);
|
||||
targets = convertSubnetProxyTargetsV2ToV1(
|
||||
targets as SubnetProxyTargetV2[]
|
||||
);
|
||||
}
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
export async function addTargets(
|
||||
newtId: string,
|
||||
targets: SubnetProxyTarget[] | SubnetProxyTargetV2[]
|
||||
) {
|
||||
targets = await convertTargetsIfNessicary(newtId, targets);
|
||||
|
||||
const batches = chunkArray<SubnetProxyTarget | SubnetProxyTargetV2>(
|
||||
targets,
|
||||
BATCH_SIZE
|
||||
);
|
||||
|
||||
for (let i = 0; i < batches.length; i++) {
|
||||
if (i > 0) {
|
||||
await sleep(BATCH_DELAY_MS);
|
||||
}
|
||||
await sendToClient(newtId, {
|
||||
type: `newt/wg/targets/add`,
|
||||
data: batches[i]
|
||||
}, { incrementConfigVersion: true });
|
||||
await sendToClient(
|
||||
newtId,
|
||||
{
|
||||
type: `newt/wg/targets/add`,
|
||||
data: batches[i]
|
||||
},
|
||||
{ incrementConfigVersion: true }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function removeTargets(
|
||||
newtId: string,
|
||||
targets: SubnetProxyTarget[]
|
||||
targets: SubnetProxyTarget[] | SubnetProxyTargetV2[]
|
||||
) {
|
||||
const batches = chunkArray(targets, BATCH_SIZE);
|
||||
targets = await convertTargetsIfNessicary(newtId, targets);
|
||||
|
||||
const batches = chunkArray<SubnetProxyTarget | SubnetProxyTargetV2>(
|
||||
targets,
|
||||
BATCH_SIZE
|
||||
);
|
||||
for (let i = 0; i < batches.length; i++) {
|
||||
if (i > 0) {
|
||||
await sleep(BATCH_DELAY_MS);
|
||||
}
|
||||
await sendToClient(newtId, {
|
||||
type: `newt/wg/targets/remove`,
|
||||
data: batches[i]
|
||||
},{ incrementConfigVersion: true });
|
||||
await sendToClient(
|
||||
newtId,
|
||||
{
|
||||
type: `newt/wg/targets/remove`,
|
||||
data: batches[i]
|
||||
},
|
||||
{ incrementConfigVersion: true }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateTargets(
|
||||
newtId: string,
|
||||
targets: {
|
||||
oldTargets: SubnetProxyTarget[];
|
||||
newTargets: SubnetProxyTarget[];
|
||||
oldTargets: SubnetProxyTarget[] | SubnetProxyTargetV2[];
|
||||
newTargets: SubnetProxyTarget[] | SubnetProxyTargetV2[];
|
||||
}
|
||||
) {
|
||||
const oldBatches = chunkArray(targets.oldTargets, BATCH_SIZE);
|
||||
const newBatches = chunkArray(targets.newTargets, BATCH_SIZE);
|
||||
// get the newt
|
||||
const [newt] = await db
|
||||
.select()
|
||||
.from(newts)
|
||||
.where(eq(newts.newtId, newtId));
|
||||
if (!newt) {
|
||||
logger.error(`addTargetsL No newt found for id: ${newtId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// check the semver
|
||||
if (
|
||||
newt.version &&
|
||||
!semver.satisfies(newt.version, NEWT_V2_TARGETS_VERSION)
|
||||
) {
|
||||
logger.debug(
|
||||
`addTargets Newt version ${newt.version} does not support targets v2 falling back`
|
||||
);
|
||||
targets = {
|
||||
oldTargets: convertSubnetProxyTargetsV2ToV1(
|
||||
targets.oldTargets as SubnetProxyTargetV2[]
|
||||
),
|
||||
newTargets: convertSubnetProxyTargetsV2ToV1(
|
||||
targets.newTargets as SubnetProxyTargetV2[]
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
const oldBatches = chunkArray<SubnetProxyTarget | SubnetProxyTargetV2>(
|
||||
targets.oldTargets,
|
||||
BATCH_SIZE
|
||||
);
|
||||
const newBatches = chunkArray<SubnetProxyTarget | SubnetProxyTargetV2>(
|
||||
targets.newTargets,
|
||||
BATCH_SIZE
|
||||
);
|
||||
|
||||
const maxBatches = Math.max(oldBatches.length, newBatches.length);
|
||||
|
||||
for (let i = 0; i < maxBatches; i++) {
|
||||
if (i > 0) {
|
||||
await sleep(BATCH_DELAY_MS);
|
||||
}
|
||||
await sendToClient(newtId, {
|
||||
type: `newt/wg/targets/update`,
|
||||
data: {
|
||||
oldTargets: oldBatches[i] || [],
|
||||
newTargets: newBatches[i] || []
|
||||
}
|
||||
}, { incrementConfigVersion: true }).catch((error) => {
|
||||
await sendToClient(
|
||||
newtId,
|
||||
{
|
||||
type: `newt/wg/targets/update`,
|
||||
data: {
|
||||
oldTargets: oldBatches[i] || [],
|
||||
newTargets: newBatches[i] || []
|
||||
}
|
||||
},
|
||||
{ incrementConfigVersion: true }
|
||||
).catch((error) => {
|
||||
logger.warn(`Error sending message:`, error);
|
||||
});
|
||||
}
|
||||
@@ -94,14 +193,18 @@ export async function addPeerData(
|
||||
olmId = olm.olmId;
|
||||
}
|
||||
|
||||
await sendToClient(olmId, {
|
||||
type: `olm/wg/peer/data/add`,
|
||||
data: {
|
||||
siteId: siteId,
|
||||
remoteSubnets: remoteSubnets,
|
||||
aliases: aliases
|
||||
}
|
||||
}, { incrementConfigVersion: true }).catch((error) => {
|
||||
await sendToClient(
|
||||
olmId,
|
||||
{
|
||||
type: `olm/wg/peer/data/add`,
|
||||
data: {
|
||||
siteId: siteId,
|
||||
remoteSubnets: remoteSubnets,
|
||||
aliases: aliases
|
||||
}
|
||||
},
|
||||
{ incrementConfigVersion: true }
|
||||
).catch((error) => {
|
||||
logger.warn(`Error sending message:`, error);
|
||||
});
|
||||
}
|
||||
@@ -125,14 +228,18 @@ export async function removePeerData(
|
||||
olmId = olm.olmId;
|
||||
}
|
||||
|
||||
await sendToClient(olmId, {
|
||||
type: `olm/wg/peer/data/remove`,
|
||||
data: {
|
||||
siteId: siteId,
|
||||
remoteSubnets: remoteSubnets,
|
||||
aliases: aliases
|
||||
}
|
||||
}, { incrementConfigVersion: true }).catch((error) => {
|
||||
await sendToClient(
|
||||
olmId,
|
||||
{
|
||||
type: `olm/wg/peer/data/remove`,
|
||||
data: {
|
||||
siteId: siteId,
|
||||
remoteSubnets: remoteSubnets,
|
||||
aliases: aliases
|
||||
}
|
||||
},
|
||||
{ incrementConfigVersion: true }
|
||||
).catch((error) => {
|
||||
logger.warn(`Error sending message:`, error);
|
||||
});
|
||||
}
|
||||
@@ -166,14 +273,18 @@ export async function updatePeerData(
|
||||
olmId = olm.olmId;
|
||||
}
|
||||
|
||||
await sendToClient(olmId, {
|
||||
type: `olm/wg/peer/data/update`,
|
||||
data: {
|
||||
siteId: siteId,
|
||||
...remoteSubnets,
|
||||
...aliases
|
||||
}
|
||||
}, { incrementConfigVersion: true }).catch((error) => {
|
||||
await sendToClient(
|
||||
olmId,
|
||||
{
|
||||
type: `olm/wg/peer/data/update`,
|
||||
data: {
|
||||
siteId: siteId,
|
||||
...remoteSubnets,
|
||||
...aliases
|
||||
}
|
||||
},
|
||||
{ incrementConfigVersion: true }
|
||||
).catch((error) => {
|
||||
logger.warn(`Error sending message:`, error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/domains",
|
||||
description: "List all domains for a organization.",
|
||||
tags: [OpenAPITags.Domain],
|
||||
tags: [OpenAPITags.Org],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string()
|
||||
|
||||
@@ -27,7 +27,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/idp/{idpId}/org/{orgId}",
|
||||
description: "Create an IDP policy for an existing IDP on an organization.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
body: {
|
||||
|
||||
@@ -37,7 +37,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/idp/oidc",
|
||||
description: "Create an OIDC IdP.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
|
||||
@@ -21,7 +21,7 @@ registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/idp/{idpId}",
|
||||
description: "Delete IDP.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
params: paramsSchema
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@ registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/idp/{idpId}/org/{orgId}",
|
||||
description: "Create an OIDC IdP for an organization.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
params: paramsSchema
|
||||
},
|
||||
|
||||
@@ -34,7 +34,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/idp/{idpId}",
|
||||
description: "Get an IDP by its IDP ID.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
params: paramsSchema
|
||||
},
|
||||
|
||||
@@ -48,7 +48,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/idp/{idpId}/org",
|
||||
description: "List all org policies on an IDP.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
query: querySchema
|
||||
|
||||
@@ -58,7 +58,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/idp",
|
||||
description: "List all IDP in the system.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
query: querySchema
|
||||
},
|
||||
|
||||
@@ -26,7 +26,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/idp/{idpId}/org/{orgId}",
|
||||
description: "Update an IDP org policy.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
body: {
|
||||
|
||||
@@ -42,7 +42,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/idp/{idpId}/oidc",
|
||||
description: "Update an OIDC IdP.",
|
||||
tags: [OpenAPITags.GlobalIdp],
|
||||
tags: [OpenAPITags.Idp],
|
||||
request: {
|
||||
params: paramsSchema,
|
||||
body: {
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
import { clients, clientSiteResourcesAssociationsCache, clientSitesAssociationsCache, db, ExitNode, resources, Site, siteResources, targetHealthCheck, targets } from "@server/db";
|
||||
import {
|
||||
clients,
|
||||
clientSiteResourcesAssociationsCache,
|
||||
clientSitesAssociationsCache,
|
||||
db,
|
||||
ExitNode,
|
||||
resources,
|
||||
Site,
|
||||
siteResources,
|
||||
targetHealthCheck,
|
||||
targets
|
||||
} from "@server/db";
|
||||
import logger from "@server/logger";
|
||||
import { initPeerAddHandshake, updatePeer } from "../olm/peers";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
import config from "@server/lib/config";
|
||||
import { generateSubnetProxyTargets, SubnetProxyTarget } from "@server/lib/ip";
|
||||
import {
|
||||
generateSubnetProxyTargetV2,
|
||||
SubnetProxyTargetV2
|
||||
} from "@server/lib/ip";
|
||||
|
||||
export async function buildClientConfigurationForNewtClient(
|
||||
site: Site,
|
||||
@@ -126,7 +140,7 @@ export async function buildClientConfigurationForNewtClient(
|
||||
.from(siteResources)
|
||||
.where(eq(siteResources.siteId, siteId));
|
||||
|
||||
const targetsToSend: SubnetProxyTarget[] = [];
|
||||
const targetsToSend: SubnetProxyTargetV2[] = [];
|
||||
|
||||
for (const resource of allSiteResources) {
|
||||
// Get clients associated with this specific resource
|
||||
@@ -151,12 +165,14 @@ export async function buildClientConfigurationForNewtClient(
|
||||
)
|
||||
);
|
||||
|
||||
const resourceTargets = generateSubnetProxyTargets(
|
||||
const resourceTarget = generateSubnetProxyTargetV2(
|
||||
resource,
|
||||
resourceClients
|
||||
);
|
||||
|
||||
targetsToSend.push(...resourceTargets);
|
||||
if (resourceTarget) {
|
||||
targetsToSend.push(resourceTarget);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { db, ExitNode, exitNodes, Newt, sites } from "@server/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { sendToExitNode } from "#dynamic/lib/exitNodes";
|
||||
import { buildClientConfigurationForNewtClient } from "./buildConfiguration";
|
||||
import { convertTargetsIfNessicary } from "../client/targets";
|
||||
|
||||
const inputSchema = z.object({
|
||||
publicKey: z.string(),
|
||||
@@ -126,13 +127,15 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
|
||||
exitNode
|
||||
);
|
||||
|
||||
const targetsToSend = await convertTargetsIfNessicary(newt.newtId, targets);
|
||||
|
||||
return {
|
||||
message: {
|
||||
type: "newt/wg/receive-config",
|
||||
data: {
|
||||
ipAddress: site.address,
|
||||
peers,
|
||||
targets
|
||||
targets: targetsToSend
|
||||
}
|
||||
},
|
||||
broadcast: false,
|
||||
|
||||
@@ -29,7 +29,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}/whitelist/add",
|
||||
description: "Add a single email to the resource whitelist.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: addEmailToResourceWhitelistParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -29,7 +29,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}/roles/add",
|
||||
description: "Add a single role to a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Role],
|
||||
request: {
|
||||
params: addRoleToResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -29,7 +29,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}/users/add",
|
||||
description: "Add a single user to a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.User],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.User],
|
||||
request: {
|
||||
params: addUserToResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -79,7 +79,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/resource",
|
||||
description: "Create a resource.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Resource],
|
||||
request: {
|
||||
params: createResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -31,7 +31,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/resource/{resourceId}/rule",
|
||||
description: "Create a resource rule.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.Rule],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Rule],
|
||||
request: {
|
||||
params: createResourceRuleParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -22,7 +22,7 @@ registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/resource/{resourceId}",
|
||||
description: "Delete a resource.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: deleteResourceSchema
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@ registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/resource/{resourceId}/rule/{ruleId}",
|
||||
description: "Delete a resource rule.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.Rule],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Rule],
|
||||
request: {
|
||||
params: deleteResourceRuleSchema
|
||||
},
|
||||
|
||||
@@ -54,7 +54,7 @@ registry.registerPath({
|
||||
path: "/org/{orgId}/resource/{niceId}",
|
||||
description:
|
||||
"Get a resource by orgId and niceId. NiceId is a readable ID for the resource and unique on a per org basis.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Resource],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string(),
|
||||
@@ -68,7 +68,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/resource/{resourceId}",
|
||||
description: "Get a resource by resourceId.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: z.object({
|
||||
resourceId: z.number()
|
||||
|
||||
@@ -31,7 +31,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/resource/{resourceId}/whitelist",
|
||||
description: "Get the whitelist of emails for a specific resource.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: getResourceWhitelistSchema
|
||||
},
|
||||
|
||||
@@ -33,7 +33,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/resources-names",
|
||||
description: "List all resource names for an organization.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Resource],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string()
|
||||
|
||||
@@ -35,7 +35,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/resource/{resourceId}/roles",
|
||||
description: "List all roles for a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Role],
|
||||
request: {
|
||||
params: listResourceRolesSchema
|
||||
},
|
||||
|
||||
@@ -56,7 +56,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/resource/{resourceId}/rules",
|
||||
description: "List rules for a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.Rule],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Rule],
|
||||
request: {
|
||||
params: listResourceRulesParamsSchema,
|
||||
query: listResourceRulesSchema
|
||||
|
||||
@@ -38,7 +38,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/resource/{resourceId}/users",
|
||||
description: "List all users for a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.User],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.User],
|
||||
request: {
|
||||
params: listResourceUsersSchema
|
||||
},
|
||||
|
||||
@@ -225,7 +225,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/resources",
|
||||
description: "List resources for an organization.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Resource],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string()
|
||||
|
||||
@@ -29,7 +29,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}/whitelist/remove",
|
||||
description: "Remove a single email from the resource whitelist.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: removeEmailFromResourceWhitelistParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -29,7 +29,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}/roles/remove",
|
||||
description: "Remove a single role from a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Role],
|
||||
request: {
|
||||
params: removeRoleFromResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -29,7 +29,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}/users/remove",
|
||||
description: "Remove a single user from a resource.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.User],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.User],
|
||||
request: {
|
||||
params: removeUserFromResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -29,7 +29,7 @@ registry.registerPath({
|
||||
path: "/resource/{resourceId}/header-auth",
|
||||
description:
|
||||
"Set or update the header authentication for a resource. If user and password is not provided, it will remove the header authentication.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: setResourceAuthMethodsParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -25,7 +25,7 @@ registry.registerPath({
|
||||
path: "/resource/{resourceId}/password",
|
||||
description:
|
||||
"Set the password for a resource. Setting the password to null will remove it.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: setResourceAuthMethodsParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -29,7 +29,7 @@ registry.registerPath({
|
||||
path: "/resource/{resourceId}/pincode",
|
||||
description:
|
||||
"Set the PIN code for a resource. Setting the PIN code to null will remove it.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: setResourceAuthMethodsParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -23,7 +23,7 @@ registry.registerPath({
|
||||
path: "/resource/{resourceId}/roles",
|
||||
description:
|
||||
"Set roles for a resource. This will replace all existing roles.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Role],
|
||||
request: {
|
||||
params: setResourceRolesParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -23,7 +23,7 @@ registry.registerPath({
|
||||
path: "/resource/{resourceId}/users",
|
||||
description:
|
||||
"Set users for a resource. This will replace all existing users.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.User],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.User],
|
||||
request: {
|
||||
params: setUserResourcesParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -32,7 +32,7 @@ registry.registerPath({
|
||||
path: "/resource/{resourceId}/whitelist",
|
||||
description:
|
||||
"Set email whitelist for a resource. This will replace all existing emails.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: setResourceWhitelistParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -136,7 +136,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}",
|
||||
description: "Update a resource.",
|
||||
tags: [OpenAPITags.PublicResource],
|
||||
tags: [OpenAPITags.Resource],
|
||||
request: {
|
||||
params: updateResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -38,7 +38,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/resource/{resourceId}/rule/{ruleId}",
|
||||
description: "Update a resource rule.",
|
||||
tags: [OpenAPITags.PublicResource, OpenAPITags.Rule],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Rule],
|
||||
request: {
|
||||
params: updateResourceRuleParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -45,7 +45,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/role",
|
||||
description: "Create a role.",
|
||||
tags: [OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Role],
|
||||
request: {
|
||||
params: createRoleParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { and, eq, inArray, sql } from "drizzle-orm";
|
||||
import { ActionsEnum } from "@server/auth/actions";
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import createHttpError from "http-errors";
|
||||
import { object, z } from "zod";
|
||||
import { z } from "zod";
|
||||
import { fromError } from "zod-validation-error";
|
||||
|
||||
const listRolesParamsSchema = z.strictObject({
|
||||
@@ -64,7 +64,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/roles",
|
||||
description: "List roles.",
|
||||
tags: [OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Role],
|
||||
request: {
|
||||
params: listRolesParamsSchema,
|
||||
query: listRolesSchema
|
||||
|
||||
@@ -58,7 +58,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/site",
|
||||
description: "Create a new site.",
|
||||
tags: [OpenAPITags.Site],
|
||||
tags: [OpenAPITags.Site, OpenAPITags.Org],
|
||||
request: {
|
||||
params: createSiteParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -51,7 +51,7 @@ registry.registerPath({
|
||||
path: "/org/{orgId}/site/{niceId}",
|
||||
description:
|
||||
"Get a site by orgId and niceId. NiceId is a readable ID for the site and unique on a per org basis.",
|
||||
tags: [OpenAPITags.Site],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Site],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string(),
|
||||
|
||||
@@ -180,7 +180,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/sites",
|
||||
description: "List all sites in an organization",
|
||||
tags: [OpenAPITags.Site],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Site],
|
||||
request: {
|
||||
params: listSitesParamsSchema,
|
||||
query: listSitesSchema
|
||||
|
||||
@@ -35,7 +35,7 @@ registry.registerPath({
|
||||
path: "/org/{orgId}/pick-site-defaults",
|
||||
description:
|
||||
"Return pre-requisite data for creating a site, such as the exit node, subnet, Newt credentials, etc.",
|
||||
tags: [OpenAPITags.Site],
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Site],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string()
|
||||
|
||||
@@ -30,7 +30,7 @@ registry.registerPath({
|
||||
path: "/site-resource/{siteResourceId}/clients/add",
|
||||
description:
|
||||
"Add a single client to a site resource. Clients with a userId cannot be added.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Client],
|
||||
request: {
|
||||
params: addClientToSiteResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -30,7 +30,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/site-resource/{siteResourceId}/roles/add",
|
||||
description: "Add a single role to a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Role],
|
||||
request: {
|
||||
params: addRoleToSiteResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -30,7 +30,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/site-resource/{siteResourceId}/users/add",
|
||||
description: "Add a single user to a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.User],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.User],
|
||||
request: {
|
||||
params: addUserToSiteResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -88,7 +88,7 @@ const createSiteResourceSchema = z
|
||||
},
|
||||
{
|
||||
message:
|
||||
"Destination must be a valid IP address or valid domain AND alias is required"
|
||||
"Destination must be a valid IPV4 address or valid domain AND alias is required"
|
||||
}
|
||||
)
|
||||
.refine(
|
||||
@@ -114,7 +114,7 @@ registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/site-resource",
|
||||
description: "Create a new site resource.",
|
||||
tags: [OpenAPITags.PrivateResource],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
params: createSiteResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -23,7 +23,7 @@ registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/site-resource/{siteResourceId}",
|
||||
description: "Delete a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
params: deleteSiteResourceParamsSchema
|
||||
},
|
||||
|
||||
@@ -65,7 +65,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/site-resource/{siteResourceId}",
|
||||
description: "Get a specific site resource by siteResourceId.",
|
||||
tags: [OpenAPITags.PrivateResource],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
params: z.object({
|
||||
siteResourceId: z.number(),
|
||||
@@ -80,7 +80,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/site/{siteId}/resource/nice/{niceId}",
|
||||
description: "Get a specific site resource by niceId.",
|
||||
tags: [OpenAPITags.PrivateResource],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
params: z.object({
|
||||
niceId: z.string(),
|
||||
|
||||
@@ -112,7 +112,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/site-resources",
|
||||
description: "List all site resources for an organization.",
|
||||
tags: [OpenAPITags.PrivateResource],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
params: listAllSiteResourcesByOrgParamsSchema,
|
||||
query: listAllSiteResourcesByOrgQuerySchema
|
||||
|
||||
@@ -39,7 +39,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/site-resource/{siteResourceId}/clients",
|
||||
description: "List all clients for a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Client],
|
||||
request: {
|
||||
params: listSiteResourceClientsSchema
|
||||
},
|
||||
|
||||
@@ -40,7 +40,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/site-resource/{siteResourceId}/roles",
|
||||
description: "List all roles for a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Role],
|
||||
request: {
|
||||
params: listSiteResourceRolesSchema
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/site-resource/{siteResourceId}/users",
|
||||
description: "List all users for a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.User],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.User],
|
||||
request: {
|
||||
params: listSiteResourceUsersSchema
|
||||
},
|
||||
|
||||
@@ -58,7 +58,7 @@ registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/site/{siteId}/resources",
|
||||
description: "List site resources for a site.",
|
||||
tags: [OpenAPITags.PrivateResource],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
params: listSiteResourcesParamsSchema,
|
||||
query: listSiteResourcesQuerySchema
|
||||
|
||||
@@ -30,7 +30,7 @@ registry.registerPath({
|
||||
path: "/site-resource/{siteResourceId}/clients/remove",
|
||||
description:
|
||||
"Remove a single client from a site resource. Clients with a userId cannot be removed.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Client],
|
||||
request: {
|
||||
params: removeClientFromSiteResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -30,7 +30,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/site-resource/{siteResourceId}/roles/remove",
|
||||
description: "Remove a single role from a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Role],
|
||||
request: {
|
||||
params: removeRoleFromSiteResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -30,7 +30,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/site-resource/{siteResourceId}/users/remove",
|
||||
description: "Remove a single user from a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.User],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.User],
|
||||
request: {
|
||||
params: removeUserFromSiteResourceParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -30,7 +30,7 @@ registry.registerPath({
|
||||
path: "/site-resource/{siteResourceId}/clients",
|
||||
description:
|
||||
"Set clients for a site resource. This will replace all existing clients. Clients with a userId cannot be added.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.Client],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Client],
|
||||
request: {
|
||||
params: setSiteResourceClientsParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -31,7 +31,7 @@ registry.registerPath({
|
||||
path: "/site-resource/{siteResourceId}/roles",
|
||||
description:
|
||||
"Set roles for a site resource. This will replace all existing roles.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.Role],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.Role],
|
||||
request: {
|
||||
params: setSiteResourceRolesParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -31,7 +31,7 @@ registry.registerPath({
|
||||
path: "/site-resource/{siteResourceId}/users",
|
||||
description:
|
||||
"Set users for a site resource. This will replace all existing users.",
|
||||
tags: [OpenAPITags.PrivateResource, OpenAPITags.User],
|
||||
tags: [OpenAPITags.Resource, OpenAPITags.User],
|
||||
request: {
|
||||
params: setSiteResourceUsersParamsSchema,
|
||||
body: {
|
||||
|
||||
@@ -24,7 +24,7 @@ import { updatePeerData, updateTargets } from "@server/routers/client/targets";
|
||||
import {
|
||||
generateAliasConfig,
|
||||
generateRemoteSubnets,
|
||||
generateSubnetProxyTargets,
|
||||
generateSubnetProxyTargetV2,
|
||||
isIpInCidr,
|
||||
portRangeStringSchema
|
||||
} from "@server/lib/ip";
|
||||
@@ -121,7 +121,7 @@ registry.registerPath({
|
||||
method: "post",
|
||||
path: "/site-resource/{siteResourceId}",
|
||||
description: "Update a site resource.",
|
||||
tags: [OpenAPITags.PrivateResource],
|
||||
tags: [OpenAPITags.Client, OpenAPITags.Org],
|
||||
request: {
|
||||
params: updateSiteResourceParamsSchema,
|
||||
body: {
|
||||
@@ -608,18 +608,18 @@ export async function handleMessagingForUpdatedSiteResource(
|
||||
|
||||
// Only update targets on newt if destination changed
|
||||
if (destinationChanged || portRangesChanged) {
|
||||
const oldTargets = generateSubnetProxyTargets(
|
||||
const oldTarget = generateSubnetProxyTargetV2(
|
||||
existingSiteResource,
|
||||
mergedAllClients
|
||||
);
|
||||
const newTargets = generateSubnetProxyTargets(
|
||||
const newTarget = generateSubnetProxyTargetV2(
|
||||
updatedSiteResource,
|
||||
mergedAllClients
|
||||
);
|
||||
|
||||
await updateTargets(newt.newtId, {
|
||||
oldTargets: oldTargets,
|
||||
newTargets: newTargets
|
||||
oldTargets: oldTarget ? [oldTarget] : [],
|
||||
newTargets: newTarget ? [newTarget] : []
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user