From f0b92405755da64e9837aaea1781ee8f942d342d Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 16 Feb 2026 15:29:23 -0800 Subject: [PATCH] Accept resource as either niceId or alias --- server/private/routers/ssh/signSshKey.ts | 42 ++++++++++++------- server/routers/resource/updateResource.ts | 2 +- .../siteResource/updateSiteResource.ts | 1 + 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/server/private/routers/ssh/signSshKey.ts b/server/private/routers/ssh/signSshKey.ts index 62a830cb..d2f4bcc7 100644 --- a/server/private/routers/ssh/signSshKey.ts +++ b/server/private/routers/ssh/signSshKey.ts @@ -20,7 +20,7 @@ import createHttpError from "http-errors"; import logger from "@server/logger"; import { fromError } from "zod-validation-error"; import { OpenAPITags, registry } from "@server/openApi"; -import { eq, or } from "drizzle-orm"; +import { eq, or, and } from "drizzle-orm"; import { canUserAccessSiteResource } from "@server/auth/canUserAccessSiteResource"; import { signPublicKey, getOrgCAKeys } from "#private/lib/sshCA"; import config from "@server/lib/config"; @@ -33,12 +33,11 @@ const bodySchema = z .strictObject({ publicKey: z.string().nonempty(), resourceId: z.number().int().positive().optional(), - niceId: z.string().nonempty().optional(), - alias: z.string().nonempty().optional() + resource: z.string().nonempty().optional() // this is either the nice id or the alias }) .refine( (data) => { - const fields = [data.resourceId, data.niceId, data.alias]; + const fields = [data.resourceId, data.resource]; const definedFields = fields.filter((field) => field !== undefined); return definedFields.length === 1; }, @@ -105,7 +104,11 @@ export async function signSshKey( } const { orgId } = parsedParams.data; - const { publicKey, resourceId, niceId, alias } = parsedBody.data; + const { + publicKey, + resourceId, + resource: resourceQueryString + } = parsedBody.data; const userId = req.user?.userId; const roleId = req.userOrgRoleId!; @@ -135,10 +138,11 @@ export async function signSshKey( let whereClause; if (resourceId !== undefined) { whereClause = eq(siteResources.siteResourceId, resourceId); - } else if (niceId !== undefined) { - whereClause = eq(siteResources.niceId, niceId); - } else if (alias !== undefined) { - whereClause = eq(siteResources.alias, alias); + } else if (resourceQueryString !== undefined) { + whereClause = or( + eq(siteResources.niceId, resourceQueryString), + eq(siteResources.alias, resourceQueryString) + ); } else { // This should never happen due to the schema validation, but TypeScript doesn't know that return next( @@ -149,21 +153,29 @@ export async function signSshKey( ); } - const [resource] = await db + const resources = await db .select() .from(siteResources) - .where(whereClause) - .limit(1); + .where(and(whereClause, eq(siteResources.orgId, orgId))); - if (!resource) { + if (!resources || resources.length === 0) { + return next( + createHttpError(HttpCode.NOT_FOUND, `Resource not found`) + ); + } + + if (resources.length > 1) { + // error but this should not happen because the nice id cant contain a dot and the alias has to have a dot and both have to be unique within the org so there should never be multiple matches return next( createHttpError( - HttpCode.NOT_FOUND, - `Resource not found` + HttpCode.BAD_REQUEST, + `Multiple resources found matching the criteria` ) ); } + const resource = resources[0]; + if (resource.orgId !== orgId) { return next( createHttpError( diff --git a/server/routers/resource/updateResource.ts b/server/routers/resource/updateResource.ts index 84b4f538..4f35739b 100644 --- a/server/routers/resource/updateResource.ts +++ b/server/routers/resource/updateResource.ts @@ -33,7 +33,7 @@ const updateResourceParamsSchema = z.strictObject({ const updateHttpResourceBodySchema = z .strictObject({ name: z.string().min(1).max(255).optional(), - niceId: z.string().min(1).max(255).optional(), + niceId: z.string().min(1).max(255).regex(/^[a-zA-Z0-9-]+$/, "niceId can only contain letters, numbers, and dashes").optional(), subdomain: subdomainSchema.nullable().optional(), ssl: z.boolean().optional(), sso: z.boolean().optional(), diff --git a/server/routers/siteResource/updateSiteResource.ts b/server/routers/siteResource/updateSiteResource.ts index fd77c74a..4c19bea1 100644 --- a/server/routers/siteResource/updateSiteResource.ts +++ b/server/routers/siteResource/updateSiteResource.ts @@ -41,6 +41,7 @@ const updateSiteResourceSchema = z .strictObject({ name: z.string().min(1).max(255).optional(), siteId: z.int(), + // niceId: z.string().min(1).max(255).regex(/^[a-zA-Z0-9-]+$/, "niceId can only contain letters, numbers, and dashes").optional(), // mode: z.enum(["host", "cidr", "port"]).optional(), mode: z.enum(["host", "cidr"]).optional(), // protocol: z.enum(["tcp", "udp"]).nullish(),