diff --git a/server/setup/scriptsSqlite/1.12.0.ts b/server/setup/scriptsSqlite/1.12.0.ts index 33e4336d..0d1d9862 100644 --- a/server/setup/scriptsSqlite/1.12.0.ts +++ b/server/setup/scriptsSqlite/1.12.0.ts @@ -10,9 +10,200 @@ export default async function migration() { const location = path.join(APP_PATH, "db", "db.sqlite"); const db = new Database(location); - db.transaction(() => { - db.prepare(`UPDATE resourceRules SET match = "COUNTRY" WHERE match = "GEOIP"`).run(); - })(); + try { + db.pragma("foreign_keys = OFF"); + + db.transaction(() => { + db.prepare( + `UPDATE resourceRules SET match = "COUNTRY" WHERE match = "GEOIP"` + ).run(); + + db.prepare( + ` + CREATE TABLE 'accessAuditLog' ( + 'id' integer PRIMARY KEY AUTOINCREMENT NOT NULL, + 'timestamp' integer NOT NULL, + 'orgId' text NOT NULL, + 'actorType' text, + 'actor' text, + 'actorId' text, + 'resourceId' integer, + 'ip' text, + 'location' text, + 'type' text NOT NULL, + 'action' integer NOT NULL, + 'userAgent' text, + 'metadata' text, + FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade + ); + ` + ).run(); + + db.prepare( + `CREATE INDEX 'idx_identityAuditLog_timestamp' ON 'accessAuditLog' ('timestamp');` + ).run(); + db.prepare( + `CREATE INDEX 'idx_identityAuditLog_org_timestamp' ON 'accessAuditLog' ('orgId','timestamp');` + ).run(); + + db.prepare( + ` + CREATE TABLE 'actionAuditLog' ( + 'id' integer PRIMARY KEY AUTOINCREMENT NOT NULL, + 'timestamp' integer NOT NULL, + 'orgId' text NOT NULL, + 'actorType' text NOT NULL, + 'actor' text NOT NULL, + 'actorId' text NOT NULL, + 'action' text NOT NULL, + 'metadata' text, + FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade + ); + ` + ).run(); + + db.prepare( + `CREATE INDEX 'idx_actionAuditLog_timestamp' ON 'actionAuditLog' ('timestamp');` + ).run(); + db.prepare( + `CREATE INDEX 'idx_actionAuditLog_org_timestamp' ON 'actionAuditLog' ('orgId','timestamp');` + ).run(); + + db.prepare( + ` + CREATE TABLE 'dnsRecords' ( + 'id' text PRIMARY KEY NOT NULL, + 'domainId' text NOT NULL, + 'recordType' text NOT NULL, + 'baseDomain' text, + 'value' text NOT NULL, + 'verified' integer DEFAULT false NOT NULL, + FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE cascade + ); + ` + ).run(); + + db.prepare( + ` + CREATE TABLE 'requestAuditLog' ( + 'id' integer PRIMARY KEY AUTOINCREMENT NOT NULL, + 'timestamp' integer NOT NULL, + 'orgId' text, + 'action' integer NOT NULL, + 'reason' integer NOT NULL, + 'actorType' text, + 'actor' text, + 'actorId' text, + 'resourceId' integer, + 'ip' text, + 'location' text, + 'userAgent' text, + 'metadata' text, + 'headers' text, + 'query' text, + 'originalRequestURL' text, + 'scheme' text, + 'host' text, + 'path' text, + 'method' text, + 'tls' integer, + FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade + ); + ` + ).run(); + + db.prepare( + `CREATE INDEX 'idx_requestAuditLog_timestamp' ON 'requestAuditLog' ('timestamp');` + ).run(); + db.prepare( + `CREATE INDEX 'idx_requestAuditLog_org_timestamp' ON 'requestAuditLog' ('orgId','timestamp');` + ).run(); + + db.prepare( + ` + CREATE TABLE '__new_resources' ( + 'resourceId' integer PRIMARY KEY AUTOINCREMENT NOT NULL, + 'resourceGuid' text(36) NOT NULL, + 'orgId' text NOT NULL, + 'niceId' text NOT NULL, + 'name' text NOT NULL, + 'subdomain' text, + 'fullDomain' text, + 'domainId' text, + 'ssl' integer DEFAULT false NOT NULL, + 'blockAccess' integer DEFAULT false NOT NULL, + 'sso' integer DEFAULT true NOT NULL, + 'http' integer DEFAULT true NOT NULL, + 'protocol' text NOT NULL, + 'proxyPort' integer, + 'emailWhitelistEnabled' integer DEFAULT false NOT NULL, + 'applyRules' integer DEFAULT false NOT NULL, + 'enabled' integer DEFAULT true NOT NULL, + 'stickySession' integer DEFAULT false NOT NULL, + 'tlsServerName' text, + 'setHostHeader' text, + 'enableProxy' integer DEFAULT true, + 'skipToIdpId' integer, + 'headers' text, + 'proxyProtocol' integer DEFAULT false NOT NULL, + 'proxyProtocolVersion' integer DEFAULT 1, + FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade, + FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE set null, + FOREIGN KEY ('skipToIdpId') REFERENCES 'idp'('idpId') ON UPDATE no action ON DELETE set null + ); + ` + ).run(); + + db.prepare( + `INSERT INTO '__new_resources'("resourceId", "resourceGuid", "orgId", "niceId", "name", "subdomain", "fullDomain", "domainId", "ssl", "blockAccess", "sso", "http", "protocol", "proxyPort", "emailWhitelistEnabled", "applyRules", "enabled", "stickySession", "tlsServerName", "setHostHeader", "enableProxy", "skipToIdpId", "headers", "proxyProtocol", "proxyProtocolVersion") SELECT "resourceId", "resourceGuid", "orgId", "niceId", "name", "subdomain", "fullDomain", "domainId", "ssl", "blockAccess", "sso", "http", "protocol", "proxyPort", "emailWhitelistEnabled", "applyRules", "enabled", "stickySession", "tlsServerName", "setHostHeader", "enableProxy", "skipToIdpId", "headers", "proxyProtocol", "proxyProtocolVersion" FROM 'resources';` + ).run(); + db.prepare(`DROP TABLE 'resources';`).run(); + db.prepare( + `ALTER TABLE '__new_resources' RENAME TO 'resources';` + ).run(); + + db.prepare( + `CREATE UNIQUE INDEX 'resources_resourceGuid_unique' ON 'resources' ('resourceGuid');` + ).run(); + db.prepare(`ALTER TABLE 'domains' ADD 'certResolver' text;`).run(); + db.prepare( + `ALTER TABLE 'domains' ADD 'preferWildcardCert' integer;` + ).run(); + db.prepare( + `ALTER TABLE 'orgs' ADD 'requireTwoFactor' integer;` + ).run(); + db.prepare( + `ALTER TABLE 'orgs' ADD 'maxSessionLengthHours' integer;` + ).run(); + db.prepare( + `ALTER TABLE 'orgs' ADD 'passwordExpiryDays' integer;` + ).run(); + db.prepare( + `ALTER TABLE 'orgs' ADD 'settingsLogRetentionDaysRequest' integer DEFAULT 7 NOT NULL;` + ).run(); + db.prepare( + `ALTER TABLE 'orgs' ADD 'settingsLogRetentionDaysAccess' integer DEFAULT 0 NOT NULL;` + ).run(); + db.prepare( + `ALTER TABLE 'orgs' ADD 'settingsLogRetentionDaysAction' integer DEFAULT 0 NOT NULL;` + ).run(); + db.prepare(`ALTER TABLE 'orgs' DROP COLUMN 'settings';`).run(); + db.prepare( + `ALTER TABLE 'resourceSessions' ADD 'issuedAt' integer;` + ).run(); + db.prepare(`ALTER TABLE 'session' ADD 'issuedAt' integer;`).run(); + db.prepare( + `ALTER TABLE 'user' ADD 'lastPasswordChange' integer;` + ).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`); }