From 108cb6216c85c928403692ee38c9ea086af1cf3d Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 1 Jul 2026 10:37:17 -0400 Subject: [PATCH] Add migration to fix policy delete issues Ref #3257 --- server/routers/site/restartSite.ts | 6 +- server/setup/migrationsSqlite.ts | 4 +- server/setup/scriptsSqlite/1.19.5.ts | 106 +++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 server/setup/scriptsSqlite/1.19.5.ts diff --git a/server/routers/site/restartSite.ts b/server/routers/site/restartSite.ts index 705b65db8..f60db77d3 100644 --- a/server/routers/site/restartSite.ts +++ b/server/routers/site/restartSite.ts @@ -10,6 +10,7 @@ import logger from "@server/logger"; import { fromError } from "zod-validation-error"; import { OpenAPITags, registry } from "@server/openApi"; import { sendToClient } from "../ws"; +import { canCompress } from "@server/lib/clientVersionChecks"; const updateSiteParamsSchema = z.strictObject({ siteId: z.coerce.number().int().positive() @@ -97,7 +98,10 @@ export async function restartSite( type: "newt/wg/restart", data: {} }, - { incrementConfigVersion: false, compress: false } + { + incrementConfigVersion: false, + compress: canCompress(newt.version, "newt") + } ); return response(res, { diff --git a/server/setup/migrationsSqlite.ts b/server/setup/migrationsSqlite.ts index bc68ba3aa..8662678d2 100644 --- a/server/setup/migrationsSqlite.ts +++ b/server/setup/migrationsSqlite.ts @@ -45,6 +45,7 @@ import m39 from "./scriptsSqlite/1.18.3"; import m40 from "./scriptsSqlite/1.18.4"; import m41 from "./scriptsSqlite/1.19.0"; import m42 from "./scriptsSqlite/1.19.1"; +import m43 from "./scriptsSqlite/1.19.5"; // THIS CANNOT IMPORT ANYTHING FROM THE SERVER // EXCEPT FOR THE DATABASE AND THE SCHEMA @@ -87,7 +88,8 @@ const migrations = [ { version: "1.18.3", run: m39 }, { version: "1.18.4", run: m40 }, { version: "1.19.0", run: m41 }, - { version: "1.19.1", run: m42 } + { version: "1.19.1", run: m42 }, + { version: "1.19.5", run: m43 } // Add new migrations here as they are created ] as const; diff --git a/server/setup/scriptsSqlite/1.19.5.ts b/server/setup/scriptsSqlite/1.19.5.ts new file mode 100644 index 000000000..b9fe43ecf --- /dev/null +++ b/server/setup/scriptsSqlite/1.19.5.ts @@ -0,0 +1,106 @@ +import { APP_PATH } from "@server/lib/consts"; +import Database from "better-sqlite3"; +import path from "path"; + +const version = "1.19.5"; + +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(() => { + // The 1.19.0 migration added policyPasswordId/policyPincodeId/policyWhitelistId to + // resourceSessions via inline REFERENCES clauses with no ON DELETE action, unlike the + // Postgres migration which correctly used "ON DELETE cascade". SQLite can't alter an + // existing foreign key, so rebuild the table to match resourceSessions in schema.ts. + db.prepare( + ` + CREATE TABLE 'resourceSessions_new' ( + 'id' text PRIMARY KEY NOT NULL, + 'resourceId' integer NOT NULL, + 'expiresAt' integer NOT NULL, + 'sessionLength' integer NOT NULL, + 'doNotExtend' integer DEFAULT false NOT NULL, + 'isRequestToken' integer, + 'userSessionId' text, + 'passwordId' integer, + 'pincodeId' integer, + 'whitelistId' integer, + 'accessTokenId' text, + 'policyPasswordId' integer, + 'policyPincodeId' integer, + 'policyWhitelistId' integer, + 'issuedAt' integer, + FOREIGN KEY ('resourceId') REFERENCES 'resources'('resourceId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('userSessionId') REFERENCES 'session'('id') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('passwordId') REFERENCES 'resourcePassword'('passwordId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('pincodeId') REFERENCES 'resourcePincode'('pincodeId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('whitelistId') REFERENCES 'resourceWhitelist'('id') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('accessTokenId') REFERENCES 'resourceAccessToken'('accessTokenId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('policyPasswordId') REFERENCES 'resourcePolicyPassword'('passwordId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('policyPincodeId') REFERENCES 'resourcePolicyPincode'('pincodeId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('policyWhitelistId') REFERENCES 'resourcePolicyWhitelist'('id') ON UPDATE no action ON DELETE cascade + ); + ` + ).run(); + + db.prepare( + ` + INSERT INTO 'resourceSessions_new' ( + "id", + "resourceId", + "expiresAt", + "sessionLength", + "doNotExtend", + "isRequestToken", + "userSessionId", + "passwordId", + "pincodeId", + "whitelistId", + "accessTokenId", + "policyPasswordId", + "policyPincodeId", + "policyWhitelistId", + "issuedAt" + ) + SELECT + "id", + "resourceId", + "expiresAt", + "sessionLength", + "doNotExtend", + "isRequestToken", + "userSessionId", + "passwordId", + "pincodeId", + "whitelistId", + "accessTokenId", + "policyPasswordId", + "policyPincodeId", + "policyWhitelistId", + "issuedAt" + FROM 'resourceSessions'; + ` + ).run(); + + db.prepare(`DROP TABLE 'resourceSessions';`).run(); + db.prepare( + `ALTER TABLE 'resourceSessions_new' RENAME TO 'resourceSessions';` + ).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`); +}