From 5f18c06e03695b2567ccd802c830d6533d825773 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Mon, 23 Feb 2026 12:25:24 +0530 Subject: [PATCH 01/46] fix: use collision-free path encoding for Traefik router key generation --- server/lib/traefik/getTraefikConfig.ts | 6 +- server/lib/traefik/pathEncoding.test.ts | 170 ++++++++++++++++++ server/lib/traefik/utils.ts | 20 +++ .../private/lib/traefik/getTraefikConfig.ts | 8 +- 4 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 server/lib/traefik/pathEncoding.test.ts diff --git a/server/lib/traefik/getTraefikConfig.ts b/server/lib/traefik/getTraefikConfig.ts index 06754ffa2..f503b88a3 100644 --- a/server/lib/traefik/getTraefikConfig.ts +++ b/server/lib/traefik/getTraefikConfig.ts @@ -14,7 +14,7 @@ import logger from "@server/logger"; import config from "@server/lib/config"; import { resources, sites, Target, targets } from "@server/db"; import createPathRewriteMiddleware from "./middleware"; -import { sanitize, validatePathRewriteConfig } from "./utils"; +import { sanitize, encodePath, validatePathRewriteConfig } from "./utils"; const redirectHttpsMiddlewareName = "redirect-to-https"; const badgerMiddlewareName = "badger"; @@ -44,7 +44,7 @@ export async function getTraefikConfig( filterOutNamespaceDomains = false, // UNUSED BUT USED IN PRIVATE generateLoginPageRouters = false, // UNUSED BUT USED IN PRIVATE allowRawResources = true, - allowMaintenancePage = true, // UNUSED BUT USED IN PRIVATE + allowMaintenancePage = true // UNUSED BUT USED IN PRIVATE ): Promise { // Get resources with their targets and sites in a single optimized query // Start from sites on this exit node, then join to targets and resources @@ -127,7 +127,7 @@ export async function getTraefikConfig( resourcesWithTargetsAndSites.forEach((row) => { const resourceId = row.resourceId; const resourceName = sanitize(row.resourceName) || ""; - const targetPath = sanitize(row.path) || ""; // Handle null/undefined paths + const targetPath = encodePath(row.path); // Encode path preserving uniqueness for key generation const pathMatchType = row.pathMatchType || ""; const rewritePath = row.rewritePath || ""; const rewritePathType = row.rewritePathType || ""; diff --git a/server/lib/traefik/pathEncoding.test.ts b/server/lib/traefik/pathEncoding.test.ts new file mode 100644 index 000000000..7e6d9266f --- /dev/null +++ b/server/lib/traefik/pathEncoding.test.ts @@ -0,0 +1,170 @@ +import { assertEquals } from "@test/assert"; +import { encodePath, sanitize } from "./utils"; + +function runTests() { + console.log("Running path encoding tests...\n"); + + // Test 1: null and empty return empty string + { + assertEquals(encodePath(null), "", "null should return empty"); + assertEquals( + encodePath(undefined), + "", + "undefined should return empty" + ); + assertEquals(encodePath(""), "", "empty string should return empty"); + console.log(" PASS: null/undefined/empty return empty string"); + } + + // Test 2: root path "/" encodes to something non-empty + { + const result = encodePath("/"); + assertEquals(result !== "", true, "root path should not be empty"); + assertEquals(result, "2f", "root path should encode to hex of '/'"); + console.log(" PASS: root path encodes to non-empty string"); + } + + // Test 3: different paths produce different encoded values + { + const paths = [ + "/", + "/api", + "/a/b", + "/a-b", + "/a.b", + "/a_b", + "/api/v1", + "/api/v2" + ]; + const encoded = new Set(); + let collision = false; + for (const p of paths) { + const e = encodePath(p); + if (encoded.has(e)) { + collision = true; + break; + } + encoded.add(e); + } + assertEquals(collision, false, "no two different paths should collide"); + console.log(" PASS: all different paths produce unique encodings"); + } + + // Test 4: alphanumeric characters pass through unchanged + { + assertEquals( + encodePath("/api"), + "2fapi", + "/api should encode slash only" + ); + assertEquals(encodePath("/v1"), "2fv1", "/v1 should encode slash only"); + console.log(" PASS: alphanumeric characters preserved"); + } + + // Test 5: special characters are hex-encoded + { + const dotEncoded = encodePath("/a.b"); + const dashEncoded = encodePath("/a-b"); + const slashEncoded = encodePath("/a/b"); + const underscoreEncoded = encodePath("/a_b"); + + // all should be different + const set = new Set([ + dotEncoded, + dashEncoded, + slashEncoded, + underscoreEncoded + ]); + assertEquals( + set.size, + 4, + "dot, dash, slash, underscore paths should all be unique" + ); + console.log(" PASS: special characters produce unique encodings"); + } + + // Test 6: full key generation - different paths create different keys + { + function makeKey( + resourceId: number, + path: string | null, + pathMatchType: string | null + ) { + const targetPath = encodePath(path); + const pmt = pathMatchType || ""; + const pathKey = [targetPath, pmt, "", ""].filter(Boolean).join("-"); + const mapKey = [resourceId, pathKey].filter(Boolean).join("-"); + return sanitize(mapKey); + } + + const keySlash = makeKey(1, "/", "prefix"); + const keyApi = makeKey(1, "/api", "prefix"); + const keyNull = makeKey(1, null, null); + + assertEquals( + keySlash !== keyApi, + true, + "/ and /api should have different keys" + ); + assertEquals( + keySlash !== keyNull, + true, + "/ and null should have different keys" + ); + assertEquals( + keyApi !== keyNull, + true, + "/api and null should have different keys" + ); + + console.log( + " PASS: different paths create different resource map keys" + ); + } + + // Test 7: same path always produces same key (deterministic) + { + assertEquals( + encodePath("/api"), + encodePath("/api"), + "same input should produce same output" + ); + assertEquals( + encodePath("/a/b/c"), + encodePath("/a/b/c"), + "same input should produce same output" + ); + console.log(" PASS: encoding is deterministic"); + } + + // Test 8: encoded result is alphanumeric (valid for Traefik names after sanitize) + { + const paths = [ + "/", + "/api", + "/a/b", + "/a-b", + "/a.b", + "/complex/path/here" + ]; + for (const p of paths) { + const e = encodePath(p); + const isAlphanumeric = /^[a-zA-Z0-9]+$/.test(e); + assertEquals( + isAlphanumeric, + true, + `encodePath("${p}") = "${e}" should be alphanumeric` + ); + } + console.log(" PASS: encoded values are alphanumeric"); + } + + console.log("\nAll path encoding tests passed!"); +} + +try { + runTests(); +} catch (error) { + console.error("Test failed:", error); + process.exit(1); +} diff --git a/server/lib/traefik/utils.ts b/server/lib/traefik/utils.ts index ec0eae5b3..da876fa07 100644 --- a/server/lib/traefik/utils.ts +++ b/server/lib/traefik/utils.ts @@ -13,6 +13,26 @@ export function sanitize(input: string | null | undefined): string | undefined { .replace(/^-|-$/g, ""); } +/** + * Encode a URL path into a collision-free alphanumeric string suitable for use + * in Traefik router/service names and map keys. + * + * Unlike sanitize(), this preserves uniqueness by encoding each non-alphanumeric + * character as its hex code. Different paths always produce different outputs. + * + * encodePath("/api") => "2fapi" + * encodePath("/a/b") => "2fa2fb" + * encodePath("/a-b") => "2fa2db" (different from /a/b) + * encodePath("/") => "2f" + * encodePath(null) => "" + */ +export function encodePath(path: string | null | undefined): string { + if (!path) return ""; + return path.replace(/[^a-zA-Z0-9]/g, (ch) => { + return ch.charCodeAt(0).toString(16); + }); +} + export function validatePathRewriteConfig( path: string | null, pathMatchType: string | null, diff --git a/server/private/lib/traefik/getTraefikConfig.ts b/server/private/lib/traefik/getTraefikConfig.ts index f0343c5d4..1652427b2 100644 --- a/server/private/lib/traefik/getTraefikConfig.ts +++ b/server/private/lib/traefik/getTraefikConfig.ts @@ -34,7 +34,11 @@ import { import logger from "@server/logger"; import config from "@server/lib/config"; import { orgs, resources, sites, Target, targets } from "@server/db"; -import { sanitize, validatePathRewriteConfig } from "@server/lib/traefik/utils"; +import { + sanitize, + encodePath, + validatePathRewriteConfig +} from "@server/lib/traefik/utils"; import privateConfig from "#private/lib/config"; import createPathRewriteMiddleware from "@server/lib/traefik/middleware"; import { @@ -170,7 +174,7 @@ export async function getTraefikConfig( resourcesWithTargetsAndSites.forEach((row) => { const resourceId = row.resourceId; const resourceName = sanitize(row.resourceName) || ""; - const targetPath = sanitize(row.path) || ""; // Handle null/undefined paths + const targetPath = encodePath(row.path); // Encode path preserving uniqueness for key generation const pathMatchType = row.pathMatchType || ""; const rewritePath = row.rewritePath || ""; const rewritePathType = row.rewritePathType || ""; From e58f0c9f07cafe58b33e2f2b718709f528d1900c Mon Sep 17 00:00:00 2001 From: Shreyas Date: Mon, 23 Feb 2026 12:31:30 +0530 Subject: [PATCH 02/46] fix: preserve backward-compatible router names while fixing path collisions Use encodePath only for internal map key grouping (collision-free) and sanitize for Traefik-facing router/service names (unchanged for existing users). Extract pure functions into pathUtils.ts so tests can run without DB dependencies. --- server/lib/traefik/getTraefikConfig.ts | 39 ++++++++--- server/lib/traefik/pathEncoding.test.ts | 70 ++++++++++++++++++- server/lib/traefik/pathUtils.ts | 37 ++++++++++ server/lib/traefik/utils.ts | 34 +-------- .../private/lib/traefik/getTraefikConfig.ts | 39 ++++++++--- 5 files changed, 165 insertions(+), 54 deletions(-) create mode 100644 server/lib/traefik/pathUtils.ts diff --git a/server/lib/traefik/getTraefikConfig.ts b/server/lib/traefik/getTraefikConfig.ts index f503b88a3..3becfb370 100644 --- a/server/lib/traefik/getTraefikConfig.ts +++ b/server/lib/traefik/getTraefikConfig.ts @@ -127,25 +127,42 @@ export async function getTraefikConfig( resourcesWithTargetsAndSites.forEach((row) => { const resourceId = row.resourceId; const resourceName = sanitize(row.resourceName) || ""; - const targetPath = encodePath(row.path); // Encode path preserving uniqueness for key generation const pathMatchType = row.pathMatchType || ""; const rewritePath = row.rewritePath || ""; const rewritePathType = row.rewritePathType || ""; const priority = row.priority ?? 100; - // Create a unique key combining resourceId, path config, and rewrite config - const pathKey = [ - targetPath, + // Use encodePath for the internal map key to avoid collisions + // (e.g. "/a/b" vs "/a-b" must map to different groups) + const encodedPath = encodePath(row.path); + const internalPathKey = [ + encodedPath, pathMatchType, rewritePath, rewritePathType ] .filter(Boolean) .join("-"); - const mapKey = [resourceId, pathKey].filter(Boolean).join("-"); - const key = sanitize(mapKey); + const internalMapKey = [resourceId, internalPathKey] + .filter(Boolean) + .join("-"); - if (!resourcesMap.has(key)) { + // Use sanitize for the Traefik-facing key to preserve backward-compatible + // router/service names (existing sticky session cookies, etc.) + const sanitizedPath = sanitize(row.path) || ""; + const traefikPathKey = [ + sanitizedPath, + pathMatchType, + rewritePath, + rewritePathType + ] + .filter(Boolean) + .join("-"); + const traefikKey = sanitize( + [resourceId, traefikPathKey].filter(Boolean).join("-") + ); + + if (!resourcesMap.has(internalMapKey)) { const validation = validatePathRewriteConfig( row.path, row.pathMatchType, @@ -160,9 +177,10 @@ export async function getTraefikConfig( return; } - resourcesMap.set(key, { + resourcesMap.set(internalMapKey, { resourceId: row.resourceId, name: resourceName, + traefikKey: traefikKey, // backward-compatible key for Traefik names fullDomain: row.fullDomain, ssl: row.ssl, http: row.http, @@ -190,7 +208,7 @@ export async function getTraefikConfig( }); } - resourcesMap.get(key).targets.push({ + resourcesMap.get(internalMapKey).targets.push({ resourceId: row.resourceId, targetId: row.targetId, ip: row.ip, @@ -227,8 +245,9 @@ export async function getTraefikConfig( }; // get the key and the resource - for (const [key, resource] of resourcesMap.entries()) { + for (const [, resource] of resourcesMap.entries()) { const targets = resource.targets as TargetWithSite[]; + const key = resource.traefikKey; // backward-compatible key for Traefik names const routerName = `${key}-${resource.name}-router`; const serviceName = `${key}-${resource.name}-service`; diff --git a/server/lib/traefik/pathEncoding.test.ts b/server/lib/traefik/pathEncoding.test.ts index 7e6d9266f..a3575b9f2 100644 --- a/server/lib/traefik/pathEncoding.test.ts +++ b/server/lib/traefik/pathEncoding.test.ts @@ -1,5 +1,5 @@ -import { assertEquals } from "@test/assert"; -import { encodePath, sanitize } from "./utils"; +import { assertEquals } from "../../../test/assert"; +import { encodePath, sanitize } from "./pathUtils"; function runTests() { console.log("Running path encoding tests...\n"); @@ -159,6 +159,72 @@ function runTests() { console.log(" PASS: encoded values are alphanumeric"); } + // Test 9: backward compatibility - Traefik names use sanitize, internal keys use encodePath + { + // Simulate the dual-key approach from getTraefikConfig + function makeKeys( + resourceId: number, + path: string | null, + pathMatchType: string | null + ) { + // Internal map key (collision-free grouping) + const encodedPath = encodePath(path); + const internalPathKey = [encodedPath, pathMatchType || ""] + .filter(Boolean) + .join("-"); + const internalMapKey = [resourceId, internalPathKey] + .filter(Boolean) + .join("-"); + + // Traefik-facing key (backward-compatible naming) + const sanitizedPath = sanitize(path) || ""; + const traefikPathKey = [sanitizedPath, pathMatchType || ""] + .filter(Boolean) + .join("-"); + const traefikKey = sanitize( + [resourceId, traefikPathKey].filter(Boolean).join("-") + ); + + return { internalMapKey, traefikKey }; + } + + // /a/b and /a-b should have DIFFERENT internal keys (no collision) + const keysAB = makeKeys(1, "/a/b", "prefix"); + const keysDash = makeKeys(1, "/a-b", "prefix"); + assertEquals( + keysAB.internalMapKey !== keysDash.internalMapKey, + true, + "/a/b and /a-b must have different internal map keys" + ); + + // /a/b and /a-b produce the SAME Traefik key (backward compat — sanitize maps both to "a-b") + assertEquals( + keysAB.traefikKey, + keysDash.traefikKey, + "/a/b and /a-b should produce same Traefik key (sanitize behavior)" + ); + + // For a resource with no path, Traefik key should match the old behavior + const keysNoPath = makeKeys(42, null, null); + assertEquals( + keysNoPath.traefikKey, + "42", + "no-path resource should have resourceId-only Traefik key" + ); + + // Traefik key for /api prefix should match old sanitize-based output + const keysApi = makeKeys(1, "/api", "prefix"); + assertEquals( + keysApi.traefikKey, + "1-api-prefix", + "Traefik key should match old sanitize-based format" + ); + + console.log( + " PASS: backward compatibility - internal keys differ, Traefik names preserved" + ); + } + console.log("\nAll path encoding tests passed!"); } diff --git a/server/lib/traefik/pathUtils.ts b/server/lib/traefik/pathUtils.ts new file mode 100644 index 000000000..1b9d57a89 --- /dev/null +++ b/server/lib/traefik/pathUtils.ts @@ -0,0 +1,37 @@ +/** + * Pure utility functions for path/name encoding. + * No external dependencies — safe to import in tests. + */ + +export function sanitize(input: string | null | undefined): string | undefined { + if (!input) return undefined; + // clean any non alphanumeric characters from the input and replace with dashes + // the input cant be too long either, so limit to 50 characters + if (input.length > 50) { + input = input.substring(0, 50); + } + return input + .replace(/[^a-zA-Z0-9-]/g, "-") + .replace(/-+/g, "-") + .replace(/^-|-$/g, ""); +} + +/** + * Encode a URL path into a collision-free alphanumeric string suitable for use + * in Traefik map keys. + * + * Unlike sanitize(), this preserves uniqueness by encoding each non-alphanumeric + * character as its hex code. Different paths always produce different outputs. + * + * encodePath("/api") => "2fapi" + * encodePath("/a/b") => "2fa2fb" + * encodePath("/a-b") => "2fa2db" (different from /a/b) + * encodePath("/") => "2f" + * encodePath(null) => "" + */ +export function encodePath(path: string | null | undefined): string { + if (!path) return ""; + return path.replace(/[^a-zA-Z0-9]/g, (ch) => { + return ch.charCodeAt(0).toString(16); + }); +} diff --git a/server/lib/traefik/utils.ts b/server/lib/traefik/utils.ts index da876fa07..f40e2eba2 100644 --- a/server/lib/traefik/utils.ts +++ b/server/lib/traefik/utils.ts @@ -1,37 +1,7 @@ import logger from "@server/logger"; -export function sanitize(input: string | null | undefined): string | undefined { - if (!input) return undefined; - // clean any non alphanumeric characters from the input and replace with dashes - // the input cant be too long either, so limit to 50 characters - if (input.length > 50) { - input = input.substring(0, 50); - } - return input - .replace(/[^a-zA-Z0-9-]/g, "-") - .replace(/-+/g, "-") - .replace(/^-|-$/g, ""); -} - -/** - * Encode a URL path into a collision-free alphanumeric string suitable for use - * in Traefik router/service names and map keys. - * - * Unlike sanitize(), this preserves uniqueness by encoding each non-alphanumeric - * character as its hex code. Different paths always produce different outputs. - * - * encodePath("/api") => "2fapi" - * encodePath("/a/b") => "2fa2fb" - * encodePath("/a-b") => "2fa2db" (different from /a/b) - * encodePath("/") => "2f" - * encodePath(null) => "" - */ -export function encodePath(path: string | null | undefined): string { - if (!path) return ""; - return path.replace(/[^a-zA-Z0-9]/g, (ch) => { - return ch.charCodeAt(0).toString(16); - }); -} +// Re-export pure functions from dependency-free module +export { sanitize, encodePath } from "./pathUtils"; export function validatePathRewriteConfig( path: string | null, diff --git a/server/private/lib/traefik/getTraefikConfig.ts b/server/private/lib/traefik/getTraefikConfig.ts index 1652427b2..b6c460072 100644 --- a/server/private/lib/traefik/getTraefikConfig.ts +++ b/server/private/lib/traefik/getTraefikConfig.ts @@ -174,7 +174,6 @@ export async function getTraefikConfig( resourcesWithTargetsAndSites.forEach((row) => { const resourceId = row.resourceId; const resourceName = sanitize(row.resourceName) || ""; - const targetPath = encodePath(row.path); // Encode path preserving uniqueness for key generation const pathMatchType = row.pathMatchType || ""; const rewritePath = row.rewritePath || ""; const rewritePathType = row.rewritePathType || ""; @@ -184,19 +183,37 @@ export async function getTraefikConfig( return; } - // Create a unique key combining resourceId, path config, and rewrite config - const pathKey = [ - targetPath, + // Use encodePath for the internal map key to avoid collisions + // (e.g. "/a/b" vs "/a-b" must map to different groups) + const encodedPath = encodePath(row.path); + const internalPathKey = [ + encodedPath, pathMatchType, rewritePath, rewritePathType ] .filter(Boolean) .join("-"); - const mapKey = [resourceId, pathKey].filter(Boolean).join("-"); - const key = sanitize(mapKey); + const internalMapKey = [resourceId, internalPathKey] + .filter(Boolean) + .join("-"); - if (!resourcesMap.has(key)) { + // Use sanitize for the Traefik-facing key to preserve backward-compatible + // router/service names (existing sticky session cookies, etc.) + const sanitizedPath = sanitize(row.path) || ""; + const traefikPathKey = [ + sanitizedPath, + pathMatchType, + rewritePath, + rewritePathType + ] + .filter(Boolean) + .join("-"); + const traefikKey = sanitize( + [resourceId, traefikPathKey].filter(Boolean).join("-") + ); + + if (!resourcesMap.has(internalMapKey)) { const validation = validatePathRewriteConfig( row.path, row.pathMatchType, @@ -211,9 +228,10 @@ export async function getTraefikConfig( return; } - resourcesMap.set(key, { + resourcesMap.set(internalMapKey, { resourceId: row.resourceId, name: resourceName, + traefikKey: traefikKey, // backward-compatible key for Traefik names fullDomain: row.fullDomain, ssl: row.ssl, http: row.http, @@ -247,7 +265,7 @@ export async function getTraefikConfig( } // Add target with its associated site data - resourcesMap.get(key).targets.push({ + resourcesMap.get(internalMapKey).targets.push({ resourceId: row.resourceId, targetId: row.targetId, ip: row.ip, @@ -300,8 +318,9 @@ export async function getTraefikConfig( }; // get the key and the resource - for (const [key, resource] of resourcesMap.entries()) { + for (const [, resource] of resourcesMap.entries()) { const targets = resource.targets as TargetWithSite[]; + const key = resource.traefikKey; // backward-compatible key for Traefik names const routerName = `${key}-${resource.name}-router`; const serviceName = `${key}-${resource.name}-service`; From 244f497a9c0c0cbdd99ac6ae2336e65c51a3a88b Mon Sep 17 00:00:00 2001 From: Shreyas Date: Mon, 23 Feb 2026 12:33:20 +0530 Subject: [PATCH 03/46] test: add comprehensive backward compatibility tests for path routing fix --- server/lib/traefik/pathEncoding.test.ts | 745 ++++++++++++++++++------ 1 file changed, 574 insertions(+), 171 deletions(-) diff --git a/server/lib/traefik/pathEncoding.test.ts b/server/lib/traefik/pathEncoding.test.ts index a3575b9f2..58dd8653d 100644 --- a/server/lib/traefik/pathEncoding.test.ts +++ b/server/lib/traefik/pathEncoding.test.ts @@ -1,10 +1,93 @@ import { assertEquals } from "../../../test/assert"; import { encodePath, sanitize } from "./pathUtils"; -function runTests() { - console.log("Running path encoding tests...\n"); +// ── Helpers ────────────────────────────────────────────────────────── - // Test 1: null and empty return empty string +/** + * Exact replica of the OLD key computation from upstream main. + * This is what existing Pangolin deployments use today for both + * map grouping AND Traefik router/service names. + * + * Source: origin/main server/lib/traefik/getTraefikConfig.ts lines 130-146 + */ +function oldKeyComputation( + resourceId: number, + path: string | null, + pathMatchType: string | null, + rewritePath: string | null, + rewritePathType: string | null +): string { + const targetPath = sanitize(path) || ""; + const pmt = pathMatchType || ""; + const rp = rewritePath || ""; + const rpt = rewritePathType || ""; + const pathKey = [targetPath, pmt, rp, rpt].filter(Boolean).join("-"); + const mapKey = [resourceId, pathKey].filter(Boolean).join("-"); + return sanitize(mapKey) || ""; +} + +/** + * Replica of the NEW dual-key computation from our fix. + * Returns both the internal map key (for grouping) and the + * Traefik-facing key (for router/service names). + * + * Source: our getTraefikConfig.ts lines 135-163 + */ +function newKeyComputation( + resourceId: number, + path: string | null, + pathMatchType: string | null, + rewritePath: string | null, + rewritePathType: string | null +): { internalMapKey: string; traefikKey: string } { + const pmt = pathMatchType || ""; + const rp = rewritePath || ""; + const rpt = rewritePathType || ""; + + // Internal map key: uses encodePath (collision-free) + const encodedPath = encodePath(path); + const internalPathKey = [encodedPath, pmt, rp, rpt] + .filter(Boolean) + .join("-"); + const internalMapKey = [resourceId, internalPathKey] + .filter(Boolean) + .join("-"); + + // Traefik-facing key: uses sanitize (backward-compatible) + const sanitizedPath = sanitize(path) || ""; + const traefikPathKey = [sanitizedPath, pmt, rp, rpt] + .filter(Boolean) + .join("-"); + const traefikKey = sanitize( + [resourceId, traefikPathKey].filter(Boolean).join("-") + ); + + return { internalMapKey, traefikKey: traefikKey || "" }; +} + +/** + * Build the full Traefik router/service names the way getTraefikConfig does. + */ +function buildTraefikNames(key: string, resourceName: string) { + const name = sanitize(resourceName) || ""; + return { + routerName: `${key}-${name}-router`, + serviceName: `${key}-${name}-service`, + transportName: `${key}-transport`, + headersMiddlewareName: `${key}-headers-middleware` + }; +} + +// ── Tests ──────────────────────────────────────────────────────────── + +function runTests() { + console.log("Running path encoding & backward compatibility tests...\n"); + + let passed = 0; + + // ── encodePath unit tests ──────────────────────────────────────── + + // Test 1: null/undefined/empty { assertEquals(encodePath(null), "", "null should return empty"); assertEquals( @@ -13,131 +96,43 @@ function runTests() { "undefined should return empty" ); assertEquals(encodePath(""), "", "empty string should return empty"); - console.log(" PASS: null/undefined/empty return empty string"); + console.log(" PASS: encodePath handles null/undefined/empty"); + passed++; } - // Test 2: root path "/" encodes to something non-empty + // Test 2: root path { - const result = encodePath("/"); - assertEquals(result !== "", true, "root path should not be empty"); - assertEquals(result, "2f", "root path should encode to hex of '/'"); - console.log(" PASS: root path encodes to non-empty string"); + assertEquals(encodePath("/"), "2f", "/ should encode to 2f"); + console.log(" PASS: encodePath encodes root path"); + passed++; } - // Test 3: different paths produce different encoded values + // Test 3: alphanumeric passthrough { - const paths = [ - "/", - "/api", - "/a/b", - "/a-b", - "/a.b", - "/a_b", - "/api/v1", - "/api/v2" - ]; - const encoded = new Set(); - let collision = false; - for (const p of paths) { - const e = encodePath(p); - if (encoded.has(e)) { - collision = true; - break; - } - encoded.add(e); - } - assertEquals(collision, false, "no two different paths should collide"); - console.log(" PASS: all different paths produce unique encodings"); + assertEquals(encodePath("/api"), "2fapi", "/api encodes slash only"); + assertEquals(encodePath("/v1"), "2fv1", "/v1 encodes slash only"); + assertEquals(encodePath("abc"), "abc", "plain alpha passes through"); + console.log(" PASS: encodePath preserves alphanumeric chars"); + passed++; } - // Test 4: alphanumeric characters pass through unchanged + // Test 4: all special chars produce unique hex { + const paths = ["/a/b", "/a-b", "/a.b", "/a_b", "/a b"]; + const results = paths.map((p) => encodePath(p)); + const unique = new Set(results); assertEquals( - encodePath("/api"), - "2fapi", - "/api should encode slash only" + unique.size, + paths.length, + "all special-char paths must produce unique encodings" ); - assertEquals(encodePath("/v1"), "2fv1", "/v1 should encode slash only"); - console.log(" PASS: alphanumeric characters preserved"); - } - - // Test 5: special characters are hex-encoded - { - const dotEncoded = encodePath("/a.b"); - const dashEncoded = encodePath("/a-b"); - const slashEncoded = encodePath("/a/b"); - const underscoreEncoded = encodePath("/a_b"); - - // all should be different - const set = new Set([ - dotEncoded, - dashEncoded, - slashEncoded, - underscoreEncoded - ]); - assertEquals( - set.size, - 4, - "dot, dash, slash, underscore paths should all be unique" - ); - console.log(" PASS: special characters produce unique encodings"); - } - - // Test 6: full key generation - different paths create different keys - { - function makeKey( - resourceId: number, - path: string | null, - pathMatchType: string | null - ) { - const targetPath = encodePath(path); - const pmt = pathMatchType || ""; - const pathKey = [targetPath, pmt, "", ""].filter(Boolean).join("-"); - const mapKey = [resourceId, pathKey].filter(Boolean).join("-"); - return sanitize(mapKey); - } - - const keySlash = makeKey(1, "/", "prefix"); - const keyApi = makeKey(1, "/api", "prefix"); - const keyNull = makeKey(1, null, null); - - assertEquals( - keySlash !== keyApi, - true, - "/ and /api should have different keys" - ); - assertEquals( - keySlash !== keyNull, - true, - "/ and null should have different keys" - ); - assertEquals( - keyApi !== keyNull, - true, - "/api and null should have different keys" - ); - console.log( - " PASS: different paths create different resource map keys" + " PASS: encodePath produces unique output for different special chars" ); + passed++; } - // Test 7: same path always produces same key (deterministic) - { - assertEquals( - encodePath("/api"), - encodePath("/api"), - "same input should produce same output" - ); - assertEquals( - encodePath("/a/b/c"), - encodePath("/a/b/c"), - "same input should produce same output" - ); - console.log(" PASS: encoding is deterministic"); - } - - // Test 8: encoded result is alphanumeric (valid for Traefik names after sanitize) + // Test 5: output is always alphanumeric (safe for Traefik names) { const paths = [ "/", @@ -149,83 +144,491 @@ function runTests() { ]; for (const p of paths) { const e = encodePath(p); - const isAlphanumeric = /^[a-zA-Z0-9]+$/.test(e); assertEquals( - isAlphanumeric, + /^[a-zA-Z0-9]+$/.test(e), true, - `encodePath("${p}") = "${e}" should be alphanumeric` + `encodePath("${p}") = "${e}" must be alphanumeric` ); } - console.log(" PASS: encoded values are alphanumeric"); + console.log(" PASS: encodePath output is always alphanumeric"); + passed++; } - // Test 9: backward compatibility - Traefik names use sanitize, internal keys use encodePath + // Test 6: deterministic { - // Simulate the dual-key approach from getTraefikConfig - function makeKeys( - resourceId: number, - path: string | null, - pathMatchType: string | null - ) { - // Internal map key (collision-free grouping) - const encodedPath = encodePath(path); - const internalPathKey = [encodedPath, pathMatchType || ""] - .filter(Boolean) - .join("-"); - const internalMapKey = [resourceId, internalPathKey] - .filter(Boolean) - .join("-"); + assertEquals( + encodePath("/api"), + encodePath("/api"), + "same input same output" + ); + assertEquals( + encodePath("/a/b/c"), + encodePath("/a/b/c"), + "same input same output" + ); + console.log(" PASS: encodePath is deterministic"); + passed++; + } - // Traefik-facing key (backward-compatible naming) - const sanitizedPath = sanitize(path) || ""; - const traefikPathKey = [sanitizedPath, pathMatchType || ""] - .filter(Boolean) - .join("-"); - const traefikKey = sanitize( - [resourceId, traefikPathKey].filter(Boolean).join("-") + // Test 7: many distinct paths never collide + { + const paths = [ + "/", + "/api", + "/api/v1", + "/api/v2", + "/a/b", + "/a-b", + "/a.b", + "/a_b", + "/health", + "/health/check", + "/admin", + "/admin/users", + "/api/v1/users", + "/api/v1/posts", + "/app", + "/app/dashboard" + ]; + const encoded = new Set(paths.map((p) => encodePath(p))); + assertEquals( + encoded.size, + paths.length, + `expected ${paths.length} unique encodings, got ${encoded.size}` + ); + console.log(" PASS: 16 realistic paths all produce unique encodings"); + passed++; + } + + // ── Backward compatibility: Traefik names must match old code ───── + + // Test 8: simple resource, no path — Traefik name unchanged + { + const oldKey = oldKeyComputation(1, null, null, null, null); + const { traefikKey } = newKeyComputation(1, null, null, null, null); + assertEquals( + traefikKey, + oldKey, + "no-path resource: Traefik key must match old" + ); + console.log(" PASS: backward compat — no path resource"); + passed++; + } + + // Test 9: resource with /api prefix — Traefik name unchanged + { + const oldKey = oldKeyComputation(1, "/api", "prefix", null, null); + const { traefikKey } = newKeyComputation( + 1, + "/api", + "prefix", + null, + null + ); + assertEquals( + traefikKey, + oldKey, + "/api prefix: Traefik key must match old" + ); + console.log(" PASS: backward compat — /api prefix"); + passed++; + } + + // Test 10: resource with exact path — Traefik name unchanged + { + const oldKey = oldKeyComputation(5, "/health", "exact", null, null); + const { traefikKey } = newKeyComputation( + 5, + "/health", + "exact", + null, + null + ); + assertEquals( + traefikKey, + oldKey, + "/health exact: Traefik key must match old" + ); + console.log(" PASS: backward compat — /health exact"); + passed++; + } + + // Test 11: resource with regex path — Traefik name unchanged + { + const oldKey = oldKeyComputation( + 3, + "^/api/v[0-9]+", + "regex", + null, + null + ); + const { traefikKey } = newKeyComputation( + 3, + "^/api/v[0-9]+", + "regex", + null, + null + ); + assertEquals( + traefikKey, + oldKey, + "regex path: Traefik key must match old" + ); + console.log(" PASS: backward compat — regex path"); + passed++; + } + + // Test 12: resource with path rewrite — Traefik name unchanged + { + const oldKey = oldKeyComputation( + 10, + "/api", + "prefix", + "/backend", + "prefix" + ); + const { traefikKey } = newKeyComputation( + 10, + "/api", + "prefix", + "/backend", + "prefix" + ); + assertEquals( + traefikKey, + oldKey, + "path rewrite: Traefik key must match old" + ); + console.log(" PASS: backward compat — path rewrite (prefix→prefix)"); + passed++; + } + + // Test 13: resource with stripPrefix rewrite — Traefik name unchanged + { + const oldKey = oldKeyComputation( + 7, + "/app", + "prefix", + null, + "stripPrefix" + ); + const { traefikKey } = newKeyComputation( + 7, + "/app", + "prefix", + null, + "stripPrefix" + ); + assertEquals( + traefikKey, + oldKey, + "stripPrefix: Traefik key must match old" + ); + console.log(" PASS: backward compat — stripPrefix rewrite"); + passed++; + } + + // Test 14: root path "/" — Traefik name unchanged + { + const oldKey = oldKeyComputation(1, "/", "prefix", null, null); + const { traefikKey } = newKeyComputation(1, "/", "prefix", null, null); + assertEquals( + traefikKey, + oldKey, + "root path: Traefik key must match old" + ); + console.log(" PASS: backward compat — root path /"); + passed++; + } + + // Test 15: full Traefik router/service names unchanged for existing users + { + const scenarios = [ + { + rid: 1, + name: "my-webapp", + path: "/api", + pmt: "prefix" as const, + rp: null, + rpt: null + }, + { + rid: 2, + name: "backend", + path: "/", + pmt: "prefix" as const, + rp: null, + rpt: null + }, + { + rid: 3, + name: "docs", + path: "/docs", + pmt: "prefix" as const, + rp: "/", + rpt: "stripPrefix" as const + }, + { + rid: 42, + name: "api-service", + path: null, + pmt: null, + rp: null, + rpt: null + }, + { + rid: 100, + name: "grafana", + path: "/grafana", + pmt: "prefix" as const, + rp: null, + rpt: null + } + ]; + for (const s of scenarios) { + const oldKey = oldKeyComputation(s.rid, s.path, s.pmt, s.rp, s.rpt); + const { traefikKey } = newKeyComputation( + s.rid, + s.path, + s.pmt, + s.rp, + s.rpt + ); + const oldNames = buildTraefikNames(oldKey, s.name); + const newNames = buildTraefikNames(traefikKey, s.name); + assertEquals( + newNames.routerName, + oldNames.routerName, + `router name mismatch for resource ${s.rid} ${s.name} path=${s.path}` + ); + assertEquals( + newNames.serviceName, + oldNames.serviceName, + `service name mismatch for resource ${s.rid} ${s.name} path=${s.path}` + ); + assertEquals( + newNames.transportName, + oldNames.transportName, + `transport name mismatch for resource ${s.rid} ${s.name} path=${s.path}` ); - - return { internalMapKey, traefikKey }; } + console.log( + " PASS: backward compat — full router/service/transport names match old code for 5 scenarios" + ); + passed++; + } - // /a/b and /a-b should have DIFFERENT internal keys (no collision) - const keysAB = makeKeys(1, "/a/b", "prefix"); - const keysDash = makeKeys(1, "/a-b", "prefix"); + // Test 16: large resourceId — Traefik name unchanged + { + const oldKey = oldKeyComputation( + 99999, + "/dashboard", + "prefix", + null, + null + ); + const { traefikKey } = newKeyComputation( + 99999, + "/dashboard", + "prefix", + null, + null + ); + assertEquals( + traefikKey, + oldKey, + "large resourceId: Traefik key must match old" + ); + console.log(" PASS: backward compat — large resourceId"); + passed++; + } + + // ── Collision fix: the actual bug we're fixing ─────────────────── + + // Test 17: /a/b and /a-b now have different internal keys (THE BUG FIX) + { + const keysAB = newKeyComputation(1, "/a/b", "prefix", null, null); + const keysDash = newKeyComputation(1, "/a-b", "prefix", null, null); assertEquals( keysAB.internalMapKey !== keysDash.internalMapKey, true, - "/a/b and /a-b must have different internal map keys" + "/a/b and /a-b MUST have different internal map keys" ); - - // /a/b and /a-b produce the SAME Traefik key (backward compat — sanitize maps both to "a-b") - assertEquals( - keysAB.traefikKey, - keysDash.traefikKey, - "/a/b and /a-b should produce same Traefik key (sanitize behavior)" - ); - - // For a resource with no path, Traefik key should match the old behavior - const keysNoPath = makeKeys(42, null, null); - assertEquals( - keysNoPath.traefikKey, - "42", - "no-path resource should have resourceId-only Traefik key" - ); - - // Traefik key for /api prefix should match old sanitize-based output - const keysApi = makeKeys(1, "/api", "prefix"); - assertEquals( - keysApi.traefikKey, - "1-api-prefix", - "Traefik key should match old sanitize-based format" - ); - console.log( - " PASS: backward compatibility - internal keys differ, Traefik names preserved" + " PASS: collision fix — /a/b vs /a-b have different internal keys" ); + passed++; } - console.log("\nAll path encoding tests passed!"); + // Test 18: demonstrate the old bug — old code maps /a/b and /a-b to same key + { + const oldKeyAB = oldKeyComputation(1, "/a/b", "prefix", null, null); + const oldKeyDash = oldKeyComputation(1, "/a-b", "prefix", null, null); + assertEquals( + oldKeyAB, + oldKeyDash, + "old code MUST have this collision (confirms the bug exists)" + ); + console.log(" PASS: confirmed old code bug — /a/b and /a-b collided"); + passed++; + } + + // Test 19: /api/v1 and /api-v1 — old code collision, new code fixes it + { + const oldKey1 = oldKeyComputation(1, "/api/v1", "prefix", null, null); + const oldKey2 = oldKeyComputation(1, "/api-v1", "prefix", null, null); + assertEquals( + oldKey1, + oldKey2, + "old code collision for /api/v1 vs /api-v1" + ); + + const new1 = newKeyComputation(1, "/api/v1", "prefix", null, null); + const new2 = newKeyComputation(1, "/api-v1", "prefix", null, null); + assertEquals( + new1.internalMapKey !== new2.internalMapKey, + true, + "new code must separate /api/v1 and /api-v1" + ); + console.log(" PASS: collision fix — /api/v1 vs /api-v1"); + passed++; + } + + // Test 20: /app.v2 and /app/v2 and /app-v2 — three-way collision fixed + { + const a = newKeyComputation(1, "/app.v2", "prefix", null, null); + const b = newKeyComputation(1, "/app/v2", "prefix", null, null); + const c = newKeyComputation(1, "/app-v2", "prefix", null, null); + const keys = new Set([ + a.internalMapKey, + b.internalMapKey, + c.internalMapKey + ]); + assertEquals( + keys.size, + 3, + "three paths must produce three unique internal keys" + ); + console.log( + " PASS: collision fix — three-way /app.v2, /app/v2, /app-v2" + ); + passed++; + } + + // ── Edge cases ─────────────────────────────────────────────────── + + // Test 21: same path in different resources — always separate + { + const res1 = newKeyComputation(1, "/api", "prefix", null, null); + const res2 = newKeyComputation(2, "/api", "prefix", null, null); + assertEquals( + res1.internalMapKey !== res2.internalMapKey, + true, + "different resources with same path must have different keys" + ); + assertEquals( + res1.traefikKey !== res2.traefikKey, + true, + "different resources with same path must have different Traefik keys" + ); + console.log(" PASS: edge case — same path, different resources"); + passed++; + } + + // Test 22: same resource, different pathMatchType — separate keys + { + const exact = newKeyComputation(1, "/api", "exact", null, null); + const prefix = newKeyComputation(1, "/api", "prefix", null, null); + assertEquals( + exact.internalMapKey !== prefix.internalMapKey, + true, + "exact vs prefix must have different internal keys" + ); + console.log(" PASS: edge case — same path, different match types"); + passed++; + } + + // Test 23: same resource and path, different rewrite config — separate keys + { + const noRewrite = newKeyComputation(1, "/api", "prefix", null, null); + const withRewrite = newKeyComputation( + 1, + "/api", + "prefix", + "/backend", + "prefix" + ); + assertEquals( + noRewrite.internalMapKey !== withRewrite.internalMapKey, + true, + "with vs without rewrite must have different internal keys" + ); + console.log(" PASS: edge case — same path, different rewrite config"); + passed++; + } + + // Test 24: paths with special URL characters + { + const paths = ["/api?foo", "/api#bar", "/api%20baz", "/api+qux"]; + const internal = new Set( + paths.map( + (p) => + newKeyComputation(1, p, "prefix", null, null).internalMapKey + ) + ); + assertEquals( + internal.size, + paths.length, + "special URL chars must produce unique keys" + ); + console.log(" PASS: edge case — special URL characters in paths"); + passed++; + } + + // Test 25: very long path (sanitize truncates at 50 chars — verify consistency) + { + const longPath = "/" + "a".repeat(100); + const oldKey = oldKeyComputation(1, longPath, "prefix", null, null); + const { traefikKey } = newKeyComputation( + 1, + longPath, + "prefix", + null, + null + ); + assertEquals( + traefikKey, + oldKey, + "long path: Traefik key must match old (both truncate)" + ); + console.log(" PASS: edge case — very long path (50-char truncation)"); + passed++; + } + + // Test 26: sticky session cookie safety — service name doesn't change + { + // Sticky sessions use cookie name "p_sticky" tied to the service name. + // If service name changes, existing cookies become invalid. + const oldKey = oldKeyComputation(1, "/api", "prefix", null, null); + const { traefikKey } = newKeyComputation( + 1, + "/api", + "prefix", + null, + null + ); + const oldServiceName = `${oldKey}-my-app-service`; + const newServiceName = `${traefikKey}-my-app-service`; + assertEquals( + newServiceName, + oldServiceName, + "service name must not change (would break sticky session cookies)" + ); + console.log(" PASS: sticky session safety — service name preserved"); + passed++; + } + + console.log(`\nAll ${passed} tests passed!`); } try { From 75a909784af857e27de2de69af74aa4fdd4e80cd Mon Sep 17 00:00:00 2001 From: Shreyas Papinwar Date: Sun, 1 Mar 2026 15:42:24 +0530 Subject: [PATCH 04/46] =?UTF-8?q?fix:=20simplify=20path=20encoding=20per?= =?UTF-8?q?=20review=20=E2=80=94=20inline=20utils,=20use=20single=20key=20?= =?UTF-8?q?scheme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address PR review comments: - Remove pathUtils.ts and move sanitize/encodePath directly into utils.ts - Simplify dual-key approach to single key using encodePath for map keys - Remove backward-compat logic (not needed per reviewer) - Update tests to match simplified approach --- server/lib/traefik/getTraefikConfig.ts | 39 +- server/lib/traefik/pathEncoding.test.ts | 430 +++--------------- server/lib/traefik/pathUtils.ts | 37 -- server/lib/traefik/utils.ts | 34 +- .../private/lib/traefik/getTraefikConfig.ts | 39 +- 5 files changed, 111 insertions(+), 468 deletions(-) delete mode 100644 server/lib/traefik/pathUtils.ts diff --git a/server/lib/traefik/getTraefikConfig.ts b/server/lib/traefik/getTraefikConfig.ts index 3becfb370..7379cad7f 100644 --- a/server/lib/traefik/getTraefikConfig.ts +++ b/server/lib/traefik/getTraefikConfig.ts @@ -127,42 +127,25 @@ export async function getTraefikConfig( resourcesWithTargetsAndSites.forEach((row) => { const resourceId = row.resourceId; const resourceName = sanitize(row.resourceName) || ""; + const targetPath = encodePath(row.path); // Use encodePath to avoid collisions (e.g. "/a/b" vs "/a-b") const pathMatchType = row.pathMatchType || ""; const rewritePath = row.rewritePath || ""; const rewritePathType = row.rewritePathType || ""; const priority = row.priority ?? 100; - // Use encodePath for the internal map key to avoid collisions - // (e.g. "/a/b" vs "/a-b" must map to different groups) - const encodedPath = encodePath(row.path); - const internalPathKey = [ - encodedPath, + // Create a unique key combining resourceId, path config, and rewrite config + const pathKey = [ + targetPath, pathMatchType, rewritePath, rewritePathType ] .filter(Boolean) .join("-"); - const internalMapKey = [resourceId, internalPathKey] - .filter(Boolean) - .join("-"); + const mapKey = [resourceId, pathKey].filter(Boolean).join("-"); + const key = sanitize(mapKey); - // Use sanitize for the Traefik-facing key to preserve backward-compatible - // router/service names (existing sticky session cookies, etc.) - const sanitizedPath = sanitize(row.path) || ""; - const traefikPathKey = [ - sanitizedPath, - pathMatchType, - rewritePath, - rewritePathType - ] - .filter(Boolean) - .join("-"); - const traefikKey = sanitize( - [resourceId, traefikPathKey].filter(Boolean).join("-") - ); - - if (!resourcesMap.has(internalMapKey)) { + if (!resourcesMap.has(mapKey)) { const validation = validatePathRewriteConfig( row.path, row.pathMatchType, @@ -177,10 +160,10 @@ export async function getTraefikConfig( return; } - resourcesMap.set(internalMapKey, { + resourcesMap.set(mapKey, { resourceId: row.resourceId, name: resourceName, - traefikKey: traefikKey, // backward-compatible key for Traefik names + key: key, fullDomain: row.fullDomain, ssl: row.ssl, http: row.http, @@ -208,7 +191,7 @@ export async function getTraefikConfig( }); } - resourcesMap.get(internalMapKey).targets.push({ + resourcesMap.get(mapKey).targets.push({ resourceId: row.resourceId, targetId: row.targetId, ip: row.ip, @@ -247,7 +230,7 @@ export async function getTraefikConfig( // get the key and the resource for (const [, resource] of resourcesMap.entries()) { const targets = resource.targets as TargetWithSite[]; - const key = resource.traefikKey; // backward-compatible key for Traefik names + const key = resource.key; const routerName = `${key}-${resource.name}-router`; const serviceName = `${key}-${resource.name}-service`; diff --git a/server/lib/traefik/pathEncoding.test.ts b/server/lib/traefik/pathEncoding.test.ts index 58dd8653d..83d53a039 100644 --- a/server/lib/traefik/pathEncoding.test.ts +++ b/server/lib/traefik/pathEncoding.test.ts @@ -1,14 +1,30 @@ import { assertEquals } from "../../../test/assert"; -import { encodePath, sanitize } from "./pathUtils"; + +// ── Pure function copies (inlined to avoid pulling in server dependencies) ── + +function sanitize(input: string | null | undefined): string | undefined { + if (!input) return undefined; + if (input.length > 50) { + input = input.substring(0, 50); + } + return input + .replace(/[^a-zA-Z0-9-]/g, "-") + .replace(/-+/g, "-") + .replace(/^-|-$/g, ""); +} + +function encodePath(path: string | null | undefined): string { + if (!path) return ""; + return path.replace(/[^a-zA-Z0-9]/g, (ch) => { + return ch.charCodeAt(0).toString(16); + }); +} // ── Helpers ────────────────────────────────────────────────────────── /** * Exact replica of the OLD key computation from upstream main. - * This is what existing Pangolin deployments use today for both - * map grouping AND Traefik router/service names. - * - * Source: origin/main server/lib/traefik/getTraefikConfig.ts lines 130-146 + * Uses sanitize() for paths — this is what had the collision bug. */ function oldKeyComputation( resourceId: number, @@ -27,11 +43,8 @@ function oldKeyComputation( } /** - * Replica of the NEW dual-key computation from our fix. - * Returns both the internal map key (for grouping) and the - * Traefik-facing key (for router/service names). - * - * Source: our getTraefikConfig.ts lines 135-163 + * Replica of the NEW key computation from our fix. + * Uses encodePath() for paths — collision-free. */ function newKeyComputation( resourceId: number, @@ -39,49 +52,20 @@ function newKeyComputation( pathMatchType: string | null, rewritePath: string | null, rewritePathType: string | null -): { internalMapKey: string; traefikKey: string } { +): string { + const targetPath = encodePath(path); const pmt = pathMatchType || ""; const rp = rewritePath || ""; const rpt = rewritePathType || ""; - - // Internal map key: uses encodePath (collision-free) - const encodedPath = encodePath(path); - const internalPathKey = [encodedPath, pmt, rp, rpt] - .filter(Boolean) - .join("-"); - const internalMapKey = [resourceId, internalPathKey] - .filter(Boolean) - .join("-"); - - // Traefik-facing key: uses sanitize (backward-compatible) - const sanitizedPath = sanitize(path) || ""; - const traefikPathKey = [sanitizedPath, pmt, rp, rpt] - .filter(Boolean) - .join("-"); - const traefikKey = sanitize( - [resourceId, traefikPathKey].filter(Boolean).join("-") - ); - - return { internalMapKey, traefikKey: traefikKey || "" }; -} - -/** - * Build the full Traefik router/service names the way getTraefikConfig does. - */ -function buildTraefikNames(key: string, resourceName: string) { - const name = sanitize(resourceName) || ""; - return { - routerName: `${key}-${name}-router`, - serviceName: `${key}-${name}-service`, - transportName: `${key}-transport`, - headersMiddlewareName: `${key}-headers-middleware` - }; + const pathKey = [targetPath, pmt, rp, rpt].filter(Boolean).join("-"); + const mapKey = [resourceId, pathKey].filter(Boolean).join("-"); + return sanitize(mapKey) || ""; } // ── Tests ──────────────────────────────────────────────────────────── function runTests() { - console.log("Running path encoding & backward compatibility tests...\n"); + console.log("Running path encoding tests...\n"); let passed = 0; @@ -200,267 +184,22 @@ function runTests() { passed++; } - // ── Backward compatibility: Traefik names must match old code ───── - - // Test 8: simple resource, no path — Traefik name unchanged - { - const oldKey = oldKeyComputation(1, null, null, null, null); - const { traefikKey } = newKeyComputation(1, null, null, null, null); - assertEquals( - traefikKey, - oldKey, - "no-path resource: Traefik key must match old" - ); - console.log(" PASS: backward compat — no path resource"); - passed++; - } - - // Test 9: resource with /api prefix — Traefik name unchanged - { - const oldKey = oldKeyComputation(1, "/api", "prefix", null, null); - const { traefikKey } = newKeyComputation( - 1, - "/api", - "prefix", - null, - null - ); - assertEquals( - traefikKey, - oldKey, - "/api prefix: Traefik key must match old" - ); - console.log(" PASS: backward compat — /api prefix"); - passed++; - } - - // Test 10: resource with exact path — Traefik name unchanged - { - const oldKey = oldKeyComputation(5, "/health", "exact", null, null); - const { traefikKey } = newKeyComputation( - 5, - "/health", - "exact", - null, - null - ); - assertEquals( - traefikKey, - oldKey, - "/health exact: Traefik key must match old" - ); - console.log(" PASS: backward compat — /health exact"); - passed++; - } - - // Test 11: resource with regex path — Traefik name unchanged - { - const oldKey = oldKeyComputation( - 3, - "^/api/v[0-9]+", - "regex", - null, - null - ); - const { traefikKey } = newKeyComputation( - 3, - "^/api/v[0-9]+", - "regex", - null, - null - ); - assertEquals( - traefikKey, - oldKey, - "regex path: Traefik key must match old" - ); - console.log(" PASS: backward compat — regex path"); - passed++; - } - - // Test 12: resource with path rewrite — Traefik name unchanged - { - const oldKey = oldKeyComputation( - 10, - "/api", - "prefix", - "/backend", - "prefix" - ); - const { traefikKey } = newKeyComputation( - 10, - "/api", - "prefix", - "/backend", - "prefix" - ); - assertEquals( - traefikKey, - oldKey, - "path rewrite: Traefik key must match old" - ); - console.log(" PASS: backward compat — path rewrite (prefix→prefix)"); - passed++; - } - - // Test 13: resource with stripPrefix rewrite — Traefik name unchanged - { - const oldKey = oldKeyComputation( - 7, - "/app", - "prefix", - null, - "stripPrefix" - ); - const { traefikKey } = newKeyComputation( - 7, - "/app", - "prefix", - null, - "stripPrefix" - ); - assertEquals( - traefikKey, - oldKey, - "stripPrefix: Traefik key must match old" - ); - console.log(" PASS: backward compat — stripPrefix rewrite"); - passed++; - } - - // Test 14: root path "/" — Traefik name unchanged - { - const oldKey = oldKeyComputation(1, "/", "prefix", null, null); - const { traefikKey } = newKeyComputation(1, "/", "prefix", null, null); - assertEquals( - traefikKey, - oldKey, - "root path: Traefik key must match old" - ); - console.log(" PASS: backward compat — root path /"); - passed++; - } - - // Test 15: full Traefik router/service names unchanged for existing users - { - const scenarios = [ - { - rid: 1, - name: "my-webapp", - path: "/api", - pmt: "prefix" as const, - rp: null, - rpt: null - }, - { - rid: 2, - name: "backend", - path: "/", - pmt: "prefix" as const, - rp: null, - rpt: null - }, - { - rid: 3, - name: "docs", - path: "/docs", - pmt: "prefix" as const, - rp: "/", - rpt: "stripPrefix" as const - }, - { - rid: 42, - name: "api-service", - path: null, - pmt: null, - rp: null, - rpt: null - }, - { - rid: 100, - name: "grafana", - path: "/grafana", - pmt: "prefix" as const, - rp: null, - rpt: null - } - ]; - for (const s of scenarios) { - const oldKey = oldKeyComputation(s.rid, s.path, s.pmt, s.rp, s.rpt); - const { traefikKey } = newKeyComputation( - s.rid, - s.path, - s.pmt, - s.rp, - s.rpt - ); - const oldNames = buildTraefikNames(oldKey, s.name); - const newNames = buildTraefikNames(traefikKey, s.name); - assertEquals( - newNames.routerName, - oldNames.routerName, - `router name mismatch for resource ${s.rid} ${s.name} path=${s.path}` - ); - assertEquals( - newNames.serviceName, - oldNames.serviceName, - `service name mismatch for resource ${s.rid} ${s.name} path=${s.path}` - ); - assertEquals( - newNames.transportName, - oldNames.transportName, - `transport name mismatch for resource ${s.rid} ${s.name} path=${s.path}` - ); - } - console.log( - " PASS: backward compat — full router/service/transport names match old code for 5 scenarios" - ); - passed++; - } - - // Test 16: large resourceId — Traefik name unchanged - { - const oldKey = oldKeyComputation( - 99999, - "/dashboard", - "prefix", - null, - null - ); - const { traefikKey } = newKeyComputation( - 99999, - "/dashboard", - "prefix", - null, - null - ); - assertEquals( - traefikKey, - oldKey, - "large resourceId: Traefik key must match old" - ); - console.log(" PASS: backward compat — large resourceId"); - passed++; - } - // ── Collision fix: the actual bug we're fixing ─────────────────── - // Test 17: /a/b and /a-b now have different internal keys (THE BUG FIX) + // Test 8: /a/b and /a-b now have different keys (THE BUG FIX) { - const keysAB = newKeyComputation(1, "/a/b", "prefix", null, null); - const keysDash = newKeyComputation(1, "/a-b", "prefix", null, null); + const keyAB = newKeyComputation(1, "/a/b", "prefix", null, null); + const keyDash = newKeyComputation(1, "/a-b", "prefix", null, null); assertEquals( - keysAB.internalMapKey !== keysDash.internalMapKey, + keyAB !== keyDash, true, - "/a/b and /a-b MUST have different internal map keys" - ); - console.log( - " PASS: collision fix — /a/b vs /a-b have different internal keys" + "/a/b and /a-b MUST have different keys" ); + console.log(" PASS: collision fix — /a/b vs /a-b have different keys"); passed++; } - // Test 18: demonstrate the old bug — old code maps /a/b and /a-b to same key + // Test 9: demonstrate the old bug — old code maps /a/b and /a-b to same key { const oldKeyAB = oldKeyComputation(1, "/a/b", "prefix", null, null); const oldKeyDash = oldKeyComputation(1, "/a-b", "prefix", null, null); @@ -473,7 +212,7 @@ function runTests() { passed++; } - // Test 19: /api/v1 and /api-v1 — old code collision, new code fixes it + // Test 10: /api/v1 and /api-v1 — old code collision, new code fixes it { const oldKey1 = oldKeyComputation(1, "/api/v1", "prefix", null, null); const oldKey2 = oldKeyComputation(1, "/api-v1", "prefix", null, null); @@ -483,10 +222,10 @@ function runTests() { "old code collision for /api/v1 vs /api-v1" ); - const new1 = newKeyComputation(1, "/api/v1", "prefix", null, null); - const new2 = newKeyComputation(1, "/api-v1", "prefix", null, null); + const newKey1 = newKeyComputation(1, "/api/v1", "prefix", null, null); + const newKey2 = newKeyComputation(1, "/api-v1", "prefix", null, null); assertEquals( - new1.internalMapKey !== new2.internalMapKey, + newKey1 !== newKey2, true, "new code must separate /api/v1 and /api-v1" ); @@ -494,20 +233,16 @@ function runTests() { passed++; } - // Test 20: /app.v2 and /app/v2 and /app-v2 — three-way collision fixed + // Test 11: /app.v2 and /app/v2 and /app-v2 — three-way collision fixed { const a = newKeyComputation(1, "/app.v2", "prefix", null, null); const b = newKeyComputation(1, "/app/v2", "prefix", null, null); const c = newKeyComputation(1, "/app-v2", "prefix", null, null); - const keys = new Set([ - a.internalMapKey, - b.internalMapKey, - c.internalMapKey - ]); + const keys = new Set([a, b, c]); assertEquals( keys.size, 3, - "three paths must produce three unique internal keys" + "three paths must produce three unique keys" ); console.log( " PASS: collision fix — three-way /app.v2, /app/v2, /app-v2" @@ -517,38 +252,33 @@ function runTests() { // ── Edge cases ─────────────────────────────────────────────────── - // Test 21: same path in different resources — always separate + // Test 12: same path in different resources — always separate { - const res1 = newKeyComputation(1, "/api", "prefix", null, null); - const res2 = newKeyComputation(2, "/api", "prefix", null, null); + const key1 = newKeyComputation(1, "/api", "prefix", null, null); + const key2 = newKeyComputation(2, "/api", "prefix", null, null); assertEquals( - res1.internalMapKey !== res2.internalMapKey, + key1 !== key2, true, "different resources with same path must have different keys" ); - assertEquals( - res1.traefikKey !== res2.traefikKey, - true, - "different resources with same path must have different Traefik keys" - ); console.log(" PASS: edge case — same path, different resources"); passed++; } - // Test 22: same resource, different pathMatchType — separate keys + // Test 13: same resource, different pathMatchType — separate keys { const exact = newKeyComputation(1, "/api", "exact", null, null); const prefix = newKeyComputation(1, "/api", "prefix", null, null); assertEquals( - exact.internalMapKey !== prefix.internalMapKey, + exact !== prefix, true, - "exact vs prefix must have different internal keys" + "exact vs prefix must have different keys" ); console.log(" PASS: edge case — same path, different match types"); passed++; } - // Test 23: same resource and path, different rewrite config — separate keys + // Test 14: same resource and path, different rewrite config — separate keys { const noRewrite = newKeyComputation(1, "/api", "prefix", null, null); const withRewrite = newKeyComputation( @@ -559,25 +289,22 @@ function runTests() { "prefix" ); assertEquals( - noRewrite.internalMapKey !== withRewrite.internalMapKey, + noRewrite !== withRewrite, true, - "with vs without rewrite must have different internal keys" + "with vs without rewrite must have different keys" ); console.log(" PASS: edge case — same path, different rewrite config"); passed++; } - // Test 24: paths with special URL characters + // Test 15: paths with special URL characters { const paths = ["/api?foo", "/api#bar", "/api%20baz", "/api+qux"]; - const internal = new Set( - paths.map( - (p) => - newKeyComputation(1, p, "prefix", null, null).internalMapKey - ) + const keys = new Set( + paths.map((p) => newKeyComputation(1, p, "prefix", null, null)) ); assertEquals( - internal.size, + keys.size, paths.length, "special URL chars must produce unique keys" ); @@ -585,49 +312,6 @@ function runTests() { passed++; } - // Test 25: very long path (sanitize truncates at 50 chars — verify consistency) - { - const longPath = "/" + "a".repeat(100); - const oldKey = oldKeyComputation(1, longPath, "prefix", null, null); - const { traefikKey } = newKeyComputation( - 1, - longPath, - "prefix", - null, - null - ); - assertEquals( - traefikKey, - oldKey, - "long path: Traefik key must match old (both truncate)" - ); - console.log(" PASS: edge case — very long path (50-char truncation)"); - passed++; - } - - // Test 26: sticky session cookie safety — service name doesn't change - { - // Sticky sessions use cookie name "p_sticky" tied to the service name. - // If service name changes, existing cookies become invalid. - const oldKey = oldKeyComputation(1, "/api", "prefix", null, null); - const { traefikKey } = newKeyComputation( - 1, - "/api", - "prefix", - null, - null - ); - const oldServiceName = `${oldKey}-my-app-service`; - const newServiceName = `${traefikKey}-my-app-service`; - assertEquals( - newServiceName, - oldServiceName, - "service name must not change (would break sticky session cookies)" - ); - console.log(" PASS: sticky session safety — service name preserved"); - passed++; - } - console.log(`\nAll ${passed} tests passed!`); } diff --git a/server/lib/traefik/pathUtils.ts b/server/lib/traefik/pathUtils.ts deleted file mode 100644 index 1b9d57a89..000000000 --- a/server/lib/traefik/pathUtils.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Pure utility functions for path/name encoding. - * No external dependencies — safe to import in tests. - */ - -export function sanitize(input: string | null | undefined): string | undefined { - if (!input) return undefined; - // clean any non alphanumeric characters from the input and replace with dashes - // the input cant be too long either, so limit to 50 characters - if (input.length > 50) { - input = input.substring(0, 50); - } - return input - .replace(/[^a-zA-Z0-9-]/g, "-") - .replace(/-+/g, "-") - .replace(/^-|-$/g, ""); -} - -/** - * Encode a URL path into a collision-free alphanumeric string suitable for use - * in Traefik map keys. - * - * Unlike sanitize(), this preserves uniqueness by encoding each non-alphanumeric - * character as its hex code. Different paths always produce different outputs. - * - * encodePath("/api") => "2fapi" - * encodePath("/a/b") => "2fa2fb" - * encodePath("/a-b") => "2fa2db" (different from /a/b) - * encodePath("/") => "2f" - * encodePath(null) => "" - */ -export function encodePath(path: string | null | undefined): string { - if (!path) return ""; - return path.replace(/[^a-zA-Z0-9]/g, (ch) => { - return ch.charCodeAt(0).toString(16); - }); -} diff --git a/server/lib/traefik/utils.ts b/server/lib/traefik/utils.ts index f40e2eba2..34c293340 100644 --- a/server/lib/traefik/utils.ts +++ b/server/lib/traefik/utils.ts @@ -1,7 +1,37 @@ import logger from "@server/logger"; -// Re-export pure functions from dependency-free module -export { sanitize, encodePath } from "./pathUtils"; +export function sanitize(input: string | null | undefined): string | undefined { + if (!input) return undefined; + // clean any non alphanumeric characters from the input and replace with dashes + // the input cant be too long either, so limit to 50 characters + if (input.length > 50) { + input = input.substring(0, 50); + } + return input + .replace(/[^a-zA-Z0-9-]/g, "-") + .replace(/-+/g, "-") + .replace(/^-|-$/g, ""); +} + +/** + * Encode a URL path into a collision-free alphanumeric string suitable for use + * in Traefik map keys. + * + * Unlike sanitize(), this preserves uniqueness by encoding each non-alphanumeric + * character as its hex code. Different paths always produce different outputs. + * + * encodePath("/api") => "2fapi" + * encodePath("/a/b") => "2fa2fb" + * encodePath("/a-b") => "2fa2db" (different from /a/b) + * encodePath("/") => "2f" + * encodePath(null) => "" + */ +export function encodePath(path: string | null | undefined): string { + if (!path) return ""; + return path.replace(/[^a-zA-Z0-9]/g, (ch) => { + return ch.charCodeAt(0).toString(16); + }); +} export function validatePathRewriteConfig( path: string | null, diff --git a/server/private/lib/traefik/getTraefikConfig.ts b/server/private/lib/traefik/getTraefikConfig.ts index b6c460072..adc3d965b 100644 --- a/server/private/lib/traefik/getTraefikConfig.ts +++ b/server/private/lib/traefik/getTraefikConfig.ts @@ -174,6 +174,7 @@ export async function getTraefikConfig( resourcesWithTargetsAndSites.forEach((row) => { const resourceId = row.resourceId; const resourceName = sanitize(row.resourceName) || ""; + const targetPath = encodePath(row.path); // Use encodePath to avoid collisions (e.g. "/a/b" vs "/a-b") const pathMatchType = row.pathMatchType || ""; const rewritePath = row.rewritePath || ""; const rewritePathType = row.rewritePathType || ""; @@ -183,37 +184,19 @@ export async function getTraefikConfig( return; } - // Use encodePath for the internal map key to avoid collisions - // (e.g. "/a/b" vs "/a-b" must map to different groups) - const encodedPath = encodePath(row.path); - const internalPathKey = [ - encodedPath, + // Create a unique key combining resourceId, path config, and rewrite config + const pathKey = [ + targetPath, pathMatchType, rewritePath, rewritePathType ] .filter(Boolean) .join("-"); - const internalMapKey = [resourceId, internalPathKey] - .filter(Boolean) - .join("-"); + const mapKey = [resourceId, pathKey].filter(Boolean).join("-"); + const key = sanitize(mapKey); - // Use sanitize for the Traefik-facing key to preserve backward-compatible - // router/service names (existing sticky session cookies, etc.) - const sanitizedPath = sanitize(row.path) || ""; - const traefikPathKey = [ - sanitizedPath, - pathMatchType, - rewritePath, - rewritePathType - ] - .filter(Boolean) - .join("-"); - const traefikKey = sanitize( - [resourceId, traefikPathKey].filter(Boolean).join("-") - ); - - if (!resourcesMap.has(internalMapKey)) { + if (!resourcesMap.has(mapKey)) { const validation = validatePathRewriteConfig( row.path, row.pathMatchType, @@ -228,10 +211,10 @@ export async function getTraefikConfig( return; } - resourcesMap.set(internalMapKey, { + resourcesMap.set(mapKey, { resourceId: row.resourceId, name: resourceName, - traefikKey: traefikKey, // backward-compatible key for Traefik names + key: key, fullDomain: row.fullDomain, ssl: row.ssl, http: row.http, @@ -265,7 +248,7 @@ export async function getTraefikConfig( } // Add target with its associated site data - resourcesMap.get(internalMapKey).targets.push({ + resourcesMap.get(mapKey).targets.push({ resourceId: row.resourceId, targetId: row.targetId, ip: row.ip, @@ -320,7 +303,7 @@ export async function getTraefikConfig( // get the key and the resource for (const [, resource] of resourcesMap.entries()) { const targets = resource.targets as TargetWithSite[]; - const key = resource.traefikKey; // backward-compatible key for Traefik names + const key = resource.key; const routerName = `${key}-${resource.name}-router`; const serviceName = `${key}-${resource.name}-service`; From 94353aea44ccf72c05e49b7f47813afaf06964be Mon Sep 17 00:00:00 2001 From: ChanningHe Date: Sun, 8 Feb 2026 12:19:51 +0900 Subject: [PATCH 05/46] feat(integration): add domain CRUD endpoints to integration API --- messages/en-US.json | 6 ++ server/middlewares/integration/index.ts | 1 + .../integration/verifyApiKeyDomainAccess.ts | 90 +++++++++++++++++++ server/routers/integration.ts | 53 ++++++++++- src/components/PermissionsSelectBox.tsx | 11 ++- 5 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 server/middlewares/integration/verifyApiKeyDomainAccess.ts diff --git a/messages/en-US.json b/messages/en-US.json index f6a9f2f24..1f868601c 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -1102,6 +1102,12 @@ "actionGetUser": "Get User", "actionGetOrgUser": "Get Organization User", "actionListOrgDomains": "List Organization Domains", + "actionGetDomain": "Get Domain", + "actionCreateOrgDomain": "Create Domain", + "actionUpdateOrgDomain": "Update Domain", + "actionDeleteOrgDomain": "Delete Domain", + "actionGetDNSRecords": "Get DNS Records", + "actionRestartOrgDomain": "Restart Domain", "actionCreateSite": "Create Site", "actionDeleteSite": "Delete Site", "actionGetSite": "Get Site", diff --git a/server/middlewares/integration/index.ts b/server/middlewares/integration/index.ts index 565751913..df186c1c8 100644 --- a/server/middlewares/integration/index.ts +++ b/server/middlewares/integration/index.ts @@ -14,3 +14,4 @@ export * from "./verifyApiKeyApiKeyAccess"; export * from "./verifyApiKeyClientAccess"; export * from "./verifyApiKeySiteResourceAccess"; export * from "./verifyApiKeyIdpAccess"; +export * from "./verifyApiKeyDomainAccess"; diff --git a/server/middlewares/integration/verifyApiKeyDomainAccess.ts b/server/middlewares/integration/verifyApiKeyDomainAccess.ts new file mode 100644 index 000000000..db0f5d95d --- /dev/null +++ b/server/middlewares/integration/verifyApiKeyDomainAccess.ts @@ -0,0 +1,90 @@ +import { Request, Response, NextFunction } from "express"; +import { db, domains, orgDomains, apiKeyOrg } from "@server/db"; +import { and, eq } from "drizzle-orm"; +import createHttpError from "http-errors"; +import HttpCode from "@server/types/HttpCode"; + +export async function verifyApiKeyDomainAccess( + req: Request, + res: Response, + next: NextFunction +) { + try { + const apiKey = req.apiKey; + const domainId = + req.params.domainId || req.body.domainId || req.query.domainId; + const orgId = req.params.orgId; + + if (!apiKey) { + return next( + createHttpError(HttpCode.UNAUTHORIZED, "Key not authenticated") + ); + } + + if (!domainId) { + return next( + createHttpError(HttpCode.BAD_REQUEST, "Invalid domain ID") + ); + } + + if (apiKey.isRoot) { + // Root keys can access any domain in any org + return next(); + } + + // Verify domain exists and belongs to the organization + const [domain] = await db + .select() + .from(domains) + .innerJoin(orgDomains, eq(orgDomains.domainId, domains.domainId)) + .where( + and( + eq(orgDomains.domainId, domainId), + eq(orgDomains.orgId, orgId) + ) + ) + .limit(1); + + if (!domain) { + return next( + createHttpError( + HttpCode.NOT_FOUND, + `Domain with ID ${domainId} not found in organization ${orgId}` + ) + ); + } + + // Verify the API key has access to this organization + if (!req.apiKeyOrg) { + const apiKeyOrgRes = await db + .select() + .from(apiKeyOrg) + .where( + and( + eq(apiKeyOrg.apiKeyId, apiKey.apiKeyId), + eq(apiKeyOrg.orgId, orgId) + ) + ) + .limit(1); + req.apiKeyOrg = apiKeyOrgRes[0]; + } + + if (!req.apiKeyOrg) { + return next( + createHttpError( + HttpCode.FORBIDDEN, + "Key does not have access to this organization" + ) + ); + } + + return next(); + } catch (error) { + return next( + createHttpError( + HttpCode.INTERNAL_SERVER_ERROR, + "Error verifying domain access" + ) + ); + } +} diff --git a/server/routers/integration.ts b/server/routers/integration.ts index 7272d740d..a36a61e84 100644 --- a/server/routers/integration.ts +++ b/server/routers/integration.ts @@ -27,7 +27,8 @@ import { verifyApiKeyClientAccess, verifyApiKeySiteResourceAccess, verifyApiKeySetResourceClients, - verifyLimits + verifyLimits, + verifyApiKeyDomainAccess } from "@server/middlewares"; import HttpCode from "@server/types/HttpCode"; import { Router } from "express"; @@ -347,6 +348,56 @@ authenticated.get( domain.listDomains ); +authenticated.get( + "/org/:orgId/domain/:domainId", + verifyApiKeyOrgAccess, + verifyApiKeyDomainAccess, + verifyApiKeyHasAction(ActionsEnum.getDomain), + domain.getDomain +); + +authenticated.put( + "/org/:orgId/domain", + verifyApiKeyOrgAccess, + verifyApiKeyHasAction(ActionsEnum.createOrgDomain), + logActionAudit(ActionsEnum.createOrgDomain), + domain.createOrgDomain +); + +authenticated.patch( + "/org/:orgId/domain/:domainId", + verifyApiKeyOrgAccess, + verifyApiKeyDomainAccess, + verifyApiKeyHasAction(ActionsEnum.updateOrgDomain), + domain.updateOrgDomain +); + +authenticated.delete( + "/org/:orgId/domain/:domainId", + verifyApiKeyOrgAccess, + verifyApiKeyDomainAccess, + verifyApiKeyHasAction(ActionsEnum.deleteOrgDomain), + logActionAudit(ActionsEnum.deleteOrgDomain), + domain.deleteAccountDomain +); + +authenticated.get( + "/org/:orgId/domain/:domainId/dns-records", + verifyApiKeyOrgAccess, + verifyApiKeyDomainAccess, + verifyApiKeyHasAction(ActionsEnum.getDNSRecords), + domain.getDNSRecords +); + +authenticated.post( + "/org/:orgId/domain/:domainId/restart", + verifyApiKeyOrgAccess, + verifyApiKeyDomainAccess, + verifyApiKeyHasAction(ActionsEnum.restartOrgDomain), + logActionAudit(ActionsEnum.restartOrgDomain), + domain.restartOrgDomain +); + authenticated.get( "/org/:orgId/invitations", verifyApiKeyOrgAccess, diff --git a/src/components/PermissionsSelectBox.tsx b/src/components/PermissionsSelectBox.tsx index b11c635a6..7536ecdcf 100644 --- a/src/components/PermissionsSelectBox.tsx +++ b/src/components/PermissionsSelectBox.tsx @@ -31,7 +31,6 @@ function getActionsCategories(root: boolean) { [t("actionListInvitations")]: "listInvitations", [t("actionRemoveUser")]: "removeUser", [t("actionListUsers")]: "listUsers", - [t("actionListOrgDomains")]: "listOrgDomains", [t("updateOrgUser")]: "updateOrgUser", [t("createOrgUser")]: "createOrgUser", [t("actionApplyBlueprint")]: "applyBlueprint", @@ -39,6 +38,16 @@ function getActionsCategories(root: boolean) { [t("actionGetBlueprint")]: "getBlueprint" }, + Domain: { + [t("actionListOrgDomains")]: "listOrgDomains", + [t("actionGetDomain")]: "getDomain", + [t("actionCreateOrgDomain")]: "createOrgDomain", + [t("actionUpdateOrgDomain")]: "updateOrgDomain", + [t("actionDeleteOrgDomain")]: "deleteOrgDomain", + [t("actionGetDNSRecords")]: "getDNSRecords", + [t("actionRestartOrgDomain")]: "restartOrgDomain" + }, + Site: { [t("actionCreateSite")]: "createSite", [t("actionDeleteSite")]: "deleteSite", From f6ee9db73001bfa345db3d09248c4f95b50ea806 Mon Sep 17 00:00:00 2001 From: Laurence Date: Thu, 26 Feb 2026 15:45:41 +0000 Subject: [PATCH 06/46] enhance(sidebar): make mobile org selector sticky Make org selector sticky on mobile sidebar Move OrgSelector outside the scrollable container so it stays fixed at the top while menu items scroll, matching the desktop sidebar behavior introduced in 9b2c0d0b. --- src/components/LayoutMobileMenu.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/LayoutMobileMenu.tsx b/src/components/LayoutMobileMenu.tsx index b661d780a..c453be72f 100644 --- a/src/components/LayoutMobileMenu.tsx +++ b/src/components/LayoutMobileMenu.tsx @@ -69,14 +69,14 @@ export function LayoutMobileMenu({ {t("navbarDescription")} +
+ +
+
-
- -
-
{!isAdminPage && user.serverAdmin && ( From d14de86f651c9a0920fcd2e261da83180e9356cf Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Sun, 1 Mar 2026 11:13:49 -0800 Subject: [PATCH 07/46] fix org selector spacing on mobile --- src/components/LayoutMobileMenu.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/LayoutMobileMenu.tsx b/src/components/LayoutMobileMenu.tsx index c453be72f..e1c883a2b 100644 --- a/src/components/LayoutMobileMenu.tsx +++ b/src/components/LayoutMobileMenu.tsx @@ -69,15 +69,16 @@ export function LayoutMobileMenu({ {t("navbarDescription")} -
- +
+
+ +
-
-
+
{!isAdminPage && user.serverAdmin && (
From c9515ae77ce5a61fcfd57498629ae76d5f83d7eb Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 2 Mar 2026 16:28:01 -0800 Subject: [PATCH 08/46] Add comment about not needing exit node --- server/routers/site/createSite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/routers/site/createSite.ts b/server/routers/site/createSite.ts index ea4bc3e85..acfd044c2 100644 --- a/server/routers/site/createSite.ts +++ b/server/routers/site/createSite.ts @@ -292,7 +292,7 @@ export async function createSite( if (type == "newt") { [newSite] = await trx .insert(sites) - .values({ + .values({ // NOTE: NO SUBNET OR EXIT NODE ID PASSED IN HERE BECAUSE ITS NOW CHOSEN ON CONNECT orgId, name, niceId, From 4cab693cfc5ac6daf8130f8ec99a392aeeea1db1 Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Mon, 2 Mar 2026 21:59:20 -0800 Subject: [PATCH 09/46] openapi and swagger ui improvements and cleanup --- server/integrationApiServer.ts | 93 ++++++++++++++++--- server/openApi.ts | 13 ++- .../routers/auditLogs/exportAccessAuditLog.ts | 2 +- .../routers/auditLogs/exportActionAuditLog.ts | 2 +- .../routers/auditLogs/queryAccessAuditLog.ts | 2 +- .../routers/auditLogs/queryActionAuditLog.ts | 2 +- server/private/routers/billing/getOrgUsage.ts | 20 ++-- .../routers/orgIdp/createOrgOidcIdp.ts | 2 +- server/private/routers/orgIdp/deleteOrgIdp.ts | 2 +- server/private/routers/orgIdp/getOrgIdp.ts | 4 +- server/private/routers/orgIdp/listOrgIdps.ts | 2 +- .../routers/orgIdp/updateOrgOidcIdp.ts | 2 +- .../routers/resource/getMaintenanceInfo.ts | 2 +- .../accessToken/generateAccessToken.ts | 2 +- .../routers/accessToken/listAccessTokens.ts | 6 +- server/routers/apiKeys/createOrgApiKey.ts | 2 +- server/routers/apiKeys/deleteApiKey.ts | 2 +- server/routers/apiKeys/listApiKeyActions.ts | 2 +- server/routers/apiKeys/listOrgApiKeys.ts | 2 +- server/routers/apiKeys/setApiKeyActions.ts | 2 +- .../auditLogs/exportRequestAuditLog.ts | 2 +- .../auditLogs/queryRequestAnalytics.ts | 2 +- .../routers/auditLogs/queryRequestAuditLog.ts | 2 +- .../routers/blueprints/applyJSONBlueprint.ts | 2 +- .../routers/blueprints/applyYAMLBlueprint.ts | 2 +- server/routers/blueprints/getBlueprint.ts | 2 +- server/routers/blueprints/listBlueprints.ts | 2 +- server/routers/client/createClient.ts | 2 +- server/routers/client/createUserClient.ts | 2 +- server/routers/client/getClient.ts | 2 +- server/routers/client/listClients.ts | 2 +- server/routers/client/listUserDevices.ts | 2 +- server/routers/client/pickClientDefaults.ts | 2 +- server/routers/domain/listDomains.ts | 2 +- server/routers/idp/createIdpOrgPolicy.ts | 2 +- server/routers/idp/createOidcIdp.ts | 2 +- server/routers/idp/deleteIdp.ts | 2 +- server/routers/idp/deleteIdpOrgPolicy.ts | 2 +- server/routers/idp/getIdp.ts | 2 +- server/routers/idp/listIdpOrgPolicies.ts | 2 +- server/routers/idp/listIdps.ts | 2 +- server/routers/idp/updateIdpOrgPolicy.ts | 2 +- server/routers/idp/updateOidcIdp.ts | 2 +- .../resource/addEmailToResourceWhitelist.ts | 2 +- server/routers/resource/addRoleToResource.ts | 2 +- server/routers/resource/addUserToResource.ts | 2 +- server/routers/resource/createResource.ts | 2 +- server/routers/resource/createResourceRule.ts | 2 +- server/routers/resource/deleteResource.ts | 2 +- server/routers/resource/deleteResourceRule.ts | 2 +- server/routers/resource/getResource.ts | 4 +- .../routers/resource/getResourceWhitelist.ts | 2 +- .../routers/resource/listAllResourceNames.ts | 2 +- server/routers/resource/listResourceRoles.ts | 2 +- server/routers/resource/listResourceRules.ts | 2 +- server/routers/resource/listResourceUsers.ts | 2 +- server/routers/resource/listResources.ts | 2 +- .../removeEmailFromResourceWhitelist.ts | 2 +- .../resource/removeRoleFromResource.ts | 2 +- .../resource/removeUserFromResource.ts | 2 +- .../routers/resource/setResourceHeaderAuth.ts | 2 +- .../routers/resource/setResourcePassword.ts | 2 +- server/routers/resource/setResourcePincode.ts | 2 +- server/routers/resource/setResourceRoles.ts | 2 +- server/routers/resource/setResourceUsers.ts | 2 +- .../routers/resource/setResourceWhitelist.ts | 2 +- server/routers/resource/updateResource.ts | 2 +- server/routers/resource/updateResourceRule.ts | 2 +- server/routers/role/createRole.ts | 2 +- server/routers/role/listRoles.ts | 4 +- server/routers/site/createSite.ts | 2 +- server/routers/site/getSite.ts | 2 +- server/routers/site/listSites.ts | 2 +- server/routers/site/pickSiteDefaults.ts | 2 +- .../siteResource/addClientToSiteResource.ts | 2 +- .../siteResource/addRoleToSiteResource.ts | 2 +- .../siteResource/addUserToSiteResource.ts | 2 +- .../siteResource/createSiteResource.ts | 2 +- .../siteResource/deleteSiteResource.ts | 2 +- .../routers/siteResource/getSiteResource.ts | 4 +- .../siteResource/listAllSiteResourcesByOrg.ts | 2 +- .../siteResource/listSiteResourceClients.ts | 2 +- .../siteResource/listSiteResourceRoles.ts | 2 +- .../siteResource/listSiteResourceUsers.ts | 2 +- .../routers/siteResource/listSiteResources.ts | 2 +- .../removeClientFromSiteResource.ts | 2 +- .../removeRoleFromSiteResource.ts | 2 +- .../removeUserFromSiteResource.ts | 2 +- .../siteResource/setSiteResourceClients.ts | 2 +- .../siteResource/setSiteResourceRoles.ts | 2 +- .../siteResource/setSiteResourceUsers.ts | 2 +- .../siteResource/updateSiteResource.ts | 2 +- server/routers/target/createTarget.ts | 2 +- server/routers/target/listTargets.ts | 2 +- server/routers/user/createOrgUser.ts | 2 +- server/routers/user/getOrgUser.ts | 2 +- server/routers/user/getOrgUserByUsername.ts | 2 +- server/routers/user/inviteUser.ts | 2 +- server/routers/user/listInvitations.ts | 2 +- server/routers/user/listUsers.ts | 2 +- server/routers/user/removeInvitation.ts | 2 +- server/routers/user/removeUserOrg.ts | 2 +- server/routers/user/updateOrgUser.ts | 2 +- 103 files changed, 206 insertions(+), 132 deletions(-) diff --git a/server/integrationApiServer.ts b/server/integrationApiServer.ts index 6d513cf6b..ce029d9b5 100644 --- a/server/integrationApiServer.ts +++ b/server/integrationApiServer.ts @@ -17,6 +17,7 @@ import fs from "fs"; import path from "path"; import { APP_PATH } from "./lib/consts"; import yaml from "js-yaml"; +import { z } from "zod"; const dev = process.env.ENVIRONMENT !== "prod"; const externalPort = config.getRawConfig().server.integration_port; @@ -38,12 +39,24 @@ export function createIntegrationApiServer() { apiServer.use(cookieParser()); apiServer.use(express.json()); + const openApiDocumentation = getOpenApiDocumentation(); + apiServer.use( "/v1/docs", swaggerUi.serve, - swaggerUi.setup(getOpenApiDocumentation()) + swaggerUi.setup(openApiDocumentation) ); + // Unauthenticated OpenAPI spec endpoints + apiServer.get("/v1/openapi.json", (_req, res) => { + res.json(openApiDocumentation); + }); + + apiServer.get("/v1/openapi.yaml", (_req, res) => { + const yamlOutput = yaml.dump(openApiDocumentation); + res.type("application/yaml").send(yamlOutput); + }); + // API routes const prefix = `/v1`; apiServer.use(logIncomingMiddleware); @@ -75,16 +88,6 @@ function getOpenApiDocumentation() { } ); - for (const def of registry.definitions) { - if (def.type === "route") { - def.route.security = [ - { - [bearerAuth.name]: [] - } - ]; - } - } - registry.registerPath({ method: "get", path: "/", @@ -94,6 +97,74 @@ function getOpenApiDocumentation() { responses: {} }); + registry.registerPath({ + method: "get", + path: "/openapi.json", + description: "Get OpenAPI specification as JSON", + tags: [], + request: {}, + responses: { + "200": { + description: "OpenAPI specification as JSON", + content: { + "application/json": { + schema: { + type: "object" + } + } + } + } + } + }); + + registry.registerPath({ + method: "get", + path: "/openapi.yaml", + description: "Get OpenAPI specification as YAML", + tags: [], + request: {}, + responses: { + "200": { + description: "OpenAPI specification as YAML", + content: { + "application/yaml": { + schema: { + type: "string" + } + } + } + } + } + }); + + for (const def of registry.definitions) { + if (def.type === "route") { + def.route.security = [ + { + [bearerAuth.name]: [] + } + ]; + + // Ensure every route has a generic JSON response schema so Swagger UI can render responses + const existingResponses = def.route.responses; + const hasExistingResponses = + existingResponses && Object.keys(existingResponses).length > 0; + + if (!hasExistingResponses) { + def.route.responses = { + "*": { + description: "", + content: { + "application/json": { + schema: z.object({}) + } + } + } + }; + } + } + } + const generator = new OpenApiGeneratorV3(registry.definitions); const generated = generator.generateDocument({ diff --git a/server/openApi.ts b/server/openApi.ts index 886265682..26c9e2f2e 100644 --- a/server/openApi.ts +++ b/server/openApi.ts @@ -5,17 +5,20 @@ export const registry = new OpenAPIRegistry(); export enum OpenAPITags { Site = "Site", Org = "Organization", - Resource = "Resource", + PublicResource = "Public Resource", + PrivateResource = "Private Resource", Role = "Role", User = "User", - Invitation = "Invitation", - Target = "Target", + Invitation = "User Invitation", + Target = "Resource Target", Rule = "Rule", AccessToken = "Access Token", - Idp = "Identity Provider", + GlobalIdp = "Identity Provider (Global)", + OrgIdp = "Identity Provider (Organization Only)", Client = "Client", ApiKey = "API Key", Domain = "Domain", Blueprint = "Blueprint", - Ssh = "SSH" + Ssh = "SSH", + Logs = "Logs" } diff --git a/server/private/routers/auditLogs/exportAccessAuditLog.ts b/server/private/routers/auditLogs/exportAccessAuditLog.ts index 7e912f8c8..68a78ff6e 100644 --- a/server/private/routers/auditLogs/exportAccessAuditLog.ts +++ b/server/private/routers/auditLogs/exportAccessAuditLog.ts @@ -32,7 +32,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/logs/access/export", description: "Export the access audit log for an organization as CSV", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Logs], request: { query: queryAccessAuditLogsQuery, params: queryAccessAuditLogsParams diff --git a/server/private/routers/auditLogs/exportActionAuditLog.ts b/server/private/routers/auditLogs/exportActionAuditLog.ts index d8987916b..853183b92 100644 --- a/server/private/routers/auditLogs/exportActionAuditLog.ts +++ b/server/private/routers/auditLogs/exportActionAuditLog.ts @@ -32,7 +32,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/logs/action/export", description: "Export the action audit log for an organization as CSV", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Logs], request: { query: queryActionAuditLogsQuery, params: queryActionAuditLogsParams diff --git a/server/private/routers/auditLogs/queryAccessAuditLog.ts b/server/private/routers/auditLogs/queryAccessAuditLog.ts index 7830dd9dc..f0f45a826 100644 --- a/server/private/routers/auditLogs/queryAccessAuditLog.ts +++ b/server/private/routers/auditLogs/queryAccessAuditLog.ts @@ -249,7 +249,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/logs/access", description: "Query the access audit log for an organization", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Logs], request: { query: queryAccessAuditLogsQuery, params: queryAccessAuditLogsParams diff --git a/server/private/routers/auditLogs/queryActionAuditLog.ts b/server/private/routers/auditLogs/queryActionAuditLog.ts index bd636dee2..8bbe73ee1 100644 --- a/server/private/routers/auditLogs/queryActionAuditLog.ts +++ b/server/private/routers/auditLogs/queryActionAuditLog.ts @@ -160,7 +160,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/logs/action", description: "Query the action audit log for an organization", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Logs], request: { query: queryActionAuditLogsQuery, params: queryActionAuditLogsParams diff --git a/server/private/routers/billing/getOrgUsage.ts b/server/private/routers/billing/getOrgUsage.ts index 4c9f22f3d..cc722cec8 100644 --- a/server/private/routers/billing/getOrgUsage.ts +++ b/server/private/routers/billing/getOrgUsage.ts @@ -31,16 +31,16 @@ const getOrgSchema = z.strictObject({ orgId: z.string() }); -registry.registerPath({ - method: "get", - path: "/org/{orgId}/billing/usage", - description: "Get an organization's billing usage", - tags: [OpenAPITags.Org], - request: { - params: getOrgSchema - }, - responses: {} -}); +// registry.registerPath({ +// method: "get", +// path: "/org/{orgId}/billing/usage", +// description: "Get an organization's billing usage", +// tags: [OpenAPITags.Org], +// request: { +// params: getOrgSchema +// }, +// responses: {} +// }); export async function getOrgUsage( req: Request, diff --git a/server/private/routers/orgIdp/createOrgOidcIdp.ts b/server/private/routers/orgIdp/createOrgOidcIdp.ts index 725e93c72..cc17d7cfc 100644 --- a/server/private/routers/orgIdp/createOrgOidcIdp.ts +++ b/server/private/routers/orgIdp/createOrgOidcIdp.ts @@ -52,7 +52,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/idp/oidc", description: "Create an OIDC IdP for a specific organization.", - tags: [OpenAPITags.Idp, OpenAPITags.Org], + tags: [OpenAPITags.OrgIdp], request: { params: paramsSchema, body: { diff --git a/server/private/routers/orgIdp/deleteOrgIdp.ts b/server/private/routers/orgIdp/deleteOrgIdp.ts index 2d6b0899b..7d201dd17 100644 --- a/server/private/routers/orgIdp/deleteOrgIdp.ts +++ b/server/private/routers/orgIdp/deleteOrgIdp.ts @@ -35,7 +35,7 @@ registry.registerPath({ method: "delete", path: "/org/{orgId}/idp/{idpId}", description: "Delete IDP for a specific organization.", - tags: [OpenAPITags.Idp, OpenAPITags.Org], + tags: [OpenAPITags.OrgIdp], request: { params: paramsSchema }, diff --git a/server/private/routers/orgIdp/getOrgIdp.ts b/server/private/routers/orgIdp/getOrgIdp.ts index dd987c443..6941fc0fc 100644 --- a/server/private/routers/orgIdp/getOrgIdp.ts +++ b/server/private/routers/orgIdp/getOrgIdp.ts @@ -50,9 +50,9 @@ async function query(idpId: number, orgId: string) { registry.registerPath({ method: "get", - path: "/org/:orgId/idp/:idpId", + path: "/org/{orgId}/idp/{idpId}", description: "Get an IDP by its IDP ID for a specific organization.", - tags: [OpenAPITags.Idp, OpenAPITags.Org], + tags: [OpenAPITags.OrgIdp], request: { params: paramsSchema }, diff --git a/server/private/routers/orgIdp/listOrgIdps.ts b/server/private/routers/orgIdp/listOrgIdps.ts index b6cf48ac0..fed8a0aab 100644 --- a/server/private/routers/orgIdp/listOrgIdps.ts +++ b/server/private/routers/orgIdp/listOrgIdps.ts @@ -67,7 +67,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/idp", description: "List all IDP for a specific organization.", - tags: [OpenAPITags.Idp, OpenAPITags.Org], + tags: [OpenAPITags.OrgIdp], request: { query: querySchema, params: paramsSchema diff --git a/server/private/routers/orgIdp/updateOrgOidcIdp.ts b/server/private/routers/orgIdp/updateOrgOidcIdp.ts index b8ee4dcb0..191f49068 100644 --- a/server/private/routers/orgIdp/updateOrgOidcIdp.ts +++ b/server/private/routers/orgIdp/updateOrgOidcIdp.ts @@ -59,7 +59,7 @@ registry.registerPath({ method: "post", path: "/org/{orgId}/idp/{idpId}/oidc", description: "Update an OIDC IdP for a specific organization.", - tags: [OpenAPITags.Idp, OpenAPITags.Org], + tags: [OpenAPITags.OrgIdp], request: { params: paramsSchema, body: { diff --git a/server/private/routers/resource/getMaintenanceInfo.ts b/server/private/routers/resource/getMaintenanceInfo.ts index cbba25194..e3e739c6e 100644 --- a/server/private/routers/resource/getMaintenanceInfo.ts +++ b/server/private/routers/resource/getMaintenanceInfo.ts @@ -52,7 +52,7 @@ registry.registerPath({ method: "get", path: "/maintenance/info", description: "Get maintenance information for a resource by domain.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { query: z.object({ fullDomain: z.string() diff --git a/server/routers/accessToken/generateAccessToken.ts b/server/routers/accessToken/generateAccessToken.ts index 35da6add3..9d0a7a7df 100644 --- a/server/routers/accessToken/generateAccessToken.ts +++ b/server/routers/accessToken/generateAccessToken.ts @@ -43,7 +43,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}/access-token", description: "Generate a new access token for a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.AccessToken], + tags: [OpenAPITags.PublicResource, OpenAPITags.AccessToken], request: { params: generateAccssTokenParamsSchema, body: { diff --git a/server/routers/accessToken/listAccessTokens.ts b/server/routers/accessToken/listAccessTokens.ts index 2f929fc62..9f8747190 100644 --- a/server/routers/accessToken/listAccessTokens.ts +++ b/server/routers/accessToken/listAccessTokens.ts @@ -122,7 +122,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/access-tokens", description: "List all access tokens in an organization.", - tags: [OpenAPITags.Org, OpenAPITags.AccessToken], + tags: [OpenAPITags.AccessToken], request: { params: z.object({ orgId: z.string() @@ -135,8 +135,8 @@ registry.registerPath({ registry.registerPath({ method: "get", path: "/resource/{resourceId}/access-tokens", - description: "List all access tokens in an organization.", - tags: [OpenAPITags.Resource, OpenAPITags.AccessToken], + description: "List all access tokens for a resource.", + tags: [OpenAPITags.PublicResource, OpenAPITags.AccessToken], request: { params: z.object({ resourceId: z.number() diff --git a/server/routers/apiKeys/createOrgApiKey.ts b/server/routers/apiKeys/createOrgApiKey.ts index d61a364b1..91ef72bc8 100644 --- a/server/routers/apiKeys/createOrgApiKey.ts +++ b/server/routers/apiKeys/createOrgApiKey.ts @@ -37,7 +37,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/api-key", description: "Create a new API key scoped to the organization.", - tags: [OpenAPITags.Org, OpenAPITags.ApiKey], + tags: [OpenAPITags.ApiKey], request: { params: paramsSchema, body: { diff --git a/server/routers/apiKeys/deleteApiKey.ts b/server/routers/apiKeys/deleteApiKey.ts index 4b97b3530..2627fd636 100644 --- a/server/routers/apiKeys/deleteApiKey.ts +++ b/server/routers/apiKeys/deleteApiKey.ts @@ -18,7 +18,7 @@ registry.registerPath({ method: "delete", path: "/org/{orgId}/api-key/{apiKeyId}", description: "Delete an API key.", - tags: [OpenAPITags.Org, OpenAPITags.ApiKey], + tags: [OpenAPITags.ApiKey], request: { params: paramsSchema }, diff --git a/server/routers/apiKeys/listApiKeyActions.ts b/server/routers/apiKeys/listApiKeyActions.ts index 073a75831..d816d4b38 100644 --- a/server/routers/apiKeys/listApiKeyActions.ts +++ b/server/routers/apiKeys/listApiKeyActions.ts @@ -48,7 +48,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/api-key/{apiKeyId}/actions", description: "List all actions set for an API key.", - tags: [OpenAPITags.Org, OpenAPITags.ApiKey], + tags: [OpenAPITags.ApiKey], request: { params: paramsSchema, query: querySchema diff --git a/server/routers/apiKeys/listOrgApiKeys.ts b/server/routers/apiKeys/listOrgApiKeys.ts index 53191ba63..24370665d 100644 --- a/server/routers/apiKeys/listOrgApiKeys.ts +++ b/server/routers/apiKeys/listOrgApiKeys.ts @@ -52,7 +52,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/api-keys", description: "List all API keys for an organization", - tags: [OpenAPITags.Org, OpenAPITags.ApiKey], + tags: [OpenAPITags.ApiKey], request: { params: paramsSchema, query: querySchema diff --git a/server/routers/apiKeys/setApiKeyActions.ts b/server/routers/apiKeys/setApiKeyActions.ts index 629673886..55b3670ac 100644 --- a/server/routers/apiKeys/setApiKeyActions.ts +++ b/server/routers/apiKeys/setApiKeyActions.ts @@ -25,7 +25,7 @@ registry.registerPath({ path: "/org/{orgId}/api-key/{apiKeyId}/actions", description: "Set actions for an API key. This will replace any existing actions.", - tags: [OpenAPITags.Org, OpenAPITags.ApiKey], + tags: [OpenAPITags.ApiKey], request: { params: paramsSchema, body: { diff --git a/server/routers/auditLogs/exportRequestAuditLog.ts b/server/routers/auditLogs/exportRequestAuditLog.ts index 8b70ec5e1..14054a5c3 100644 --- a/server/routers/auditLogs/exportRequestAuditLog.ts +++ b/server/routers/auditLogs/exportRequestAuditLog.ts @@ -20,7 +20,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/logs/request", description: "Query the request audit log for an organization", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Logs], request: { query: queryAccessAuditLogsQuery.omit({ limit: true, diff --git a/server/routers/auditLogs/queryRequestAnalytics.ts b/server/routers/auditLogs/queryRequestAnalytics.ts index e838c5f56..1e0f1f401 100644 --- a/server/routers/auditLogs/queryRequestAnalytics.ts +++ b/server/routers/auditLogs/queryRequestAnalytics.ts @@ -151,7 +151,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/logs/analytics", description: "Query the request audit analytics for an organization", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Logs], request: { query: queryAccessAuditLogsQuery, params: queryRequestAuditLogsParams diff --git a/server/routers/auditLogs/queryRequestAuditLog.ts b/server/routers/auditLogs/queryRequestAuditLog.ts index 3b598e030..176a9e5d3 100644 --- a/server/routers/auditLogs/queryRequestAuditLog.ts +++ b/server/routers/auditLogs/queryRequestAuditLog.ts @@ -182,7 +182,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/logs/request", description: "Query the request audit log for an organization", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Logs], request: { query: queryAccessAuditLogsQuery, params: queryRequestAuditLogsParams diff --git a/server/routers/blueprints/applyJSONBlueprint.ts b/server/routers/blueprints/applyJSONBlueprint.ts index 7eee15bf1..fa7ed46ae 100644 --- a/server/routers/blueprints/applyJSONBlueprint.ts +++ b/server/routers/blueprints/applyJSONBlueprint.ts @@ -20,7 +20,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/blueprint", description: "Apply a base64 encoded JSON blueprint to an organization", - tags: [OpenAPITags.Org, OpenAPITags.Blueprint], + tags: [OpenAPITags.Blueprint], request: { params: applyBlueprintParamsSchema, body: { diff --git a/server/routers/blueprints/applyYAMLBlueprint.ts b/server/routers/blueprints/applyYAMLBlueprint.ts index 19751e469..665943edd 100644 --- a/server/routers/blueprints/applyYAMLBlueprint.ts +++ b/server/routers/blueprints/applyYAMLBlueprint.ts @@ -43,7 +43,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/blueprint", description: "Create and apply a YAML blueprint to an organization", - tags: [OpenAPITags.Org, OpenAPITags.Blueprint], + tags: [OpenAPITags.Blueprint], request: { params: applyBlueprintParamsSchema, body: { diff --git a/server/routers/blueprints/getBlueprint.ts b/server/routers/blueprints/getBlueprint.ts index 915e04814..ea2ac2d05 100644 --- a/server/routers/blueprints/getBlueprint.ts +++ b/server/routers/blueprints/getBlueprint.ts @@ -53,7 +53,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/blueprint/{blueprintId}", description: "Get a blueprint by its blueprint ID.", - tags: [OpenAPITags.Org, OpenAPITags.Blueprint], + tags: [OpenAPITags.Blueprint], request: { params: getBlueprintSchema }, diff --git a/server/routers/blueprints/listBlueprints.ts b/server/routers/blueprints/listBlueprints.ts index 2ece9e53d..0235e7a18 100644 --- a/server/routers/blueprints/listBlueprints.ts +++ b/server/routers/blueprints/listBlueprints.ts @@ -67,7 +67,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/blueprints", description: "List all blueprints for a organization.", - tags: [OpenAPITags.Org, OpenAPITags.Blueprint], + tags: [OpenAPITags.Blueprint], request: { params: z.object({ orgId: z.string() diff --git a/server/routers/client/createClient.ts b/server/routers/client/createClient.ts index 4eafb0616..6f26d8cf3 100644 --- a/server/routers/client/createClient.ts +++ b/server/routers/client/createClient.ts @@ -48,7 +48,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/client", description: "Create a new client for an organization.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.Client], request: { params: createClientParamsSchema, body: { diff --git a/server/routers/client/createUserClient.ts b/server/routers/client/createUserClient.ts index 5e9840f9d..d61eab15f 100644 --- a/server/routers/client/createUserClient.ts +++ b/server/routers/client/createUserClient.ts @@ -49,7 +49,7 @@ registry.registerPath({ path: "/org/{orgId}/user/{userId}/client", description: "Create a new client for a user and associate it with an existing olm.", - tags: [OpenAPITags.Client, OpenAPITags.Org, OpenAPITags.User], + tags: [OpenAPITags.Client], request: { params: paramsSchema, body: { diff --git a/server/routers/client/getClient.ts b/server/routers/client/getClient.ts index bb2ff8fda..375c027a7 100644 --- a/server/routers/client/getClient.ts +++ b/server/routers/client/getClient.ts @@ -243,7 +243,7 @@ registry.registerPath({ path: "/org/{orgId}/client/{niceId}", description: "Get a client by orgId and niceId. NiceId is a readable ID for the site and unique on a per org basis.", - tags: [OpenAPITags.Org, OpenAPITags.Site], + tags: [OpenAPITags.Site], request: { params: z.object({ orgId: z.string(), diff --git a/server/routers/client/listClients.ts b/server/routers/client/listClients.ts index 59f9137d2..84226a6dc 100644 --- a/server/routers/client/listClients.ts +++ b/server/routers/client/listClients.ts @@ -237,7 +237,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/clients", description: "List all clients for an organization.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.Client], request: { query: listClientsSchema, params: listClientsParamsSchema diff --git a/server/routers/client/listUserDevices.ts b/server/routers/client/listUserDevices.ts index 54fffe43b..eb63812c6 100644 --- a/server/routers/client/listUserDevices.ts +++ b/server/routers/client/listUserDevices.ts @@ -256,7 +256,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/user-devices", description: "List all user devices for an organization.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.Client], request: { query: listUserDevicesSchema, params: listUserDevicesParamsSchema diff --git a/server/routers/client/pickClientDefaults.ts b/server/routers/client/pickClientDefaults.ts index fd31da127..5dffd77d7 100644 --- a/server/routers/client/pickClientDefaults.ts +++ b/server/routers/client/pickClientDefaults.ts @@ -23,7 +23,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/pick-client-defaults", description: "Return pre-requisite data for creating a client.", - tags: [OpenAPITags.Client, OpenAPITags.Site], + tags: [OpenAPITags.Client], request: { params: pickClientDefaultsSchema }, diff --git a/server/routers/domain/listDomains.ts b/server/routers/domain/listDomains.ts index 20b236346..88cd5d7c7 100644 --- a/server/routers/domain/listDomains.ts +++ b/server/routers/domain/listDomains.ts @@ -59,7 +59,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/domains", description: "List all domains for a organization.", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Domain], request: { params: z.object({ orgId: z.string() diff --git a/server/routers/idp/createIdpOrgPolicy.ts b/server/routers/idp/createIdpOrgPolicy.ts index dc7af5377..da12bc12a 100644 --- a/server/routers/idp/createIdpOrgPolicy.ts +++ b/server/routers/idp/createIdpOrgPolicy.ts @@ -27,7 +27,7 @@ registry.registerPath({ method: "put", path: "/idp/{idpId}/org/{orgId}", description: "Create an IDP policy for an existing IDP on an organization.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { params: paramsSchema, body: { diff --git a/server/routers/idp/createOidcIdp.ts b/server/routers/idp/createOidcIdp.ts index 03626bfde..5b53f6820 100644 --- a/server/routers/idp/createOidcIdp.ts +++ b/server/routers/idp/createOidcIdp.ts @@ -37,7 +37,7 @@ registry.registerPath({ method: "put", path: "/idp/oidc", description: "Create an OIDC IdP.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { body: { content: { diff --git a/server/routers/idp/deleteIdp.ts b/server/routers/idp/deleteIdp.ts index f2b550993..8c15eada1 100644 --- a/server/routers/idp/deleteIdp.ts +++ b/server/routers/idp/deleteIdp.ts @@ -21,7 +21,7 @@ registry.registerPath({ method: "delete", path: "/idp/{idpId}", description: "Delete IDP.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { params: paramsSchema }, diff --git a/server/routers/idp/deleteIdpOrgPolicy.ts b/server/routers/idp/deleteIdpOrgPolicy.ts index b52a37df2..6793474a8 100644 --- a/server/routers/idp/deleteIdpOrgPolicy.ts +++ b/server/routers/idp/deleteIdpOrgPolicy.ts @@ -19,7 +19,7 @@ registry.registerPath({ method: "delete", path: "/idp/{idpId}/org/{orgId}", description: "Create an OIDC IdP for an organization.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { params: paramsSchema }, diff --git a/server/routers/idp/getIdp.ts b/server/routers/idp/getIdp.ts index 072537513..db199f2d6 100644 --- a/server/routers/idp/getIdp.ts +++ b/server/routers/idp/getIdp.ts @@ -34,7 +34,7 @@ registry.registerPath({ method: "get", path: "/idp/{idpId}", description: "Get an IDP by its IDP ID.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { params: paramsSchema }, diff --git a/server/routers/idp/listIdpOrgPolicies.ts b/server/routers/idp/listIdpOrgPolicies.ts index 9f7cdb42b..ecfd6f33a 100644 --- a/server/routers/idp/listIdpOrgPolicies.ts +++ b/server/routers/idp/listIdpOrgPolicies.ts @@ -48,7 +48,7 @@ registry.registerPath({ method: "get", path: "/idp/{idpId}/org", description: "List all org policies on an IDP.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { params: paramsSchema, query: querySchema diff --git a/server/routers/idp/listIdps.ts b/server/routers/idp/listIdps.ts index 9dda11bbf..ca0fd5fbf 100644 --- a/server/routers/idp/listIdps.ts +++ b/server/routers/idp/listIdps.ts @@ -58,7 +58,7 @@ registry.registerPath({ method: "get", path: "/idp", description: "List all IDP in the system.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { query: querySchema }, diff --git a/server/routers/idp/updateIdpOrgPolicy.ts b/server/routers/idp/updateIdpOrgPolicy.ts index ea08de420..5a9f882d4 100644 --- a/server/routers/idp/updateIdpOrgPolicy.ts +++ b/server/routers/idp/updateIdpOrgPolicy.ts @@ -26,7 +26,7 @@ registry.registerPath({ method: "post", path: "/idp/{idpId}/org/{orgId}", description: "Update an IDP org policy.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { params: paramsSchema, body: { diff --git a/server/routers/idp/updateOidcIdp.ts b/server/routers/idp/updateOidcIdp.ts index 82aed75ce..fe32a8b08 100644 --- a/server/routers/idp/updateOidcIdp.ts +++ b/server/routers/idp/updateOidcIdp.ts @@ -42,7 +42,7 @@ registry.registerPath({ method: "post", path: "/idp/{idpId}/oidc", description: "Update an OIDC IdP.", - tags: [OpenAPITags.Idp], + tags: [OpenAPITags.GlobalIdp], request: { params: paramsSchema, body: { diff --git a/server/routers/resource/addEmailToResourceWhitelist.ts b/server/routers/resource/addEmailToResourceWhitelist.ts index 53828b44c..27ba34699 100644 --- a/server/routers/resource/addEmailToResourceWhitelist.ts +++ b/server/routers/resource/addEmailToResourceWhitelist.ts @@ -29,7 +29,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}/whitelist/add", description: "Add a single email to the resource whitelist.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: addEmailToResourceWhitelistParamsSchema, body: { diff --git a/server/routers/resource/addRoleToResource.ts b/server/routers/resource/addRoleToResource.ts index ba344c6c0..7a5c8fb63 100644 --- a/server/routers/resource/addRoleToResource.ts +++ b/server/routers/resource/addRoleToResource.ts @@ -29,7 +29,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}/roles/add", description: "Add a single role to a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Role], + tags: [OpenAPITags.PublicResource, OpenAPITags.Role], request: { params: addRoleToResourceParamsSchema, body: { diff --git a/server/routers/resource/addUserToResource.ts b/server/routers/resource/addUserToResource.ts index ee6081ff8..9880d9c27 100644 --- a/server/routers/resource/addUserToResource.ts +++ b/server/routers/resource/addUserToResource.ts @@ -29,7 +29,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}/users/add", description: "Add a single user to a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.User], + tags: [OpenAPITags.PublicResource, OpenAPITags.User], request: { params: addUserToResourceParamsSchema, body: { diff --git a/server/routers/resource/createResource.ts b/server/routers/resource/createResource.ts index 232cea266..6c88c5797 100644 --- a/server/routers/resource/createResource.ts +++ b/server/routers/resource/createResource.ts @@ -79,7 +79,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/resource", description: "Create a resource.", - tags: [OpenAPITags.Org, OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: createResourceParamsSchema, body: { diff --git a/server/routers/resource/createResourceRule.ts b/server/routers/resource/createResourceRule.ts index a516d14af..b2ce2ee7c 100644 --- a/server/routers/resource/createResourceRule.ts +++ b/server/routers/resource/createResourceRule.ts @@ -31,7 +31,7 @@ registry.registerPath({ method: "put", path: "/resource/{resourceId}/rule", description: "Create a resource rule.", - tags: [OpenAPITags.Resource, OpenAPITags.Rule], + tags: [OpenAPITags.PublicResource, OpenAPITags.Rule], request: { params: createResourceRuleParamsSchema, body: { diff --git a/server/routers/resource/deleteResource.ts b/server/routers/resource/deleteResource.ts index d8891d75d..e63301867 100644 --- a/server/routers/resource/deleteResource.ts +++ b/server/routers/resource/deleteResource.ts @@ -22,7 +22,7 @@ registry.registerPath({ method: "delete", path: "/resource/{resourceId}", description: "Delete a resource.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: deleteResourceSchema }, diff --git a/server/routers/resource/deleteResourceRule.ts b/server/routers/resource/deleteResourceRule.ts index 638f2e1de..0fe9007f8 100644 --- a/server/routers/resource/deleteResourceRule.ts +++ b/server/routers/resource/deleteResourceRule.ts @@ -19,7 +19,7 @@ registry.registerPath({ method: "delete", path: "/resource/{resourceId}/rule/{ruleId}", description: "Delete a resource rule.", - tags: [OpenAPITags.Resource, OpenAPITags.Rule], + tags: [OpenAPITags.PublicResource, OpenAPITags.Rule], request: { params: deleteResourceRuleSchema }, diff --git a/server/routers/resource/getResource.ts b/server/routers/resource/getResource.ts index 7f3e8a0ea..cd870dcbf 100644 --- a/server/routers/resource/getResource.ts +++ b/server/routers/resource/getResource.ts @@ -54,7 +54,7 @@ registry.registerPath({ path: "/org/{orgId}/resource/{niceId}", description: "Get a resource by orgId and niceId. NiceId is a readable ID for the resource and unique on a per org basis.", - tags: [OpenAPITags.Org, OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: z.object({ orgId: z.string(), @@ -68,7 +68,7 @@ registry.registerPath({ method: "get", path: "/resource/{resourceId}", description: "Get a resource by resourceId.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: z.object({ resourceId: z.number() diff --git a/server/routers/resource/getResourceWhitelist.ts b/server/routers/resource/getResourceWhitelist.ts index 52cff0c72..5eb05184f 100644 --- a/server/routers/resource/getResourceWhitelist.ts +++ b/server/routers/resource/getResourceWhitelist.ts @@ -31,7 +31,7 @@ registry.registerPath({ method: "get", path: "/resource/{resourceId}/whitelist", description: "Get the whitelist of emails for a specific resource.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: getResourceWhitelistSchema }, diff --git a/server/routers/resource/listAllResourceNames.ts b/server/routers/resource/listAllResourceNames.ts index df78e2640..37ae945fd 100644 --- a/server/routers/resource/listAllResourceNames.ts +++ b/server/routers/resource/listAllResourceNames.ts @@ -33,7 +33,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/resources-names", description: "List all resource names for an organization.", - tags: [OpenAPITags.Org, OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: z.object({ orgId: z.string() diff --git a/server/routers/resource/listResourceRoles.ts b/server/routers/resource/listResourceRoles.ts index 68dc58a21..4af631191 100644 --- a/server/routers/resource/listResourceRoles.ts +++ b/server/routers/resource/listResourceRoles.ts @@ -35,7 +35,7 @@ registry.registerPath({ method: "get", path: "/resource/{resourceId}/roles", description: "List all roles for a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Role], + tags: [OpenAPITags.PublicResource, OpenAPITags.Role], request: { params: listResourceRolesSchema }, diff --git a/server/routers/resource/listResourceRules.ts b/server/routers/resource/listResourceRules.ts index dae7922d9..92d738cbb 100644 --- a/server/routers/resource/listResourceRules.ts +++ b/server/routers/resource/listResourceRules.ts @@ -56,7 +56,7 @@ registry.registerPath({ method: "get", path: "/resource/{resourceId}/rules", description: "List rules for a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Rule], + tags: [OpenAPITags.PublicResource, OpenAPITags.Rule], request: { params: listResourceRulesParamsSchema, query: listResourceRulesSchema diff --git a/server/routers/resource/listResourceUsers.ts b/server/routers/resource/listResourceUsers.ts index e7f73287e..2802ac827 100644 --- a/server/routers/resource/listResourceUsers.ts +++ b/server/routers/resource/listResourceUsers.ts @@ -38,7 +38,7 @@ registry.registerPath({ method: "get", path: "/resource/{resourceId}/users", description: "List all users for a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.User], + tags: [OpenAPITags.PublicResource, OpenAPITags.User], request: { params: listResourceUsersSchema }, diff --git a/server/routers/resource/listResources.ts b/server/routers/resource/listResources.ts index f00b0294c..f9dd14e98 100644 --- a/server/routers/resource/listResources.ts +++ b/server/routers/resource/listResources.ts @@ -225,7 +225,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/resources", description: "List resources for an organization.", - tags: [OpenAPITags.Org, OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: z.object({ orgId: z.string() diff --git a/server/routers/resource/removeEmailFromResourceWhitelist.ts b/server/routers/resource/removeEmailFromResourceWhitelist.ts index d60133b85..f419c4136 100644 --- a/server/routers/resource/removeEmailFromResourceWhitelist.ts +++ b/server/routers/resource/removeEmailFromResourceWhitelist.ts @@ -29,7 +29,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}/whitelist/remove", description: "Remove a single email from the resource whitelist.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: removeEmailFromResourceWhitelistParamsSchema, body: { diff --git a/server/routers/resource/removeRoleFromResource.ts b/server/routers/resource/removeRoleFromResource.ts index eab7660c3..eef55277b 100644 --- a/server/routers/resource/removeRoleFromResource.ts +++ b/server/routers/resource/removeRoleFromResource.ts @@ -29,7 +29,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}/roles/remove", description: "Remove a single role from a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Role], + tags: [OpenAPITags.PublicResource, OpenAPITags.Role], request: { params: removeRoleFromResourceParamsSchema, body: { diff --git a/server/routers/resource/removeUserFromResource.ts b/server/routers/resource/removeUserFromResource.ts index 9da96d3c8..152316e62 100644 --- a/server/routers/resource/removeUserFromResource.ts +++ b/server/routers/resource/removeUserFromResource.ts @@ -29,7 +29,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}/users/remove", description: "Remove a single user from a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.User], + tags: [OpenAPITags.PublicResource, OpenAPITags.User], request: { params: removeUserFromResourceParamsSchema, body: { diff --git a/server/routers/resource/setResourceHeaderAuth.ts b/server/routers/resource/setResourceHeaderAuth.ts index edd911cb8..9c28bf9f0 100644 --- a/server/routers/resource/setResourceHeaderAuth.ts +++ b/server/routers/resource/setResourceHeaderAuth.ts @@ -29,7 +29,7 @@ registry.registerPath({ path: "/resource/{resourceId}/header-auth", description: "Set or update the header authentication for a resource. If user and password is not provided, it will remove the header authentication.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: setResourceAuthMethodsParamsSchema, body: { diff --git a/server/routers/resource/setResourcePassword.ts b/server/routers/resource/setResourcePassword.ts index 9bd845a4e..d9fcb5f0b 100644 --- a/server/routers/resource/setResourcePassword.ts +++ b/server/routers/resource/setResourcePassword.ts @@ -25,7 +25,7 @@ registry.registerPath({ path: "/resource/{resourceId}/password", description: "Set the password for a resource. Setting the password to null will remove it.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: setResourceAuthMethodsParamsSchema, body: { diff --git a/server/routers/resource/setResourcePincode.ts b/server/routers/resource/setResourcePincode.ts index 0d5272731..54057ba08 100644 --- a/server/routers/resource/setResourcePincode.ts +++ b/server/routers/resource/setResourcePincode.ts @@ -29,7 +29,7 @@ registry.registerPath({ path: "/resource/{resourceId}/pincode", description: "Set the PIN code for a resource. Setting the PIN code to null will remove it.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: setResourceAuthMethodsParamsSchema, body: { diff --git a/server/routers/resource/setResourceRoles.ts b/server/routers/resource/setResourceRoles.ts index 751fe4f91..ff3cd7377 100644 --- a/server/routers/resource/setResourceRoles.ts +++ b/server/routers/resource/setResourceRoles.ts @@ -23,7 +23,7 @@ registry.registerPath({ path: "/resource/{resourceId}/roles", description: "Set roles for a resource. This will replace all existing roles.", - tags: [OpenAPITags.Resource, OpenAPITags.Role], + tags: [OpenAPITags.PublicResource, OpenAPITags.Role], request: { params: setResourceRolesParamsSchema, body: { diff --git a/server/routers/resource/setResourceUsers.ts b/server/routers/resource/setResourceUsers.ts index 5ddceb8f0..46b5d1523 100644 --- a/server/routers/resource/setResourceUsers.ts +++ b/server/routers/resource/setResourceUsers.ts @@ -23,7 +23,7 @@ registry.registerPath({ path: "/resource/{resourceId}/users", description: "Set users for a resource. This will replace all existing users.", - tags: [OpenAPITags.Resource, OpenAPITags.User], + tags: [OpenAPITags.PublicResource, OpenAPITags.User], request: { params: setUserResourcesParamsSchema, body: { diff --git a/server/routers/resource/setResourceWhitelist.ts b/server/routers/resource/setResourceWhitelist.ts index 18f612f24..aa5dc8cdb 100644 --- a/server/routers/resource/setResourceWhitelist.ts +++ b/server/routers/resource/setResourceWhitelist.ts @@ -32,7 +32,7 @@ registry.registerPath({ path: "/resource/{resourceId}/whitelist", description: "Set email whitelist for a resource. This will replace all existing emails.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: setResourceWhitelistParamsSchema, body: { diff --git a/server/routers/resource/updateResource.ts b/server/routers/resource/updateResource.ts index 4a3e65fa1..34b75ebbd 100644 --- a/server/routers/resource/updateResource.ts +++ b/server/routers/resource/updateResource.ts @@ -136,7 +136,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}", description: "Update a resource.", - tags: [OpenAPITags.Resource], + tags: [OpenAPITags.PublicResource], request: { params: updateResourceParamsSchema, body: { diff --git a/server/routers/resource/updateResourceRule.ts b/server/routers/resource/updateResourceRule.ts index b443bd1c2..3e8f395dd 100644 --- a/server/routers/resource/updateResourceRule.ts +++ b/server/routers/resource/updateResourceRule.ts @@ -38,7 +38,7 @@ registry.registerPath({ method: "post", path: "/resource/{resourceId}/rule/{ruleId}", description: "Update a resource rule.", - tags: [OpenAPITags.Resource, OpenAPITags.Rule], + tags: [OpenAPITags.PublicResource, OpenAPITags.Rule], request: { params: updateResourceRuleParamsSchema, body: { diff --git a/server/routers/role/createRole.ts b/server/routers/role/createRole.ts index e732b4054..1fad18d72 100644 --- a/server/routers/role/createRole.ts +++ b/server/routers/role/createRole.ts @@ -45,7 +45,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/role", description: "Create a role.", - tags: [OpenAPITags.Org, OpenAPITags.Role], + tags: [OpenAPITags.Role], request: { params: createRoleParamsSchema, body: { diff --git a/server/routers/role/listRoles.ts b/server/routers/role/listRoles.ts index d4cb580f2..f1b057a11 100644 --- a/server/routers/role/listRoles.ts +++ b/server/routers/role/listRoles.ts @@ -7,7 +7,7 @@ import { and, eq, inArray, sql } from "drizzle-orm"; import { ActionsEnum } from "@server/auth/actions"; import { NextFunction, Request, Response } from "express"; import createHttpError from "http-errors"; -import { z } from "zod"; +import { object, z } from "zod"; import { fromError } from "zod-validation-error"; const listRolesParamsSchema = z.strictObject({ @@ -64,7 +64,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/roles", description: "List roles.", - tags: [OpenAPITags.Org, OpenAPITags.Role], + tags: [OpenAPITags.Role], request: { params: listRolesParamsSchema, query: listRolesSchema diff --git a/server/routers/site/createSite.ts b/server/routers/site/createSite.ts index acfd044c2..cc63a2e9b 100644 --- a/server/routers/site/createSite.ts +++ b/server/routers/site/createSite.ts @@ -58,7 +58,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/site", description: "Create a new site.", - tags: [OpenAPITags.Site, OpenAPITags.Org], + tags: [OpenAPITags.Site], request: { params: createSiteParamsSchema, body: { diff --git a/server/routers/site/getSite.ts b/server/routers/site/getSite.ts index c82bf1999..45d49abe6 100644 --- a/server/routers/site/getSite.ts +++ b/server/routers/site/getSite.ts @@ -51,7 +51,7 @@ registry.registerPath({ path: "/org/{orgId}/site/{niceId}", description: "Get a site by orgId and niceId. NiceId is a readable ID for the site and unique on a per org basis.", - tags: [OpenAPITags.Org, OpenAPITags.Site], + tags: [OpenAPITags.Site], request: { params: z.object({ orgId: z.string(), diff --git a/server/routers/site/listSites.ts b/server/routers/site/listSites.ts index 103187b7a..9ff7a6933 100644 --- a/server/routers/site/listSites.ts +++ b/server/routers/site/listSites.ts @@ -180,7 +180,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/sites", description: "List all sites in an organization", - tags: [OpenAPITags.Org, OpenAPITags.Site], + tags: [OpenAPITags.Site], request: { params: listSitesParamsSchema, query: listSitesSchema diff --git a/server/routers/site/pickSiteDefaults.ts b/server/routers/site/pickSiteDefaults.ts index 69ed76886..f5e95ca10 100644 --- a/server/routers/site/pickSiteDefaults.ts +++ b/server/routers/site/pickSiteDefaults.ts @@ -35,7 +35,7 @@ registry.registerPath({ path: "/org/{orgId}/pick-site-defaults", description: "Return pre-requisite data for creating a site, such as the exit node, subnet, Newt credentials, etc.", - tags: [OpenAPITags.Org, OpenAPITags.Site], + tags: [OpenAPITags.Site], request: { params: z.object({ orgId: z.string() diff --git a/server/routers/siteResource/addClientToSiteResource.ts b/server/routers/siteResource/addClientToSiteResource.ts index 27d7f0573..4a67df94f 100644 --- a/server/routers/siteResource/addClientToSiteResource.ts +++ b/server/routers/siteResource/addClientToSiteResource.ts @@ -30,7 +30,7 @@ registry.registerPath({ path: "/site-resource/{siteResourceId}/clients/add", description: "Add a single client to a site resource. Clients with a userId cannot be added.", - tags: [OpenAPITags.Resource, OpenAPITags.Client], + tags: [OpenAPITags.PrivateResource, OpenAPITags.Client], request: { params: addClientToSiteResourceParamsSchema, body: { diff --git a/server/routers/siteResource/addRoleToSiteResource.ts b/server/routers/siteResource/addRoleToSiteResource.ts index abc2d221e..f6501463b 100644 --- a/server/routers/siteResource/addRoleToSiteResource.ts +++ b/server/routers/siteResource/addRoleToSiteResource.ts @@ -30,7 +30,7 @@ registry.registerPath({ method: "post", path: "/site-resource/{siteResourceId}/roles/add", description: "Add a single role to a site resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Role], + tags: [OpenAPITags.PrivateResource, OpenAPITags.Role], request: { params: addRoleToSiteResourceParamsSchema, body: { diff --git a/server/routers/siteResource/addUserToSiteResource.ts b/server/routers/siteResource/addUserToSiteResource.ts index 4edf741cd..68151077c 100644 --- a/server/routers/siteResource/addUserToSiteResource.ts +++ b/server/routers/siteResource/addUserToSiteResource.ts @@ -30,7 +30,7 @@ registry.registerPath({ method: "post", path: "/site-resource/{siteResourceId}/users/add", description: "Add a single user to a site resource.", - tags: [OpenAPITags.Resource, OpenAPITags.User], + tags: [OpenAPITags.PrivateResource, OpenAPITags.User], request: { params: addUserToSiteResourceParamsSchema, body: { diff --git a/server/routers/siteResource/createSiteResource.ts b/server/routers/siteResource/createSiteResource.ts index bbdc3638d..b9494776e 100644 --- a/server/routers/siteResource/createSiteResource.ts +++ b/server/routers/siteResource/createSiteResource.ts @@ -114,7 +114,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/site-resource", description: "Create a new site resource.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.PrivateResource], request: { params: createSiteResourceParamsSchema, body: { diff --git a/server/routers/siteResource/deleteSiteResource.ts b/server/routers/siteResource/deleteSiteResource.ts index 336c5080d..5b50b0ea3 100644 --- a/server/routers/siteResource/deleteSiteResource.ts +++ b/server/routers/siteResource/deleteSiteResource.ts @@ -23,7 +23,7 @@ registry.registerPath({ method: "delete", path: "/site-resource/{siteResourceId}", description: "Delete a site resource.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.PrivateResource], request: { params: deleteSiteResourceParamsSchema }, diff --git a/server/routers/siteResource/getSiteResource.ts b/server/routers/siteResource/getSiteResource.ts index f97a5e22f..be28d36e4 100644 --- a/server/routers/siteResource/getSiteResource.ts +++ b/server/routers/siteResource/getSiteResource.ts @@ -65,7 +65,7 @@ registry.registerPath({ method: "get", path: "/site-resource/{siteResourceId}", description: "Get a specific site resource by siteResourceId.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.PrivateResource], request: { params: z.object({ siteResourceId: z.number(), @@ -80,7 +80,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/site/{siteId}/resource/nice/{niceId}", description: "Get a specific site resource by niceId.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.PrivateResource], request: { params: z.object({ niceId: z.string(), diff --git a/server/routers/siteResource/listAllSiteResourcesByOrg.ts b/server/routers/siteResource/listAllSiteResourcesByOrg.ts index 110bf2234..3320aa3b7 100644 --- a/server/routers/siteResource/listAllSiteResourcesByOrg.ts +++ b/server/routers/siteResource/listAllSiteResourcesByOrg.ts @@ -112,7 +112,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/site-resources", description: "List all site resources for an organization.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.PrivateResource], request: { params: listAllSiteResourcesByOrgParamsSchema, query: listAllSiteResourcesByOrgQuerySchema diff --git a/server/routers/siteResource/listSiteResourceClients.ts b/server/routers/siteResource/listSiteResourceClients.ts index 772750d16..867e66b49 100644 --- a/server/routers/siteResource/listSiteResourceClients.ts +++ b/server/routers/siteResource/listSiteResourceClients.ts @@ -39,7 +39,7 @@ registry.registerPath({ method: "get", path: "/site-resource/{siteResourceId}/clients", description: "List all clients for a site resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Client], + tags: [OpenAPITags.PrivateResource, OpenAPITags.Client], request: { params: listSiteResourceClientsSchema }, diff --git a/server/routers/siteResource/listSiteResourceRoles.ts b/server/routers/siteResource/listSiteResourceRoles.ts index 0dc5913b6..679a93f7e 100644 --- a/server/routers/siteResource/listSiteResourceRoles.ts +++ b/server/routers/siteResource/listSiteResourceRoles.ts @@ -40,7 +40,7 @@ registry.registerPath({ method: "get", path: "/site-resource/{siteResourceId}/roles", description: "List all roles for a site resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Role], + tags: [OpenAPITags.PrivateResource, OpenAPITags.Role], request: { params: listSiteResourceRolesSchema }, diff --git a/server/routers/siteResource/listSiteResourceUsers.ts b/server/routers/siteResource/listSiteResourceUsers.ts index daf754801..e50d8684e 100644 --- a/server/routers/siteResource/listSiteResourceUsers.ts +++ b/server/routers/siteResource/listSiteResourceUsers.ts @@ -43,7 +43,7 @@ registry.registerPath({ method: "get", path: "/site-resource/{siteResourceId}/users", description: "List all users for a site resource.", - tags: [OpenAPITags.Resource, OpenAPITags.User], + tags: [OpenAPITags.PrivateResource, OpenAPITags.User], request: { params: listSiteResourceUsersSchema }, diff --git a/server/routers/siteResource/listSiteResources.ts b/server/routers/siteResource/listSiteResources.ts index 648931647..358aa0497 100644 --- a/server/routers/siteResource/listSiteResources.ts +++ b/server/routers/siteResource/listSiteResources.ts @@ -58,7 +58,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/site/{siteId}/resources", description: "List site resources for a site.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.PrivateResource], request: { params: listSiteResourcesParamsSchema, query: listSiteResourcesQuerySchema diff --git a/server/routers/siteResource/removeClientFromSiteResource.ts b/server/routers/siteResource/removeClientFromSiteResource.ts index 351128d18..51e54dd92 100644 --- a/server/routers/siteResource/removeClientFromSiteResource.ts +++ b/server/routers/siteResource/removeClientFromSiteResource.ts @@ -30,7 +30,7 @@ registry.registerPath({ path: "/site-resource/{siteResourceId}/clients/remove", description: "Remove a single client from a site resource. Clients with a userId cannot be removed.", - tags: [OpenAPITags.Resource, OpenAPITags.Client], + tags: [OpenAPITags.PrivateResource, OpenAPITags.Client], request: { params: removeClientFromSiteResourceParamsSchema, body: { diff --git a/server/routers/siteResource/removeRoleFromSiteResource.ts b/server/routers/siteResource/removeRoleFromSiteResource.ts index c9857e841..19478ed0f 100644 --- a/server/routers/siteResource/removeRoleFromSiteResource.ts +++ b/server/routers/siteResource/removeRoleFromSiteResource.ts @@ -30,7 +30,7 @@ registry.registerPath({ method: "post", path: "/site-resource/{siteResourceId}/roles/remove", description: "Remove a single role from a site resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Role], + tags: [OpenAPITags.PrivateResource, OpenAPITags.Role], request: { params: removeRoleFromSiteResourceParamsSchema, body: { diff --git a/server/routers/siteResource/removeUserFromSiteResource.ts b/server/routers/siteResource/removeUserFromSiteResource.ts index 84347b2f6..70bb5e22e 100644 --- a/server/routers/siteResource/removeUserFromSiteResource.ts +++ b/server/routers/siteResource/removeUserFromSiteResource.ts @@ -30,7 +30,7 @@ registry.registerPath({ method: "post", path: "/site-resource/{siteResourceId}/users/remove", description: "Remove a single user from a site resource.", - tags: [OpenAPITags.Resource, OpenAPITags.User], + tags: [OpenAPITags.PrivateResource, OpenAPITags.User], request: { params: removeUserFromSiteResourceParamsSchema, body: { diff --git a/server/routers/siteResource/setSiteResourceClients.ts b/server/routers/siteResource/setSiteResourceClients.ts index 5a8acbcf5..7aff3875f 100644 --- a/server/routers/siteResource/setSiteResourceClients.ts +++ b/server/routers/siteResource/setSiteResourceClients.ts @@ -30,7 +30,7 @@ registry.registerPath({ path: "/site-resource/{siteResourceId}/clients", description: "Set clients for a site resource. This will replace all existing clients. Clients with a userId cannot be added.", - tags: [OpenAPITags.Resource, OpenAPITags.Client], + tags: [OpenAPITags.PrivateResource, OpenAPITags.Client], request: { params: setSiteResourceClientsParamsSchema, body: { diff --git a/server/routers/siteResource/setSiteResourceRoles.ts b/server/routers/siteResource/setSiteResourceRoles.ts index bb71a16b6..a1ee80b40 100644 --- a/server/routers/siteResource/setSiteResourceRoles.ts +++ b/server/routers/siteResource/setSiteResourceRoles.ts @@ -31,7 +31,7 @@ registry.registerPath({ path: "/site-resource/{siteResourceId}/roles", description: "Set roles for a site resource. This will replace all existing roles.", - tags: [OpenAPITags.Resource, OpenAPITags.Role], + tags: [OpenAPITags.PrivateResource, OpenAPITags.Role], request: { params: setSiteResourceRolesParamsSchema, body: { diff --git a/server/routers/siteResource/setSiteResourceUsers.ts b/server/routers/siteResource/setSiteResourceUsers.ts index eacd826cc..109e8c429 100644 --- a/server/routers/siteResource/setSiteResourceUsers.ts +++ b/server/routers/siteResource/setSiteResourceUsers.ts @@ -31,7 +31,7 @@ registry.registerPath({ path: "/site-resource/{siteResourceId}/users", description: "Set users for a site resource. This will replace all existing users.", - tags: [OpenAPITags.Resource, OpenAPITags.User], + tags: [OpenAPITags.PrivateResource, OpenAPITags.User], request: { params: setSiteResourceUsersParamsSchema, body: { diff --git a/server/routers/siteResource/updateSiteResource.ts b/server/routers/siteResource/updateSiteResource.ts index 242b92265..b748e26d3 100644 --- a/server/routers/siteResource/updateSiteResource.ts +++ b/server/routers/siteResource/updateSiteResource.ts @@ -121,7 +121,7 @@ registry.registerPath({ method: "post", path: "/site-resource/{siteResourceId}", description: "Update a site resource.", - tags: [OpenAPITags.Client, OpenAPITags.Org], + tags: [OpenAPITags.PrivateResource], request: { params: updateSiteResourceParamsSchema, body: { diff --git a/server/routers/target/createTarget.ts b/server/routers/target/createTarget.ts index 5d37f6173..47495cbbc 100644 --- a/server/routers/target/createTarget.ts +++ b/server/routers/target/createTarget.ts @@ -58,7 +58,7 @@ registry.registerPath({ method: "put", path: "/resource/{resourceId}/target", description: "Create a target for a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Target], + tags: [OpenAPITags.PublicResource, OpenAPITags.Target], request: { params: createTargetParamsSchema, body: { diff --git a/server/routers/target/listTargets.ts b/server/routers/target/listTargets.ts index 11a23f025..e4ef45f3b 100644 --- a/server/routers/target/listTargets.ts +++ b/server/routers/target/listTargets.ts @@ -88,7 +88,7 @@ registry.registerPath({ method: "get", path: "/resource/{resourceId}/targets", description: "List targets for a resource.", - tags: [OpenAPITags.Resource, OpenAPITags.Target], + tags: [OpenAPITags.PublicResource, OpenAPITags.Target], request: { params: listTargetsParamsSchema, query: listTargetsSchema diff --git a/server/routers/user/createOrgUser.ts b/server/routers/user/createOrgUser.ts index b39ea22e2..3b8e70f7a 100644 --- a/server/routers/user/createOrgUser.ts +++ b/server/routers/user/createOrgUser.ts @@ -37,7 +37,7 @@ registry.registerPath({ method: "put", path: "/org/{orgId}/user", description: "Create an organization user.", - tags: [OpenAPITags.User, OpenAPITags.Org], + tags: [OpenAPITags.User], request: { params: paramsSchema, body: { diff --git a/server/routers/user/getOrgUser.ts b/server/routers/user/getOrgUser.ts index c0a990eeb..b117ca569 100644 --- a/server/routers/user/getOrgUser.ts +++ b/server/routers/user/getOrgUser.ts @@ -55,7 +55,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/user/{userId}", description: "Get a user in an organization.", - tags: [OpenAPITags.Org, OpenAPITags.User], + tags: [OpenAPITags.User], request: { params: getOrgUserParamsSchema }, diff --git a/server/routers/user/getOrgUserByUsername.ts b/server/routers/user/getOrgUserByUsername.ts index b047fdc06..a6a764a54 100644 --- a/server/routers/user/getOrgUserByUsername.ts +++ b/server/routers/user/getOrgUserByUsername.ts @@ -35,7 +35,7 @@ registry.registerPath({ path: "/org/{orgId}/user-by-username", description: "Get a user in an organization by username. When idpId is not passed, only internal users are searched (username is globally unique for them). For external (OIDC) users, pass idpId to search by username within that identity provider.", - tags: [OpenAPITags.Org, OpenAPITags.User], + tags: [OpenAPITags.User], request: { params: getOrgUserByUsernameParamsSchema, query: getOrgUserByUsernameQuerySchema diff --git a/server/routers/user/inviteUser.ts b/server/routers/user/inviteUser.ts index b7fe615a9..06d9512fb 100644 --- a/server/routers/user/inviteUser.ts +++ b/server/routers/user/inviteUser.ts @@ -44,7 +44,7 @@ registry.registerPath({ method: "post", path: "/org/{orgId}/create-invite", description: "Invite a user to join an organization.", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Invitation], request: { params: inviteUserParamsSchema, body: { diff --git a/server/routers/user/listInvitations.ts b/server/routers/user/listInvitations.ts index 4289b877f..2733c8395 100644 --- a/server/routers/user/listInvitations.ts +++ b/server/routers/user/listInvitations.ts @@ -54,7 +54,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/invitations", description: "List invitations in an organization.", - tags: [OpenAPITags.Org, OpenAPITags.Invitation], + tags: [OpenAPITags.Invitation], request: { params: listInvitationsParamsSchema, query: listInvitationsQuerySchema diff --git a/server/routers/user/listUsers.ts b/server/routers/user/listUsers.ts index 401dcf58b..40ca7ef2f 100644 --- a/server/routers/user/listUsers.ts +++ b/server/routers/user/listUsers.ts @@ -69,7 +69,7 @@ registry.registerPath({ method: "get", path: "/org/{orgId}/users", description: "List users in an organization.", - tags: [OpenAPITags.Org, OpenAPITags.User], + tags: [OpenAPITags.User], request: { params: listUsersParamsSchema, query: listUsersSchema diff --git a/server/routers/user/removeInvitation.ts b/server/routers/user/removeInvitation.ts index ab6a96d20..0f76fd30c 100644 --- a/server/routers/user/removeInvitation.ts +++ b/server/routers/user/removeInvitation.ts @@ -19,7 +19,7 @@ registry.registerPath({ method: "delete", path: "/org/{orgId}/invitations/{inviteId}", description: "Remove an open invitation from an organization", - tags: [OpenAPITags.Org], + tags: [OpenAPITags.Invitation], request: { params: removeInvitationParamsSchema }, diff --git a/server/routers/user/removeUserOrg.ts b/server/routers/user/removeUserOrg.ts index 4c321ad38..3c86a03c5 100644 --- a/server/routers/user/removeUserOrg.ts +++ b/server/routers/user/removeUserOrg.ts @@ -33,7 +33,7 @@ registry.registerPath({ method: "delete", path: "/org/{orgId}/user/{userId}", description: "Remove a user from an organization.", - tags: [OpenAPITags.Org, OpenAPITags.User], + tags: [OpenAPITags.User], request: { params: removeUserSchema }, diff --git a/server/routers/user/updateOrgUser.ts b/server/routers/user/updateOrgUser.ts index 97bedb5f9..a95c3fb5e 100644 --- a/server/routers/user/updateOrgUser.ts +++ b/server/routers/user/updateOrgUser.ts @@ -26,7 +26,7 @@ registry.registerPath({ method: "post", path: "/org/{orgId}/user/{userId}", description: "Update a user in an org.", - tags: [OpenAPITags.Org, OpenAPITags.User], + tags: [OpenAPITags.Org], request: { params: paramsSchema, body: { From 0ab6ff91481e802d907a09b4b7e08241b968ce80 Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Wed, 4 Mar 2026 15:50:42 -0800 Subject: [PATCH 10/46] add consent boolean to schema --- server/db/pg/schema/schema.ts | 1 + server/db/sqlite/schema/schema.ts | 3 +++ server/routers/auth/signup.ts | 1 + 3 files changed, 5 insertions(+) diff --git a/server/db/pg/schema/schema.ts b/server/db/pg/schema/schema.ts index ae90020a0..504ea761f 100644 --- a/server/db/pg/schema/schema.ts +++ b/server/db/pg/schema/schema.ts @@ -283,6 +283,7 @@ export const users = pgTable("user", { dateCreated: varchar("dateCreated").notNull(), termsAcceptedTimestamp: varchar("termsAcceptedTimestamp"), termsVersion: varchar("termsVersion"), + marketingEmailConsent: boolean("marketingEmailConsent").default(false), serverAdmin: boolean("serverAdmin").notNull().default(false), lastPasswordChange: bigint("lastPasswordChange", { mode: "number" }) }); diff --git a/server/db/sqlite/schema/schema.ts b/server/db/sqlite/schema/schema.ts index 64866e679..2bd11ee0c 100644 --- a/server/db/sqlite/schema/schema.ts +++ b/server/db/sqlite/schema/schema.ts @@ -314,6 +314,9 @@ export const users = sqliteTable("user", { dateCreated: text("dateCreated").notNull(), termsAcceptedTimestamp: text("termsAcceptedTimestamp"), termsVersion: text("termsVersion"), + marketingEmailConsent: integer("marketingEmailConsent", { + mode: "boolean" + }).default(false), serverAdmin: integer("serverAdmin", { mode: "boolean" }) .notNull() .default(false), diff --git a/server/routers/auth/signup.ts b/server/routers/auth/signup.ts index cf8e41417..93403a503 100644 --- a/server/routers/auth/signup.ts +++ b/server/routers/auth/signup.ts @@ -189,6 +189,7 @@ export async function signup( dateCreated: moment().toISOString(), termsAcceptedTimestamp: termsAcceptedTimestamp || null, termsVersion: "1", + marketingEmailConsent: marketingEmailConsent ?? false, lastPasswordChange: new Date().getTime() }); From d60ab281cf1a6bbc1e10925c1271053f0fdfd7b1 Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Wed, 4 Mar 2026 17:42:25 -0800 Subject: [PATCH 11/46] remove resend from package.json --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 625853042..56caec09a 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,6 @@ "react-icons": "5.5.0", "recharts": "2.15.4", "reodotdev": "1.0.0", - "resend": "6.9.2", "semver": "7.7.4", "sshpk": "^1.18.0", "stripe": "20.3.1", From e87e12898c67a620c1b23d6af2178fe14adb5c59 Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Wed, 4 Mar 2026 17:45:22 -0800 Subject: [PATCH 12/46] remove resend --- server/lib/resend.ts | 16 --- server/private/lib/resend.ts | 127 ------------------ .../hooks/handleSubscriptionCreated.ts | 3 +- .../hooks/handleSubscriptionDeleted.ts | 3 +- server/routers/auth/signup.ts | 3 +- 5 files changed, 3 insertions(+), 149 deletions(-) delete mode 100644 server/lib/resend.ts delete mode 100644 server/private/lib/resend.ts diff --git a/server/lib/resend.ts b/server/lib/resend.ts deleted file mode 100644 index 0c21b1bef..000000000 --- a/server/lib/resend.ts +++ /dev/null @@ -1,16 +0,0 @@ -export enum AudienceIds { - SignUps = "", - Subscribed = "", - Churned = "", - Newsletter = "" -} - -let resend; -export default resend; - -export async function moveEmailToAudience( - email: string, - audienceId: AudienceIds -) { - return; -} diff --git a/server/private/lib/resend.ts b/server/private/lib/resend.ts deleted file mode 100644 index 42a11c152..000000000 --- a/server/private/lib/resend.ts +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is part of a proprietary work. - * - * Copyright (c) 2025 Fossorial, Inc. - * All rights reserved. - * - * This file is licensed under the Fossorial Commercial License. - * You may not use this file except in compliance with the License. - * Unauthorized use, copying, modification, or distribution is strictly prohibited. - * - * This file is not licensed under the AGPLv3. - */ - -import { Resend } from "resend"; -import privateConfig from "#private/lib/config"; -import logger from "@server/logger"; - -export enum AudienceIds { - SignUps = "6c4e77b2-0851-4bd6-bac8-f51f91360f1a", - Subscribed = "870b43fd-387f-44de-8fc1-707335f30b20", - Churned = "f3ae92bd-2fdb-4d77-8746-2118afd62549", - Newsletter = "5500c431-191c-42f0-a5d4-8b6d445b4ea0" -} - -const resend = new Resend( - privateConfig.getRawPrivateConfig().server.resend_api_key || "missing" -); - -export default resend; - -export async function moveEmailToAudience( - email: string, - audienceId: AudienceIds -) { - if (process.env.ENVIRONMENT !== "prod") { - logger.debug( - `Skipping moving email ${email} to audience ${audienceId} in non-prod environment` - ); - return; - } - const { error, data } = await retryWithBackoff(async () => { - const { data, error } = await resend.contacts.create({ - email, - unsubscribed: false, - audienceId - }); - if (error) { - throw new Error( - `Error adding email ${email} to audience ${audienceId}: ${error}` - ); - } - return { error, data }; - }); - - if (error) { - logger.error( - `Error adding email ${email} to audience ${audienceId}: ${error}` - ); - return; - } - - if (data) { - logger.debug( - `Added email ${email} to audience ${audienceId} with contact ID ${data.id}` - ); - } - - const otherAudiences = Object.values(AudienceIds).filter( - (id) => id !== audienceId - ); - - for (const otherAudienceId of otherAudiences) { - const { error, data } = await retryWithBackoff(async () => { - const { data, error } = await resend.contacts.remove({ - email, - audienceId: otherAudienceId - }); - if (error) { - throw new Error( - `Error removing email ${email} from audience ${otherAudienceId}: ${error}` - ); - } - return { error, data }; - }); - - if (error) { - logger.error( - `Error removing email ${email} from audience ${otherAudienceId}: ${error}` - ); - } - - if (data) { - logger.info( - `Removed email ${email} from audience ${otherAudienceId}` - ); - } - } -} - -type RetryOptions = { - retries?: number; - initialDelayMs?: number; - factor?: number; -}; - -export async function retryWithBackoff( - fn: () => Promise, - options: RetryOptions = {} -): Promise { - const { retries = 5, initialDelayMs = 500, factor = 2 } = options; - - let attempt = 0; - let delay = initialDelayMs; - - while (true) { - try { - return await fn(); - } catch (err) { - attempt++; - - if (attempt > retries) throw err; - - await new Promise((resolve) => setTimeout(resolve, delay)); - delay *= factor; - } - } -} diff --git a/server/private/routers/billing/hooks/handleSubscriptionCreated.ts b/server/private/routers/billing/hooks/handleSubscriptionCreated.ts index 1152f223e..a40142526 100644 --- a/server/private/routers/billing/hooks/handleSubscriptionCreated.ts +++ b/server/private/routers/billing/hooks/handleSubscriptionCreated.ts @@ -24,7 +24,6 @@ import { eq, and } from "drizzle-orm"; import logger from "@server/logger"; import stripe from "#private/lib/stripe"; import { handleSubscriptionLifesycle } from "../subscriptionLifecycle"; -import { AudienceIds, moveEmailToAudience } from "#private/lib/resend"; import { getSubType } from "./getSubType"; import privateConfig from "#private/lib/config"; import { getLicensePriceSet, LicenseId } from "@server/lib/billing/licenses"; @@ -172,7 +171,7 @@ export async function handleSubscriptionCreated( const email = orgUserRes.user.email; if (email) { - moveEmailToAudience(email, AudienceIds.Subscribed); + // TODO: update user in Sendy } } } else if (type === "license") { diff --git a/server/private/routers/billing/hooks/handleSubscriptionDeleted.ts b/server/private/routers/billing/hooks/handleSubscriptionDeleted.ts index d92741be8..a029fc5c3 100644 --- a/server/private/routers/billing/hooks/handleSubscriptionDeleted.ts +++ b/server/private/routers/billing/hooks/handleSubscriptionDeleted.ts @@ -23,7 +23,6 @@ import { import { eq, and } from "drizzle-orm"; import logger from "@server/logger"; import { handleSubscriptionLifesycle } from "../subscriptionLifecycle"; -import { AudienceIds, moveEmailToAudience } from "#private/lib/resend"; import { getSubType } from "./getSubType"; import stripe from "#private/lib/stripe"; import privateConfig from "#private/lib/config"; @@ -109,7 +108,7 @@ export async function handleSubscriptionDeleted( const email = orgUserRes.user.email; if (email) { - moveEmailToAudience(email, AudienceIds.Churned); + // TODO: update user in Sendy } } } else if (type === "license") { diff --git a/server/routers/auth/signup.ts b/server/routers/auth/signup.ts index 93403a503..af3c670db 100644 --- a/server/routers/auth/signup.ts +++ b/server/routers/auth/signup.ts @@ -22,7 +22,6 @@ import { checkValidInvite } from "@server/auth/checkValidInvite"; import { passwordSchema } from "@server/auth/passwordSchema"; import { UserType } from "@server/types/UserTypes"; import { build } from "@server/build"; -import resend, { AudienceIds, moveEmailToAudience } from "#dynamic/lib/resend"; export const signupBodySchema = z.object({ email: z.email().toLowerCase(), @@ -213,7 +212,7 @@ export async function signup( logger.debug( `User ${email} opted in to marketing emails during signup.` ); - moveEmailToAudience(email, AudienceIds.SignUps); + // TODO: update user in Sendy } if (config.getRawConfig().flags?.require_email_verification) { From ebcef28b05abcf2b39451eb89c8d6f464637199e Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Wed, 4 Mar 2026 17:45:48 -0800 Subject: [PATCH 13/46] remove resend from config --- server/private/lib/readConfigFile.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/private/lib/readConfigFile.ts b/server/private/lib/readConfigFile.ts index a9de84e82..0ce6d0272 100644 --- a/server/private/lib/readConfigFile.ts +++ b/server/private/lib/readConfigFile.ts @@ -38,10 +38,6 @@ export const privateConfigSchema = z.object({ .string() .optional() .transform(getEnvOrYaml("SERVER_ENCRYPTION_KEY")), - resend_api_key: z - .string() - .optional() - .transform(getEnvOrYaml("RESEND_API_KEY")), reo_client_id: z .string() .optional() From 8c6d44677dbb390f6d0fa4ae0cdc06f0e9ad8842 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 4 Mar 2026 17:48:58 -0800 Subject: [PATCH 14/46] Update lock --- package-lock.json | 130 +++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 77 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06dccc8bf..b48f368ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -87,7 +87,6 @@ "react-icons": "5.5.0", "recharts": "2.15.4", "reodotdev": "1.0.0", - "resend": "6.9.2", "semver": "7.7.4", "sshpk": "^1.18.0", "stripe": "20.3.1", @@ -1087,6 +1086,7 @@ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", @@ -2809,6 +2809,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2831,6 +2832,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2853,6 +2855,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2869,6 +2872,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2885,6 +2889,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2901,6 +2906,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2917,6 +2923,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2933,6 +2940,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2949,6 +2957,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2965,6 +2974,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2981,6 +2991,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2997,6 +3008,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3019,6 +3031,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3041,6 +3054,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3063,6 +3077,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3085,6 +3100,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3107,6 +3123,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3129,6 +3146,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3151,6 +3169,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -3170,6 +3189,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -3189,6 +3209,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -3208,6 +3229,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -3467,6 +3489,7 @@ "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^14.21.3 || >=16" }, @@ -7897,6 +7920,7 @@ "resolved": "https://registry.npmjs.org/@react-email/text/-/text-0.1.6.tgz", "integrity": "sha512-TYqkioRS45wTR5il3dYk/SbUjjEdhSwh9BtRNB99qNH1pXAwA45H7rAuxehiu8iJQJH0IyIr+6n62gBz9ezmsw==", "license": "MIT", + "peer": true, "engines": { "node": ">=20.0.0" }, @@ -8713,12 +8737,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@stablelib/base64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz", - "integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==", - "license": "MIT" - }, "node_modules/@standard-schema/utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", @@ -9315,6 +9333,7 @@ "version": "5.90.21", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz", "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==", + "peer": true, "dependencies": { "@tanstack/query-core": "5.90.20" }, @@ -9430,6 +9449,7 @@ "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*" } @@ -9770,6 +9790,7 @@ "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", @@ -9864,6 +9885,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", "devOptional": true, + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -9891,6 +9913,7 @@ "integrity": "sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*", "pg-protocol": "*", @@ -9916,6 +9939,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -9926,6 +9950,7 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -10012,8 +10037,7 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/@types/ws": { "version": "8.18.1", @@ -10084,6 +10108,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz", "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.55.0", "@typescript-eslint/types": "8.55.0", @@ -10588,6 +10613,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -11052,6 +11078,7 @@ "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/types": "^7.26.0" } @@ -11118,6 +11145,7 @@ "integrity": "sha512-Ba0KR+Fzxh2jDRhdg6TSH0SJGzb8C0aBY4hR8w8madIdIzzC6Y1+kx5qR6eS1Z+Gy20h6ZU28aeyg0z1VIrShQ==", "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" @@ -11244,6 +11272,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -12197,6 +12226,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -12637,7 +12667,6 @@ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", "license": "(MPL-2.0 OR Apache-2.0)", - "peer": true, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } @@ -13751,6 +13780,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -13849,6 +13879,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -14034,6 +14065,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -14353,6 +14385,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -14494,12 +14527,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-sha256": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", - "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", - "license": "Unlicense" - }, "node_modules/fast-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", @@ -16865,7 +16892,6 @@ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", "license": "MIT", - "peer": true, "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" @@ -16876,7 +16902,6 @@ "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -16964,6 +16989,7 @@ "version": "15.5.12", "resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz", "integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==", + "peer": true, "dependencies": { "@next/env": "15.5.12", "@swc/helpers": "0.5.15", @@ -17898,6 +17924,7 @@ "resolved": "https://registry.npmjs.org/pg/-/pg-8.19.0.tgz", "integrity": "sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==", "license": "MIT", + "peer": true, "dependencies": { "pg-connection-string": "^2.11.0", "pg-pool": "^3.12.0", @@ -18042,11 +18069,6 @@ "node": ">= 0.4" } }, - "node_modules/postal-mime": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/postal-mime/-/postal-mime-2.7.3.tgz", - "integrity": "sha512-MjhXadAJaWgYzevi46+3kLak8y6gbg0ku14O1gO/LNOuay8dO+1PtcSGvAdgDR0DoIsSaiIA8y/Ddw6MnrO0Tw==" - }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -18393,6 +18415,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -18422,6 +18445,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -19261,6 +19285,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.2.tgz", "integrity": "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -19540,26 +19565,6 @@ "node": ">=0.10.0" } }, - "node_modules/resend": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/resend/-/resend-6.9.2.tgz", - "integrity": "sha512-uIM6CQ08tS+hTCRuKBFbOBvHIGaEhqZe8s4FOgqsVXSbQLAhmNWpmUhG3UAtRnmcwTWFUqnHa/+Vux8YGPyDBA==", - "dependencies": { - "postal-mime": "2.7.3", - "svix": "1.84.1" - }, - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "@react-email/render": "*" - }, - "peerDependenciesMeta": { - "@react-email/render": { - "optional": true - } - } - }, "node_modules/resolve": { "version": "1.22.11", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", @@ -20334,16 +20339,6 @@ "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", "license": "MIT" }, - "node_modules/standardwebhooks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.0.0.tgz", - "integrity": "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==", - "license": "MIT", - "dependencies": { - "@stablelib/base64": "^1.0.0", - "fast-sha256": "^1.3.0" - } - }, "node_modules/state-local": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", @@ -20651,29 +20646,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svix": { - "version": "1.84.1", - "resolved": "https://registry.npmjs.org/svix/-/svix-1.84.1.tgz", - "integrity": "sha512-K8DPPSZaW/XqXiz1kEyzSHYgmGLnhB43nQCMeKjWGCUpLIpAMMM8kx3rVVOSm6Bo6EHyK1RQLPT4R06skM/MlQ==", - "license": "MIT", - "dependencies": { - "standardwebhooks": "1.0.0", - "uuid": "^10.0.0" - } - }, - "node_modules/svix/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/swagger-ui-dist": { "version": "5.30.3", "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.30.3.tgz", @@ -20731,7 +20703,8 @@ "version": "4.1.18", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tapable": { "version": "2.3.0", @@ -21205,6 +21178,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -21631,6 +21605,7 @@ "resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz", "integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==", "license": "MIT", + "peer": true, "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.8", @@ -21837,6 +21812,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } From 1a2069a6d92f5bb5a03008966893ef3d4405c4b7 Mon Sep 17 00:00:00 2001 From: Fizza-Mukhtar Date: Thu, 5 Mar 2026 00:39:03 -0800 Subject: [PATCH 15/46] fix: prevent resource creation with dashboard domain to avoid redirect loop --- server/routers/resource/createResource.ts | 14 ++++++++++++++ server/routers/resource/updateResource.ts | 14 ++++++++++++++ .../settings/resources/proxy/create/page.tsx | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/server/routers/resource/createResource.ts b/server/routers/resource/createResource.ts index 6c88c5797..384bb8b53 100644 --- a/server/routers/resource/createResource.ts +++ b/server/routers/resource/createResource.ts @@ -223,6 +223,20 @@ async function createHttpResource( ); } + // Prevent creating resource with same domain as dashboard + const dashboardUrl = process.env.DASHBOARD_URL; + if (dashboardUrl) { + const dashboardHost = new URL(dashboardUrl).hostname; + if (fullDomain === dashboardHost) { + return next( + createHttpError( + HttpCode.CONFLICT, + "Resource domain cannot be the same as the dashboard domain" + ) + ); + } + } + if (build != "oss") { const existingLoginPages = await db .select() diff --git a/server/routers/resource/updateResource.ts b/server/routers/resource/updateResource.ts index 42e2849f6..becad5d2c 100644 --- a/server/routers/resource/updateResource.ts +++ b/server/routers/resource/updateResource.ts @@ -353,6 +353,20 @@ async function updateHttpResource( ); } + // Prevent updating resource with same domain as dashboard + const dashboardUrl = process.env.DASHBOARD_URL; + if (dashboardUrl) { + const dashboardHost = new URL(dashboardUrl).hostname; + if (fullDomain === dashboardHost) { + return next( + createHttpError( + HttpCode.CONFLICT, + "Resource domain cannot be the same as the dashboard domain" + ) + ); + } + } + if (build != "oss") { const existingLoginPages = await db .select() diff --git a/src/app/[orgId]/settings/resources/proxy/create/page.tsx b/src/app/[orgId]/settings/resources/proxy/create/page.tsx index ff51a311b..127917555 100644 --- a/src/app/[orgId]/settings/resources/proxy/create/page.tsx +++ b/src/app/[orgId]/settings/resources/proxy/create/page.tsx @@ -559,7 +559,7 @@ export default function Page() { toast({ variant: "destructive", title: t("resourceErrorCreate"), - description: t("resourceErrorCreateMessageDescription") + description: formatAxiosError(e, t("resourceErrorCreateMessageDescription")) }); } From 4cfcc64481f0b6c0c2f880ac41899661aa54a8b0 Mon Sep 17 00:00:00 2001 From: Fizza-Mukhtar Date: Thu, 5 Mar 2026 01:07:30 -0800 Subject: [PATCH 16/46] fix: use config instead of process.env for dashboard URL check --- server/routers/resource/createResource.ts | 2 +- server/routers/resource/updateResource.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/routers/resource/createResource.ts b/server/routers/resource/createResource.ts index 384bb8b53..e07880ac2 100644 --- a/server/routers/resource/createResource.ts +++ b/server/routers/resource/createResource.ts @@ -224,7 +224,7 @@ async function createHttpResource( } // Prevent creating resource with same domain as dashboard - const dashboardUrl = process.env.DASHBOARD_URL; + const dashboardUrl = config.getRawConfig().app.dashboard_url; if (dashboardUrl) { const dashboardHost = new URL(dashboardUrl).hostname; if (fullDomain === dashboardHost) { diff --git a/server/routers/resource/updateResource.ts b/server/routers/resource/updateResource.ts index becad5d2c..01f3e79ff 100644 --- a/server/routers/resource/updateResource.ts +++ b/server/routers/resource/updateResource.ts @@ -354,7 +354,7 @@ async function updateHttpResource( } // Prevent updating resource with same domain as dashboard - const dashboardUrl = process.env.DASHBOARD_URL; + const dashboardUrl = config.getRawConfig().app.dashboard_url; if (dashboardUrl) { const dashboardHost = new URL(dashboardUrl).hostname; if (fullDomain === dashboardHost) { From cebcf3e33787043326c5116b4df11ba60527e841 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:40:41 +0000 Subject: [PATCH 17/46] Bump express-rate-limit from 8.2.1 to 8.2.2 Bumps [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) from 8.2.1 to 8.2.2. - [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases) - [Commits](https://github.com/express-rate-limit/express-rate-limit/compare/v8.2.1...v8.2.2) --- updated-dependencies: - dependency-name: express-rate-limit dependency-version: 8.2.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06dccc8bf..1e946c3ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,7 @@ "d3": "7.9.0", "drizzle-orm": "0.45.1", "express": "5.2.1", - "express-rate-limit": "8.2.1", + "express-rate-limit": "8.2.2", "glob": "13.0.6", "helmet": "8.1.0", "http-errors": "2.0.1", @@ -14392,12 +14392,12 @@ } }, "node_modules/express-rate-limit": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz", - "integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.2.tgz", + "integrity": "sha512-Ybv7bqtOgA914MLwaHWVFXMpMYeR1MQu/D+z2MaLYteqBsTIp9sY3AU7mGNLMJv8eLg8uQMpE20I+L2Lv49nSg==", "license": "MIT", "dependencies": { - "ip-address": "10.0.1" + "ip-address": "10.1.0" }, "engines": { "node": ">= 16" @@ -15490,9 +15490,9 @@ } }, "node_modules/ip-address": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", - "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "license": "MIT", "engines": { "node": ">= 12" diff --git a/package.json b/package.json index 625853042..df92d1a64 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "d3": "7.9.0", "drizzle-orm": "0.45.1", "express": "5.2.1", - "express-rate-limit": "8.2.1", + "express-rate-limit": "8.2.2", "glob": "13.0.6", "helmet": "8.1.0", "http-errors": "2.0.1", From a26ee4ac1a78c851b5f430ca141da24a28768e69 Mon Sep 17 00:00:00 2001 From: Owen Date: Fri, 6 Mar 2026 12:17:26 -0800 Subject: [PATCH 18/46] Adjust billing upgrade language --- .../settings/(private)/billing/page.tsx | 543 +++++++++++++----- 1 file changed, 407 insertions(+), 136 deletions(-) diff --git a/src/app/[orgId]/settings/(private)/billing/page.tsx b/src/app/[orgId]/settings/(private)/billing/page.tsx index 35b950650..ba08f6022 100644 --- a/src/app/[orgId]/settings/(private)/billing/page.tsx +++ b/src/app/[orgId]/settings/(private)/billing/page.tsx @@ -35,11 +35,7 @@ import { } from "@app/components/Credenza"; import { cn } from "@app/lib/cn"; import { CreditCard, ExternalLink, Check, AlertTriangle } from "lucide-react"; -import { - Alert, - AlertTitle, - AlertDescription -} from "@app/components/ui/alert"; +import { Alert, AlertTitle, AlertDescription } from "@app/components/ui/alert"; import { Tooltip, TooltipTrigger, @@ -69,6 +65,7 @@ type PlanOption = { price: string; priceDetail?: string; tierType: Tier | null; + features: string[]; }; const planOptions: PlanOption[] = [ @@ -76,41 +73,87 @@ const planOptions: PlanOption[] = [ id: "basic", name: "Basic", price: "Free", - tierType: null + tierType: null, + features: [ + "Basic Pangolin features", + "Free provided domains", + "Web-based proxy resources", + "Private resources and clients", + "Peer-to-peer connections" + ] }, { id: "home", name: "Home", price: "$12.50", priceDetail: "/ month", - tierType: "tier1" + tierType: "tier1", + features: [ + "Everything in Basic", + "OAuth2/OIDC, Google, & Azure SSO", + "Bring your own identity provider", + "Pangolin SSH", + "Custom branding", + "Device admin approvals" + ] }, { id: "team", name: "Team", price: "$4", priceDetail: "per user / month", - tierType: "tier2" + tierType: "tier2", + features: [ + "Everything in Basic", + "Custom domains", + "OAuth2/OIDC, Google, & Azure SSO", + "Access and action audit logs", + "Device posture information" + ] }, { id: "business", name: "Business", price: "$9", priceDetail: "per user / month", - tierType: "tier3" + tierType: "tier3", + features: [ + "Everything in Team", + "Multiple organizations (multi-tenancy)", + "Auto-provisioning via IdP", + "Pangolin SSH", + "Device approvals", + "Custom branding", + "Business support" + ] }, { id: "enterprise", name: "Enterprise", price: "Custom", - tierType: null + tierType: null, + features: [ + "Everything in Business", + "Custom limits", + "Priority support and SLA", + "Log push and export", + "Private and Gov-Cloud deployment options", + "Dedicated, premium relay/exit nodes", + "Pay by invoice " + ] } ]; // Tier limits mapping derived from limit sets const tierLimits: Record< Tier | "basic", - { users: number; sites: number; domains: number; remoteNodes: number; organizations: number } + { + users: number; + sites: number; + domains: number; + remoteNodes: number; + organizations: number; + } > = { basic: { users: freeLimitSet[FeatureId.USERS]?.value ?? 0, @@ -463,31 +506,43 @@ export default function BillingPage() { const isProblematicState = hasProblematicSubscription(); // Get user-friendly subscription status message - const getSubscriptionStatusMessage = (): { title: string; description: string } | null => { + const getSubscriptionStatusMessage = (): { + title: string; + description: string; + } | null => { if (!tierSubscription?.subscription || !isProblematicState) return null; - + const status = tierSubscription.subscription.status; - + switch (status) { case "past_due": return { title: t("billingPastDueTitle") || "Payment Past Due", - description: t("billingPastDueDescription") || "Your payment is past due. Please update your payment method to continue using your current plan features. If not resolved, your subscription will be canceled and you'll be reverted to the free tier." + description: + t("billingPastDueDescription") || + "Your payment is past due. Please update your payment method to continue using your current plan features. If not resolved, your subscription will be canceled and you'll be reverted to the free tier." }; case "unpaid": return { title: t("billingUnpaidTitle") || "Subscription Unpaid", - description: t("billingUnpaidDescription") || "Your subscription is unpaid and you have been reverted to the free tier. Please update your payment method to restore your subscription." + description: + t("billingUnpaidDescription") || + "Your subscription is unpaid and you have been reverted to the free tier. Please update your payment method to restore your subscription." }; case "incomplete": return { title: t("billingIncompleteTitle") || "Payment Incomplete", - description: t("billingIncompleteDescription") || "Your payment is incomplete. Please complete the payment process to activate your subscription." + description: + t("billingIncompleteDescription") || + "Your payment is incomplete. Please complete the payment process to activate your subscription." }; case "incomplete_expired": return { - title: t("billingIncompleteExpiredTitle") || "Payment Expired", - description: t("billingIncompleteExpiredDescription") || "Your payment was never completed and has expired. You have been reverted to the free tier. Please subscribe again to restore access to paid features." + title: + t("billingIncompleteExpiredTitle") || "Payment Expired", + description: + t("billingIncompleteExpiredDescription") || + "Your payment was never completed and has expired. You have been reverted to the free tier. Please subscribe again to restore access to paid features." }; default: return null; @@ -509,7 +564,11 @@ export default function BillingPage() { if (plan.id === currentPlanId) { // If it's the basic plan (basic with no subscription), show as current but disabled - if (plan.id === "basic" && !hasSubscription && !isProblematicState) { + if ( + plan.id === "basic" && + !hasSubscription && + !isProblematicState + ) { return { label: "Current Plan", action: () => {}, @@ -632,7 +691,9 @@ export default function BillingPage() { }; // Check if downgrading to a tier would violate current usage limits - const checkLimitViolations = (targetTier: Tier | "basic"): Array<{ + const checkLimitViolations = ( + targetTier: Tier | "basic" + ): Array<{ feature: string; currentUsage: number; newLimit: number; @@ -687,7 +748,10 @@ export default function BillingPage() { // Check organizations const organizationsUsage = getUsageValue(ORGINIZATIONS); - if (limits.organizations > 0 && organizationsUsage > limits.organizations) { + if ( + limits.organizations > 0 && + organizationsUsage > limits.organizations + ) { violations.push({ feature: "Organizations", currentUsage: organizationsUsage, @@ -712,17 +776,15 @@ export default function BillingPage() { {isProblematicState && statusMessage && ( - - {statusMessage.title} - + {statusMessage.title} - {statusMessage.description} - {" "} + {statusMessage.description}{" "} @@ -772,7 +834,10 @@ export default function BillingPage() {
- {isProblematicState && planAction.disabled && !isCurrentPlan && plan.id !== "enterprise" ? ( + {isProblematicState && + planAction.disabled && + !isCurrentPlan && + plan.id !== "enterprise" ? (
@@ -784,18 +849,29 @@ export default function BillingPage() { } size="sm" className="w-full" - onClick={planAction.action} - disabled={ - isLoading || planAction.disabled + onClick={ + planAction.action + } + disabled={ + isLoading || + planAction.disabled + } + loading={ + isLoading && + isCurrentPlan } - loading={isLoading && isCurrentPlan} > {planAction.label}
-

{t("billingResolvePaymentIssue") || "Please resolve your payment issue before upgrading or downgrading"}

+

+ {t( + "billingResolvePaymentIssue" + ) || + "Please resolve your payment issue before upgrading or downgrading"} +

) : ( @@ -809,9 +885,12 @@ export default function BillingPage() { className="w-full" onClick={planAction.action} disabled={ - isLoading || planAction.disabled + isLoading || + planAction.disabled + } + loading={ + isLoading && isCurrentPlan } - loading={isLoading && isCurrentPlan} > {planAction.label} @@ -886,18 +965,38 @@ export default function BillingPage() { - + {getLimitValue(USERS) ?? - t("billingUnlimited") ?? + t( + "billingUnlimited" + ) ?? "∞"}{" "} - {getLimitValue(USERS) !== null && - "users"} + {getLimitValue( + USERS + ) !== null && "users"} -

{t("billingUsageExceedsLimit", { current: getUsageValue(USERS), limit: getLimitValue(USERS) ?? 0 }) || `Current usage (${getUsageValue(USERS)}) exceeds limit (${getLimitValue(USERS)})`}

+

+ {t( + "billingUsageExceedsLimit", + { + current: + getUsageValue( + USERS + ), + limit: + getLimitValue( + USERS + ) ?? 0 + } + ) || + `Current usage (${getUsageValue(USERS)}) exceeds limit (${getLimitValue(USERS)})`} +

) : ( @@ -905,8 +1004,8 @@ export default function BillingPage() { {getLimitValue(USERS) ?? t("billingUnlimited") ?? "∞"}{" "} - {getLimitValue(USERS) !== null && - "users"} + {getLimitValue(USERS) !== + null && "users"} )} @@ -920,18 +1019,38 @@ export default function BillingPage() { - + {getLimitValue(SITES) ?? - t("billingUnlimited") ?? + t( + "billingUnlimited" + ) ?? "∞"}{" "} - {getLimitValue(SITES) !== null && - "sites"} + {getLimitValue( + SITES + ) !== null && "sites"} -

{t("billingUsageExceedsLimit", { current: getUsageValue(SITES), limit: getLimitValue(SITES) ?? 0 }) || `Current usage (${getUsageValue(SITES)}) exceeds limit (${getLimitValue(SITES)})`}

+

+ {t( + "billingUsageExceedsLimit", + { + current: + getUsageValue( + SITES + ), + limit: + getLimitValue( + SITES + ) ?? 0 + } + ) || + `Current usage (${getUsageValue(SITES)}) exceeds limit (${getLimitValue(SITES)})`} +

) : ( @@ -939,8 +1058,8 @@ export default function BillingPage() { {getLimitValue(SITES) ?? t("billingUnlimited") ?? "∞"}{" "} - {getLimitValue(SITES) !== null && - "sites"} + {getLimitValue(SITES) !== + null && "sites"} )} @@ -954,18 +1073,40 @@ export default function BillingPage() { - - {getLimitValue(DOMAINS) ?? - t("billingUnlimited") ?? + + {getLimitValue( + DOMAINS + ) ?? + t( + "billingUnlimited" + ) ?? "∞"}{" "} - {getLimitValue(DOMAINS) !== null && - "domains"} + {getLimitValue( + DOMAINS + ) !== null && "domains"} -

{t("billingUsageExceedsLimit", { current: getUsageValue(DOMAINS), limit: getLimitValue(DOMAINS) ?? 0 }) || `Current usage (${getUsageValue(DOMAINS)}) exceeds limit (${getLimitValue(DOMAINS)})`}

+

+ {t( + "billingUsageExceedsLimit", + { + current: + getUsageValue( + DOMAINS + ), + limit: + getLimitValue( + DOMAINS + ) ?? 0 + } + ) || + `Current usage (${getUsageValue(DOMAINS)}) exceeds limit (${getLimitValue(DOMAINS)})`} +

) : ( @@ -973,8 +1114,8 @@ export default function BillingPage() { {getLimitValue(DOMAINS) ?? t("billingUnlimited") ?? "∞"}{" "} - {getLimitValue(DOMAINS) !== null && - "domains"} + {getLimitValue(DOMAINS) !== + null && "domains"} )} @@ -989,18 +1130,40 @@ export default function BillingPage() { - - {getLimitValue(ORGINIZATIONS) ?? - t("billingUnlimited") ?? + + {getLimitValue( + ORGINIZATIONS + ) ?? + t( + "billingUnlimited" + ) ?? "∞"}{" "} - {getLimitValue(ORGINIZATIONS) !== - null && "orgs"} + {getLimitValue( + ORGINIZATIONS + ) !== null && "orgs"} -

{t("billingUsageExceedsLimit", { current: getUsageValue(ORGINIZATIONS), limit: getLimitValue(ORGINIZATIONS) ?? 0 }) || `Current usage (${getUsageValue(ORGINIZATIONS)}) exceeds limit (${getLimitValue(ORGINIZATIONS)})`}

+

+ {t( + "billingUsageExceedsLimit", + { + current: + getUsageValue( + ORGINIZATIONS + ), + limit: + getLimitValue( + ORGINIZATIONS + ) ?? 0 + } + ) || + `Current usage (${getUsageValue(ORGINIZATIONS)}) exceeds limit (${getLimitValue(ORGINIZATIONS)})`} +

) : ( @@ -1008,8 +1171,9 @@ export default function BillingPage() { {getLimitValue(ORGINIZATIONS) ?? t("billingUnlimited") ?? "∞"}{" "} - {getLimitValue(ORGINIZATIONS) !== - null && "orgs"} + {getLimitValue( + ORGINIZATIONS + ) !== null && "orgs"} )} @@ -1024,27 +1188,52 @@ export default function BillingPage() { - - {getLimitValue(REMOTE_EXIT_NODES) ?? - t("billingUnlimited") ?? + + {getLimitValue( + REMOTE_EXIT_NODES + ) ?? + t( + "billingUnlimited" + ) ?? "∞"}{" "} - {getLimitValue(REMOTE_EXIT_NODES) !== - null && "nodes"} + {getLimitValue( + REMOTE_EXIT_NODES + ) !== null && "nodes"} -

{t("billingUsageExceedsLimit", { current: getUsageValue(REMOTE_EXIT_NODES), limit: getLimitValue(REMOTE_EXIT_NODES) ?? 0 }) || `Current usage (${getUsageValue(REMOTE_EXIT_NODES)}) exceeds limit (${getLimitValue(REMOTE_EXIT_NODES)})`}

+

+ {t( + "billingUsageExceedsLimit", + { + current: + getUsageValue( + REMOTE_EXIT_NODES + ), + limit: + getLimitValue( + REMOTE_EXIT_NODES + ) ?? 0 + } + ) || + `Current usage (${getUsageValue(REMOTE_EXIT_NODES)}) exceeds limit (${getLimitValue(REMOTE_EXIT_NODES)})`} +

) : ( <> - {getLimitValue(REMOTE_EXIT_NODES) ?? + {getLimitValue( + REMOTE_EXIT_NODES + ) ?? t("billingUnlimited") ?? "∞"}{" "} - {getLimitValue(REMOTE_EXIT_NODES) !== - null && "nodes"} + {getLimitValue( + REMOTE_EXIT_NODES + ) !== null && "nodes"} )} @@ -1072,7 +1261,8 @@ export default function BillingPage() {
- {t("billingCurrentKeys") || "Current Keys"} + {t("billingCurrentKeys") || + "Current Keys"}
@@ -1137,61 +1327,101 @@ export default function BillingPage() {
+ {/* Features with check marks */} + {(() => { + const plan = planOptions.find( + (p) => + p.tierType === pendingTier.tier || + (pendingTier.tier === "basic" && + p.id === "basic") + ); + return plan?.features?.length ? ( +
+

+ {"What's included:"} +

+
+ {plan.features.map( + (feature, i) => ( +
+ + + {feature} + +
+ ) + )} +
+
+ ) : null; + })()} + + {/* Limits without check marks */} {tierLimits[pendingTier.tier] && (

- {t("billingPlanIncludes") || - "Plan Includes:"} + {"Up to:"}

-
+
- + { - tierLimits[pendingTier.tier] - .users + tierLimits[ + pendingTier.tier + ].users }{" "} - {t("billingUsers") || "Users"} + {t("billingUsers") || + "Users"}
- + { - tierLimits[pendingTier.tier] - .sites + tierLimits[ + pendingTier.tier + ].sites }{" "} - {t("billingSites") || "Sites"} + {t("billingSites") || + "Sites"}
- + { - tierLimits[pendingTier.tier] - .domains + tierLimits[ + pendingTier.tier + ].domains }{" "} {t("billingDomains") || "Domains"}
- + { - tierLimits[pendingTier.tier] - .organizations + tierLimits[ + pendingTier.tier + ].organizations }{" "} - {t("billingOrganizations") || - "Organizations"} + {t( + "billingOrganizations" + ) || "Organizations"}
- + { - tierLimits[pendingTier.tier] - .remoteNodes + tierLimits[ + pendingTier.tier + ].remoteNodes }{" "} {t("billingRemoteNodes") || "Remote Nodes"} @@ -1202,43 +1432,84 @@ export default function BillingPage() { )} {/* Warning for limit violations when downgrading */} - {pendingTier.action === "downgrade" && (() => { - const violations = checkLimitViolations(pendingTier.tier); - if (violations.length > 0) { - return ( - - - - {t("billingLimitViolationWarning") || "Usage Exceeds New Plan Limits"} - - -

- {t("billingLimitViolationDescription") || "Your current usage exceeds the limits of this plan. The following features will be disabled until you reduce usage:"} -

-
    - {violations.map((violation, index) => ( -
  • - {violation.feature}: - Currently using {violation.currentUsage}, new limit is {violation.newLimit} -
  • - ))} -
-
-
+ {pendingTier.action === "downgrade" && + (() => { + const violations = checkLimitViolations( + pendingTier.tier ); - } - return null; - })()} + if (violations.length > 0) { + return ( + + + + {t( + "billingLimitViolationWarning" + ) || + "Usage Exceeds New Plan Limits"} + + +

+ {t( + "billingLimitViolationDescription" + ) || + "Your current usage exceeds the limits of this plan. The following features will be disabled until you reduce usage:"} +

+
    + {violations.map( + ( + violation, + index + ) => ( +
  • + + { + violation.feature + } + : + + + Currently + using{" "} + { + violation.currentUsage + } + , + new + limit + is{" "} + { + violation.newLimit + } + +
  • + ) + )} +
+
+
+ ); + } + return null; + })()} {/* Warning for feature loss when downgrading */} {pendingTier.action === "downgrade" && ( - {t("billingFeatureLossWarning") || "Feature Availability Notice"} + {t("billingFeatureLossWarning") || + "Feature Availability Notice"} - {t("billingFeatureLossDescription") || "By downgrading, features not available in the new plan will be automatically disabled. Some settings and configurations may be lost. Please review the pricing matrix to understand which features will no longer be available."} + {t( + "billingFeatureLossDescription" + ) || + "By downgrading, features not available in the new plan will be automatically disabled. Some settings and configurations may be lost. Please review the pricing matrix to understand which features will no longer be available."} )} From 14d6ff25a717e995ddf20d21a19c045324117788 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 22:14:56 +0000 Subject: [PATCH 19/46] Bump fast-xml-parser and @aws-sdk/xml-builder Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) and [@aws-sdk/xml-builder](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/xml-builder). These dependencies needed to be updated together. Updates `fast-xml-parser` from 5.3.6 to 5.4.1 - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.6...v5.4.1) Updates `@aws-sdk/xml-builder` from 3.972.5 to 3.972.10 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/xml-builder/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/xml-builder) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.4.1 dependency-type: indirect - dependency-name: "@aws-sdk/xml-builder" dependency-version: 3.972.10 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e946c3ed..3e070b8ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1035,13 +1035,13 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.5.tgz", - "integrity": "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.10.tgz", + "integrity": "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "fast-xml-parser": "5.3.6", + "@smithy/types": "^4.13.0", + "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" }, "engines": { @@ -8463,9 +8463,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", - "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", + "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -14517,10 +14517,22 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fast-xml-builder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", + "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/fast-xml-parser": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz", - "integrity": "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", + "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", "funding": [ { "type": "github", @@ -14529,6 +14541,7 @@ ], "license": "MIT", "dependencies": { + "fast-xml-builder": "^1.0.0", "strnum": "^2.1.2" }, "bin": { @@ -20574,9 +20587,9 @@ } }, "node_modules/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz", + "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==", "funding": [ { "type": "github", From be609b5000ec07dc857a268c39609ba0543b6594 Mon Sep 17 00:00:00 2001 From: Laurence Date: Sat, 7 Mar 2026 06:28:10 +0000 Subject: [PATCH 20/46] Fix missing hcStatus field in health check config on reconnect The buildTargetConfigurationForNewtClient function was not including the hcStatus field when building health check targets for the newt/wg/connect message. This caused custom expected response codes (e.g., 409) to revert to the default 2xx range check after Pangolin server restart. Added hcStatus to both the database select query and the returned health check target object, matching the behavior in targets.ts addTargets. --- server/routers/newt/buildConfiguration.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/routers/newt/buildConfiguration.ts b/server/routers/newt/buildConfiguration.ts index 65cb18a21..32c358dee 100644 --- a/server/routers/newt/buildConfiguration.ts +++ b/server/routers/newt/buildConfiguration.ts @@ -188,7 +188,8 @@ export async function buildTargetConfigurationForNewtClient(siteId: number) { hcTimeout: targetHealthCheck.hcTimeout, hcHeaders: targetHealthCheck.hcHeaders, hcMethod: targetHealthCheck.hcMethod, - hcTlsServerName: targetHealthCheck.hcTlsServerName + hcTlsServerName: targetHealthCheck.hcTlsServerName, + hcStatus: targetHealthCheck.hcStatus }) .from(targets) .innerJoin(resources, eq(targets.resourceId, resources.resourceId)) @@ -261,7 +262,8 @@ export async function buildTargetConfigurationForNewtClient(siteId: number) { hcTimeout: target.hcTimeout, // in seconds hcHeaders: hcHeadersSend, hcMethod: target.hcMethod, - hcTlsServerName: target.hcTlsServerName + hcTlsServerName: target.hcTlsServerName, + hcStatus: target.hcStatus }; }); From 7d0b3ec6b5dc02d8b7b1c35d44f3e4be0bbb423c Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:34:48 -0700 Subject: [PATCH 21/46] Fix not pulling wildcard cert updates --- server/lib/traefik/TraefikConfigManager.ts | 89 +++++++++++++++++++--- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/server/lib/traefik/TraefikConfigManager.ts b/server/lib/traefik/TraefikConfigManager.ts index 46d5ccc85..de9249291 100644 --- a/server/lib/traefik/TraefikConfigManager.ts +++ b/server/lib/traefik/TraefikConfigManager.ts @@ -218,10 +218,11 @@ export class TraefikConfigManager { return true; } - // Fetch if it's been more than 24 hours (for renewals) const dayInMs = 24 * 60 * 60 * 1000; const timeSinceLastFetch = Date.now() - this.lastCertificateFetch.getTime(); + + // Fetch if it's been more than 24 hours (daily routine check) if (timeSinceLastFetch > dayInMs) { logger.info("Fetching certificates due to 24-hour renewal check"); return true; @@ -265,7 +266,7 @@ export class TraefikConfigManager { return true; } - // Check if any local certificates are missing or appear to be outdated + // Check if any local certificates are missing (needs immediate fetch) for (const domain of domainsNeedingCerts) { const localState = this.lastLocalCertificateState.get(domain); if (!localState || !localState.exists) { @@ -274,17 +275,55 @@ export class TraefikConfigManager { ); return true; } + } - // Check if certificate is expiring soon (within 30 days) - if (localState.expiresAt) { - const nowInSeconds = Math.floor(Date.now() / 1000); - const secondsUntilExpiry = localState.expiresAt - nowInSeconds; - const daysUntilExpiry = secondsUntilExpiry / (60 * 60 * 24); - if (daysUntilExpiry < 30) { - logger.info( - `Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)` - ); - return true; + // For expiry checks, throttle to every 6 hours to avoid querying the + // API/DB on every monitor loop. The certificate-service renews certs + // 45 days before expiry, so checking every 6 hours is plenty frequent + // to pick up renewed certs promptly. + const renewalCheckIntervalMs = 6 * 60 * 60 * 1000; // 6 hours + if (timeSinceLastFetch > renewalCheckIntervalMs) { + // Check non-wildcard certs for expiry (within 45 days to match + // the server-side renewal window in certificate-service) + for (const domain of domainsNeedingCerts) { + const localState = + this.lastLocalCertificateState.get(domain); + if (localState?.expiresAt) { + const nowInSeconds = Math.floor(Date.now() / 1000); + const secondsUntilExpiry = + localState.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + logger.info( + `Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)` + ); + return true; + } + } + } + + // Also check wildcard certificates for expiry. These are not + // included in domainsNeedingCerts since their subdomains are + // filtered out, so we must check them separately. + for (const [certDomain, state] of this + .lastLocalCertificateState) { + if ( + state.exists && + state.wildcard && + state.expiresAt + ) { + const nowInSeconds = Math.floor(Date.now() / 1000); + const secondsUntilExpiry = + state.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + logger.info( + `Fetching certificates due to upcoming expiry for wildcard cert ${certDomain} (${Math.round(daysUntilExpiry)} days remaining)` + ); + return true; + } } } } @@ -361,6 +400,32 @@ export class TraefikConfigManager { } } + // Also include wildcard cert base domains that are + // expiring or expired so they get re-fetched even though + // their subdomains were filtered out above. + for (const [certDomain, state] of this + .lastLocalCertificateState) { + if ( + state.exists && + state.wildcard && + state.expiresAt + ) { + const nowInSeconds = Math.floor( + Date.now() / 1000 + ); + const secondsUntilExpiry = + state.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + domainsToFetch.add(certDomain); + logger.info( + `Including expiring wildcard cert domain ${certDomain} in fetch (${Math.round(daysUntilExpiry)} days remaining)` + ); + } + } + } + if (domainsToFetch.size > 0) { // Get valid certificates for domains not covered by wildcards validCertificates = From af688d2a232621c9f81a1357497446f74ea1ec79 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:35:04 -0700 Subject: [PATCH 22/46] Add demo link --- messages/en-US.json | 4 ++-- src/components/PaidFeaturesAlert.tsx | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index d84f4f337..6a35d79bb 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -2343,8 +2343,8 @@ "logRetentionEndOfFollowingYear": "End of following year", "actionLogsDescription": "View a history of actions performed in this organization", "accessLogsDescription": "View access auth requests for resources in this organization", - "licenseRequiredToUse": "An Enterprise Edition license or Pangolin Cloud is required to use this feature.", - "ossEnterpriseEditionRequired": "The Enterprise Edition is required to use this feature. This feature is also available in Pangolin Cloud.", + "licenseRequiredToUse": "An Enterprise Edition license or Pangolin Cloud is required to use this feature. Book a demo or POC trial.", + "ossEnterpriseEditionRequired": "The Enterprise Edition is required to use this feature. This feature is also available in Pangolin Cloud. Book a demo or POC trial.", "certResolver": "Certificate Resolver", "certResolverDescription": "Select the certificate resolver to use for this resource.", "selectCertResolver": "Select Certificate Resolver", diff --git a/src/components/PaidFeaturesAlert.tsx b/src/components/PaidFeaturesAlert.tsx index adbb49d9e..95179ea78 100644 --- a/src/components/PaidFeaturesAlert.tsx +++ b/src/components/PaidFeaturesAlert.tsx @@ -51,6 +51,7 @@ const docsLinkClassName = const PANGOLIN_CLOUD_SIGNUP_URL = "https://app.pangolin.net/auth/signup/"; const ENTERPRISE_DOCS_URL = "https://docs.pangolin.net/self-host/enterprise-edition"; +const BOOK_A_DEMO_URL = "https://click.fossorial.io/ep922"; function getTierLinkRenderer(billingHref: string) { return function tierLinkRenderer(chunks: React.ReactNode) { @@ -78,6 +79,22 @@ function getPangolinCloudLinkRenderer() { }; } +function getBookADemoLinkRenderer() { + return function bookADemoLinkRenderer(chunks: React.ReactNode) { + return ( + + {chunks} + + + ); + }; +} + function getDocsLinkRenderer(href: string) { return function docsLinkRenderer(chunks: React.ReactNode) { return ( @@ -116,6 +133,7 @@ export function PaidFeaturesAlert({ tiers }: Props) { const tierLinkRenderer = getTierLinkRenderer(billingHref); const pangolinCloudLinkRenderer = getPangolinCloudLinkRenderer(); const enterpriseDocsLinkRenderer = getDocsLinkRenderer(ENTERPRISE_DOCS_URL); + const bookADemoLinkRenderer = getBookADemoLinkRenderer(); if (env.flags.disableEnterpriseFeatures) { return null; @@ -157,7 +175,8 @@ export function PaidFeaturesAlert({ tiers }: Props) { {t.rich("licenseRequiredToUse", { enterpriseLicenseLink: enterpriseDocsLinkRenderer, - pangolinCloudLink: pangolinCloudLinkRenderer + pangolinCloudLink: pangolinCloudLinkRenderer, + bookADemoLink: bookADemoLinkRenderer })}
@@ -174,7 +193,8 @@ export function PaidFeaturesAlert({ tiers }: Props) { {t.rich("ossEnterpriseEditionRequired", { enterpriseEditionLink: enterpriseDocsLinkRenderer, - pangolinCloudLink: pangolinCloudLinkRenderer + pangolinCloudLink: pangolinCloudLinkRenderer, + bookADemoLink: bookADemoLinkRenderer })}
From 06015d51910d57463f8c5008de7ba50dc1e6c131 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:35:16 -0700 Subject: [PATCH 23/46] Handle gerbil rejecting 0 Closes #2605 --- server/lib/rebuildClientAssociations.ts | 4 ++-- server/routers/gerbil/getAllRelays.ts | 4 ++-- server/routers/gerbil/updateHolePunch.ts | 2 +- server/routers/newt/handleGetConfigMessage.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/lib/rebuildClientAssociations.ts b/server/lib/rebuildClientAssociations.ts index 625e57935..af43a6d00 100644 --- a/server/lib/rebuildClientAssociations.ts +++ b/server/lib/rebuildClientAssociations.ts @@ -571,7 +571,7 @@ export async function updateClientSiteDestinations( destinations: [ { destinationIP: site.sites.subnet.split("/")[0], - destinationPort: site.sites.listenPort || 0 + destinationPort: site.sites.listenPort || 1 // this satisfies gerbil for now but should be reevaluated } ] }; @@ -579,7 +579,7 @@ export async function updateClientSiteDestinations( // add to the existing destinations destinations.destinations.push({ destinationIP: site.sites.subnet.split("/")[0], - destinationPort: site.sites.listenPort || 0 + destinationPort: site.sites.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }); } diff --git a/server/routers/gerbil/getAllRelays.ts b/server/routers/gerbil/getAllRelays.ts index b7d33b955..bbe314b2a 100644 --- a/server/routers/gerbil/getAllRelays.ts +++ b/server/routers/gerbil/getAllRelays.ts @@ -125,7 +125,7 @@ export async function generateRelayMappings(exitNode: ExitNode) { // Add site as a destination for this client const destination: PeerDestination = { destinationIP: site.subnet.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }; // Check if this destination is already in the array to avoid duplicates @@ -165,7 +165,7 @@ export async function generateRelayMappings(exitNode: ExitNode) { const destination: PeerDestination = { destinationIP: peer.subnet.split("/")[0], - destinationPort: peer.listenPort + destinationPort: peer.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }; // Check for duplicates diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index 3f24430bf..13d0ed276 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -262,7 +262,7 @@ export async function updateAndGenerateEndpointDestinations( if (site.subnet && site.listenPort) { destinations.push({ destinationIP: site.subnet.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }); } } diff --git a/server/routers/newt/handleGetConfigMessage.ts b/server/routers/newt/handleGetConfigMessage.ts index 801c8b65a..24cca17a2 100644 --- a/server/routers/newt/handleGetConfigMessage.ts +++ b/server/routers/newt/handleGetConfigMessage.ts @@ -104,11 +104,11 @@ export const handleGetConfigMessage: MessageHandler = async (context) => { const payload = { oldDestination: { destinationIP: existingSite.subnet?.split("/")[0], - destinationPort: existingSite.listenPort + destinationPort: existingSite.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }, newDestination: { destinationIP: site.subnet?.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated } }; From e9a2a7e75246ed0c8313a3d5ae5fd70ba3882bcd Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 20:46:27 -0700 Subject: [PATCH 24/46] Reorder delete --- server/lib/deleteOrg.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index cca2ea974..86c32e9a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -121,6 +121,9 @@ export async function deleteOrgById( eq(clientSitesAssociationsCache.clientId, client.clientId) ); } + + await trx.delete(resources).where(eq(resources.orgId, orgId)); + const allOrgDomains = await trx .select() .from(orgDomains) @@ -147,7 +150,6 @@ export async function deleteOrgById( .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); } - await trx.delete(resources).where(eq(resources.orgId, orgId)); await usageService.add(orgId, FeatureId.ORGINIZATIONS, -1, trx); // here we are decreasing the org count BEFORE deleting the org because we need to still be able to get the org to get the billing org inside of here From e98f873f8103aede2909527cfd43fce55b92e8b5 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 21:16:37 -0700 Subject: [PATCH 25/46] Clean up --- server/lib/deleteOrg.ts | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index 86c32e9a1..56f2848a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -85,9 +85,7 @@ export async function deleteOrgById( deletedNewtIds.push(deletedNewt.newtId); await trx .delete(newtSessions) - .where( - eq(newtSessions.newtId, deletedNewt.newtId) - ); + .where(eq(newtSessions.newtId, deletedNewt.newtId)); } } } @@ -127,7 +125,7 @@ export async function deleteOrgById( const allOrgDomains = await trx .select() .from(orgDomains) - .innerJoin(domains, eq(domains.domainId, orgDomains.domainId)) + .innerJoin(domains, eq(orgDomains.domainId, domains.domainId)) .where( and( eq(orgDomains.orgId, orgId), @@ -136,16 +134,17 @@ export async function deleteOrgById( ); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { - const domainId = orgDomain.domains.domainId; + const domainId = orgDomain.domainId; const orgCount = await trx - .select({ count: sql`count(*)` }) + .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); - if (orgCount[0].count === 1) { + if (orgCount[0].count == 1) { domainIdsToDelete.push(domainId); } } if (domainIdsToDelete.length > 0) { + // delete the orgDomain await trx .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); @@ -233,15 +232,13 @@ export function sendTerminationMessages(result: DeleteOrgByIdResult): void { ); } for (const olmId of result.olmsToTerminate) { - sendTerminateClient( - 0, - OlmErrorCodes.TERMINATED_REKEYED, - olmId - ).catch((error) => { - logger.error( - "Failed to send termination message to olm:", - error - ); - }); + sendTerminateClient(0, OlmErrorCodes.TERMINATED_REKEYED, olmId).catch( + (error) => { + logger.error( + "Failed to send termination message to olm:", + error + ); + } + ); } } From dec358c4cde83835612f83fe0d7c90ccde313882 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 10:03:49 -0700 Subject: [PATCH 26/46] Use native drizzle count --- server/lib/deleteOrg.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index 56f2848a1..b32667d24 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -134,17 +134,16 @@ export async function deleteOrgById( ); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { - const domainId = orgDomain.domainId; - const orgCount = await trx + const domainId = orgDomain.domains.domainId; + const [orgCount] = await trx .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); - if (orgCount[0].count == 1) { + if (orgCount.count === 1) { domainIdsToDelete.push(domainId); } } if (domainIdsToDelete.length > 0) { - // delete the orgDomain await trx .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); From fa0818d3faac56a02fb98f7df2f9e8ae49172977 Mon Sep 17 00:00:00 2001 From: Shreyas Papinwar Date: Tue, 10 Mar 2026 12:01:24 +0530 Subject: [PATCH 27/46] fix: ensure Credenza dialog max-height --- src/components/Credenza.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Credenza.tsx b/src/components/Credenza.tsx index 63b847462..63b98c671 100644 --- a/src/components/Credenza.tsx +++ b/src/components/Credenza.tsx @@ -84,7 +84,7 @@ const CredenzaContent = ({ className, children, ...props }: CredenzaProps) => { return ( Date: Tue, 10 Mar 2026 14:24:57 -0700 Subject: [PATCH 28/46] Add some logging to debug --- server/lib/deleteOrg.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index b32667d24..065f216a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -132,6 +132,7 @@ export async function deleteOrgById( eq(domains.configManaged, false) ) ); + logger.info(`Found ${allOrgDomains.length} domains to delete`); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { const domainId = orgDomain.domains.domainId; @@ -139,10 +140,12 @@ export async function deleteOrgById( .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); + logger.info(`Found ${orgCount.count} orgs using domain ${domainId}`); if (orgCount.count === 1) { domainIdsToDelete.push(domainId); } } + logger.info(`Found ${domainIdsToDelete.length} domains to delete`); if (domainIdsToDelete.length > 0) { await trx .delete(domains) From 2ba225299e60c57a902a3cb950a17e3864749479 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 01:38:15 +0000 Subject: [PATCH 29/46] Bump the dev-minor-updates group across 1 directory with 5 updates Bumps the dev-minor-updates group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@dotenvx/dotenvx](https://github.com/dotenvx/dotenvx) | `1.52.0` | `1.53.0` | | [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss) | `4.1.18` | `4.2.1` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.2.3` | `25.3.5` | | [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.1.18` | `4.2.1` | | [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.55.0` | `8.56.1` | Updates `@dotenvx/dotenvx` from 1.52.0 to 1.53.0 - [Release notes](https://github.com/dotenvx/dotenvx/releases) - [Changelog](https://github.com/dotenvx/dotenvx/blob/main/CHANGELOG.md) - [Commits](https://github.com/dotenvx/dotenvx/compare/v1.52.0...v1.53.0) Updates `@tailwindcss/postcss` from 4.1.18 to 4.2.1 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.1/packages/@tailwindcss-postcss) Updates `@types/node` from 25.2.3 to 25.3.5 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `tailwindcss` from 4.1.18 to 4.2.1 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.1/packages/tailwindcss) Updates `typescript-eslint` from 8.55.0 to 8.56.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: "@dotenvx/dotenvx" dependency-version: 1.53.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates - dependency-name: "@tailwindcss/postcss" dependency-version: 4.2.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates - dependency-name: "@types/node" dependency-version: 25.3.5 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates - dependency-name: tailwindcss dependency-version: 4.2.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates - dependency-name: typescript-eslint dependency-version: 8.56.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates ... Signed-off-by: dependabot[bot] --- package-lock.json | 489 ++++++++++++++++++++++++---------------------- package.json | 10 +- 2 files changed, 265 insertions(+), 234 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3e070b8ad..3fa1177d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -108,10 +108,10 @@ "zod-validation-error": "5.0.0" }, "devDependencies": { - "@dotenvx/dotenvx": "1.52.0", + "@dotenvx/dotenvx": "1.54.1", "@esbuild-plugins/tsconfig-paths": "0.1.2", "@react-email/preview-server": "5.2.8", - "@tailwindcss/postcss": "4.1.18", + "@tailwindcss/postcss": "4.2.1", "@tanstack/react-query-devtools": "5.91.3", "@types/better-sqlite3": "7.6.13", "@types/cookie-parser": "1.4.10", @@ -123,7 +123,7 @@ "@types/jmespath": "0.15.2", "@types/js-yaml": "4.0.9", "@types/jsonwebtoken": "9.0.10", - "@types/node": "25.2.3", + "@types/node": "25.3.5", "@types/nodemailer": "7.0.11", "@types/nprogress": "0.2.3", "@types/pg": "8.16.0", @@ -144,11 +144,11 @@ "postcss": "8.5.6", "prettier": "3.8.1", "react-email": "5.2.8", - "tailwindcss": "4.1.18", + "tailwindcss": "4.2.1", "tsc-alias": "1.8.16", "tsx": "4.21.0", "typescript": "5.9.3", - "typescript-eslint": "8.55.0" + "typescript-eslint": "8.56.1" } }, "node_modules/@alloc/quick-lru": { @@ -1454,9 +1454,9 @@ "license": "MIT" }, "node_modules/@dotenvx/dotenvx": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.52.0.tgz", - "integrity": "sha512-CaQcc8JvtzQhUSm9877b6V4Tb7HCotkcyud9X2YwdqtQKwgljkMRwU96fVYKnzN3V0Hj74oP7Es+vZ0mS+Aa1w==", + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.54.1.tgz", + "integrity": "sha512-41gU3q7v05GM92QPuPUf4CmUw+mmF8p4wLUh6MCRlxpCkJ9ByLcY9jUf6MwrMNmiKyG/rIckNxj9SCfmNCmCqw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -8960,49 +8960,49 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", - "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "enhanced-resolve": "^5.18.3", + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", - "lightningcss": "1.30.2", + "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.18" + "tailwindcss": "4.2.1" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", - "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10" + "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-x64": "4.1.18", - "@tailwindcss/oxide-freebsd-x64": "4.1.18", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-x64-musl": "4.1.18", - "@tailwindcss/oxide-wasm32-wasi": "4.1.18", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", - "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", "cpu": [ "arm64" ], @@ -9013,13 +9013,13 @@ "android" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", - "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", "cpu": [ "arm64" ], @@ -9030,13 +9030,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", - "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", "cpu": [ "x64" ], @@ -9047,13 +9047,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", - "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", "cpu": [ "x64" ], @@ -9064,13 +9064,13 @@ "freebsd" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", - "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", "cpu": [ "arm" ], @@ -9081,13 +9081,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", - "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", "cpu": [ "arm64" ], @@ -9098,13 +9098,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", - "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", "cpu": [ "arm64" ], @@ -9115,13 +9115,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", - "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", "cpu": [ "x64" ], @@ -9132,13 +9132,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", - "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", "cpu": [ "x64" ], @@ -9149,13 +9149,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", - "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -9171,19 +9171,19 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.4.0" + "tslib": "^2.8.1" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.7.1", + "version": "1.8.1", "dev": true, "inBundle": true, "license": "MIT", @@ -9194,7 +9194,7 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.7.1", + "version": "1.8.1", "dev": true, "inBundle": true, "license": "MIT", @@ -9214,7 +9214,7 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.0", + "version": "1.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -9223,6 +9223,10 @@ "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { @@ -9243,9 +9247,9 @@ "optional": true }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", - "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", "cpu": [ "arm64" ], @@ -9256,13 +9260,13 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", - "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", "cpu": [ "x64" ], @@ -9273,21 +9277,21 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz", - "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.2.1.tgz", + "integrity": "sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==", "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.18", - "@tailwindcss/oxide": "4.1.18", - "postcss": "^8.4.41", - "tailwindcss": "4.1.18" + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "postcss": "^8.5.6", + "tailwindcss": "4.2.1" } }, "node_modules/@tanstack/query-core": { @@ -9860,12 +9864,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", - "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", + "version": "25.3.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.5.tgz", + "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==", "devOptional": true, + "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/nodemailer": { @@ -10043,16 +10048,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", - "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/type-utils": "8.55.0", - "@typescript-eslint/utils": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -10065,8 +10071,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.55.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -10075,20 +10081,22 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz", - "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "engines": { @@ -10099,18 +10107,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", - "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.55.0", - "@typescript-eslint/types": "^8.55.0", + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "engines": { @@ -10125,13 +10134,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10142,10 +10152,11 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", - "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -10158,14 +10169,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz", - "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -10177,15 +10189,16 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -10195,17 +10208,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.55.0", - "@typescript-eslint/tsconfig-utils": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -10232,9 +10246,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { @@ -10245,31 +10259,32 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10279,18 +10294,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10300,6 +10316,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", @@ -13533,14 +13562,14 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.4", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", - "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -16226,9 +16255,9 @@ } }, "node_modules/lightningcss": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", - "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", + "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -16242,23 +16271,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.30.2", - "lightningcss-darwin-arm64": "1.30.2", - "lightningcss-darwin-x64": "1.30.2", - "lightningcss-freebsd-x64": "1.30.2", - "lightningcss-linux-arm-gnueabihf": "1.30.2", - "lightningcss-linux-arm64-gnu": "1.30.2", - "lightningcss-linux-arm64-musl": "1.30.2", - "lightningcss-linux-x64-gnu": "1.30.2", - "lightningcss-linux-x64-musl": "1.30.2", - "lightningcss-win32-arm64-msvc": "1.30.2", - "lightningcss-win32-x64-msvc": "1.30.2" + "lightningcss-android-arm64": "1.31.1", + "lightningcss-darwin-arm64": "1.31.1", + "lightningcss-darwin-x64": "1.31.1", + "lightningcss-freebsd-x64": "1.31.1", + "lightningcss-linux-arm-gnueabihf": "1.31.1", + "lightningcss-linux-arm64-gnu": "1.31.1", + "lightningcss-linux-arm64-musl": "1.31.1", + "lightningcss-linux-x64-gnu": "1.31.1", + "lightningcss-linux-x64-musl": "1.31.1", + "lightningcss-win32-arm64-msvc": "1.31.1", + "lightningcss-win32-x64-msvc": "1.31.1" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", "cpu": [ "arm64" ], @@ -16277,9 +16306,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", + "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", "cpu": [ "arm64" ], @@ -16298,9 +16327,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", "cpu": [ "x64" ], @@ -16319,9 +16348,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", "cpu": [ "x64" ], @@ -16340,9 +16369,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", "cpu": [ "arm" ], @@ -16361,9 +16390,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", "cpu": [ "arm64" ], @@ -16382,9 +16411,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", "cpu": [ "arm64" ], @@ -16403,9 +16432,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", "cpu": [ "x64" ], @@ -16424,9 +16453,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", "cpu": [ "x64" ], @@ -16445,9 +16474,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", "cpu": [ "arm64" ], @@ -16466,9 +16495,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", "cpu": [ "x64" ], @@ -20741,9 +20770,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", - "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", + "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", "license": "MIT" }, "node_modules/tapable": { @@ -20891,6 +20920,7 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.12" }, @@ -21227,15 +21257,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.55.0.tgz", - "integrity": "sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.1.tgz", + "integrity": "sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.55.0", - "@typescript-eslint/parser": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0" + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -21245,7 +21276,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -21282,9 +21313,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "devOptional": true, "license": "MIT" }, diff --git a/package.json b/package.json index df92d1a64..f0bb0b9b4 100644 --- a/package.json +++ b/package.json @@ -131,10 +131,10 @@ "zod-validation-error": "5.0.0" }, "devDependencies": { - "@dotenvx/dotenvx": "1.52.0", + "@dotenvx/dotenvx": "1.54.1", "@esbuild-plugins/tsconfig-paths": "0.1.2", "@react-email/preview-server": "5.2.8", - "@tailwindcss/postcss": "4.1.18", + "@tailwindcss/postcss": "4.2.1", "@tanstack/react-query-devtools": "5.91.3", "@types/better-sqlite3": "7.6.13", "@types/cookie-parser": "1.4.10", @@ -146,7 +146,7 @@ "@types/jmespath": "0.15.2", "@types/js-yaml": "4.0.9", "@types/jsonwebtoken": "9.0.10", - "@types/node": "25.2.3", + "@types/node": "25.3.5", "@types/nodemailer": "7.0.11", "@types/nprogress": "0.2.3", "@types/pg": "8.16.0", @@ -167,10 +167,10 @@ "postcss": "8.5.6", "prettier": "3.8.1", "react-email": "5.2.8", - "tailwindcss": "4.1.18", + "tailwindcss": "4.2.1", "tsc-alias": "1.8.16", "tsx": "4.21.0", "typescript": "5.9.3", - "typescript-eslint": "8.55.0" + "typescript-eslint": "8.56.1" } } From 42b9d5158dde72b895e2de10a9ae8ee7c590daab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 01:40:39 +0000 Subject: [PATCH 30/46] Bump the prod-minor-updates group across 1 directory with 10 updates Bumps the prod-minor-updates group with 10 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) | `3.989.0` | `3.1003.0` | | [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) | `8.2.1` | `8.3.0` | | [ioredis](https://github.com/luin/ioredis) | `5.9.3` | `5.10.0` | | [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `0.563.0` | `0.577.0` | | [pg](https://github.com/brianc/node-postgres/tree/HEAD/packages/pg) | `8.19.0` | `8.20.0` | | [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.26.0` | `5.28.0` | | [react-day-picker](https://github.com/gpbl/react-day-picker) | `9.13.2` | `9.14.0` | | [react-icons](https://github.com/react-icons/react-icons) | `5.5.0` | `5.6.0` | | reodotdev | `1.0.0` | `1.1.0` | | [stripe](https://github.com/stripe/stripe-node) | `20.3.1` | `20.4.0` | Updates `@aws-sdk/client-s3` from 3.989.0 to 3.1003.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1003.0/clients/client-s3) Updates `express-rate-limit` from 8.2.1 to 8.3.0 - [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases) - [Commits](https://github.com/express-rate-limit/express-rate-limit/compare/v8.2.1...v8.3.0) Updates `ioredis` from 5.9.3 to 5.10.0 - [Release notes](https://github.com/luin/ioredis/releases) - [Changelog](https://github.com/redis/ioredis/blob/main/CHANGELOG.md) - [Commits](https://github.com/luin/ioredis/compare/v5.9.3...v5.10.0) Updates `lucide-react` from 0.563.0 to 0.577.0 - [Release notes](https://github.com/lucide-icons/lucide/releases) - [Commits](https://github.com/lucide-icons/lucide/commits/0.577.0/packages/lucide-react) Updates `pg` from 8.19.0 to 8.20.0 - [Changelog](https://github.com/brianc/node-postgres/blob/master/CHANGELOG.md) - [Commits](https://github.com/brianc/node-postgres/commits/pg@8.20.0/packages/pg) Updates `posthog-node` from 5.26.0 to 5.28.0 - [Release notes](https://github.com/PostHog/posthog-js/releases) - [Changelog](https://github.com/PostHog/posthog-js/blob/main/packages/node/CHANGELOG.md) - [Commits](https://github.com/PostHog/posthog-js/commits/posthog-node@5.28.0/packages/node) Updates `react-day-picker` from 9.13.2 to 9.14.0 - [Release notes](https://github.com/gpbl/react-day-picker/releases) - [Changelog](https://github.com/gpbl/react-day-picker/blob/main/CHANGELOG.md) - [Commits](https://github.com/gpbl/react-day-picker/compare/v9.13.2...v9.14.0) Updates `react-icons` from 5.5.0 to 5.6.0 - [Release notes](https://github.com/react-icons/react-icons/releases) - [Commits](https://github.com/react-icons/react-icons/compare/v5.5.0...v5.6.0) Updates `reodotdev` from 1.0.0 to 1.1.0 Updates `stripe` from 20.3.1 to 20.4.0 - [Release notes](https://github.com/stripe/stripe-node/releases) - [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/stripe/stripe-node/compare/v20.3.1...v20.4.0) --- updated-dependencies: - dependency-name: "@aws-sdk/client-s3" dependency-version: 3.1003.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: express-rate-limit dependency-version: 8.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: ioredis dependency-version: 5.10.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: lucide-react dependency-version: 0.577.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: pg dependency-version: 8.20.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: posthog-node dependency-version: 5.28.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: react-day-picker dependency-version: 9.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: react-icons dependency-version: 5.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: reodotdev dependency-version: 1.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: stripe dependency-version: 20.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates ... Signed-off-by: dependabot[bot] --- package-lock.json | 1464 +++++++++++++++++++++++---------------------- package.json | 22 +- 2 files changed, 766 insertions(+), 720 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3fa1177d5..9e3b0e759 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "SEE LICENSE IN LICENSE AND README.md", "dependencies": { "@asteasolutions/zod-to-openapi": "8.4.1", - "@aws-sdk/client-s3": "3.989.0", + "@aws-sdk/client-s3": "3.1004.0", "@faker-js/faker": "10.3.0", "@headlessui/react": "2.2.9", "@hookform/resolvers": "5.2.2", @@ -57,16 +57,16 @@ "d3": "7.9.0", "drizzle-orm": "0.45.1", "express": "5.2.1", - "express-rate-limit": "8.2.2", + "express-rate-limit": "8.3.0", "glob": "13.0.6", "helmet": "8.1.0", "http-errors": "2.0.1", "input-otp": "1.4.2", - "ioredis": "5.9.3", + "ioredis": "5.10.0", "jmespath": "0.16.0", "js-yaml": "4.1.1", "jsonwebtoken": "9.0.3", - "lucide-react": "0.563.0", + "lucide-react": "0.577.0", "maxmind": "5.0.5", "moment": "2.30.1", "next": "15.5.12", @@ -76,21 +76,21 @@ "node-cache": "5.1.2", "nodemailer": "8.0.1", "oslo": "1.2.1", - "pg": "8.19.0", - "posthog-node": "5.26.0", + "pg": "8.20.0", + "posthog-node": "5.28.0", "qrcode.react": "4.2.0", "react": "19.2.4", - "react-day-picker": "9.13.2", + "react-day-picker": "9.14.0", "react-dom": "19.2.4", "react-easy-sort": "1.8.0", "react-hook-form": "7.71.2", - "react-icons": "5.5.0", + "react-icons": "5.6.0", "recharts": "2.15.4", - "reodotdev": "1.0.0", + "reodotdev": "1.1.0", "resend": "6.9.2", "semver": "7.7.4", "sshpk": "^1.18.0", - "stripe": "20.3.1", + "stripe": "20.4.1", "swagger-ui-express": "5.0.1", "tailwind-merge": "3.5.0", "topojson-client": "3.1.0", @@ -126,7 +126,7 @@ "@types/node": "25.3.5", "@types/nodemailer": "7.0.11", "@types/nprogress": "0.2.3", - "@types/pg": "8.16.0", + "@types/pg": "8.18.0", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", "@types/semver": "7.7.1", @@ -208,6 +208,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -270,6 +271,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", @@ -284,6 +286,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -295,6 +298,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -307,6 +311,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -319,6 +324,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -387,112 +393,65 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.989.0.tgz", - "integrity": "sha512-ccz2miIetWAgrJYmKCpSnRjF8jew7DPstl54nufhfPMtM1MLxD2z55eSk1eJj3Umhu4CioNN1aY1ILT7fwlSiw==", + "version": "3.1004.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1004.0.tgz", + "integrity": "sha512-m0zNfpsona9jQdX1cHtHArOiuvSGZPsgp/KRZS2YjJhKah96G2UN3UNGZQ6aVjXIQjCY6UanCJo0uW9Xf2U41w==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/credential-provider-node": "^3.972.8", - "@aws-sdk/middleware-bucket-endpoint": "^3.972.3", - "@aws-sdk/middleware-expect-continue": "^3.972.3", - "@aws-sdk/middleware-flexible-checksums": "^3.972.7", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-location-constraint": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-sdk-s3": "^3.972.9", - "@aws-sdk/middleware-ssec": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/signature-v4-multi-region": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.23.0", - "@smithy/eventstream-serde-browser": "^4.2.8", - "@smithy/eventstream-serde-config-resolver": "^4.3.8", - "@smithy/eventstream-serde-node": "^4.2.8", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-blob-browser": "^4.2.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/hash-stream-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/md5-js": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.14", - "@smithy/middleware-retry": "^4.4.31", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.30", - "@smithy/util-defaults-mode-node": "^4.2.33", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-stream": "^4.5.12", - "@smithy/util-utf8": "^4.2.0", - "@smithy/util-waiter": "^4.2.8", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.989.0.tgz", - "integrity": "sha512-3sC+J1ru5VFXLgt9KZmXto0M7mnV5RkS6FNGwRMK3XrojSjHso9DLOWjbnXhbNv4motH8vu53L1HK2VC1+Nj5w==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.23.0", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.14", - "@smithy/middleware-retry": "^4.4.31", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.30", - "@smithy/util-defaults-mode-node": "^4.2.33", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/credential-provider-node": "^3.972.18", + "@aws-sdk/middleware-bucket-endpoint": "^3.972.7", + "@aws-sdk/middleware-expect-continue": "^3.972.7", + "@aws-sdk/middleware-flexible-checksums": "^3.973.4", + "@aws-sdk/middleware-host-header": "^3.972.7", + "@aws-sdk/middleware-location-constraint": "^3.972.7", + "@aws-sdk/middleware-logger": "^3.972.7", + "@aws-sdk/middleware-recursion-detection": "^3.972.7", + "@aws-sdk/middleware-sdk-s3": "^3.972.18", + "@aws-sdk/middleware-ssec": "^3.972.7", + "@aws-sdk/middleware-user-agent": "^3.972.19", + "@aws-sdk/region-config-resolver": "^3.972.7", + "@aws-sdk/signature-v4-multi-region": "^3.996.6", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@aws-sdk/util-user-agent-browser": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.973.4", + "@smithy/config-resolver": "^4.4.10", + "@smithy/core": "^3.23.8", + "@smithy/eventstream-serde-browser": "^4.2.11", + "@smithy/eventstream-serde-config-resolver": "^4.3.11", + "@smithy/eventstream-serde-node": "^4.2.11", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/hash-blob-browser": "^4.2.12", + "@smithy/hash-node": "^4.2.11", + "@smithy/hash-stream-node": "^4.2.11", + "@smithy/invalid-dependency": "^4.2.11", + "@smithy/md5-js": "^4.2.11", + "@smithy/middleware-content-length": "^4.2.11", + "@smithy/middleware-endpoint": "^4.4.22", + "@smithy/middleware-retry": "^4.4.39", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.38", + "@smithy/util-defaults-mode-node": "^4.2.41", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -500,22 +459,23 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.973.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.9.tgz", - "integrity": "sha512-cyUOfJSizn8da7XrBEFBf4UMI4A6JQNX6ZFcKtYmh/CrwfzsDcabv3k/z0bNwQ3pX5aeq5sg/8Bs/ASiL0bJaA==", + "version": "3.973.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.18.tgz", + "integrity": "sha512-GUIlegfcK2LO1J2Y98sCJy63rQSiLiDOgVw7HiHPRqfI2vb3XozTVqemwO0VSGXp54ngCnAQz0Lf0YPCBINNxA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/xml-builder": "^3.972.4", - "@smithy/core": "^3.23.0", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/xml-builder": "^3.972.10", + "@smithy/core": "^3.23.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/signature-v4": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -523,11 +483,12 @@ } }, "node_modules/@aws-sdk/crc64-nvme": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.0.tgz", - "integrity": "sha512-ThlLhTqX68jvoIVv+pryOdb5coP1cX1/MaTbB9xkGDCbWbsqQcLqzPxuSoW1DCnAAIacmXCWpzUNOB9pv+xXQw==", + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.4.tgz", + "integrity": "sha512-HKZIZLbRyvzo/bXZU7Zmk6XqU+1C9DjI56xd02vwuDIxedxBEqP17t9ExhbP9QFeNq/a3l9GOcyirFXxmbDhmw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -535,14 +496,15 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.7.tgz", - "integrity": "sha512-r8kBtglvLjGxBT87l6Lqkh9fL8yJJ6O4CYQPjKlj3AkCuL4/4784x3rxxXWw9LTKXOo114VB6mjxAuy5pI7XIg==", + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.16.tgz", + "integrity": "sha512-HrdtnadvTGAQUr18sPzGlE5El3ICphnH6SU7UQOMOWFgRKbTRNN8msTxM4emzguUso9CzaHU2xy5ctSrmK5YNA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -550,19 +512,20 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.9.tgz", - "integrity": "sha512-40caFblEg/TPrp9EpvyMxp4xlJ5TuTI+A8H6g8FhHn2hfH2PObFAPLF9d5AljK/G69E1YtTklkuQeAwPlV3w8Q==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.18.tgz", + "integrity": "sha512-NyB6smuZAixND5jZumkpkunQ0voc4Mwgkd+SZ6cvAzIB7gK8HV8Zd4rS8Kn5MmoGgusyNfVGG+RLoYc4yFiw+A==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/util-stream": "^4.5.12", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" }, "engines": { @@ -570,23 +533,24 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.7.tgz", - "integrity": "sha512-zeYKrMwM5bCkHFho/x3+1OL0vcZQ0OhTR7k35tLq74+GP5ieV3juHXTZfa2LVE0Bg75cHIIerpX0gomVOhzo/w==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.17.tgz", + "integrity": "sha512-dFqh7nfX43B8dO1aPQHOcjC0SnCJ83H3F+1LoCh3X1P7E7N09I+0/taID0asU6GCddfDExqnEvQtDdkuMe5tKQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/credential-provider-env": "^3.972.7", - "@aws-sdk/credential-provider-http": "^3.972.9", - "@aws-sdk/credential-provider-login": "^3.972.7", - "@aws-sdk/credential-provider-process": "^3.972.7", - "@aws-sdk/credential-provider-sso": "^3.972.7", - "@aws-sdk/credential-provider-web-identity": "^3.972.7", - "@aws-sdk/nested-clients": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/credential-provider-env": "^3.972.16", + "@aws-sdk/credential-provider-http": "^3.972.18", + "@aws-sdk/credential-provider-login": "^3.972.17", + "@aws-sdk/credential-provider-process": "^3.972.16", + "@aws-sdk/credential-provider-sso": "^3.972.17", + "@aws-sdk/credential-provider-web-identity": "^3.972.17", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/types": "^3.973.5", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -594,17 +558,18 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.7.tgz", - "integrity": "sha512-Q103cLU6OjAllYjX7+V+PKQw654jjvZUkD+lbUUiFbqut6gR5zwl1DrelvJPM5hnzIty7BCaxaRB3KMuz3M/ug==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.17.tgz", + "integrity": "sha512-gf2E5b7LpKb+JX2oQsRIDxdRZjBFZt2olCGlWCdb3vBERbXIPgm2t1R5mEnwd4j0UEO/Tbg5zN2KJbHXttJqwA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -612,21 +577,22 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.8.tgz", - "integrity": "sha512-AaDVOT7iNJyLjc3j91VlucPZ4J8Bw+eu9sllRDugJqhHWYyR3Iyp2huBUW8A3+DfHoh70sxGkY92cThAicSzlQ==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.18.tgz", + "integrity": "sha512-ZDJa2gd1xiPg/nBDGhUlat02O8obaDEnICBAVS8qieZ0+nDfaB0Z3ec6gjZj27OqFTjnB/Q5a0GwQwb7rMVViw==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.7", - "@aws-sdk/credential-provider-http": "^3.972.9", - "@aws-sdk/credential-provider-ini": "^3.972.7", - "@aws-sdk/credential-provider-process": "^3.972.7", - "@aws-sdk/credential-provider-sso": "^3.972.7", - "@aws-sdk/credential-provider-web-identity": "^3.972.7", - "@aws-sdk/types": "^3.973.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/credential-provider-env": "^3.972.16", + "@aws-sdk/credential-provider-http": "^3.972.18", + "@aws-sdk/credential-provider-ini": "^3.972.17", + "@aws-sdk/credential-provider-process": "^3.972.16", + "@aws-sdk/credential-provider-sso": "^3.972.17", + "@aws-sdk/credential-provider-web-identity": "^3.972.17", + "@aws-sdk/types": "^3.973.5", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -634,15 +600,16 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.7.tgz", - "integrity": "sha512-hxMo1V3ujWWrQSONxQJAElnjredkRpB6p8SDjnvRq70IwYY38R/CZSys0IbhRPxdgWZ5j12yDRk2OXhxw4Gj3g==", + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.16.tgz", + "integrity": "sha512-n89ibATwnLEg0ZdZmUds5bq8AfBAdoYEDpqP3uzPLaRuGelsKlIvCYSNNvfgGLi8NaHPNNhs1HjJZYbqkW9b+g==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -650,17 +617,18 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.7.tgz", - "integrity": "sha512-ZGKBOHEj8Ap15jhG2XMncQmKLTqA++2DVU2eZfLu3T/pkwDyhCp5eZv5c/acFxbZcA/6mtxke+vzO/n+aeHs4A==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.17.tgz", + "integrity": "sha512-wGtte+48xnhnhHMl/MsxzacBPs5A+7JJedjiP452IkHY7vsbYKcvQBqFye8LwdTJVeHtBHv+JFeTscnwepoWGg==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.989.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/token-providers": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/token-providers": "3.1004.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -668,16 +636,17 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.7.tgz", - "integrity": "sha512-AbYupBIoSJoVMlbMqBhNvPhqj+CdGtzW7Uk4ZIMBm2br18pc3rkG1VaKVFV85H87QCvLHEnni1idJjaX1wOmIw==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.17.tgz", + "integrity": "sha512-8aiVJh6fTdl8gcyL+sVNcNwTtWpmoFa1Sh7xlj6Z7L/cZ/tYMEBHq44wTYG8Kt0z/PpGNopD89nbj3FHl9QmTA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -685,17 +654,17 @@ } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.3.tgz", - "integrity": "sha512-fmbgWYirF67YF1GfD7cg5N6HHQ96EyRNx/rDIrTF277/zTWVuPI2qS/ZHgofwR1NZPe/NWvoppflQY01LrbVLg==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.7.tgz", + "integrity": "sha512-goX+axlJ6PQlRnzE2bQisZ8wVrlm6dXJfBzMJhd8LhAIBan/w1Kl73fJnalM/S+18VnpzIHumyV6DtgmvqG5IA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-arn-parser": "^3.972.2", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -703,14 +672,14 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.3.tgz", - "integrity": "sha512-4msC33RZsXQpUKR5QR4HnvBSNCPLGHmB55oDiROqqgyOc+TOfVu2xgi5goA7ms6MdZLeEh2905UfWMnMMF4mRg==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.7.tgz", + "integrity": "sha512-mvWqvm61bmZUKmmrtl2uWbokqpenY3Mc3Jf4nXB/Hse6gWxLPaCQThmhPBDzsPSV8/Odn8V6ovWt3pZ7vy4BFQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -718,23 +687,24 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.7.tgz", - "integrity": "sha512-YU/5rpz8k2mwFGi2M0px9ChOQZY7Bbow5knB2WLRVPqDM/cG8T5zj55UaWS1qcaFpE7vCX9a9/kvYBlKGcD+KA==", + "version": "3.973.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.973.4.tgz", + "integrity": "sha512-7CH2jcGmkvkHc5Buz9IGbdjq1729AAlgYJiAvGq7qhCHqYleCsriWdSnmsqWTwdAfXHMT+pkxX3w6v5tJNcSug==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/crc64-nvme": "3.972.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/is-array-buffer": "^4.2.0", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.12", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/crc64-nvme": "^3.972.4", + "@aws-sdk/types": "^3.973.5", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -742,13 +712,14 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.3.tgz", - "integrity": "sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.7.tgz", + "integrity": "sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -756,13 +727,13 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.3.tgz", - "integrity": "sha512-nIg64CVrsXp67vbK0U1/Is8rik3huS3QkRHn2DRDx4NldrEFMgdkZGI/+cZMKD9k4YOS110Dfu21KZLHrFA/1g==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.7.tgz", + "integrity": "sha512-vdK1LJfffBp87Lj0Bw3WdK1rJk9OLDYdQpqoKgmpIZPe+4+HawZ6THTbvjhJt4C4MNnRrHTKHQjkwBiIpDBoig==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -770,12 +741,13 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.3.tgz", - "integrity": "sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.7.tgz", + "integrity": "sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -783,14 +755,15 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.3.tgz", - "integrity": "sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.7.tgz", + "integrity": "sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", + "@aws-sdk/types": "^3.973.5", "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -798,23 +771,24 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.9.tgz", - "integrity": "sha512-F4Ak2HM7te/o3izFTqg/jUTBLjavpaJ5iynKM6aLMwNddXbwAZQ1VbIG8RFUHBo7fBHj2eeN2FNLtIFT4ejWYQ==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.18.tgz", + "integrity": "sha512-5E3XxaElrdyk6ZJ0TjH7Qm6ios4b/qQCiLr6oQ8NK7e4Kn6JBTJCaYioQCQ65BpZ1+l1mK5wTAac2+pEz0Smpw==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-arn-parser": "^3.972.2", - "@smithy/core": "^3.23.0", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.12", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/core": "^3.23.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/signature-v4": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -822,13 +796,13 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.3.tgz", - "integrity": "sha512-dU6kDuULN3o3jEHcjm0c4zWJlY1zWVkjG9NPe9qxYLLpcbdj5kRYBS2DdWYD+1B9f910DezRuws7xDEqKkHQIg==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.7.tgz", + "integrity": "sha512-G9clGVuAml7d8DYzY6DnRi7TIIDRvZ3YpqJPz/8wnWS5fYx/FNWNmkO6iJVlVkQg9BfeMzd+bVPtPJOvC4B+nQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -836,16 +810,18 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.9.tgz", - "integrity": "sha512-1g1B7yf7KzessB0mKNiV9gAHEwbM662xgU+VE4LxyGe6kVGZ8LqYsngjhE+Stna09CJ7Pxkjr6Uq1OtbGwJJJg==", + "version": "3.972.19", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.19.tgz", + "integrity": "sha512-Km90fcXt3W/iqujHzuM6IaDkYCj73gsYufcuWXApWdzoTy6KGk8fnchAjePMARU0xegIR3K4N3yIo1vy7OVe8A==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", - "@smithy/core": "^3.23.0", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@smithy/core": "^3.23.8", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-retry": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -853,47 +829,48 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.989.0.tgz", - "integrity": "sha512-Dbk2HMPU3mb6RrSRzgf0WCaWSbgtZG258maCpuN2/ONcAQNpOTw99V5fU5CA1qVK6Vkm4Fwj2cnOnw7wbGVlOw==", + "version": "3.996.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.7.tgz", + "integrity": "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.23.0", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.14", - "@smithy/middleware-retry": "^4.4.31", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.30", - "@smithy/util-defaults-mode-node": "^4.2.33", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/middleware-host-header": "^3.972.7", + "@aws-sdk/middleware-logger": "^3.972.7", + "@aws-sdk/middleware-recursion-detection": "^3.972.7", + "@aws-sdk/middleware-user-agent": "^3.972.19", + "@aws-sdk/region-config-resolver": "^3.972.7", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@aws-sdk/util-user-agent-browser": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.973.4", + "@smithy/config-resolver": "^4.4.10", + "@smithy/core": "^3.23.8", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/hash-node": "^4.2.11", + "@smithy/invalid-dependency": "^4.2.11", + "@smithy/middleware-content-length": "^4.2.11", + "@smithy/middleware-endpoint": "^4.4.22", + "@smithy/middleware-retry": "^4.4.39", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.38", + "@smithy/util-defaults-mode-node": "^4.2.41", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -901,14 +878,15 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.3.tgz", - "integrity": "sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.7.tgz", + "integrity": "sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/config-resolver": "^4.4.10", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -916,15 +894,16 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.989.0.tgz", - "integrity": "sha512-rVhR/BUZdnru7tLlxWD+uzoKB1LAs2L0pcoh6rYgIYuCtQflnsC6Ud0SpfqIsOapBSBKXdoW73IITFf+XFMdCQ==", + "version": "3.996.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.6.tgz", + "integrity": "sha512-NnsOQsVmJXy4+IdPFUjRCWPn9qNH1TzS/f7MiWgXeoHs903tJpAWQWQtoFvLccyPoBgomKP9L89RRr2YsT/L0g==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "^3.972.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/middleware-sdk-s3": "^3.972.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/protocol-http": "^5.3.11", + "@smithy/signature-v4": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -932,16 +911,17 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.989.0.tgz", - "integrity": "sha512-OdBByMv+OjOZoekrk4THPFpLuND5aIQbDHCGh3n2rvifAbm31+6e0OLhxSeCF1UMPm+nKq12bXYYEoCIx5SQBg==", + "version": "3.1004.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1004.0.tgz", + "integrity": "sha512-j9BwZZId9sFp+4GPhf6KrwO8Tben2sXibZA8D1vv2I1zBdvkUHcBA2g4pkqIpTRalMTLC0NPkBPX0gERxfy/iA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -949,12 +929,12 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.973.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.1.tgz", - "integrity": "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==", + "version": "3.973.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.5.tgz", + "integrity": "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -962,9 +942,9 @@ } }, "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.2.tgz", - "integrity": "sha512-VkykWbqMjlSgBFDyrY3nOSqupMc6ivXuGmvci6Q3NnLq5kC+mKQe2QBZ4nrWRE/jqOxeFP2uYzLtwncYYcvQDg==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.3.tgz", + "integrity": "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -974,14 +954,15 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.989.0.tgz", - "integrity": "sha512-eKmAOeQM4Qusq0jtcbZPiNWky8XaojByKC/n+THbJ8vJf7t4ys8LlcZ4PrBSHZISe9cC484mQsPVOQh6iySjqw==", + "version": "3.996.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.4.tgz", + "integrity": "sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-endpoints": "^3.2.8", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-endpoints": "^3.3.2", "tslib": "^2.6.2" }, "engines": { @@ -1001,25 +982,27 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.3.tgz", - "integrity": "sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.7.tgz", + "integrity": "sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.7.tgz", - "integrity": "sha512-oyhv+FjrgHjP+F16cmsrJzNP4qaRJzkV1n9Lvv4uyh3kLqo3rIe9NSBSBa35f2TedczfG2dD+kaQhHBB47D6Og==", + "version": "3.973.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.4.tgz", + "integrity": "sha512-uqKeLqZ9D3nQjH7HGIERNXK9qnSpUK08l4MlJ5/NZqSSdeJsVANYp437EM9sEzwU28c2xfj2V6qlkqzsgtKs6Q==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/middleware-user-agent": "^3.972.19", + "@aws-sdk/types": "^3.973.5", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1052,6 +1035,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.3.tgz", "integrity": "sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==", + "license": "Apache-2.0", "engines": { "node": ">=18.0.0" } @@ -3221,9 +3205,9 @@ } }, "node_modules/@ioredis/commands": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.0.tgz", - "integrity": "sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz", + "integrity": "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==", "license": "MIT" }, "node_modules/@isaacs/cliui": { @@ -4599,9 +4583,9 @@ } }, "node_modules/@posthog/core": { - "version": "1.23.1", - "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.23.1.tgz", - "integrity": "sha512-GViD5mOv/mcbZcyzz3z9CS0R79JzxVaqEz4sP5Dsea178M/j3ZWe6gaHDZB9yuyGfcmIMQ/8K14yv+7QrK4sQQ==", + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.23.2.tgz", + "integrity": "sha512-zTDdda9NuSHrnwSOfFMxX/pyXiycF4jtU1kTr8DL61dHhV+7LF6XF1ndRZZTuaGGbfbb/GJYkEsjEX9SXfNZeQ==", "license": "MIT", "dependencies": { "cross-spawn": "^7.0.6" @@ -7993,12 +7977,12 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", - "integrity": "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.11.tgz", + "integrity": "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8006,9 +7990,9 @@ } }, "node_modules/@smithy/chunked-blob-reader": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.0.tgz", - "integrity": "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.2.tgz", + "integrity": "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8018,12 +8002,12 @@ } }, "node_modules/@smithy/chunked-blob-reader-native": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.1.tgz", - "integrity": "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.3.tgz", + "integrity": "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-base64": "^4.3.0", + "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" }, "engines": { @@ -8031,15 +8015,16 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.6.tgz", - "integrity": "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.10.tgz", + "integrity": "sha512-IRTkd6ps0ru+lTWnfnsbXzW80A8Od8p3pYiZnW98K2Hb20rqfsX7VTlfUwhrcOeSSy68Gn9WBofwPuw3e5CCsg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -8047,19 +8032,20 @@ } }, "node_modules/@smithy/core": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.0.tgz", - "integrity": "sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg==", + "version": "3.23.9", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.9.tgz", + "integrity": "sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.2.9", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.12", - "@smithy/util-utf8": "^4.2.0", - "@smithy/uuid": "^1.1.0", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", + "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" }, "engines": { @@ -8067,14 +8053,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.8.tgz", - "integrity": "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.11.tgz", + "integrity": "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -8082,14 +8069,14 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.8.tgz", - "integrity": "sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.11.tgz", + "integrity": "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.12.0", - "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8097,13 +8084,13 @@ } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.8.tgz", - "integrity": "sha512-MTfQT/CRQz5g24ayXdjg53V0mhucZth4PESoA5IhvaWVDTOQLfo8qI9vzqHcPsdd2v6sqfTYqF5L/l+pea5Uyw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.11.tgz", + "integrity": "sha512-3rEpo3G6f/nRS7fQDsZmxw/ius6rnlIpz4UX6FlALEzz8JoSxFmdBt0SZnthis+km7sQo6q5/3e+UJcuQivoXA==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-serde-universal": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8111,12 +8098,12 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.8.tgz", - "integrity": "sha512-ah12+luBiDGzBruhu3efNy1IlbwSEdNiw8fOZksoKoWW1ZHvO/04MQsdnws/9Aj+5b0YXSSN2JXKy/ClIsW8MQ==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.11.tgz", + "integrity": "sha512-XeNIA8tcP/GDWnnKkO7qEm/bg0B/bP9lvIXZBXcGZwZ+VYM8h8k9wuDvUODtdQ2Wcp2RcBkPTCSMmaniVHrMlA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8124,13 +8111,13 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.8.tgz", - "integrity": "sha512-cYpCpp29z6EJHa5T9WL0KAlq3SOKUQkcgSoeRfRVwjGgSFl7Uh32eYGt7IDYCX20skiEdRffyDpvF2efEZPC0A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.11.tgz", + "integrity": "sha512-fzbCh18rscBDTQSCrsp1fGcclLNF//nJyhjldsEl/5wCYmgpHblv5JSppQAyQI24lClsFT0wV06N1Porn0IsEw==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-serde-universal": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8138,13 +8125,13 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.8.tgz", - "integrity": "sha512-iJ6YNJd0bntJYnX6s52NC4WFYcZeKrPUr1Kmmr5AwZcwCSzVpS7oavAmxMR7pMq7V+D1G4s9F5NJK0xwOsKAlQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.11.tgz", + "integrity": "sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-codec": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8152,14 +8139,15 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.9.tgz", - "integrity": "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==", + "version": "5.3.13", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.13.tgz", + "integrity": "sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/querystring-builder": "^4.2.11", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" }, "engines": { @@ -8167,14 +8155,14 @@ } }, "node_modules/@smithy/hash-blob-browser": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.9.tgz", - "integrity": "sha512-m80d/iicI7DlBDxyQP6Th7BW/ejDGiF0bgI754+tiwK0lgMkcaIBgvwwVc7OFbY4eUzpGtnig52MhPAEJ7iNYg==", + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.12.tgz", + "integrity": "sha512-1wQE33DsxkM/waftAhCH9VtJbUGyt1PJ9YRDpOu+q9FUi73LLFUZ2fD8A61g2mT1UY9k7b99+V1xZ41Rz4SHRQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/chunked-blob-reader": "^5.2.0", - "@smithy/chunked-blob-reader-native": "^4.2.1", - "@smithy/types": "^4.12.0", + "@smithy/chunked-blob-reader": "^5.2.2", + "@smithy/chunked-blob-reader-native": "^4.2.3", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8182,13 +8170,14 @@ } }, "node_modules/@smithy/hash-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.8.tgz", - "integrity": "sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.11.tgz", + "integrity": "sha512-T+p1pNynRkydpdL015ruIoyPSRw9e/SQOWmSAMmmprfswMrd5Ow5igOWNVlvyVFZlxXqGmyH3NQwfwy8r5Jx0A==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8196,13 +8185,13 @@ } }, "node_modules/@smithy/hash-stream-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.8.tgz", - "integrity": "sha512-v0FLTXgHrTeheYZFGhR+ehX5qUm4IQsjAiL9qehad2cyjMWcN2QG6/4mSwbSgEQzI7jwfoXj7z4fxZUx/Mhj2w==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.11.tgz", + "integrity": "sha512-hQsTjwPCRY8w9GK07w1RqJi3e+myh0UaOWBBhZ1UMSDgofH/Q1fEYzU1teaX6HkpX/eWDdm7tAGR0jBPlz9QEQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8210,11 +8199,12 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.8.tgz", - "integrity": "sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.11.tgz", + "integrity": "sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8222,9 +8212,9 @@ } }, "node_modules/@smithy/is-array-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", - "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", + "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8234,13 +8224,13 @@ } }, "node_modules/@smithy/md5-js": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.8.tgz", - "integrity": "sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.11.tgz", + "integrity": "sha512-350X4kGIrty0Snx2OWv7rPM6p6vM7RzryvFs6B/56Cux3w3sChOb3bymo5oidXJlPcP9fIRxGUCk7GqpiSOtng==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8248,12 +8238,13 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.8.tgz", - "integrity": "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.11.tgz", + "integrity": "sha512-UvIfKYAKhCzr4p6jFevPlKhQwyQwlJ6IeKLDhmV1PlYfcW3RL4ROjNEDtSik4NYMi9kDkH7eSwyTP3vNJ/u/Dw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8261,17 +8252,18 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.4.14", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.14.tgz", - "integrity": "sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag==", + "version": "4.4.23", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.23.tgz", + "integrity": "sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.23.0", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-middleware": "^4.2.8", + "@smithy/core": "^3.23.9", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -8279,18 +8271,19 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.4.31", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.31.tgz", - "integrity": "sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg==", + "version": "4.4.40", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.40.tgz", + "integrity": "sha512-YhEMakG1Ae57FajERdHNZ4ShOPIY7DsgV+ZoAxo/5BT0KIe+f6DDU2rtIymNNFIj22NJfeeI6LWIifrwM0f+rA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/service-error-classification": "^4.2.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/uuid": "^1.1.0", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/service-error-classification": "^4.2.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" }, "engines": { @@ -8298,12 +8291,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.9.tgz", - "integrity": "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==", + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.12.tgz", + "integrity": "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng==", + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8311,11 +8305,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.8.tgz", - "integrity": "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.11.tgz", + "integrity": "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8323,14 +8318,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.8.tgz", - "integrity": "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.11.tgz", + "integrity": "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8338,14 +8333,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.10.tgz", - "integrity": "sha512-u4YeUwOWRZaHbWaebvrs3UhwQwj+2VNmcVCwXcYTvPIuVyM7Ex1ftAj+fdbG/P4AkBwLq/+SKn+ydOI4ZJE9PA==", + "version": "4.4.14", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.14.tgz", + "integrity": "sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A==", + "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/abort-controller": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/querystring-builder": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8353,12 +8349,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.8.tgz", - "integrity": "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.11.tgz", + "integrity": "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8366,12 +8362,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.8.tgz", - "integrity": "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.11.tgz", + "integrity": "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8379,12 +8375,13 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.8.tgz", - "integrity": "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.11.tgz", + "integrity": "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-uri-escape": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8392,11 +8389,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.8.tgz", - "integrity": "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.11.tgz", + "integrity": "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8404,23 +8402,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.8.tgz", - "integrity": "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.11.tgz", + "integrity": "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0" + "@smithy/types": "^4.13.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.3.tgz", - "integrity": "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.6.tgz", + "integrity": "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8428,17 +8427,18 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.8.tgz", - "integrity": "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.11.tgz", + "integrity": "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.2.0", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-uri-escape": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8446,16 +8446,17 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.11.3.tgz", - "integrity": "sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg==", + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.3.tgz", + "integrity": "sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.23.0", - "@smithy/middleware-endpoint": "^4.4.14", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-stream": "^4.5.12", + "@smithy/core": "^3.23.9", + "@smithy/middleware-endpoint": "^4.4.23", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" }, "engines": { @@ -8475,12 +8476,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.8.tgz", - "integrity": "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.11.tgz", + "integrity": "sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing==", + "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/querystring-parser": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8488,13 +8490,13 @@ } }, "node_modules/@smithy/util-base64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", - "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz", + "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8502,9 +8504,10 @@ } }, "node_modules/@smithy/util-body-length-browser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", - "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz", + "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -8513,9 +8516,10 @@ } }, "node_modules/@smithy/util-body-length-node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", - "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz", + "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -8524,12 +8528,12 @@ } }, "node_modules/@smithy/util-buffer-from": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", - "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", + "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.2.0", + "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8537,9 +8541,9 @@ } }, "node_modules/@smithy/util-config-provider": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", - "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", + "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8549,13 +8553,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.3.30", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.30.tgz", - "integrity": "sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng==", + "version": "4.3.39", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.39.tgz", + "integrity": "sha512-ui7/Ho/+VHqS7Km2wBw4/Ab4RktoiSshgcgpJzC4keFPs6tLJS4IQwbeahxQS3E/w98uq6E1mirCH/id9xIXeQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", + "@smithy/property-provider": "^4.2.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8563,16 +8568,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.33", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.33.tgz", - "integrity": "sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA==", + "version": "4.2.42", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.42.tgz", + "integrity": "sha512-QDA84CWNe8Akpj15ofLO+1N3Rfg8qa2K5uX0y6HnOp4AnRYRgWrKx/xzbYNbVF9ZsyJUYOfcoaN3y93wA/QJ2A==", + "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.4.6", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", + "@smithy/config-resolver": "^4.4.10", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8580,12 +8586,13 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.8.tgz", - "integrity": "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.3.2.tgz", + "integrity": "sha512-+4HFLpE5u29AbFlTdlKIT7jfOzZ8PDYZKTb3e+AgLz986OYwqTourQ5H+jg79/66DB69Un1+qKecLnkZdAsYcA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8593,9 +8600,9 @@ } }, "node_modules/@smithy/util-hex-encoding": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", - "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", + "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8605,11 +8612,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.8.tgz", - "integrity": "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.11.tgz", + "integrity": "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8617,12 +8625,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.8.tgz", - "integrity": "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.11.tgz", + "integrity": "sha512-XSZULmL5x6aCTTii59wJqKsY1l3eMIAomRAccW7Tzh9r8s7T/7rdo03oektuH5jeYRlJMPcNP92EuRDvk9aXbw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/service-error-classification": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8630,17 +8639,18 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.5.12", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.12.tgz", - "integrity": "sha512-D8tgkrmhAX/UNeCZbqbEO3uqyghUnEmmoO9YEvRuwxjlkKKUE7FOgCJnqpTlQPe9MApdWPky58mNQQHbnCzoNg==", + "version": "4.5.17", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.17.tgz", + "integrity": "sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8648,9 +8658,10 @@ } }, "node_modules/@smithy/util-uri-escape": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", - "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", + "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -8659,12 +8670,12 @@ } }, "node_modules/@smithy/util-utf8": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", - "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8672,13 +8683,13 @@ } }, "node_modules/@smithy/util-waiter": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.8.tgz", - "integrity": "sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.11.tgz", + "integrity": "sha512-x7Rh2azQPs3XxbvCzcttRErKKvLnbZfqRf/gOjw2pb+ZscX88e5UkRPCB67bVnsFHxayvMvmePfKTqsRb+is1A==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/abort-controller": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8686,9 +8697,10 @@ } }, "node_modules/@smithy/uuid": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", - "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz", + "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -8947,6 +8959,15 @@ "@swc/counter": "^0.1.3" } }, + "node_modules/@tabby_ai/hijri-converter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@tabby_ai/hijri-converter/-/hijri-converter-1.0.5.tgz", + "integrity": "sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@tailwindcss/forms": { "version": "0.5.11", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.11.tgz", @@ -9891,9 +9912,9 @@ "license": "MIT" }, "node_modules/@types/pg": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.16.0.tgz", - "integrity": "sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.18.0.tgz", + "integrity": "sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==", "devOptional": true, "license": "MIT", "dependencies": { @@ -11228,7 +11249,8 @@ "node_modules/bowser": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", - "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==" + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.12", @@ -14421,9 +14443,9 @@ } }, "node_modules/express-rate-limit": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.2.tgz", - "integrity": "sha512-Ybv7bqtOgA914MLwaHWVFXMpMYeR1MQu/D+z2MaLYteqBsTIp9sY3AU7mGNLMJv8eLg8uQMpE20I+L2Lv49nSg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.0.tgz", + "integrity": "sha512-KJzBawY6fB9FiZGdE/0aftepZ91YlaGIrV8vgblRM3J8X+dHx/aiowJWwkx6LIGyuqGiANsjSwwrbb8mifOJ4Q==", "license": "MIT", "dependencies": { "ip-address": "10.1.0" @@ -15509,11 +15531,12 @@ } }, "node_modules/ioredis": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.9.3.tgz", - "integrity": "sha512-VI5tMCdeoxZWU5vjHWsiE/Su76JGhBvWF1MJnV9ZtGltHk9BmD48oDq8Tj8haZ85aceXZMxLNDQZRVo5QKNgXA==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.10.0.tgz", + "integrity": "sha512-HVBe9OFuqs+Z6n64q09PQvP1/R4Bm+30PAyyD4wIEqssh3v9L21QjCVk4kRLucMBcDokJTcLjsGeVRlq/nH6DA==", + "license": "MIT", "dependencies": { - "@ioredis/commands": "1.5.0", + "@ioredis/commands": "1.5.1", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", @@ -16638,9 +16661,9 @@ } }, "node_modules/lucide-react": { - "version": "0.563.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.563.0.tgz", - "integrity": "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA==", + "version": "0.577.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz", + "integrity": "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -17936,14 +17959,14 @@ } }, "node_modules/pg": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.19.0.tgz", - "integrity": "sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", + "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", "license": "MIT", "dependencies": { - "pg-connection-string": "^2.11.0", - "pg-pool": "^3.12.0", - "pg-protocol": "^1.12.0", + "pg-connection-string": "^2.12.0", + "pg-pool": "^3.13.0", + "pg-protocol": "^1.13.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, @@ -17970,9 +17993,9 @@ "optional": true }, "node_modules/pg-connection-string": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz", - "integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz", + "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==", "license": "MIT" }, "node_modules/pg-int8": { @@ -17985,18 +18008,18 @@ } }, "node_modules/pg-pool": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.12.0.tgz", - "integrity": "sha512-eIJ0DES8BLaziFHW7VgJEBPi5hg3Nyng5iKpYtj3wbcAUV9A1wLgWiY7ajf/f/oO1wfxt83phXPY8Emztg7ITg==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz", + "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.12.0.tgz", - "integrity": "sha512-uOANXNRACNdElMXJ0tPz6RBM0XQ61nONGAwlt8da5zs/iUOOCLBQOHSXnrC6fMsvtjxbOJrZZl5IScGv+7mpbg==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", "license": "MIT" }, "node_modules/pg-types": { @@ -18158,15 +18181,23 @@ } }, "node_modules/posthog-node": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.26.0.tgz", - "integrity": "sha512-DK1XF/RiunhvT57cFyPxW9OaliZzl5aREHFwY/AISL3MVOaDUb4wIccMn0G3ws3Ounen8iGH7xvzZQ0x2vEOEQ==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.28.0.tgz", + "integrity": "sha512-EETYV0zA+7BLQmXzY+vGyDMoQK8uHf8f/1utbRjKncI41gPkw+4piGP7l4UT5Luld+4vQpJPOR1q1YrbXm7XjQ==", "license": "MIT", "dependencies": { - "@posthog/core": "1.23.1" + "@posthog/core": "1.23.2" }, "engines": { "node": "^20.20.0 || >=22.22.0" + }, + "peerDependencies": { + "rxjs": "^7.0.0" + }, + "peerDependenciesMeta": { + "rxjs": { + "optional": true + } } }, "node_modules/prebuild-install": { @@ -18440,13 +18471,15 @@ } }, "node_modules/react-day-picker": { - "version": "9.13.2", - "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.13.2.tgz", - "integrity": "sha512-IMPiXfXVIAuR5Yk58DDPBC8QKClrhdXV+Tr/alBrwrHUw0qDDYB1m5zPNuTnnPIr/gmJ4ChMxmtqPdxm8+R4Eg==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.14.0.tgz", + "integrity": "sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==", + "license": "MIT", "dependencies": { "@date-fns/tz": "^1.4.1", + "@tabby_ai/hijri-converter": "1.0.5", "date-fns": "^4.1.0", - "date-fns-jalali": "^4.1.0-0" + "date-fns-jalali": "4.1.0-0" }, "engines": { "node": ">=18" @@ -19315,9 +19348,9 @@ } }, "node_modules/react-icons": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.6.0.tgz", + "integrity": "sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==", "license": "MIT", "peerDependencies": { "react": "*" @@ -19566,11 +19599,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/reo-census": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/reo-census/-/reo-census-1.2.8.tgz", + "integrity": "sha512-UMwpNwOieUTeymIITWCbo0In0FHGWZwnXIIYphpCPO/Bjl5z/385DWLnTxBcfFFCH/r/fEq/TZ0ivlPb6Smi9Q==", + "hasInstallScript": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/reodotdev": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/reodotdev/-/reodotdev-1.0.0.tgz", - "integrity": "sha512-wXe1vJucZjrhQL0SxOL9EvmJrtbMCIEGMdZX5lj/57n2T3UhBHZsAcM5TQASJ0T6ZBbrETRnMhH33bsbJeRO6Q==", - "license": "MIT" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reodotdev/-/reodotdev-1.1.0.tgz", + "integrity": "sha512-BeIlYk59p4Gw+zPHJj249xPBQ0wHfI8NsksVFRTdPLkPXDSYyn6IBvbR0s7pELK9qk3p79UBcBWP84IsYLsvbg==", + "license": "MIT", + "dependencies": { + "reo-census": "^1.2.6" + } }, "node_modules/require-from-string": { "version": "2.0.2", @@ -20599,9 +20645,9 @@ } }, "node_modules/stripe": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-20.3.1.tgz", - "integrity": "sha512-k990yOT5G5rhX3XluRPw5Y8RLdJDW4dzQ29wWT66piHrbnM2KyamJ1dKgPsw4HzGHRWjDiSSdcI2WdxQUPV3aQ==", + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-20.4.1.tgz", + "integrity": "sha512-axCguHItc8Sxt0HC6aSkdVRPffjYPV7EQqZRb2GkIa8FzWDycE7nHJM19C6xAIynH1Qp1/BHiopSi96jGBxT0w==", "license": "MIT", "engines": { "node": ">=16" diff --git a/package.json b/package.json index f0bb0b9b4..ec8e99cce 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ }, "dependencies": { "@asteasolutions/zod-to-openapi": "8.4.1", - "@aws-sdk/client-s3": "3.989.0", + "@aws-sdk/client-s3": "3.1004.0", "@faker-js/faker": "10.3.0", "@headlessui/react": "2.2.9", "@hookform/resolvers": "5.2.2", @@ -80,16 +80,16 @@ "d3": "7.9.0", "drizzle-orm": "0.45.1", "express": "5.2.1", - "express-rate-limit": "8.2.2", + "express-rate-limit": "8.3.0", "glob": "13.0.6", "helmet": "8.1.0", "http-errors": "2.0.1", "input-otp": "1.4.2", - "ioredis": "5.9.3", + "ioredis": "5.10.0", "jmespath": "0.16.0", "js-yaml": "4.1.1", "jsonwebtoken": "9.0.3", - "lucide-react": "0.563.0", + "lucide-react": "0.577.0", "maxmind": "5.0.5", "moment": "2.30.1", "next": "15.5.12", @@ -99,21 +99,21 @@ "node-cache": "5.1.2", "nodemailer": "8.0.1", "oslo": "1.2.1", - "pg": "8.19.0", - "posthog-node": "5.26.0", + "pg": "8.20.0", + "posthog-node": "5.28.0", "qrcode.react": "4.2.0", "react": "19.2.4", - "react-day-picker": "9.13.2", + "react-day-picker": "9.14.0", "react-dom": "19.2.4", "react-easy-sort": "1.8.0", "react-hook-form": "7.71.2", - "react-icons": "5.5.0", + "react-icons": "5.6.0", "recharts": "2.15.4", - "reodotdev": "1.0.0", + "reodotdev": "1.1.0", "resend": "6.9.2", "semver": "7.7.4", "sshpk": "^1.18.0", - "stripe": "20.3.1", + "stripe": "20.4.1", "swagger-ui-express": "5.0.1", "tailwind-merge": "3.5.0", "topojson-client": "3.1.0", @@ -149,7 +149,7 @@ "@types/node": "25.3.5", "@types/nodemailer": "7.0.11", "@types/nprogress": "0.2.3", - "@types/pg": "8.16.0", + "@types/pg": "8.18.0", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", "@types/semver": "7.7.1", From dbdff6812deed65693d3df14f55f32c6a345e788 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 16:31:19 -0700 Subject: [PATCH 31/46] Bump esbuild --- package-lock.json | 1864 --------------------------------------------- package.json | 3 + 2 files changed, 3 insertions(+), 1864 deletions(-) diff --git a/package-lock.json b/package-lock.json index b48f368ac..84bfc70a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1542,418 +1542,6 @@ "source-map-support": "^0.5.21" } }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, "node_modules/@esbuild-kit/esm-loader": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", @@ -7096,448 +6684,6 @@ "next": "16.1.6" } }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/darwin-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-loong64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-s390x": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", - "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/sunos-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@react-email/preview-server/node_modules/@next/env": { "version": "16.1.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.6.tgz", @@ -7691,48 +6837,6 @@ "tslib": "^2.8.0" } }, - "node_modules/@react-email/preview-server/node_modules/esbuild": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", - "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.10", - "@esbuild/android-arm": "0.25.10", - "@esbuild/android-arm64": "0.25.10", - "@esbuild/android-x64": "0.25.10", - "@esbuild/darwin-arm64": "0.25.10", - "@esbuild/darwin-x64": "0.25.10", - "@esbuild/freebsd-arm64": "0.25.10", - "@esbuild/freebsd-x64": "0.25.10", - "@esbuild/linux-arm": "0.25.10", - "@esbuild/linux-arm64": "0.25.10", - "@esbuild/linux-ia32": "0.25.10", - "@esbuild/linux-loong64": "0.25.10", - "@esbuild/linux-mips64el": "0.25.10", - "@esbuild/linux-ppc64": "0.25.10", - "@esbuild/linux-riscv64": "0.25.10", - "@esbuild/linux-s390x": "0.25.10", - "@esbuild/linux-x64": "0.25.10", - "@esbuild/netbsd-arm64": "0.25.10", - "@esbuild/netbsd-x64": "0.25.10", - "@esbuild/openbsd-arm64": "0.25.10", - "@esbuild/openbsd-x64": "0.25.10", - "@esbuild/openharmony-arm64": "0.25.10", - "@esbuild/sunos-x64": "0.25.10", - "@esbuild/win32-arm64": "0.25.10", - "@esbuild/win32-ia32": "0.25.10", - "@esbuild/win32-x64": "0.25.10" - } - }, "node_modules/@react-email/preview-server/node_modules/next": { "version": "16.1.6", "resolved": "https://registry.npmjs.org/next/-/next-16.1.6.tgz", @@ -12729,490 +11833,6 @@ "drizzle-kit": "bin.cjs" } }, - "node_modules/drizzle-kit/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/drizzle-orm": { "version": "0.45.1", "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.1.tgz", @@ -18501,448 +17121,6 @@ "node": ">=20.0.0" } }, - "node_modules/react-email/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/react-email/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -19012,48 +17190,6 @@ "dev": true, "license": "MIT" }, - "node_modules/react-email/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/react-email/node_modules/glob": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", diff --git a/package.json b/package.json index 56caec09a..9be5dd261 100644 --- a/package.json +++ b/package.json @@ -171,5 +171,8 @@ "tsx": "4.21.0", "typescript": "5.9.3", "typescript-eslint": "8.55.0" + }, + "overrides": { + "esbuild": "0.27.3" } } From 072c89e704841fca9e266bfb43426b3fff277f79 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 16:43:40 -0700 Subject: [PATCH 32/46] Bump dompurify --- package-lock.json | 9 ++++++--- package.json | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 84bfc70a0..cc8adc58b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11767,10 +11767,13 @@ } }, "node_modules/dompurify": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", - "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", + "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==", "license": "(MPL-2.0 OR Apache-2.0)", + "engines": { + "node": ">=20" + }, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } diff --git a/package.json b/package.json index 9be5dd261..9eec59b43 100644 --- a/package.json +++ b/package.json @@ -173,6 +173,7 @@ "typescript-eslint": "8.55.0" }, "overrides": { - "esbuild": "0.27.3" + "esbuild": "0.27.3", + "dompurify": "3.3.2" } } From 5c50590d7b3a097e523fb8553c06b36e8d02296e Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 16:31:19 -0700 Subject: [PATCH 33/46] Bump esbuild --- package-lock.json | 1864 --------------------------------------------- package.json | 3 + 2 files changed, 3 insertions(+), 1864 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e3b0e759..bcf0f55d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1526,418 +1526,6 @@ "source-map-support": "^0.5.21" } }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, "node_modules/@esbuild-kit/esm-loader": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", @@ -7057,448 +6645,6 @@ "next": "16.1.6" } }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/darwin-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-loong64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-s390x": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", - "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/sunos-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@react-email/preview-server/node_modules/@next/env": { "version": "16.1.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.6.tgz", @@ -7652,48 +6798,6 @@ "tslib": "^2.8.0" } }, - "node_modules/@react-email/preview-server/node_modules/esbuild": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", - "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.10", - "@esbuild/android-arm": "0.25.10", - "@esbuild/android-arm64": "0.25.10", - "@esbuild/android-x64": "0.25.10", - "@esbuild/darwin-arm64": "0.25.10", - "@esbuild/darwin-x64": "0.25.10", - "@esbuild/freebsd-arm64": "0.25.10", - "@esbuild/freebsd-x64": "0.25.10", - "@esbuild/linux-arm": "0.25.10", - "@esbuild/linux-arm64": "0.25.10", - "@esbuild/linux-ia32": "0.25.10", - "@esbuild/linux-loong64": "0.25.10", - "@esbuild/linux-mips64el": "0.25.10", - "@esbuild/linux-ppc64": "0.25.10", - "@esbuild/linux-riscv64": "0.25.10", - "@esbuild/linux-s390x": "0.25.10", - "@esbuild/linux-x64": "0.25.10", - "@esbuild/netbsd-arm64": "0.25.10", - "@esbuild/netbsd-x64": "0.25.10", - "@esbuild/openbsd-arm64": "0.25.10", - "@esbuild/openbsd-x64": "0.25.10", - "@esbuild/openharmony-arm64": "0.25.10", - "@esbuild/sunos-x64": "0.25.10", - "@esbuild/win32-arm64": "0.25.10", - "@esbuild/win32-ia32": "0.25.10", - "@esbuild/win32-x64": "0.25.10" - } - }, "node_modules/@react-email/preview-server/node_modules/next": { "version": "16.1.6", "resolved": "https://registry.npmjs.org/next/-/next-16.1.6.tgz", @@ -12751,490 +11855,6 @@ "drizzle-kit": "bin.cjs" } }, - "node_modules/drizzle-kit/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/drizzle-orm": { "version": "0.45.1", "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.1.tgz", @@ -18552,448 +17172,6 @@ "node": ">=20.0.0" } }, - "node_modules/react-email/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/react-email/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -19063,48 +17241,6 @@ "dev": true, "license": "MIT" }, - "node_modules/react-email/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/react-email/node_modules/glob": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", diff --git a/package.json b/package.json index ec8e99cce..5906f363c 100644 --- a/package.json +++ b/package.json @@ -172,5 +172,8 @@ "tsx": "4.21.0", "typescript": "5.9.3", "typescript-eslint": "8.56.1" + }, + "overrides": { + "esbuild": "0.27.3" } } From 99e6bd31b6f35f6142ff834e9b4692303b96a8f0 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 16:43:40 -0700 Subject: [PATCH 34/46] Bump dompurify --- package-lock.json | 68 ++++++++++++++++++++++++++++++++++++++++------- package.json | 3 ++- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index bcf0f55d4..03ff44d30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1071,6 +1071,7 @@ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", @@ -2381,6 +2382,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2403,6 +2405,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2425,6 +2428,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2441,6 +2445,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2457,6 +2462,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2473,6 +2479,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2489,6 +2496,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2505,6 +2513,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2521,6 +2530,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2537,6 +2547,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2553,6 +2564,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2569,6 +2581,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2591,6 +2604,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2613,6 +2627,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2635,6 +2650,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2657,6 +2673,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2679,6 +2696,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2701,6 +2719,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2723,6 +2742,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -2742,6 +2762,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -2761,6 +2782,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -2780,6 +2802,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -3039,6 +3062,7 @@ "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^14.21.3 || >=16" }, @@ -6985,6 +7009,7 @@ "resolved": "https://registry.npmjs.org/@react-email/text/-/text-0.1.6.tgz", "integrity": "sha512-TYqkioRS45wTR5il3dYk/SbUjjEdhSwh9BtRNB99qNH1pXAwA45H7rAuxehiu8iJQJH0IyIr+6n62gBz9ezmsw==", "license": "MIT", + "peer": true, "engines": { "node": ">=20.0.0" }, @@ -8444,6 +8469,7 @@ "version": "5.90.21", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz", "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==", + "peer": true, "dependencies": { "@tanstack/query-core": "5.90.20" }, @@ -8559,6 +8585,7 @@ "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*" } @@ -8899,6 +8926,7 @@ "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", @@ -8994,6 +9022,7 @@ "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.18.0" } @@ -9021,6 +9050,7 @@ "integrity": "sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*", "pg-protocol": "*", @@ -9046,6 +9076,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -9056,6 +9087,7 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -9142,8 +9174,7 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/@types/ws": { "version": "8.18.1", @@ -9217,6 +9248,7 @@ "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", @@ -9742,6 +9774,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -10206,6 +10239,7 @@ "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/types": "^7.26.0" } @@ -10272,6 +10306,7 @@ "integrity": "sha512-Ba0KR+Fzxh2jDRhdg6TSH0SJGzb8C0aBY4hR8w8madIdIzzC6Y1+kx5qR6eS1Z+Gy20h6ZU28aeyg0z1VIrShQ==", "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" @@ -10399,6 +10434,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -11352,6 +11388,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -11788,11 +11825,13 @@ } }, "node_modules/dompurify": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", - "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", + "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==", "license": "(MPL-2.0 OR Apache-2.0)", - "peer": true, + "engines": { + "node": ">=20" + }, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } @@ -12422,6 +12461,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -12520,6 +12560,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -12705,6 +12746,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -13024,6 +13066,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -15550,7 +15593,6 @@ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", "license": "MIT", - "peer": true, "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" @@ -15561,7 +15603,6 @@ "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -15649,6 +15690,7 @@ "version": "15.5.12", "resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz", "integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==", + "peer": true, "dependencies": { "@next/env": "15.5.12", "@swc/helpers": "0.5.15", @@ -16583,6 +16625,7 @@ "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", "license": "MIT", + "peer": true, "dependencies": { "pg-connection-string": "^2.12.0", "pg-pool": "^3.13.0", @@ -17086,6 +17129,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -17117,6 +17161,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -17472,6 +17517,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.2.tgz", "integrity": "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -18955,7 +19001,8 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tapable": { "version": "2.3.0", @@ -19430,6 +19477,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -19857,6 +19905,7 @@ "resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz", "integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==", "license": "MIT", + "peer": true, "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.8", @@ -20063,6 +20112,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 5906f363c..3529de66a 100644 --- a/package.json +++ b/package.json @@ -174,6 +174,7 @@ "typescript-eslint": "8.56.1" }, "overrides": { - "esbuild": "0.27.3" + "esbuild": "0.27.3", + "dompurify": "3.3.2" } } From 82f88f2cd3a9a56e2b544aa8d28bade74c761cd0 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 20:46:27 -0700 Subject: [PATCH 35/46] Reorder delete --- server/lib/deleteOrg.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index cca2ea974..86c32e9a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -121,6 +121,9 @@ export async function deleteOrgById( eq(clientSitesAssociationsCache.clientId, client.clientId) ); } + + await trx.delete(resources).where(eq(resources.orgId, orgId)); + const allOrgDomains = await trx .select() .from(orgDomains) @@ -147,7 +150,6 @@ export async function deleteOrgById( .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); } - await trx.delete(resources).where(eq(resources.orgId, orgId)); await usageService.add(orgId, FeatureId.ORGINIZATIONS, -1, trx); // here we are decreasing the org count BEFORE deleting the org because we need to still be able to get the org to get the billing org inside of here From 225591094f437625e21884b452653efc3033eaea Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 21:16:37 -0700 Subject: [PATCH 36/46] Clean up --- server/lib/deleteOrg.ts | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index 86c32e9a1..56f2848a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -85,9 +85,7 @@ export async function deleteOrgById( deletedNewtIds.push(deletedNewt.newtId); await trx .delete(newtSessions) - .where( - eq(newtSessions.newtId, deletedNewt.newtId) - ); + .where(eq(newtSessions.newtId, deletedNewt.newtId)); } } } @@ -127,7 +125,7 @@ export async function deleteOrgById( const allOrgDomains = await trx .select() .from(orgDomains) - .innerJoin(domains, eq(domains.domainId, orgDomains.domainId)) + .innerJoin(domains, eq(orgDomains.domainId, domains.domainId)) .where( and( eq(orgDomains.orgId, orgId), @@ -136,16 +134,17 @@ export async function deleteOrgById( ); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { - const domainId = orgDomain.domains.domainId; + const domainId = orgDomain.domainId; const orgCount = await trx - .select({ count: sql`count(*)` }) + .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); - if (orgCount[0].count === 1) { + if (orgCount[0].count == 1) { domainIdsToDelete.push(domainId); } } if (domainIdsToDelete.length > 0) { + // delete the orgDomain await trx .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); @@ -233,15 +232,13 @@ export function sendTerminationMessages(result: DeleteOrgByIdResult): void { ); } for (const olmId of result.olmsToTerminate) { - sendTerminateClient( - 0, - OlmErrorCodes.TERMINATED_REKEYED, - olmId - ).catch((error) => { - logger.error( - "Failed to send termination message to olm:", - error - ); - }); + sendTerminateClient(0, OlmErrorCodes.TERMINATED_REKEYED, olmId).catch( + (error) => { + logger.error( + "Failed to send termination message to olm:", + error + ); + } + ); } } From 4975cabb2c35fd9dc74786262f2a914d89b593d3 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 10:03:49 -0700 Subject: [PATCH 37/46] Use native drizzle count --- server/lib/deleteOrg.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index 56f2848a1..b32667d24 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -134,17 +134,16 @@ export async function deleteOrgById( ); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { - const domainId = orgDomain.domainId; - const orgCount = await trx + const domainId = orgDomain.domains.domainId; + const [orgCount] = await trx .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); - if (orgCount[0].count == 1) { + if (orgCount.count === 1) { domainIdsToDelete.push(domainId); } } if (domainIdsToDelete.length > 0) { - // delete the orgDomain await trx .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); From 4e2d88efdd37c3fc3670135b08c513c01629c203 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 14:24:57 -0700 Subject: [PATCH 38/46] Add some logging to debug --- server/lib/deleteOrg.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index b32667d24..065f216a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -132,6 +132,7 @@ export async function deleteOrgById( eq(domains.configManaged, false) ) ); + logger.info(`Found ${allOrgDomains.length} domains to delete`); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { const domainId = orgDomain.domains.domainId; @@ -139,10 +140,12 @@ export async function deleteOrgById( .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); + logger.info(`Found ${orgCount.count} orgs using domain ${domainId}`); if (orgCount.count === 1) { domainIdsToDelete.push(domainId); } } + logger.info(`Found ${domainIdsToDelete.length} domains to delete`); if (domainIdsToDelete.length > 0) { await trx .delete(domains) From 1cc5f59f66d3b14dcef455a024fabe510468308b Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 11:37:27 -0700 Subject: [PATCH 39/46] Implement email and ip banning --- server/db/pg/schema/privateSchema.ts | 8 ++++++++ server/db/sqlite/schema/privateSchema.ts | 9 ++++++++ server/routers/auth/signup.ts | 26 +++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/server/db/pg/schema/privateSchema.ts b/server/db/pg/schema/privateSchema.ts index 6ff542de2..c9d7cc907 100644 --- a/server/db/pg/schema/privateSchema.ts +++ b/server/db/pg/schema/privateSchema.ts @@ -328,6 +328,14 @@ export const approvals = pgTable("approvals", { .notNull() }); +export const bannedEmails = pgTable("bannedEmails", { + email: varchar("email", { length: 255 }).primaryKey(), +}); + +export const bannedIps = pgTable("bannedIps", { + ip: varchar("ip", { length: 255 }).primaryKey(), +}); + export type Approval = InferSelectModel; export type Limit = InferSelectModel; export type Account = InferSelectModel; diff --git a/server/db/sqlite/schema/privateSchema.ts b/server/db/sqlite/schema/privateSchema.ts index 40f6d7134..8baeb5220 100644 --- a/server/db/sqlite/schema/privateSchema.ts +++ b/server/db/sqlite/schema/privateSchema.ts @@ -318,6 +318,15 @@ export const approvals = sqliteTable("approvals", { .notNull() }); + +export const bannedEmails = sqliteTable("bannedEmails", { + email: text("email").primaryKey() +}); + +export const bannedIps = sqliteTable("bannedIps", { + ip: text("ip").primaryKey() +}); + export type Approval = InferSelectModel; export type Limit = InferSelectModel; export type Account = InferSelectModel; diff --git a/server/routers/auth/signup.ts b/server/routers/auth/signup.ts index 93403a503..171653789 100644 --- a/server/routers/auth/signup.ts +++ b/server/routers/auth/signup.ts @@ -1,5 +1,5 @@ import { NextFunction, Request, Response } from "express"; -import { db, users } from "@server/db"; +import { bannedEmails, bannedIps, db, users } from "@server/db"; import HttpCode from "@server/types/HttpCode"; import { email, z } from "zod"; import { fromError } from "zod-validation-error"; @@ -66,6 +66,30 @@ export async function signup( skipVerificationEmail } = parsedBody.data; + const [bannedEmail] = await db + .select() + .from(bannedEmails) + .where(eq(bannedEmails.email, email)) + .limit(1); + if (bannedEmail) { + return next( + createHttpError(HttpCode.FORBIDDEN, "Signup blocked. Do not attempt to continue to use this service.") + ); + } + + if (req.ip) { + const [bannedIp] = await db + .select() + .from(bannedIps) + .where(eq(bannedIps.ip, req.ip)) + .limit(1); + if (bannedIp) { + return next( + createHttpError(HttpCode.FORBIDDEN, "Signup blocked. Do not attempt to continue to use this service.") + ); + } + } + const passwordHash = await hashPassword(password); const userId = generateId(15); From 82c9a1eb701a90c31cb0d155e3b4073197b14e75 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:35:04 -0700 Subject: [PATCH 40/46] Add demo link --- messages/en-US.json | 4 ++-- src/components/PaidFeaturesAlert.tsx | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index d84f4f337..6a35d79bb 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -2343,8 +2343,8 @@ "logRetentionEndOfFollowingYear": "End of following year", "actionLogsDescription": "View a history of actions performed in this organization", "accessLogsDescription": "View access auth requests for resources in this organization", - "licenseRequiredToUse": "An Enterprise Edition license or Pangolin Cloud is required to use this feature.", - "ossEnterpriseEditionRequired": "The Enterprise Edition is required to use this feature. This feature is also available in Pangolin Cloud.", + "licenseRequiredToUse": "An Enterprise Edition license or Pangolin Cloud is required to use this feature. Book a demo or POC trial.", + "ossEnterpriseEditionRequired": "The Enterprise Edition is required to use this feature. This feature is also available in Pangolin Cloud. Book a demo or POC trial.", "certResolver": "Certificate Resolver", "certResolverDescription": "Select the certificate resolver to use for this resource.", "selectCertResolver": "Select Certificate Resolver", diff --git a/src/components/PaidFeaturesAlert.tsx b/src/components/PaidFeaturesAlert.tsx index adbb49d9e..95179ea78 100644 --- a/src/components/PaidFeaturesAlert.tsx +++ b/src/components/PaidFeaturesAlert.tsx @@ -51,6 +51,7 @@ const docsLinkClassName = const PANGOLIN_CLOUD_SIGNUP_URL = "https://app.pangolin.net/auth/signup/"; const ENTERPRISE_DOCS_URL = "https://docs.pangolin.net/self-host/enterprise-edition"; +const BOOK_A_DEMO_URL = "https://click.fossorial.io/ep922"; function getTierLinkRenderer(billingHref: string) { return function tierLinkRenderer(chunks: React.ReactNode) { @@ -78,6 +79,22 @@ function getPangolinCloudLinkRenderer() { }; } +function getBookADemoLinkRenderer() { + return function bookADemoLinkRenderer(chunks: React.ReactNode) { + return ( + + {chunks} + + + ); + }; +} + function getDocsLinkRenderer(href: string) { return function docsLinkRenderer(chunks: React.ReactNode) { return ( @@ -116,6 +133,7 @@ export function PaidFeaturesAlert({ tiers }: Props) { const tierLinkRenderer = getTierLinkRenderer(billingHref); const pangolinCloudLinkRenderer = getPangolinCloudLinkRenderer(); const enterpriseDocsLinkRenderer = getDocsLinkRenderer(ENTERPRISE_DOCS_URL); + const bookADemoLinkRenderer = getBookADemoLinkRenderer(); if (env.flags.disableEnterpriseFeatures) { return null; @@ -157,7 +175,8 @@ export function PaidFeaturesAlert({ tiers }: Props) { {t.rich("licenseRequiredToUse", { enterpriseLicenseLink: enterpriseDocsLinkRenderer, - pangolinCloudLink: pangolinCloudLinkRenderer + pangolinCloudLink: pangolinCloudLinkRenderer, + bookADemoLink: bookADemoLinkRenderer })}
@@ -174,7 +193,8 @@ export function PaidFeaturesAlert({ tiers }: Props) { {t.rich("ossEnterpriseEditionRequired", { enterpriseEditionLink: enterpriseDocsLinkRenderer, - pangolinCloudLink: pangolinCloudLinkRenderer + pangolinCloudLink: pangolinCloudLinkRenderer, + bookADemoLink: bookADemoLinkRenderer })}
From eda43dffe14e831301e61d435b8ebacc88b04428 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:34:48 -0700 Subject: [PATCH 41/46] Fix not pulling wildcard cert updates --- server/lib/traefik/TraefikConfigManager.ts | 89 +++++++++++++++++++--- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/server/lib/traefik/TraefikConfigManager.ts b/server/lib/traefik/TraefikConfigManager.ts index 46d5ccc85..de9249291 100644 --- a/server/lib/traefik/TraefikConfigManager.ts +++ b/server/lib/traefik/TraefikConfigManager.ts @@ -218,10 +218,11 @@ export class TraefikConfigManager { return true; } - // Fetch if it's been more than 24 hours (for renewals) const dayInMs = 24 * 60 * 60 * 1000; const timeSinceLastFetch = Date.now() - this.lastCertificateFetch.getTime(); + + // Fetch if it's been more than 24 hours (daily routine check) if (timeSinceLastFetch > dayInMs) { logger.info("Fetching certificates due to 24-hour renewal check"); return true; @@ -265,7 +266,7 @@ export class TraefikConfigManager { return true; } - // Check if any local certificates are missing or appear to be outdated + // Check if any local certificates are missing (needs immediate fetch) for (const domain of domainsNeedingCerts) { const localState = this.lastLocalCertificateState.get(domain); if (!localState || !localState.exists) { @@ -274,17 +275,55 @@ export class TraefikConfigManager { ); return true; } + } - // Check if certificate is expiring soon (within 30 days) - if (localState.expiresAt) { - const nowInSeconds = Math.floor(Date.now() / 1000); - const secondsUntilExpiry = localState.expiresAt - nowInSeconds; - const daysUntilExpiry = secondsUntilExpiry / (60 * 60 * 24); - if (daysUntilExpiry < 30) { - logger.info( - `Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)` - ); - return true; + // For expiry checks, throttle to every 6 hours to avoid querying the + // API/DB on every monitor loop. The certificate-service renews certs + // 45 days before expiry, so checking every 6 hours is plenty frequent + // to pick up renewed certs promptly. + const renewalCheckIntervalMs = 6 * 60 * 60 * 1000; // 6 hours + if (timeSinceLastFetch > renewalCheckIntervalMs) { + // Check non-wildcard certs for expiry (within 45 days to match + // the server-side renewal window in certificate-service) + for (const domain of domainsNeedingCerts) { + const localState = + this.lastLocalCertificateState.get(domain); + if (localState?.expiresAt) { + const nowInSeconds = Math.floor(Date.now() / 1000); + const secondsUntilExpiry = + localState.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + logger.info( + `Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)` + ); + return true; + } + } + } + + // Also check wildcard certificates for expiry. These are not + // included in domainsNeedingCerts since their subdomains are + // filtered out, so we must check them separately. + for (const [certDomain, state] of this + .lastLocalCertificateState) { + if ( + state.exists && + state.wildcard && + state.expiresAt + ) { + const nowInSeconds = Math.floor(Date.now() / 1000); + const secondsUntilExpiry = + state.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + logger.info( + `Fetching certificates due to upcoming expiry for wildcard cert ${certDomain} (${Math.round(daysUntilExpiry)} days remaining)` + ); + return true; + } } } } @@ -361,6 +400,32 @@ export class TraefikConfigManager { } } + // Also include wildcard cert base domains that are + // expiring or expired so they get re-fetched even though + // their subdomains were filtered out above. + for (const [certDomain, state] of this + .lastLocalCertificateState) { + if ( + state.exists && + state.wildcard && + state.expiresAt + ) { + const nowInSeconds = Math.floor( + Date.now() / 1000 + ); + const secondsUntilExpiry = + state.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + domainsToFetch.add(certDomain); + logger.info( + `Including expiring wildcard cert domain ${certDomain} in fetch (${Math.round(daysUntilExpiry)} days remaining)` + ); + } + } + } + if (domainsToFetch.size > 0) { // Get valid certificates for domains not covered by wildcards validCertificates = From b24de85157c87c20c9bc31fb86dae525fc787e23 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:35:16 -0700 Subject: [PATCH 42/46] Handle gerbil rejecting 0 Closes #2605 --- server/lib/rebuildClientAssociations.ts | 4 ++-- server/routers/gerbil/getAllRelays.ts | 4 ++-- server/routers/gerbil/updateHolePunch.ts | 2 +- server/routers/newt/handleGetConfigMessage.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/lib/rebuildClientAssociations.ts b/server/lib/rebuildClientAssociations.ts index 625e57935..af43a6d00 100644 --- a/server/lib/rebuildClientAssociations.ts +++ b/server/lib/rebuildClientAssociations.ts @@ -571,7 +571,7 @@ export async function updateClientSiteDestinations( destinations: [ { destinationIP: site.sites.subnet.split("/")[0], - destinationPort: site.sites.listenPort || 0 + destinationPort: site.sites.listenPort || 1 // this satisfies gerbil for now but should be reevaluated } ] }; @@ -579,7 +579,7 @@ export async function updateClientSiteDestinations( // add to the existing destinations destinations.destinations.push({ destinationIP: site.sites.subnet.split("/")[0], - destinationPort: site.sites.listenPort || 0 + destinationPort: site.sites.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }); } diff --git a/server/routers/gerbil/getAllRelays.ts b/server/routers/gerbil/getAllRelays.ts index b7d33b955..bbe314b2a 100644 --- a/server/routers/gerbil/getAllRelays.ts +++ b/server/routers/gerbil/getAllRelays.ts @@ -125,7 +125,7 @@ export async function generateRelayMappings(exitNode: ExitNode) { // Add site as a destination for this client const destination: PeerDestination = { destinationIP: site.subnet.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }; // Check if this destination is already in the array to avoid duplicates @@ -165,7 +165,7 @@ export async function generateRelayMappings(exitNode: ExitNode) { const destination: PeerDestination = { destinationIP: peer.subnet.split("/")[0], - destinationPort: peer.listenPort + destinationPort: peer.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }; // Check for duplicates diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index 3f24430bf..13d0ed276 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -262,7 +262,7 @@ export async function updateAndGenerateEndpointDestinations( if (site.subnet && site.listenPort) { destinations.push({ destinationIP: site.subnet.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }); } } diff --git a/server/routers/newt/handleGetConfigMessage.ts b/server/routers/newt/handleGetConfigMessage.ts index 801c8b65a..24cca17a2 100644 --- a/server/routers/newt/handleGetConfigMessage.ts +++ b/server/routers/newt/handleGetConfigMessage.ts @@ -104,11 +104,11 @@ export const handleGetConfigMessage: MessageHandler = async (context) => { const payload = { oldDestination: { destinationIP: existingSite.subnet?.split("/")[0], - destinationPort: existingSite.listenPort + destinationPort: existingSite.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }, newDestination: { destinationIP: site.subnet?.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated } }; From 90afe5a7acb32c8bf7f68335bc309615670cad37 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 15:41:57 -0700 Subject: [PATCH 43/46] Log errors --- server/routers/gerbil/updateHolePunch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index 13d0ed276..3eacc1da1 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -112,7 +112,7 @@ export async function updateHolePunch( destinations: destinations }); } catch (error) { - // logger.error(error); // FIX THIS + logger.error(error); return next( createHttpError( HttpCode.INTERNAL_SERVER_ERROR, From 9b0e7b381c753c235ae5a035bc98de497af53194 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 15:48:20 -0700 Subject: [PATCH 44/46] Fix error to gerbil --- server/routers/gerbil/updateHolePunch.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index 3eacc1da1..810c44ff7 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -339,10 +339,10 @@ export async function updateAndGenerateEndpointDestinations( handleSiteEndpointChange(newt.siteId, updatedSite.endpoint!); } - if (!updatedSite || !updatedSite.subnet) { - logger.warn(`Site not found: ${newt.siteId}`); - throw new Error("Site not found"); - } + // if (!updatedSite || !updatedSite.subnet) { + // logger.warn(`Site not found: ${newt.siteId}`); + // throw new Error("Site not found"); + // } // Find all clients that connect to this site // const sitesClientPairs = await db From 74f4751bcc8b897f4a4d6027a3f0dd55f87b5670 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 17:47:15 -0700 Subject: [PATCH 45/46] Dont show raw resource option unless remote node --- .../settings/resources/proxy/create/page.tsx | 110 ++++++++++++------ 1 file changed, 76 insertions(+), 34 deletions(-) diff --git a/src/app/[orgId]/settings/resources/proxy/create/page.tsx b/src/app/[orgId]/settings/resources/proxy/create/page.tsx index 127917555..4c8cb8443 100644 --- a/src/app/[orgId]/settings/resources/proxy/create/page.tsx +++ b/src/app/[orgId]/settings/resources/proxy/create/page.tsx @@ -54,6 +54,7 @@ import { TooltipProvider, TooltipTrigger } from "@app/components/ui/tooltip"; +import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { toast } from "@app/hooks/useToast"; import { createApiClient, formatAxiosError } from "@app/lib/api"; @@ -65,6 +66,7 @@ import { build } from "@server/build"; import { Resource } from "@server/db"; import { isTargetValid } from "@server/lib/validators"; import { ListTargetsResponse } from "@server/routers/target"; +import { ListRemoteExitNodesResponse } from "@server/routers/remoteExitNode/types"; import { ArrayElement } from "@server/types/ArrayElement"; import { useQuery } from "@tanstack/react-query"; import { @@ -81,6 +83,7 @@ import { CircleCheck, CircleX, Info, + InfoIcon, Plus, Settings, SquareArrowOutUpRight @@ -210,6 +213,13 @@ export default function Page() { orgQueries.sites({ orgId: orgId as string }) ); + const [remoteExitNodes, setRemoteExitNodes] = useState< + ListRemoteExitNodesResponse["remoteExitNodes"] + >([]); + const [loadingExitNodes, setLoadingExitNodes] = useState( + build === "saas" + ); + const [createLoading, setCreateLoading] = useState(false); const [showSnippets, setShowSnippets] = useState(false); const [niceId, setNiceId] = useState(""); @@ -224,6 +234,27 @@ export default function Page() { useState(null); const [healthCheckDialogOpen, setHealthCheckDialogOpen] = useState(false); + useEffect(() => { + if (build !== "saas") return; + + const fetchExitNodes = async () => { + try { + const res = await api.get< + AxiosResponse + >(`/org/${orgId}/remote-exit-nodes`); + if (res && res.status === 200) { + setRemoteExitNodes(res.data.data.remoteExitNodes); + } + } catch (e) { + console.error("Failed to fetch remote exit nodes:", e); + } finally { + setLoadingExitNodes(false); + } + }; + + fetchExitNodes(); + }, [orgId]); + const [isAdvancedMode, setIsAdvancedMode] = useState(() => { if (typeof window !== "undefined") { const saved = localStorage.getItem("create-advanced-mode"); @@ -289,15 +320,25 @@ export default function Page() { }, ...(!env.flags.allowRawResources ? [] - : [ - { - id: "raw" as ResourceType, - title: t("resourceRaw"), - description: build == "saas" ? t("resourceRawDescriptionCloud") : t("resourceRawDescription") - } - ]) + : build === "saas" && remoteExitNodes.length === 0 + ? [] + : [ + { + id: "raw" as ResourceType, + title: t("resourceRaw"), + description: + build == "saas" + ? t("resourceRawDescriptionCloud") + : t("resourceRawDescription") + } + ]) ]; + // In saas mode with no exit nodes, force HTTP + const showTypeSelector = + build !== "saas" || + (!loadingExitNodes && remoteExitNodes.length > 0); + const baseForm = useForm({ resolver: zodResolver(baseResourceFormSchema), defaultValues: { @@ -984,34 +1025,35 @@ export default function Page() { - {resourceTypes.length > 1 && ( - <> -
- - {t("type")} - -
+ {showTypeSelector && + resourceTypes.length > 1 && ( + <> +
+ + {t("type")} + +
- { - baseForm.setValue( - "http", - value === "http" - ); - // Update method default when switching resource type - addTargetForm.setValue( - "method", - value === "http" - ? "http" - : null - ); - }} - cols={2} - /> - - )} + { + baseForm.setValue( + "http", + value === "http" + ); + // Update method default when switching resource type + addTargetForm.setValue( + "method", + value === "http" + ? "http" + : null + ); + }} + cols={2} + /> + + )}
From f021b73458bea9c40d9fffc7cc3e6c009d585bc5 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 17:59:28 -0700 Subject: [PATCH 46/46] Add alert about domain error --- messages/en-US.json | 3 +- server/db/pg/schema/schema.ts | 3 +- server/db/sqlite/schema/schema.ts | 3 +- server/routers/domain/listDomains.ts | 3 +- .../settings/domains/[domainId]/page.tsx | 1 + src/components/DomainInfoCard.tsx | 20 ++++++++- src/components/DomainsTable.tsx | 41 ++++++++++++++++++- 7 files changed, 68 insertions(+), 6 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index 6a35d79bb..3d5352293 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -2681,5 +2681,6 @@ "approvalsEmptyStateStep2Title": "Enable Device Approvals", "approvalsEmptyStateStep2Description": "Edit a role and enable the 'Require Device Approvals' option. Users with this role will need admin approval for new devices.", "approvalsEmptyStatePreviewDescription": "Preview: When enabled, pending device requests will appear here for review", - "approvalsEmptyStateButtonText": "Manage Roles" + "approvalsEmptyStateButtonText": "Manage Roles", + "domainErrorTitle": "We are having trouble verifying your domain" } diff --git a/server/db/pg/schema/schema.ts b/server/db/pg/schema/schema.ts index 504ea761f..b578b66e7 100644 --- a/server/db/pg/schema/schema.ts +++ b/server/db/pg/schema/schema.ts @@ -22,7 +22,8 @@ export const domains = pgTable("domains", { tries: integer("tries").notNull().default(0), certResolver: varchar("certResolver"), customCertResolver: varchar("customCertResolver"), - preferWildcardCert: boolean("preferWildcardCert") + preferWildcardCert: boolean("preferWildcardCert"), + errorMessage: text("errorMessage") }); export const dnsRecords = pgTable("dnsRecords", { diff --git a/server/db/sqlite/schema/schema.ts b/server/db/sqlite/schema/schema.ts index 2bd11ee0c..b02098896 100644 --- a/server/db/sqlite/schema/schema.ts +++ b/server/db/sqlite/schema/schema.ts @@ -13,7 +13,8 @@ export const domains = sqliteTable("domains", { failed: integer("failed", { mode: "boolean" }).notNull().default(false), tries: integer("tries").notNull().default(0), certResolver: text("certResolver"), - preferWildcardCert: integer("preferWildcardCert", { mode: "boolean" }) + preferWildcardCert: integer("preferWildcardCert", { mode: "boolean" }), + errorMessage: text("errorMessage") }); export const dnsRecords = sqliteTable("dnsRecords", { diff --git a/server/routers/domain/listDomains.ts b/server/routers/domain/listDomains.ts index 88cd5d7c7..085acf0c6 100644 --- a/server/routers/domain/listDomains.ts +++ b/server/routers/domain/listDomains.ts @@ -40,7 +40,8 @@ async function queryDomains(orgId: string, limit: number, offset: number) { tries: domains.tries, configManaged: domains.configManaged, certResolver: domains.certResolver, - preferWildcardCert: domains.preferWildcardCert + preferWildcardCert: domains.preferWildcardCert, + errorMessage: domains.errorMessage }) .from(orgDomains) .where(eq(orgDomains.orgId, orgId)) diff --git a/src/app/[orgId]/settings/domains/[domainId]/page.tsx b/src/app/[orgId]/settings/domains/[domainId]/page.tsx index 39ad02db2..cf23e81be 100644 --- a/src/app/[orgId]/settings/domains/[domainId]/page.tsx +++ b/src/app/[orgId]/settings/domains/[domainId]/page.tsx @@ -69,6 +69,7 @@ export default async function DomainSettingsPage({ failed={domain.failed} verified={domain.verified} type={domain.type} + errorMessage={domain.errorMessage} /> diff --git a/src/components/DomainInfoCard.tsx b/src/components/DomainInfoCard.tsx index e33998da2..7db17511b 100644 --- a/src/components/DomainInfoCard.tsx +++ b/src/components/DomainInfoCard.tsx @@ -10,17 +10,20 @@ import { import { useTranslations } from "next-intl"; import { Badge } from "./ui/badge"; import { useEnvContext } from "@app/hooks/useEnvContext"; +import { AlertTriangle } from "lucide-react"; type DomainInfoCardProps = { failed: boolean; verified: boolean; type: string | null; + errorMessage?: string | null; }; export default function DomainInfoCard({ failed, verified, - type + type, + errorMessage }: DomainInfoCardProps) { const t = useTranslations(); const env = useEnvContext(); @@ -39,6 +42,7 @@ export default function DomainInfoCard({ }; return ( +
@@ -79,5 +83,19 @@ export default function DomainInfoCard({ + {errorMessage && (failed || !verified) && ( + + + + {failed + ? t("domainErrorTitle", { fallback: "Domain Error" }) + : t("domainPendingErrorTitle", { fallback: "Verification Issue" })} + + + {errorMessage} + + + )} +
); } diff --git a/src/components/DomainsTable.tsx b/src/components/DomainsTable.tsx index ff23df67b..f5cb1ae74 100644 --- a/src/components/DomainsTable.tsx +++ b/src/components/DomainsTable.tsx @@ -27,6 +27,12 @@ import { DropdownMenuItem, DropdownMenuTrigger } from "./ui/dropdown-menu"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from "./ui/tooltip"; import Link from "next/link"; export type DomainRow = { @@ -39,6 +45,7 @@ export type DomainRow = { configManaged: boolean; certResolver: string; preferWildcardCert: boolean; + errorMessage?: string | null; }; type Props = { @@ -175,7 +182,7 @@ export default function DomainsTable({ domains, orgId }: Props) { ); }, cell: ({ row }) => { - const { verified, failed, type } = row.original; + const { verified, failed, type, errorMessage } = row.original; if (verified) { return type == "wildcard" ? ( {t("manual")} @@ -183,12 +190,44 @@ export default function DomainsTable({ domains, orgId }: Props) { {t("verified")} ); } else if (failed) { + if (errorMessage) { + return ( + + + + + {t("failed", { fallback: "Failed" })} + + + +

{errorMessage}

+
+
+
+ ); + } return ( {t("failed", { fallback: "Failed" })} ); } else { + if (errorMessage) { + return ( + + + + + {t("pending")} + + + +

{errorMessage}

+
+
+
+ ); + } return {t("pending")}; } }