From 55f3807491f5f84a6656d800fd1d4c811d40f878 Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 16 Jul 2026 15:10:38 -0400 Subject: [PATCH] Enforce uniqueness of aliases in blueprints --- server/lib/blueprints/privateResources.ts | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/server/lib/blueprints/privateResources.ts b/server/lib/blueprints/privateResources.ts index 44901e8c8..f3fa7bf5d 100644 --- a/server/lib/blueprints/privateResources.ts +++ b/server/lib/blueprints/privateResources.ts @@ -239,6 +239,31 @@ export async function updatePrivateResources( ); } + if (resourceData.alias) { + const [aliasConflict] = await trx + .select({ + siteResourceId: siteResources.siteResourceId + }) + .from(siteResources) + .where( + and( + eq(siteResources.orgId, orgId), + eq(siteResources.alias, resourceData.alias), + ne( + siteResources.siteResourceId, + existingResource.siteResourceId + ) + ) + ) + .limit(1); + + if (aliasConflict) { + throw new Error( + `Alias ${resourceData.alias} already in use by another site resource in org ${orgId}` + ); + } + } + // Update existing resource const [updatedResource] = await trx .update(siteResources) @@ -480,6 +505,27 @@ export async function updatePrivateResources( ); } + if (resourceData.alias) { + const [aliasConflict] = await trx + .select({ + siteResourceId: siteResources.siteResourceId + }) + .from(siteResources) + .where( + and( + eq(siteResources.orgId, orgId), + eq(siteResources.alias, resourceData.alias) + ) + ) + .limit(1); + + if (aliasConflict) { + throw new Error( + `Alias ${resourceData.alias} already in use by another site resource in org ${orgId}` + ); + } + } + const [network] = await trx .insert(networks) .values({