From 021bc073a2704acec424522fdf472571f17fecc9 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 16 Jul 2025 11:35:38 -0700 Subject: [PATCH] Make org subnet optional --- server/db/pg/schema.ts | 2 +- server/db/sqlite/schema.ts | 2 +- server/lib/ip.ts | 10 +++++++++- server/routers/client/createClient.ts | 9 +++++++++ server/routers/site/createSite.ts | 9 +++++++++ server/setup/scriptsPg/1.7.0.ts | 3 ++- 6 files changed, 31 insertions(+), 4 deletions(-) diff --git a/server/db/pg/schema.ts b/server/db/pg/schema.ts index 6df02338..39f14598 100644 --- a/server/db/pg/schema.ts +++ b/server/db/pg/schema.ts @@ -22,7 +22,7 @@ export const domains = pgTable("domains", { export const orgs = pgTable("orgs", { orgId: varchar("orgId").primaryKey(), name: varchar("name").notNull(), - subnet: varchar("subnet").notNull() + subnet: varchar("subnet") }); export const orgDomains = pgTable("orgDomains", { diff --git a/server/db/sqlite/schema.ts b/server/db/sqlite/schema.ts index 94f3e1bc..3e442d07 100644 --- a/server/db/sqlite/schema.ts +++ b/server/db/sqlite/schema.ts @@ -16,7 +16,7 @@ export const domains = sqliteTable("domains", { export const orgs = sqliteTable("orgs", { orgId: text("orgId").primaryKey(), name: text("name").notNull(), - subnet: text("subnet").notNull(), + subnet: text("subnet") }); export const userDomains = sqliteTable("userDomains", { diff --git a/server/lib/ip.ts b/server/lib/ip.ts index cf886fad..ad952098 100644 --- a/server/lib/ip.ts +++ b/server/lib/ip.ts @@ -240,6 +240,14 @@ export async function getNextAvailableClientSubnet( ): Promise { const [org] = await db.select().from(orgs).where(eq(orgs.orgId, orgId)); + if (!org) { + throw new Error(`Organization with ID ${orgId} not found`); + } + + if (!org.subnet) { + throw new Error(`Organization with ID ${orgId} has no subnet defined`); + } + const existingAddressesSites = await db .select({ address: sites.address @@ -279,7 +287,7 @@ export async function getNextAvailableOrgSubnet(): Promise { .from(orgs) .where(isNotNull(orgs.subnet)); - const addresses = existingAddresses.map((org) => org.subnet); + const addresses = existingAddresses.map((org) => org.subnet!); let subnet = findNextAvailableCidr( addresses, diff --git a/server/routers/client/createClient.ts b/server/routers/client/createClient.ts index f5a67e68..34aef346 100644 --- a/server/routers/client/createClient.ts +++ b/server/routers/client/createClient.ts @@ -120,6 +120,15 @@ export async function createClient( ); } + if (!org.subnet) { + return next( + createHttpError( + HttpCode.BAD_REQUEST, + `Organization with ID ${orgId} has no subnet defined` + ) + ); + } + if (!isIpInCidr(subnet, org.subnet)) { return next( createHttpError( diff --git a/server/routers/site/createSite.ts b/server/routers/site/createSite.ts index 5d72ee35..56811c6e 100644 --- a/server/routers/site/createSite.ts +++ b/server/routers/site/createSite.ts @@ -129,6 +129,15 @@ export async function createSite( ); } + if (!org.subnet) { + return next( + createHttpError( + HttpCode.BAD_REQUEST, + `Organization with ID ${orgId} has no subnet defined` + ) + ); + } + let updatedAddress = null; if (address) { if (!isValidIP(address)) { diff --git a/server/setup/scriptsPg/1.7.0.ts b/server/setup/scriptsPg/1.7.0.ts index 63438b06..cbe6db16 100644 --- a/server/setup/scriptsPg/1.7.0.ts +++ b/server/setup/scriptsPg/1.7.0.ts @@ -86,7 +86,7 @@ export default async function migration() { ALTER TABLE "domains" ADD COLUMN "tries" integer DEFAULT 0 NOT NULL; ALTER TABLE "exitNodes" ADD COLUMN "maxConnections" integer; ALTER TABLE "newt" ADD COLUMN "version" varchar; - ALTER TABLE "orgs" ADD COLUMN "subnet" varchar NOT NULL; + ALTER TABLE "orgs" ADD COLUMN "subnet" varchar; ALTER TABLE "sites" ADD COLUMN "address" varchar; ALTER TABLE "sites" ADD COLUMN "endpoint" varchar; ALTER TABLE "sites" ADD COLUMN "publicKey" varchar; @@ -112,6 +112,7 @@ export default async function migration() { } catch (e) { console.log("Unable to migrate database schema"); console.log(e); + throw e; } console.log(`${version} migration complete`);