diff --git a/server/setup/migrationsPg.ts b/server/setup/migrationsPg.ts index d65e09cfa..971be1b23 100644 --- a/server/setup/migrationsPg.ts +++ b/server/setup/migrationsPg.ts @@ -31,6 +31,7 @@ import m22 from "./scriptsPg/1.21.0"; import m23 from "./scriptsPg/1.22.0"; import m24 from "./scriptsPg/1.23.0"; import m25 from "./scriptsPg/1.24.0"; +import m26 from "./scriptsPg/1.25.0"; // THIS CANNOT IMPORT ANYTHING FROM THE SERVER // EXCEPT FOR THE DATABASE AND THE SCHEMA @@ -61,7 +62,8 @@ const migrations = [ { version: "1.21.0", run: m22 }, { version: "1.22.0", run: m23 }, { version: "1.23.0", run: m24 }, - { version: "1.24.0", run: m25 } + { version: "1.24.0", run: m25 }, + { version: "1.25.0", run: m26 } // Add new migrations here as they are created ] as { version: string; diff --git a/server/setup/migrationsSqlite.ts b/server/setup/migrationsSqlite.ts index b47e7989c..2ee520a96 100644 --- a/server/setup/migrationsSqlite.ts +++ b/server/setup/migrationsSqlite.ts @@ -51,6 +51,7 @@ import m44 from "./scriptsSqlite/1.21.0"; import m45 from "./scriptsSqlite/1.22.0"; import m46 from "./scriptsSqlite/1.23.0"; import m47 from "./scriptsSqlite/1.24.0"; +import m48 from "./scriptsSqlite/1.25.0"; // THIS CANNOT IMPORT ANYTHING FROM THE SERVER // EXCEPT FOR THE DATABASE AND THE SCHEMA @@ -98,7 +99,8 @@ const migrations = [ { version: "1.21.0", run: m44 }, { version: "1.22.0", run: m45 }, { version: "1.23.0", run: m46 }, - { version: "1.24.0", run: m47 } + { version: "1.24.0", run: m47 }, + { version: "1.25.0", run: m48 } // Add new migrations here as they are created ] as const; diff --git a/server/setup/scriptsPg/1.25.0.ts b/server/setup/scriptsPg/1.25.0.ts new file mode 100644 index 000000000..d64c74d31 --- /dev/null +++ b/server/setup/scriptsPg/1.25.0.ts @@ -0,0 +1,99 @@ +import { db } from "@server/db/pg/driver"; +import { sql } from "drizzle-orm"; + +const version = "1.25.0"; + +export default async function migration() { + console.log(`Running setup script ${version}...`); + + try { + await db.execute(sql`BEGIN`); + + await db.execute(sql` + CREATE TABLE "resourceMtlsCertificates" ( + "mtlsCertificateId" serial PRIMARY KEY NOT NULL, + "resourceId" integer NOT NULL, + "name" varchar, + "certificate" text NOT NULL, + "subject" varchar, + "issuer" varchar, + "serialNumber" varchar, + "fingerprint" varchar, + "notBefore" bigint, + "notAfter" bigint, + "createdAt" bigint NOT NULL + ); + `); + await db.execute(sql` + CREATE TABLE "clientOrgRoles" ( + "clientId" integer NOT NULL, + "orgId" varchar NOT NULL, + "roleId" integer NOT NULL, + CONSTRAINT "clientOrgRoles_clientId_orgId_roleId_unique" UNIQUE("clientId","orgId","roleId") + ); + `); + await db.execute(sql` + CREATE TABLE "redirects" ( + "redirectId" serial PRIMARY KEY NOT NULL, + "orgId" varchar NOT NULL, + "resourceId" integer, + "domainId" varchar, + "niceId" text NOT NULL, + "name" varchar NOT NULL, + "subdomain" varchar, + "destinationHost" varchar NOT NULL, + "pathMatchType" varchar DEFAULT 'regex' NOT NULL, + "matchPath" varchar, + "rewritePath" varchar, + "rewritePathType" varchar, + "priority" integer DEFAULT 100, + "permanent" boolean DEFAULT false NOT NULL, + "ssl" boolean DEFAULT true NOT NULL, + "enabled" boolean DEFAULT true NOT NULL + ); + `); + await db.execute( + sql`ALTER TABLE "exitNodes" ADD COLUMN "relayPort" integer NOT NULL;` + ); + await db.execute( + sql`ALTER TABLE "resources" ADD COLUMN "loadBalancingStrategy" varchar(32) DEFAULT 'wrr' NOT NULL;` + ); + await db.execute( + sql`ALTER TABLE "resources" ADD COLUMN "mtlsEnabled" boolean DEFAULT false NOT NULL;` + ); + await db.execute( + sql`ALTER TABLE "resourceMtlsCertificates" ADD CONSTRAINT "resourceMtlsCertificates_resourceId_resources_resourceId_fk" FOREIGN KEY ("resourceId") REFERENCES "public"."resources"("resourceId") ON DELETE cascade ON UPDATE no action;` + ); + await db.execute( + sql`ALTER TABLE "clientOrgRoles" ADD CONSTRAINT "clientOrgRoles_clientId_clients_clientId_fk" FOREIGN KEY ("clientId") REFERENCES "public"."clients"("clientId") ON DELETE cascade ON UPDATE no action;` + ); + await db.execute( + sql`ALTER TABLE "clientOrgRoles" ADD CONSTRAINT "clientOrgRoles_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;` + ); + await db.execute( + sql`ALTER TABLE "clientOrgRoles" ADD CONSTRAINT "clientOrgRoles_roleId_roles_roleId_fk" FOREIGN KEY ("roleId") REFERENCES "public"."roles"("roleId") ON DELETE cascade ON UPDATE no action;` + ); + await db.execute( + sql`ALTER TABLE "redirects" ADD CONSTRAINT "redirects_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;` + ); + await db.execute( + sql`ALTER TABLE "redirects" ADD CONSTRAINT "redirects_resourceId_resources_resourceId_fk" FOREIGN KEY ("resourceId") REFERENCES "public"."resources"("resourceId") ON DELETE cascade ON UPDATE no action;` + ); + await db.execute( + sql`ALTER TABLE "redirects" ADD CONSTRAINT "redirects_domainId_domains_domainId_fk" FOREIGN KEY ("domainId") REFERENCES "public"."domains"("domainId") ON DELETE cascade ON UPDATE no action;` + ); + await db.execute( + sql`CREATE INDEX "idx_clientorgroles_roleid" ON "clientOrgRoles" USING btree ("roleId");` + ); + + await db.execute(sql`COMMIT`); + console.log("Migrated database"); + } catch (e) { + await db.execute(sql`ROLLBACK`); + console.log("Unable to migrate database"); + console.log(e); + throw e; + } + + console.log(`${version} migration complete`); +} diff --git a/server/setup/scriptsSqlite/1.25.0.ts b/server/setup/scriptsSqlite/1.25.0.ts new file mode 100644 index 000000000..624b09ff8 --- /dev/null +++ b/server/setup/scriptsSqlite/1.25.0.ts @@ -0,0 +1,108 @@ +import { APP_PATH } from "@server/lib/consts"; +import Database from "better-sqlite3"; +import path from "path"; + +const version = "1.25.0"; + +export default async function migration() { + console.log(`Running setup script ${version}...`); + + const location = path.join(APP_PATH, "db", "db.sqlite"); + const db = new Database(location); + + try { + db.pragma("foreign_keys = OFF"); + + db.transaction(() => { + db.prepare( + ` + CREATE TABLE 'resourceMtlsCertificates' ( + 'mtlsCertificateId' integer PRIMARY KEY AUTOINCREMENT NOT NULL, + 'resourceId' integer NOT NULL, + 'name' text, + 'certificate' text NOT NULL, + 'subject' text, + 'issuer' text, + 'serialNumber' text, + 'fingerprint' text, + 'notBefore' integer, + 'notAfter' integer, + 'createdAt' integer NOT NULL, + FOREIGN KEY ('resourceId') REFERENCES 'resources'('resourceId') ON UPDATE no action ON DELETE cascade + ); + ` + ).run(); + db.prepare( + ` + CREATE TABLE 'clientOrgRoles' ( + 'clientId' integer NOT NULL, + 'orgId' text NOT NULL, + 'roleId' integer NOT NULL, + FOREIGN KEY ('clientId') REFERENCES 'clients'('clientId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('roleId') REFERENCES 'roles'('roleId') ON UPDATE no action ON DELETE cascade + ); + ` + ).run(); + db.prepare( + ` + CREATE INDEX 'idx_clientOrgRoles_roleId' ON 'clientOrgRoles' ('roleId'); + ` + ).run(); + db.prepare( + ` + CREATE UNIQUE INDEX 'clientOrgRoles_clientId_orgId_roleId_unique' ON 'clientOrgRoles' ('clientId','orgId','roleId'); + ` + ).run(); + db.prepare( + ` + CREATE TABLE 'redirects' ( + 'redirectId' integer PRIMARY KEY AUTOINCREMENT NOT NULL, + 'orgId' text NOT NULL, + 'resourceId' integer, + 'domainId' text, + 'niceId' text NOT NULL, + 'name' text NOT NULL, + 'subdomain' text, + 'destinationHost' text NOT NULL, + 'pathMatchType' text DEFAULT 'regex' NOT NULL, + 'matchPath' text, + 'rewritePath' text, + 'rewritePathType' text, + 'priority' integer DEFAULT 100, + 'permanent' integer DEFAULT false NOT NULL, + 'ssl' integer DEFAULT true NOT NULL, + 'enabled' integer DEFAULT true NOT NULL, + FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('resourceId') REFERENCES 'resources'('resourceId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE cascade + ); + ` + ).run(); + db.prepare( + ` + ALTER TABLE 'exitNodes' ADD 'relayPort' integer NOT NULL; + ` + ).run(); + db.prepare( + ` + ALTER TABLE 'resources' ADD 'loadBalancingStrategy' text DEFAULT 'wrr' NOT NULL; + ` + ).run(); + db.prepare( + ` + ALTER TABLE 'resources' ADD 'mtlsEnabled' integer DEFAULT false NOT NULL; + ` + ).run(); + })(); + + db.pragma("foreign_keys = ON"); + + console.log("Migrated database"); + } catch (e) { + console.log("Failed to migrate db:", e); + throw e; + } + + console.log(`${version} migration complete`); +}