mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-08 15:14:52 +02:00
Make feilds optional
This commit is contained in:
@@ -68,9 +68,9 @@ const updateSiteResourceSchema = z
|
|||||||
"Fully qualified domain name with optional wildcards, e.g., example.internal, *.example.internal, or host-0?.example.internal",
|
"Fully qualified domain name with optional wildcards, e.g., example.internal, *.example.internal, or host-0?.example.internal",
|
||||||
example: "service.example.internal"
|
example: "service.example.internal"
|
||||||
}),
|
}),
|
||||||
userIds: z.array(z.string()),
|
userIds: z.array(z.string()).optional(),
|
||||||
roleIds: z.array(z.int()),
|
roleIds: z.array(z.int()).optional(),
|
||||||
clientIds: z.array(z.int()),
|
clientIds: z.array(z.int()).optional(),
|
||||||
tcpPortRangeString: portRangeStringSchema,
|
tcpPortRangeString: portRangeStringSchema,
|
||||||
udpPortRangeString: portRangeStringSchema,
|
udpPortRangeString: portRangeStringSchema,
|
||||||
disableIcmp: z.boolean().optional(),
|
disableIcmp: z.boolean().optional(),
|
||||||
@@ -167,6 +167,10 @@ const updateSiteResourceSchema = z
|
|||||||
)
|
)
|
||||||
.refine(
|
.refine(
|
||||||
(data) => {
|
(data) => {
|
||||||
|
// if neither is provided, the existing site associations are left unchanged
|
||||||
|
if (data.siteIds === undefined && data.siteId === undefined) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
(data.siteIds !== undefined && data.siteIds.length > 0) ||
|
(data.siteIds !== undefined && data.siteIds.length > 0) ||
|
||||||
data.siteId !== undefined
|
data.siteId !== undefined
|
||||||
@@ -263,7 +267,7 @@ export async function updateSiteResource(
|
|||||||
const { siteResourceId } = parsedParams.data;
|
const { siteResourceId } = parsedParams.data;
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
siteIds: siteIdsInput = [], // because it can change
|
siteIds: siteIdsInput,
|
||||||
siteId,
|
siteId,
|
||||||
niceId,
|
niceId,
|
||||||
mode,
|
mode,
|
||||||
@@ -287,9 +291,14 @@ export async function updateSiteResource(
|
|||||||
} = parsedBody.data;
|
} = parsedBody.data;
|
||||||
|
|
||||||
// Backward compatibility: merge deprecated siteId into siteIds array
|
// Backward compatibility: merge deprecated siteId into siteIds array
|
||||||
const siteIds = [...siteIdsInput];
|
const siteIdsProvided =
|
||||||
if (siteId !== undefined && !siteIds.includes(siteId)) {
|
siteIdsInput !== undefined || siteId !== undefined;
|
||||||
siteIds.push(siteId);
|
let siteIds: number[] | undefined;
|
||||||
|
if (siteIdsProvided) {
|
||||||
|
siteIds = [...(siteIdsInput ?? [])];
|
||||||
|
if (siteId !== undefined && !siteIds.includes(siteId)) {
|
||||||
|
siteIds.push(siteId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if site resource exists
|
// Check if site resource exists
|
||||||
@@ -356,20 +365,22 @@ export async function updateSiteResource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify the site exists and belongs to the org
|
// Verify the site exists and belongs to the org
|
||||||
const sitesToAssign = await db
|
if (siteIds !== undefined) {
|
||||||
.select()
|
const sitesToAssign = await db
|
||||||
.from(sites)
|
.select()
|
||||||
.where(
|
.from(sites)
|
||||||
and(
|
.where(
|
||||||
inArray(sites.siteId, siteIds),
|
and(
|
||||||
eq(sites.orgId, existingSiteResource.orgId)
|
inArray(sites.siteId, siteIds),
|
||||||
)
|
eq(sites.orgId, existingSiteResource.orgId)
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (sitesToAssign.length !== siteIds.length) {
|
if (sitesToAssign.length !== siteIds.length) {
|
||||||
return next(
|
return next(
|
||||||
createHttpError(HttpCode.NOT_FOUND, "Some site not found")
|
createHttpError(HttpCode.NOT_FOUND, "Some site not found")
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only check if destination is an IP address
|
// Only check if destination is an IP address
|
||||||
@@ -463,7 +474,8 @@ export async function updateSiteResource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let updatedSiteResource: SiteResource | undefined;
|
let updatedSiteResource: SiteResource | undefined;
|
||||||
let updatedSiteIds: number[] = [];
|
// defaults to the existing sites; only overwritten below if siteIds/siteId was provided
|
||||||
|
let updatedSiteIds: number[] = [...existingSiteIds];
|
||||||
await db.transaction(async (trx) => {
|
await db.transaction(async (trx) => {
|
||||||
// Update the site resource
|
// Update the site resource
|
||||||
const sshPamSet =
|
const sshPamSet =
|
||||||
@@ -522,81 +534,103 @@ export async function updateSiteResource(
|
|||||||
|
|
||||||
//////////////////// update the associations ////////////////////
|
//////////////////// update the associations ////////////////////
|
||||||
|
|
||||||
// delete the site - site resources associations
|
if (siteIds !== undefined) {
|
||||||
await trx
|
// delete the site - site resources associations
|
||||||
.delete(siteNetworks)
|
|
||||||
.where(
|
|
||||||
eq(siteNetworks.networkId, updatedSiteResource.networkId!)
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const siteId of siteIds) {
|
|
||||||
await trx.insert(siteNetworks).values({
|
|
||||||
siteId: siteId,
|
|
||||||
networkId: updatedSiteResource.networkId!
|
|
||||||
});
|
|
||||||
updatedSiteIds.push(siteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
await trx
|
|
||||||
.delete(clientSiteResources)
|
|
||||||
.where(eq(clientSiteResources.siteResourceId, siteResourceId));
|
|
||||||
|
|
||||||
if (clientIds.length > 0) {
|
|
||||||
await trx.insert(clientSiteResources).values(
|
|
||||||
clientIds.map((clientId) => ({
|
|
||||||
clientId,
|
|
||||||
siteResourceId
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await trx
|
|
||||||
.delete(userSiteResources)
|
|
||||||
.where(eq(userSiteResources.siteResourceId, siteResourceId));
|
|
||||||
|
|
||||||
if (userIds.length > 0) {
|
|
||||||
await trx.insert(userSiteResources).values(
|
|
||||||
userIds.map((userId) => ({
|
|
||||||
userId,
|
|
||||||
siteResourceId
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all admin role IDs for this org to exclude from deletion
|
|
||||||
const adminRoles = await trx
|
|
||||||
.select()
|
|
||||||
.from(roles)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(roles.isAdmin, true),
|
|
||||||
eq(roles.orgId, updatedSiteResource.orgId)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const adminRoleIds = adminRoles.map((role) => role.roleId);
|
|
||||||
|
|
||||||
if (adminRoleIds.length > 0) {
|
|
||||||
await trx.delete(roleSiteResources).where(
|
|
||||||
and(
|
|
||||||
eq(roleSiteResources.siteResourceId, siteResourceId),
|
|
||||||
ne(roleSiteResources.roleId, adminRoleIds[0]) // delete all but the admin role
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
await trx
|
await trx
|
||||||
.delete(roleSiteResources)
|
.delete(siteNetworks)
|
||||||
.where(
|
.where(
|
||||||
eq(roleSiteResources.siteResourceId, siteResourceId)
|
eq(
|
||||||
|
siteNetworks.networkId,
|
||||||
|
updatedSiteResource.networkId!
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
updatedSiteIds = [];
|
||||||
|
for (const siteId of siteIds) {
|
||||||
|
await trx.insert(siteNetworks).values({
|
||||||
|
siteId: siteId,
|
||||||
|
networkId: updatedSiteResource.networkId!
|
||||||
|
});
|
||||||
|
updatedSiteIds.push(siteId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roleIds.length > 0) {
|
if (clientIds !== undefined) {
|
||||||
await trx.insert(roleSiteResources).values(
|
await trx
|
||||||
roleIds.map((roleId) => ({
|
.delete(clientSiteResources)
|
||||||
roleId,
|
.where(
|
||||||
siteResourceId
|
eq(clientSiteResources.siteResourceId, siteResourceId)
|
||||||
}))
|
);
|
||||||
);
|
|
||||||
|
if (clientIds.length > 0) {
|
||||||
|
await trx.insert(clientSiteResources).values(
|
||||||
|
clientIds.map((clientId) => ({
|
||||||
|
clientId,
|
||||||
|
siteResourceId
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userIds !== undefined) {
|
||||||
|
await trx
|
||||||
|
.delete(userSiteResources)
|
||||||
|
.where(
|
||||||
|
eq(userSiteResources.siteResourceId, siteResourceId)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (userIds.length > 0) {
|
||||||
|
await trx.insert(userSiteResources).values(
|
||||||
|
userIds.map((userId) => ({
|
||||||
|
userId,
|
||||||
|
siteResourceId
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roleIds !== undefined) {
|
||||||
|
// Get all admin role IDs for this org to exclude from deletion
|
||||||
|
const adminRoles = await trx
|
||||||
|
.select()
|
||||||
|
.from(roles)
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(roles.isAdmin, true),
|
||||||
|
eq(roles.orgId, updatedSiteResource.orgId)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const adminRoleIds = adminRoles.map((role) => role.roleId);
|
||||||
|
|
||||||
|
if (adminRoleIds.length > 0) {
|
||||||
|
await trx.delete(roleSiteResources).where(
|
||||||
|
and(
|
||||||
|
eq(
|
||||||
|
roleSiteResources.siteResourceId,
|
||||||
|
siteResourceId
|
||||||
|
),
|
||||||
|
ne(roleSiteResources.roleId, adminRoleIds[0]) // delete all but the admin role
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await trx
|
||||||
|
.delete(roleSiteResources)
|
||||||
|
.where(
|
||||||
|
eq(
|
||||||
|
roleSiteResources.siteResourceId,
|
||||||
|
siteResourceId
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roleIds.length > 0) {
|
||||||
|
await trx.insert(roleSiteResources).values(
|
||||||
|
roleIds.map((roleId) => ({
|
||||||
|
roleId,
|
||||||
|
siteResourceId
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Updated site resource ${siteResourceId}`);
|
logger.info(`Updated site resource ${siteResourceId}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user