From 5d2f65daa920898f38d3ffe72f32fa0a85c1b3f7 Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Mon, 17 Nov 2025 13:23:30 +0000 Subject: [PATCH] fix for zod --- Makefile | 5 +- server/lib/blueprints/types.ts | 130 +++++------------- .../routers/auditLogs/queryAccessAuditLog.ts | 2 +- .../routers/auditLogs/queryActionAuditLog.ts | 2 +- .../routers/auditLogs/queryRequstAuditLog.ts | 2 +- .../[orgId]/settings/clients/create/page.tsx | 3 +- 6 files changed, 44 insertions(+), 100 deletions(-) diff --git a/Makefile b/Makefile index 3d4d8ad8..8805a3b7 100644 --- a/Makefile +++ b/Makefile @@ -101,4 +101,7 @@ test-local: - npx tsc --noEmit - docker build --build-arg DATABASE=pg -t fosrl/pangolin:postgresql-latest . - docker build --build-arg DATABASE=sqlite -t fosrl/pangolin:latest . - \ No newline at end of file + npm run set:saas + - npx tsc --noEmit + - docker build --build-arg DATABASE=pg -t fosrl/pangolin:postgresql-saas-latest . + - docker build --build-arg DATABASE=sqlite -t fosrl/pangolin:saas-latest . \ No newline at end of file diff --git a/server/lib/blueprints/types.ts b/server/lib/blueprints/types.ts index 490cd7f8..a5ee5700 100644 --- a/server/lib/blueprints/types.ts +++ b/server/lib/blueprints/types.ts @@ -116,6 +116,20 @@ export const ResourceSchema = z (target) => target == null || target.method !== undefined ); } + return true; + }, + { + path: ["targets"], + error: "When protocol is 'http', all targets must have a 'method' field" + + } + ) + .refine( + (resource) => { + if (isTargetsOnlyResource(resource)) { + return true; + } + // If protocol is tcp or udp, no target should have method field if (resource.protocol === "tcp" || resource.protocol === "udp") { return resource.targets.every( @@ -124,19 +138,9 @@ export const ResourceSchema = z } return true; }, - (resource) => { - if (resource.protocol === "http") { - return { - message: - "When protocol is 'http', all targets must have a 'method' field", - path: ["targets"] - }; - } - return { - message: - "When protocol is 'tcp' or 'udp', targets must not have a 'method' field", - path: ["targets"] - }; + { + path: ["targets"], + error: "When protocol is 'tcp' or 'udp', targets must not have a 'method' field" } ) .refine( @@ -218,30 +222,6 @@ export const ConfigSchema = z }) .refine( // Enforce the full-domain uniqueness across resources in the same stack - (config) => { - // Extract all full-domain values with their resource keys - const fullDomainMap = new Map(); - - Object.entries(config["proxy-resources"]).forEach( - ([resourceKey, resource]) => { - const fullDomain = resource["full-domain"]; - if (fullDomain) { - // Only process if full-domain is defined - if (!fullDomainMap.has(fullDomain)) { - fullDomainMap.set(fullDomain, []); - } - fullDomainMap.get(fullDomain)!.push(resourceKey); - } - } - ); - - // Find duplicates - const duplicates = Array.from(fullDomainMap.entries()).filter( - ([_, resourceKeys]) => resourceKeys.length > 1 - ); - - return duplicates.length === 0; - }, (config) => { // Extract duplicates for error message const fullDomainMap = new Map(); @@ -267,38 +247,16 @@ export const ConfigSchema = z ) .join("; "); - return { - message: `Duplicate 'full-domain' values found: ${duplicates}`, - path: ["resources"] - }; + if (duplicates.length !== 0) { + return { + path: ["resources"], + error: `Duplicate 'full-domain' values found: ${duplicates}` + }; + } } ) .refine( // Enforce proxy-port uniqueness within proxy-resources per protocol - (config) => { - const protocolPortMap = new Map(); - - Object.entries(config["proxy-resources"]).forEach( - ([resourceKey, resource]) => { - const proxyPort = resource["proxy-port"]; - const protocol = resource.protocol; - if (proxyPort !== undefined && protocol !== undefined) { - const key = `${protocol}:${proxyPort}`; - if (!protocolPortMap.has(key)) { - protocolPortMap.set(key, []); - } - protocolPortMap.get(key)!.push(resourceKey); - } - } - ); - - // Find duplicates - const duplicates = Array.from(protocolPortMap.entries()).filter( - ([_, resourceKeys]) => resourceKeys.length > 1 - ); - - return duplicates.length === 0; - }, (config) => { // Extract duplicates for error message const protocolPortMap = new Map(); @@ -327,36 +285,16 @@ export const ConfigSchema = z ) .join("; "); - return { - message: `Duplicate 'proxy-port' values found in proxy-resources: ${duplicates}`, - path: ["proxy-resources"] - }; + if (duplicates.length !== 0) { + return { + path: ["proxy-resources"], + error: `Duplicate 'proxy-port' values found in proxy-resources: ${duplicates}` + }; + } } ) .refine( // Enforce proxy-port uniqueness within client-resources - (config) => { - const proxyPortMap = new Map(); - - Object.entries(config["client-resources"]).forEach( - ([resourceKey, resource]) => { - const proxyPort = resource["proxy-port"]; - if (proxyPort !== undefined) { - if (!proxyPortMap.has(proxyPort)) { - proxyPortMap.set(proxyPort, []); - } - proxyPortMap.get(proxyPort)!.push(resourceKey); - } - } - ); - - // Find duplicates - const duplicates = Array.from(proxyPortMap.entries()).filter( - ([_, resourceKeys]) => resourceKeys.length > 1 - ); - - return duplicates.length === 0; - }, (config) => { // Extract duplicates for error message const proxyPortMap = new Map(); @@ -381,10 +319,12 @@ export const ConfigSchema = z ) .join("; "); - return { - message: `Duplicate 'proxy-port' values found in client-resources: ${duplicates}`, - path: ["client-resources"] - }; + if (duplicates.length !== 0) { + return { + path: ["client-resources"], + error: `Duplicate 'proxy-port' values found in client-resources: ${duplicates}` + }; + } } ); diff --git a/server/private/routers/auditLogs/queryAccessAuditLog.ts b/server/private/routers/auditLogs/queryAccessAuditLog.ts index 6329206d..3e0b4601 100644 --- a/server/private/routers/auditLogs/queryAccessAuditLog.ts +++ b/server/private/routers/auditLogs/queryAccessAuditLog.ts @@ -40,7 +40,7 @@ export const queryAccessAuditLogsQuery = z.object({ }) .transform((val) => Math.floor(new Date(val).getTime() / 1000)) .optional() - .default(new Date().toISOString()), + .prefault(new Date().toISOString()), action: z .union([z.boolean(), z.string()]) .transform((val) => (typeof val === "string" ? val === "true" : val)) diff --git a/server/private/routers/auditLogs/queryActionAuditLog.ts b/server/private/routers/auditLogs/queryActionAuditLog.ts index eb22cc0a..6a5bde6d 100644 --- a/server/private/routers/auditLogs/queryActionAuditLog.ts +++ b/server/private/routers/auditLogs/queryActionAuditLog.ts @@ -40,7 +40,7 @@ export const queryActionAuditLogsQuery = z.object({ }) .transform((val) => Math.floor(new Date(val).getTime() / 1000)) .optional() - .default(new Date().toISOString()), + .prefault(new Date().toISOString()), action: z.string().optional(), actorType: z.string().optional(), actorId: z.string().optional(), diff --git a/server/routers/auditLogs/queryRequstAuditLog.ts b/server/routers/auditLogs/queryRequstAuditLog.ts index 7c412994..342b7091 100644 --- a/server/routers/auditLogs/queryRequstAuditLog.ts +++ b/server/routers/auditLogs/queryRequstAuditLog.ts @@ -27,7 +27,7 @@ export const queryAccessAuditLogsQuery = z.object({ }) .transform((val) => Math.floor(new Date(val).getTime() / 1000)) .optional() - .default(new Date().toISOString()), + .prefault(new Date().toISOString()), action: z .union([z.boolean(), z.string()]) .transform((val) => (typeof val === "string" ? val === "true" : val)) diff --git a/src/app/[orgId]/settings/clients/create/page.tsx b/src/app/[orgId]/settings/clients/create/page.tsx index 0f44d79c..aaee4d31 100644 --- a/src/app/[orgId]/settings/clients/create/page.tsx +++ b/src/app/[orgId]/settings/clients/create/page.tsx @@ -103,7 +103,8 @@ export default function Page() { .refine((val) => val.length > 0, { message: t("siteRequired") }), - subnet: z.union([z.ipv4(), z.ipv6()]).min(1, { + subnet: z.union([z.ipv4(), z.ipv6()]) + .refine((val) => val.length > 0, { message: t("subnetRequired") }) });