Merge dev into fix/log-analytics-adjustments

This commit is contained in:
Fred KISSIE
2025-12-10 03:19:14 +01:00
parent 9db2feff77
commit d490cab48c
555 changed files with 9375 additions and 9287 deletions

View File

@@ -1,5 +1,5 @@
import { build } from "@server/build";
import { db, sessionTransferToken } from "@server/db";
import { db, deviceWebAuthCodes, sessionTransferToken } from "@server/db";
import {
emailVerificationCodes,
newtSessions,
@@ -89,4 +89,12 @@ export async function clearStaleData() {
logger.warn("Error clearing expired sessionTransferToken:", e);
}
}
try {
await db
.delete(deviceWebAuthCodes)
.where(lt(deviceWebAuthCodes.expiresAt, new Date().getTime()));
} catch (e) {
logger.warn("Error clearing expired deviceWebAuthCodes:", e);
}
}

View File

@@ -31,7 +31,9 @@ export async function ensureSetupToken() {
// If admin exists, no need for setup token
if (existingAdmin) {
logger.debug("Server admin exists. Setup token generation skipped.");
logger.debug(
"Server admin exists. Setup token generation skipped."
);
return;
}

View File

@@ -30,7 +30,7 @@ const migrations = [
{ version: "1.11.0", run: m7 },
{ version: "1.11.1", run: m8 },
{ version: "1.12.0", run: m9 },
{ version: "1.13.0", run: m10 },
{ version: "1.13.0", run: m10 }
// Add new migrations here as they are created
] as {
version: string;

View File

@@ -9,7 +9,9 @@ export default async function migration() {
try {
await db.execute(sql`BEGIN`);
await db.execute(sql`UPDATE "resourceRules" SET "match" = 'COUNTRY' WHERE "match" = 'GEOIP'`);
await db.execute(
sql`UPDATE "resourceRules" SET "match" = 'COUNTRY' WHERE "match" = 'GEOIP'`
);
await db.execute(sql`
CREATE TABLE "accessAuditLog" (
@@ -92,40 +94,97 @@ export default async function migration() {
);
`);
await db.execute(sql`ALTER TABLE "blueprints" ADD CONSTRAINT "blueprints_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(
sql`ALTER TABLE "blueprints" ADD CONSTRAINT "blueprints_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(sql`ALTER TABLE "remoteExitNode" ADD COLUMN "secondaryVersion" varchar;`);
await db.execute(sql`ALTER TABLE "resources" DROP CONSTRAINT "resources_skipToIdpId_idp_idpId_fk";`);
await db.execute(sql`ALTER TABLE "domains" ADD COLUMN "certResolver" varchar;`);
await db.execute(sql`ALTER TABLE "domains" ADD COLUMN "customCertResolver" varchar;`);
await db.execute(sql`ALTER TABLE "domains" ADD COLUMN "preferWildcardCert" boolean;`);
await db.execute(sql`ALTER TABLE "orgs" ADD COLUMN "requireTwoFactor" boolean;`);
await db.execute(sql`ALTER TABLE "orgs" ADD COLUMN "maxSessionLengthHours" integer;`);
await db.execute(sql`ALTER TABLE "orgs" ADD COLUMN "passwordExpiryDays" integer;`);
await db.execute(sql`ALTER TABLE "orgs" ADD COLUMN "settingsLogRetentionDaysRequest" integer DEFAULT 7 NOT NULL;`);
await db.execute(sql`ALTER TABLE "orgs" ADD COLUMN "settingsLogRetentionDaysAccess" integer DEFAULT 0 NOT NULL;`);
await db.execute(sql`ALTER TABLE "orgs" ADD COLUMN "settingsLogRetentionDaysAction" integer DEFAULT 0 NOT NULL;`);
await db.execute(sql`ALTER TABLE "resourceSessions" ADD COLUMN "issuedAt" bigint;`);
await db.execute(sql`ALTER TABLE "resources" ADD COLUMN "proxyProtocol" boolean DEFAULT false NOT NULL;`);
await db.execute(sql`ALTER TABLE "resources" ADD COLUMN "proxyProtocolVersion" integer DEFAULT 1;`);
await db.execute(sql`ALTER TABLE "session" ADD COLUMN "issuedAt" bigint;`);
await db.execute(sql`ALTER TABLE "user" ADD COLUMN "lastPasswordChange" bigint;`);
await db.execute(sql`ALTER TABLE "accessAuditLog" ADD CONSTRAINT "accessAuditLog_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(sql`ALTER TABLE "actionAuditLog" ADD CONSTRAINT "actionAuditLog_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(sql`ALTER TABLE "dnsRecords" ADD CONSTRAINT "dnsRecords_domainId_domains_domainId_fk" FOREIGN KEY ("domainId") REFERENCES "public"."domains"("domainId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(sql`ALTER TABLE "requestAuditLog" ADD CONSTRAINT "requestAuditLog_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(sql`CREATE INDEX "idx_identityAuditLog_timestamp" ON "accessAuditLog" USING btree ("timestamp");`);
await db.execute(sql`CREATE INDEX "idx_identityAuditLog_org_timestamp" ON "accessAuditLog" USING btree ("orgId","timestamp");`);
await db.execute(sql`CREATE INDEX "idx_actionAuditLog_timestamp" ON "actionAuditLog" USING btree ("timestamp");`);
await db.execute(sql`CREATE INDEX "idx_actionAuditLog_org_timestamp" ON "actionAuditLog" USING btree ("orgId","timestamp");`);
await db.execute(sql`CREATE INDEX "idx_requestAuditLog_timestamp" ON "requestAuditLog" USING btree ("timestamp");`);
await db.execute(sql`CREATE INDEX "idx_requestAuditLog_org_timestamp" ON "requestAuditLog" USING btree ("orgId","timestamp");`);
await db.execute(sql`ALTER TABLE "resources" ADD CONSTRAINT "resources_skipToIdpId_idp_idpId_fk" FOREIGN KEY ("skipToIdpId") REFERENCES "public"."idp"("idpId") ON DELETE set null ON UPDATE no action;`);
await db.execute(
sql`ALTER TABLE "remoteExitNode" ADD COLUMN "secondaryVersion" varchar;`
);
await db.execute(
sql`ALTER TABLE "resources" DROP CONSTRAINT "resources_skipToIdpId_idp_idpId_fk";`
);
await db.execute(
sql`ALTER TABLE "domains" ADD COLUMN "certResolver" varchar;`
);
await db.execute(
sql`ALTER TABLE "domains" ADD COLUMN "customCertResolver" varchar;`
);
await db.execute(
sql`ALTER TABLE "domains" ADD COLUMN "preferWildcardCert" boolean;`
);
await db.execute(
sql`ALTER TABLE "orgs" ADD COLUMN "requireTwoFactor" boolean;`
);
await db.execute(
sql`ALTER TABLE "orgs" ADD COLUMN "maxSessionLengthHours" integer;`
);
await db.execute(
sql`ALTER TABLE "orgs" ADD COLUMN "passwordExpiryDays" integer;`
);
await db.execute(
sql`ALTER TABLE "orgs" ADD COLUMN "settingsLogRetentionDaysRequest" integer DEFAULT 7 NOT NULL;`
);
await db.execute(
sql`ALTER TABLE "orgs" ADD COLUMN "settingsLogRetentionDaysAccess" integer DEFAULT 0 NOT NULL;`
);
await db.execute(
sql`ALTER TABLE "orgs" ADD COLUMN "settingsLogRetentionDaysAction" integer DEFAULT 0 NOT NULL;`
);
await db.execute(
sql`ALTER TABLE "resourceSessions" ADD COLUMN "issuedAt" bigint;`
);
await db.execute(
sql`ALTER TABLE "resources" ADD COLUMN "proxyProtocol" boolean DEFAULT false NOT NULL;`
);
await db.execute(
sql`ALTER TABLE "resources" ADD COLUMN "proxyProtocolVersion" integer DEFAULT 1;`
);
await db.execute(
sql`ALTER TABLE "session" ADD COLUMN "issuedAt" bigint;`
);
await db.execute(
sql`ALTER TABLE "user" ADD COLUMN "lastPasswordChange" bigint;`
);
await db.execute(
sql`ALTER TABLE "accessAuditLog" ADD CONSTRAINT "accessAuditLog_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(
sql`ALTER TABLE "actionAuditLog" ADD CONSTRAINT "actionAuditLog_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(
sql`ALTER TABLE "dnsRecords" ADD CONSTRAINT "dnsRecords_domainId_domains_domainId_fk" FOREIGN KEY ("domainId") REFERENCES "public"."domains"("domainId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(
sql`ALTER TABLE "requestAuditLog" ADD CONSTRAINT "requestAuditLog_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(
sql`CREATE INDEX "idx_identityAuditLog_timestamp" ON "accessAuditLog" USING btree ("timestamp");`
);
await db.execute(
sql`CREATE INDEX "idx_identityAuditLog_org_timestamp" ON "accessAuditLog" USING btree ("orgId","timestamp");`
);
await db.execute(
sql`CREATE INDEX "idx_actionAuditLog_timestamp" ON "actionAuditLog" USING btree ("timestamp");`
);
await db.execute(
sql`CREATE INDEX "idx_actionAuditLog_org_timestamp" ON "actionAuditLog" USING btree ("orgId","timestamp");`
);
await db.execute(
sql`CREATE INDEX "idx_requestAuditLog_timestamp" ON "requestAuditLog" USING btree ("timestamp");`
);
await db.execute(
sql`CREATE INDEX "idx_requestAuditLog_org_timestamp" ON "requestAuditLog" USING btree ("orgId","timestamp");`
);
await db.execute(
sql`ALTER TABLE "resources" ADD CONSTRAINT "resources_skipToIdpId_idp_idpId_fk" FOREIGN KEY ("skipToIdpId") REFERENCES "public"."idp"("idpId") ON DELETE set null ON UPDATE no action;`
);
await db.execute(sql`ALTER TABLE "orgs" DROP COLUMN "settings";`);
// get all of the domains
const domainsQuery = await db.execute(sql`SELECT "domainId", "baseDomain" FROM "domains"`);
const domainsQuery = await db.execute(
sql`SELECT "domainId", "baseDomain" FROM "domains"`
);
const domains = domainsQuery.rows as {
domainId: string;
baseDomain: string;
@@ -135,11 +194,11 @@ export default async function migration() {
// insert two records into the dnsRecords table for each domain
await db.execute(sql`
INSERT INTO "dnsRecords" ("domainId", "recordType", "baseDomain", "value", "verified")
VALUES (${domain.domainId}, 'A', ${`*.${domain.baseDomain}`}, ${'Server IP Address'}, true)
VALUES (${domain.domainId}, 'A', ${`*.${domain.baseDomain}`}, ${"Server IP Address"}, true)
`);
await db.execute(sql`
INSERT INTO "dnsRecords" ("domainId", "recordType", "baseDomain", "value", "verified")
VALUES (${domain.domainId}, 'A', ${domain.baseDomain}, ${'Server IP Address'}, true)
VALUES (${domain.domainId}, 'A', ${domain.baseDomain}, ${"Server IP Address"}, true)
`);
}

View File

@@ -255,7 +255,9 @@ export default async function migration() {
const siteDataQuery = await db.execute(sql`
SELECT "orgId" FROM "sites" WHERE "siteId" = ${site.siteId}
`);
const siteData = siteDataQuery.rows[0] as { orgId: string } | undefined;
const siteData = siteDataQuery.rows[0] as
| { orgId: string }
| undefined;
if (!siteData) continue;
const subnets = site.remoteSubnets.split(",");

View File

@@ -121,7 +121,7 @@ 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'`);

View File

@@ -11,7 +11,9 @@ export default async function migration() {
try {
// Get the first siteId to use as default
const firstSite = await db.execute(sql`SELECT "siteId" FROM "sites" LIMIT 1`);
const firstSite = await db.execute(
sql`SELECT "siteId" FROM "sites" LIMIT 1`
);
if (firstSite.rows.length > 0) {
firstSiteId = firstSite.rows[0].siteId as number;
}
@@ -52,33 +54,59 @@ export default async function migration() {
"enabled" boolean DEFAULT true NOT NULL
);`);
await db.execute(sql`ALTER TABLE "resources" DROP CONSTRAINT "resources_siteId_sites_siteId_fk";`);
await db.execute(
sql`ALTER TABLE "resources" DROP CONSTRAINT "resources_siteId_sites_siteId_fk";`
);
await db.execute(sql`ALTER TABLE "clients" ALTER COLUMN "lastPing" TYPE integer USING NULL;`);
await db.execute(
sql`ALTER TABLE "clients" ALTER COLUMN "lastPing" TYPE integer USING NULL;`
);
await db.execute(sql`ALTER TABLE "clientSites" ADD COLUMN "endpoint" varchar;`);
await db.execute(
sql`ALTER TABLE "clientSites" ADD COLUMN "endpoint" varchar;`
);
await db.execute(sql`ALTER TABLE "exitNodes" ADD COLUMN "online" boolean DEFAULT false NOT NULL;`);
await db.execute(
sql`ALTER TABLE "exitNodes" ADD COLUMN "online" boolean DEFAULT false NOT NULL;`
);
await db.execute(sql`ALTER TABLE "exitNodes" ADD COLUMN "lastPing" integer;`);
await db.execute(
sql`ALTER TABLE "exitNodes" ADD COLUMN "lastPing" integer;`
);
await db.execute(sql`ALTER TABLE "exitNodes" ADD COLUMN "type" text DEFAULT 'gerbil';`);
await db.execute(
sql`ALTER TABLE "exitNodes" ADD COLUMN "type" text DEFAULT 'gerbil';`
);
await db.execute(sql`ALTER TABLE "olms" ADD COLUMN "version" text;`);
await db.execute(sql`ALTER TABLE "orgs" ADD COLUMN "createdAt" text;`);
await db.execute(sql`ALTER TABLE "resources" ADD COLUMN "skipToIdpId" integer;`);
await db.execute(
sql`ALTER TABLE "resources" ADD COLUMN "skipToIdpId" integer;`
);
await db.execute(sql.raw(`ALTER TABLE "targets" ADD COLUMN "siteId" integer NOT NULL DEFAULT ${firstSiteId || 1};`));
await db.execute(
sql.raw(
`ALTER TABLE "targets" ADD COLUMN "siteId" integer NOT NULL DEFAULT ${firstSiteId || 1};`
)
);
await db.execute(sql`ALTER TABLE "siteResources" ADD CONSTRAINT "siteResources_siteId_sites_siteId_fk" FOREIGN KEY ("siteId") REFERENCES "public"."sites"("siteId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(
sql`ALTER TABLE "siteResources" ADD CONSTRAINT "siteResources_siteId_sites_siteId_fk" FOREIGN KEY ("siteId") REFERENCES "public"."sites"("siteId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(sql`ALTER TABLE "siteResources" ADD CONSTRAINT "siteResources_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(
sql`ALTER TABLE "siteResources" ADD CONSTRAINT "siteResources_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(sql`ALTER TABLE "resources" ADD CONSTRAINT "resources_skipToIdpId_idp_idpId_fk" FOREIGN KEY ("skipToIdpId") REFERENCES "public"."idp"("idpId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(
sql`ALTER TABLE "resources" ADD CONSTRAINT "resources_skipToIdpId_idp_idpId_fk" FOREIGN KEY ("skipToIdpId") REFERENCES "public"."idp"("idpId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(sql`ALTER TABLE "targets" ADD CONSTRAINT "targets_siteId_sites_siteId_fk" FOREIGN KEY ("siteId") REFERENCES "public"."sites"("siteId") ON DELETE cascade ON UPDATE no action;`);
await db.execute(
sql`ALTER TABLE "targets" ADD CONSTRAINT "targets_siteId_sites_siteId_fk" FOREIGN KEY ("siteId") REFERENCES "public"."sites"("siteId") ON DELETE cascade ON UPDATE no action;`
);
await db.execute(sql`ALTER TABLE "clients" DROP COLUMN "endpoint";`);

View File

@@ -25,7 +25,9 @@ export default async function migration() {
console.log(`Added new table and column: resourceRules, applyRules`);
} catch (e) {
console.log("Unable to add new table and column: resourceRules, applyRules");
console.log(
"Unable to add new table and column: resourceRules, applyRules"
);
throw e;
}

View File

@@ -38,4 +38,4 @@ export default async function migration() {
fs.writeFileSync(filePath, updatedYaml, "utf8");
console.log("Done.");
}
}

View File

@@ -43,7 +43,9 @@ export default async function migration() {
const updatedYaml = yaml.dump(rawConfig);
fs.writeFileSync(filePath, updatedYaml, "utf8");
} catch (error) {
console.log("We were unable to add CORS to your config file. Please add it manually.");
console.log(
"We were unable to add CORS to your config file. Please add it manually."
);
console.error(error);
}

View File

@@ -182,12 +182,15 @@ export default async function migration() {
if (parsedConfig.success) {
// delete permanent from redirect-to-https middleware
delete traefikConfig.http.middlewares["redirect-to-https"].redirectScheme.permanent;
delete traefikConfig.http.middlewares["redirect-to-https"]
.redirectScheme.permanent;
const updatedTraefikYaml = yaml.dump(traefikConfig);
fs.writeFileSync(traefikPath, updatedTraefikYaml, "utf8");
console.log("Deleted permanent from redirect-to-https middleware.");
console.log(
"Deleted permanent from redirect-to-https middleware."
);
} else {
console.log(fromZodError(parsedConfig.error));
console.log(

View File

@@ -13,15 +13,11 @@ export default async function migration() {
try {
const resources = db
.prepare(
"SELECT resourceId FROM resources"
)
.prepare("SELECT resourceId FROM resources")
.all() as Array<{ resourceId: number }>;
const siteResources = db
.prepare(
"SELECT siteResourceId FROM siteResources"
)
.prepare("SELECT siteResourceId FROM siteResources")
.all() as Array<{ siteResourceId: number }>;
db.transaction(() => {
@@ -82,17 +78,13 @@ export default async function migration() {
// Handle auto-provisioned users for identity providers
const autoProvisionIdps = db
.prepare(
"SELECT idpId FROM idp WHERE autoProvision = 1"
)
.prepare("SELECT idpId FROM idp WHERE autoProvision = 1")
.all() as Array<{ idpId: number }>;
for (const idp of autoProvisionIdps) {
// Get all users with this identity provider
const usersWithIdp = db
.prepare(
"SELECT id FROM user WHERE idpId = ?"
)
.prepare("SELECT id FROM user WHERE idpId = ?")
.all(idp.idpId) as Array<{ id: string }>;
// Update userOrgs to set autoProvisioned to true for these users

View File

@@ -5,16 +5,16 @@ import path from "path";
const version = "1.10.1";
export default async function migration() {
console.log(`Running setup script ${version}...`);
console.log(`Running setup script ${version}...`);
const location = path.join(APP_PATH, "db", "db.sqlite");
const db = new Database(location);
const location = path.join(APP_PATH, "db", "db.sqlite");
const db = new Database(location);
try {
db.pragma("foreign_keys = OFF");
try {
db.pragma("foreign_keys = OFF");
db.transaction(() => {
db.exec(`ALTER TABLE "targets" RENAME TO "targets_old";
db.transaction(() => {
db.exec(`ALTER TABLE "targets" RENAME TO "targets_old";
--> statement-breakpoint
CREATE TABLE "targets" (
"targetId" INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -57,13 +57,13 @@ SELECT
FROM "targets_old";
--> statement-breakpoint
DROP TABLE "targets_old";`);
})();
})();
db.pragma("foreign_keys = ON");
db.pragma("foreign_keys = ON");
console.log(`Migrated database`);
} catch (e) {
console.log("Failed to migrate db:", e);
throw e;
}
}
console.log(`Migrated database`);
} catch (e) {
console.log("Failed to migrate db:", e);
throw e;
}
}

View File

@@ -13,25 +13,29 @@ export default async function migration() {
const db = new Database(location);
db.transaction(() => {
db.prepare(`
db.prepare(
`
CREATE TABLE 'account' (
'accountId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
'userId' text NOT NULL,
FOREIGN KEY ('userId') REFERENCES 'user'('id') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'accountDomains' (
'accountId' integer NOT NULL,
'domainId' text NOT NULL,
FOREIGN KEY ('accountId') REFERENCES 'account'('accountId') ON UPDATE no action ON DELETE cascade,
FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'certificates' (
'certId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
'domain' text NOT NULL,
@@ -49,11 +53,15 @@ export default async function migration() {
'keyFile' text,
FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`CREATE UNIQUE INDEX 'certificates_domain_unique' ON 'certificates' ('domain');`).run();
db.prepare(
`CREATE UNIQUE INDEX 'certificates_domain_unique' ON 'certificates' ('domain');`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'customers' (
'customerId' text PRIMARY KEY NOT NULL,
'orgId' text NOT NULL,
@@ -65,9 +73,11 @@ export default async function migration() {
'updatedAt' integer NOT NULL,
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'dnsChallenges' (
'dnsChallengeId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
'domain' text NOT NULL,
@@ -77,26 +87,32 @@ export default async function migration() {
'expiresAt' integer NOT NULL,
'completed' integer DEFAULT false
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'domainNamespaces' (
'domainNamespaceId' text PRIMARY KEY NOT NULL,
'domainId' text NOT NULL,
FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE set null
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'exitNodeOrgs' (
'exitNodeId' integer NOT NULL,
'orgId' text NOT NULL,
FOREIGN KEY ('exitNodeId') REFERENCES 'exitNodes'('exitNodeId') ON UPDATE no action ON DELETE cascade,
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'loginPage' (
'loginPageId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
'subdomain' text,
@@ -106,27 +122,33 @@ export default async function migration() {
FOREIGN KEY ('exitNodeId') REFERENCES 'exitNodes'('exitNodeId') ON UPDATE no action ON DELETE set null,
FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE set null
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'loginPageOrg' (
'loginPageId' integer NOT NULL,
'orgId' text NOT NULL,
FOREIGN KEY ('loginPageId') REFERENCES 'loginPage'('loginPageId') ON UPDATE no action ON DELETE cascade,
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'remoteExitNodeSession' (
'id' text PRIMARY KEY NOT NULL,
'remoteExitNodeId' text NOT NULL,
'expiresAt' integer NOT NULL,
FOREIGN KEY ('remoteExitNodeId') REFERENCES 'remoteExitNode'('id') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'remoteExitNode' (
'id' text PRIMARY KEY NOT NULL,
'secretHash' text NOT NULL,
@@ -135,9 +157,11 @@ export default async function migration() {
'exitNodeId' integer,
FOREIGN KEY ('exitNodeId') REFERENCES 'exitNodes'('exitNodeId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'sessionTransferToken' (
'token' text PRIMARY KEY NOT NULL,
'sessionId' text NOT NULL,
@@ -145,9 +169,11 @@ export default async function migration() {
'expiresAt' integer NOT NULL,
FOREIGN KEY ('sessionId') REFERENCES 'session'('id') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'subscriptionItems' (
'subscriptionItemId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
'subscriptionId' text NOT NULL,
@@ -162,9 +188,11 @@ export default async function migration() {
'name' text,
FOREIGN KEY ('subscriptionId') REFERENCES 'subscriptions'('subscriptionId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'subscriptions' (
'subscriptionId' text PRIMARY KEY NOT NULL,
'customerId' text NOT NULL,
@@ -175,9 +203,11 @@ export default async function migration() {
'billingCycleAnchor' integer,
FOREIGN KEY ('customerId') REFERENCES 'customers'('customerId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'usage' (
'usageId' text PRIMARY KEY NOT NULL,
'featureId' text NOT NULL,
@@ -191,9 +221,11 @@ export default async function migration() {
'nextRolloverAt' integer,
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'usageNotifications' (
'notificationId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
'orgId' text NOT NULL,
@@ -203,18 +235,22 @@ export default async function migration() {
'sentAt' integer NOT NULL,
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'resourceHeaderAuth' (
'headerAuthId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
'resourceId' integer NOT NULL,
'headerAuthHash' text NOT NULL,
FOREIGN KEY ('resourceId') REFERENCES 'resources'('resourceId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'targetHealthCheck' (
'targetHealthCheckId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
'targetId' integer NOT NULL,
@@ -234,11 +270,13 @@ export default async function migration() {
'hcHealth' text DEFAULT 'unknown',
FOREIGN KEY ('targetId') REFERENCES 'targets'('targetId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`DROP TABLE 'limits';`).run();
db.prepare(`
db.prepare(
`
CREATE TABLE 'limits' (
'limitId' text PRIMARY KEY NOT NULL,
'featureId' text NOT NULL,
@@ -247,12 +285,15 @@ export default async function migration() {
'description' text,
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade
);
`).run();
`
).run();
db.prepare(`ALTER TABLE 'orgs' ADD 'settings' text;`).run();
db.prepare(`ALTER TABLE 'targets' ADD 'rewritePath' text;`).run();
db.prepare(`ALTER TABLE 'targets' ADD 'rewritePathType' text;`).run();
db.prepare(`ALTER TABLE 'targets' ADD 'priority' integer DEFAULT 100 NOT NULL;`).run();
db.prepare(
`ALTER TABLE 'targets' ADD 'priority' integer DEFAULT 100 NOT NULL;`
).run();
const webauthnCredentials = db
.prepare(
@@ -269,7 +310,7 @@ export default async function migration() {
dateCreated: string;
}[];
db.prepare(`DELETE FROM 'webauthnCredentials';`).run();
db.prepare(`DELETE FROM 'webauthnCredentials';`).run();
for (const webauthnCredential of webauthnCredentials) {
const newCredentialId = isoBase64URL.fromBuffer(
@@ -304,7 +345,9 @@ export default async function migration() {
).run();
// 2. Select all rows
const resources = db.prepare(`SELECT resourceId FROM resources`).all() as {
const resources = db
.prepare(`SELECT resourceId FROM resources`)
.all() as {
resourceId: number;
}[];

View File

@@ -112,7 +112,6 @@ export default async function migration() {
`
).run();
db.prepare(
`
CREATE TABLE 'blueprints' (
@@ -212,10 +211,14 @@ export default async function migration() {
db.prepare(
`ALTER TABLE 'user' ADD 'lastPasswordChange' integer;`
).run();
db.prepare(`ALTER TABLE 'remoteExitNode' ADD 'secondaryVersion' text;`).run();
db.prepare(
`ALTER TABLE 'remoteExitNode' ADD 'secondaryVersion' text;`
).run();
// get all of the domains
const domains = db.prepare(`SELECT domainId, baseDomain from domains`).all() as {
const domains = db
.prepare(`SELECT domainId, baseDomain from domains`)
.all() as {
domainId: number;
baseDomain: string;
}[];

View File

@@ -287,7 +287,10 @@ export default async function migration() {
let aliasIpOctet = 8;
for (const siteResource of siteResourcesForAlias) {
const aliasAddress = `100.96.128.${aliasIpOctet}`;
updateAliasAddress.run(aliasAddress, siteResource.siteResourceId);
updateAliasAddress.run(
aliasAddress,
siteResource.siteResourceId
);
aliasIpOctet++;
}
@@ -303,7 +306,12 @@ export default async function migration() {
for (const subnet of subnets) {
// Generate a unique niceId for each new site resource
let niceId = generateName();
insertCidrResource.run(site.siteId, subnet.trim(), niceId, site.siteId);
insertCidrResource.run(
site.siteId,
subnet.trim(),
niceId,
site.siteId
);
}
}
}

View File

@@ -48,9 +48,7 @@ export default async function migration() {
const rawConfig = yaml.load(fileContents) as any;
if (rawConfig.cors?.headers) {
const headers = JSON.parse(
JSON.stringify(rawConfig.cors.headers)
);
const headers = JSON.parse(JSON.stringify(rawConfig.cors.headers));
rawConfig.cors.allowed_headers = headers;
delete rawConfig.cors.headers;
}
@@ -61,9 +59,7 @@ export default async function migration() {
console.log(`Migrated CORS headers to allowed_headers`);
} catch (e) {
console.log(
`Unable to migrate config file. Error: ${e}`
);
console.log(`Unable to migrate config file. Error: ${e}`);
}
console.log(`${version} migration complete`);

View File

@@ -58,7 +58,9 @@ export default async function migration() {
console.log(`Set trust_proxy to 1 in config file`);
} catch (e) {
console.log(`Unable to migrate config file. Please do it manually. Error: ${e}`);
console.log(
`Unable to migrate config file. Please do it manually. Error: ${e}`
);
}
console.log(`${version} migration complete`);

View File

@@ -11,26 +11,28 @@ export default async function migration() {
const db = new Database(location);
const resourceSiteMap = new Map<number, number>();
let firstSiteId: number = 1;
let firstSiteId: number = 1;
try {
// Get the first siteId to use as default
const firstSite = db.prepare("SELECT siteId FROM sites LIMIT 1").get() as { siteId: number } | undefined;
if (firstSite) {
firstSiteId = firstSite.siteId;
}
try {
// Get the first siteId to use as default
const firstSite = db
.prepare("SELECT siteId FROM sites LIMIT 1")
.get() as { siteId: number } | undefined;
if (firstSite) {
firstSiteId = firstSite.siteId;
}
const resources = db
.prepare(
"SELECT resourceId, siteId FROM resources WHERE siteId IS NOT NULL"
)
.all() as Array<{ resourceId: number; siteId: number }>;
for (const resource of resources) {
resourceSiteMap.set(resource.resourceId, resource.siteId);
}
} catch (e) {
console.log("Error getting resources:", e);
}
const resources = db
.prepare(
"SELECT resourceId, siteId FROM resources WHERE siteId IS NOT NULL"
)
.all() as Array<{ resourceId: number; siteId: number }>;
for (const resource of resources) {
resourceSiteMap.set(resource.resourceId, resource.siteId);
}
} catch (e) {
console.log("Error getting resources:", e);
}
try {
db.pragma("foreign_keys = OFF");