Moving to mode replacing http and protocol fields

This commit is contained in:
Owen
2026-05-27 12:04:00 -07:00
parent 464d4990df
commit 06cc13c637
15 changed files with 150 additions and 71 deletions

View File

@@ -35,16 +35,54 @@ const createResourceParamsSchema = z.strictObject({
orgId: z.string()
});
function resolveModeFromLegacyFields(data: {
mode?: "http" | "ssh" | "rdp" | "vnc" | "tcp" | "udp";
http?: boolean;
protocol?: "tcp" | "udp";
}): {
mode?: "http" | "ssh" | "rdp" | "vnc" | "tcp" | "udp";
error?: string;
} {
if (data.mode) {
return { mode: data.mode };
}
if (typeof data.http === "boolean" && data.protocol) {
if (data.http && data.protocol === "tcp") {
return { mode: "http" };
}
if (!data.http && data.protocol === "tcp") {
return { mode: "tcp" };
}
if (!data.http && data.protocol === "udp") {
return { mode: "udp" };
}
return {
error: "Invalid deprecated http/protocol combination"
};
}
return { mode: undefined };
}
const createHttpResourceSchema = z
.strictObject({
name: z.string().min(1).max(255),
subdomain: z.string().nullable().optional(),
http: z.boolean(),
protocol: z.enum(["tcp", "udp"]),
http: z.boolean().optional().openapi({
deprecated: true,
description:
"Deprecated. Use `mode` instead. Legacy compatibility only."
}),
protocol: z.enum(["tcp", "udp"]).optional().openapi({
deprecated: true,
description:
"Deprecated. Use `mode` instead. Legacy compatibility only."
}),
domainId: z.string(),
stickySession: z.boolean().optional(),
postAuthPath: z.string().nullable().optional(),
browserAccessType: z.enum(["http", "ssh", "rdp", "vnc"]).optional(),
mode: z.enum(["http", "ssh", "rdp", "vnc", "tcp", "udp"]).optional(),
// SSH Settings
pamMode: z.enum(["passthrough", "push"]).optional(),
authDaemonPort: z.int().positive().optional(),
@@ -68,13 +106,27 @@ const createHttpResourceSchema = z
const createRawResourceSchema = z
.strictObject({
name: z.string().min(1).max(255),
http: z.boolean(),
protocol: z.enum(["tcp", "udp"]),
http: z.boolean().optional().openapi({
deprecated: true,
description:
"Deprecated. Use `mode` instead. Legacy compatibility only."
}),
protocol: z.enum(["tcp", "udp"]).optional().openapi({
deprecated: true,
description:
"Deprecated. Use `mode` instead. Legacy compatibility only."
}),
mode: z.enum(["tcp", "udp"]).optional(),
proxyPort: z.int().min(1).max(65535)
// enableProxy: z.boolean().default(true) // always true now
})
.refine(
(data) => {
const resolved = resolveModeFromLegacyFields(data);
if (resolved.error || !resolved.mode) {
return false;
}
if (!config.getRawConfig().flags?.allow_raw_resources) {
if (data.proxyPort !== undefined) {
return false;
@@ -151,17 +203,18 @@ export async function createResource(
);
}
if (typeof req.body.http !== "boolean") {
const resolvedMode = resolveModeFromLegacyFields(req.body);
if (resolvedMode.error) {
return next(
createHttpError(HttpCode.BAD_REQUEST, "http field is required")
createHttpError(HttpCode.BAD_REQUEST, resolvedMode.error)
);
}
const { http } = req.body;
if (resolvedMode.mode) {
req.body.mode = resolvedMode.mode;
}
if (http) {
return await createHttpResource({ req, res, next }, { orgId });
} else {
if (typeof req.body.proxyPort === "number") {
if (
!config.getRawConfig().flags?.allow_raw_resources &&
build == "oss"
@@ -175,6 +228,17 @@ export async function createResource(
}
return await createRawResource({ req, res, next }, { orgId });
}
if (req.body.mode) {
return await createHttpResource({ req, res, next }, { orgId });
} else {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"mode is required when deprecated fields are not provided"
)
);
}
} catch (error) {
logger.error(error);
return next(
@@ -210,7 +274,7 @@ async function createHttpResource(
name,
domainId,
postAuthPath,
browserAccessType,
mode,
authDaemonPort,
authDaemonMode,
pamMode
@@ -338,12 +402,10 @@ async function createHttpResource(
orgId,
name,
subdomain: finalSubdomain,
http: true,
browserAccessType: browserAccessType,
mode: mode,
pamMode: pamMode,
authDaemonMode: authDaemonMode,
authDaemonPort: authDaemonPort,
protocol: "tcp",
ssl: true,
stickySession: stickySession,
postAuthPath: postAuthPath,
@@ -425,7 +487,17 @@ async function createRawResource(
);
}
const { name, http, protocol, proxyPort } = parsedBody.data;
const { name, proxyPort } = parsedBody.data;
const resolvedMode = resolveModeFromLegacyFields(parsedBody.data);
if (resolvedMode.error || !resolvedMode.mode) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
resolvedMode.error ||
"mode is required when deprecated fields are not provided"
)
);
}
let resource: Resource | undefined;
@@ -438,9 +510,8 @@ async function createRawResource(
niceId,
orgId,
name,
http,
protocol,
proxyPort
proxyPort,
mode: resolvedMode.mode
// enableProxy
})
.returning();