From 300175ac6740c8db2c32461f957e2d93e7324375 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 16 Jul 2025 11:56:00 -0700 Subject: [PATCH 1/5] Defaults for org --- server/lib/readConfigFile.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/lib/readConfigFile.ts b/server/lib/readConfigFile.ts index f3057128..0d82defd 100644 --- a/server/lib/readConfigFile.ts +++ b/server/lib/readConfigFile.ts @@ -174,9 +174,9 @@ export const configSchema = z .optional() .default({}), orgs: z.object({ - block_size: z.number().positive().gt(0), - subnet_group: z.string() - }), + block_size: z.number().positive().gt(0).optional().default(24), + subnet_group: z.string().optional().default("100.90.128.0/24") + }).optional(), rate_limits: z .object({ global: z From 779532b1c94a7d7a32465d317a31ef340cf76f82 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 16 Jul 2025 11:56:16 -0700 Subject: [PATCH 2/5] Generate the initial subnets for sites and orgs --- server/setup/scriptsSqlite/1.7.0.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/server/setup/scriptsSqlite/1.7.0.ts b/server/setup/scriptsSqlite/1.7.0.ts index e7df9d81..e4be598b 100644 --- a/server/setup/scriptsSqlite/1.7.0.ts +++ b/server/setup/scriptsSqlite/1.7.0.ts @@ -155,5 +155,32 @@ export default async function migration() { throw e; } + db.transaction(() => { + // Update all existing orgs to have the default subnet + db.exec(`UPDATE 'orgs' SET 'subnet' = '100.90.128.0/24'`); + + // Get all orgs and their sites to assign sequential IP addresses + const orgs = db.prepare(`SELECT orgId FROM 'orgs'`).all() as { + orgId: string; + }[]; + + for (const org of orgs) { + const sites = db + .prepare( + `SELECT siteId FROM 'sites' WHERE orgId = ? ORDER BY siteId` + ) + .all(org.orgId) as { siteId: number }[]; + + let ipIndex = 1; + for (const site of sites) { + const address = `100.90.128.${ipIndex}/24`; + db.prepare( + `UPDATE 'sites' SET 'address' = ? WHERE siteId = ?` + ).run(address, site.siteId); + ipIndex++; + } + } + })(); + console.log(`${version} migration complete`); } From 2992de5139d38ca2eba2a828d7f517ec45238382 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 16 Jul 2025 12:00:38 -0700 Subject: [PATCH 3/5] Add basic org subnet thing to postgres T# --- server/setup/scriptsPg/1.7.0.ts | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/server/setup/scriptsPg/1.7.0.ts b/server/setup/scriptsPg/1.7.0.ts index cbe6db16..bbaab3bb 100644 --- a/server/setup/scriptsPg/1.7.0.ts +++ b/server/setup/scriptsPg/1.7.0.ts @@ -115,5 +115,41 @@ export default async function migration() { throw e; } + try { + // Update all existing orgs to have the default subnet + await db.execute(sql`UPDATE "orgs" SET "subnet" = '100.90.128.0/24'`); + + // Get all orgs and their sites to assign sequential IP addresses + const orgsQuery = await db.execute(sql`SELECT "orgId" FROM "orgs"`); + + const orgs = orgsQuery.rows as { orgId: string }[]; + + for (const org of orgs) { + const sitesQuery = await db.execute(sql` + SELECT "siteId" FROM "sites" + WHERE "orgId" = ${org.orgId} + ORDER BY "siteId" + `); + + const sites = sitesQuery.rows as { siteId: number }[]; + + let ipIndex = 1; + for (const site of sites) { + const address = `100.90.128.${ipIndex}/24`; + await db.execute(sql` + UPDATE "sites" SET "address" = ${address} + WHERE "siteId" = ${site.siteId} + `); + ipIndex++; + } + } + + console.log(`Updated org subnets and site addresses`); + } catch (e) { + console.log("Unable to update org subnets"); + console.log(e); + throw e; + } + console.log(`${version} migration complete`); } From e557bda48ea71c9bfa1264ca282efc94bde2eb83 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 16 Jul 2025 12:34:42 -0700 Subject: [PATCH 4/5] Fix default --- server/lib/readConfigFile.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/lib/readConfigFile.ts b/server/lib/readConfigFile.ts index 0d82defd..07203213 100644 --- a/server/lib/readConfigFile.ts +++ b/server/lib/readConfigFile.ts @@ -176,7 +176,10 @@ export const configSchema = z orgs: z.object({ block_size: z.number().positive().gt(0).optional().default(24), subnet_group: z.string().optional().default("100.90.128.0/24") - }).optional(), + }).optional().default({ + block_size: 24, + subnet_group: "100.90.128.0/24" + }), rate_limits: z .object({ global: z From f0f68632ffc19db75f0a1707025ecfc52c9ebf9a Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 16 Jul 2025 12:34:53 -0700 Subject: [PATCH 5/5] Add transaction --- server/setup/scriptsPg/1.7.0.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/server/setup/scriptsPg/1.7.0.ts b/server/setup/scriptsPg/1.7.0.ts index bbaab3bb..3cb799e0 100644 --- a/server/setup/scriptsPg/1.7.0.ts +++ b/server/setup/scriptsPg/1.7.0.ts @@ -7,7 +7,9 @@ export default async function migration() { console.log(`Running setup script ${version}...`); try { - db.execute(sql` + await db.execute(sql` + BEGIN; + CREATE TABLE "clientSites" ( "clientId" integer NOT NULL, "siteId" integer NOT NULL, @@ -106,6 +108,8 @@ export default async function migration() { ALTER TABLE "userClients" ADD CONSTRAINT "userClients_clientId_clients_id_fk" FOREIGN KEY ("clientId") REFERENCES "public"."clients"("id") ON DELETE cascade ON UPDATE no action; ALTER TABLE "webauthnChallenge" ADD CONSTRAINT "webauthnChallenge_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action; ALTER TABLE "resources" DROP COLUMN "isBaseDomain"; + + COMMIT; `); console.log(`Migrated database schema`); @@ -116,6 +120,8 @@ export default async function migration() { } try { + await db.execute(sql`BEGIN`); + // Update all existing orgs to have the default subnet await db.execute(sql`UPDATE "orgs" SET "subnet" = '100.90.128.0/24'`); @@ -144,8 +150,10 @@ export default async function migration() { } } + await db.execute(sql`COMMIT`); console.log(`Updated org subnets and site addresses`); } catch (e) { + await db.execute(sql`ROLLBACK`); console.log("Unable to update org subnets"); console.log(e); throw e;