From bd5cc790d6671db9e95905bd4102475232158df0 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 27 Oct 2025 17:52:39 -0700 Subject: [PATCH] Fixing various things --- install/config/config.yml | 1 - server/db/pg/schema/schema.ts | 2 +- server/db/sqlite/schema/schema.ts | 2 +- server/lib/consts.ts | 2 +- server/lib/readConfigFile.ts | 2 +- server/lib/serverIpService.ts | 2 +- server/private/routers/hybrid.ts | 12 +++- server/routers/domain/createOrgDomain.ts | 3 - server/routers/org/updateOrg.ts | 5 +- server/setup/copyInConfig.ts | 85 +++++++++++++++++++----- server/setup/scriptsPg/1.12.0.ts | 6 +- server/setup/scriptsSqlite/1.12.0.ts | 2 +- src/components/DNSRecordsDataTable.tsx | 2 +- src/components/DomainsTable.tsx | 38 +++++++---- 14 files changed, 117 insertions(+), 47 deletions(-) diff --git a/install/config/config.yml b/install/config/config.yml index 4d6aeb51..90d1bf5d 100644 --- a/install/config/config.yml +++ b/install/config/config.yml @@ -14,7 +14,6 @@ app: domains: domain1: base_domain: "{{.BaseDomain}}" - cert_resolver: "letsencrypt" server: secret: "{{.Secret}}" diff --git a/server/db/pg/schema/schema.ts b/server/db/pg/schema/schema.ts index 713ecef3..8d1987f1 100644 --- a/server/db/pg/schema/schema.ts +++ b/server/db/pg/schema/schema.ts @@ -27,7 +27,7 @@ export const domains = pgTable("domains", { export const dnsRecords = pgTable("dnsRecords", { - id: varchar("id").primaryKey(), + id: serial("id").primaryKey(), domainId: varchar("domainId") .notNull() .references(() => domains.domainId, { onDelete: "cascade" }), diff --git a/server/db/sqlite/schema/schema.ts b/server/db/sqlite/schema/schema.ts index 01d50b05..aed12477 100644 --- a/server/db/sqlite/schema/schema.ts +++ b/server/db/sqlite/schema/schema.ts @@ -18,7 +18,7 @@ export const domains = sqliteTable("domains", { }); export const dnsRecords = sqliteTable("dnsRecords", { - id: text("id").primaryKey(), + id: integer("id").primaryKey({ autoIncrement: true }), domainId: text("domainId") .notNull() .references(() => domains.domainId, { onDelete: "cascade" }), diff --git a/server/lib/consts.ts b/server/lib/consts.ts index 8ad98167..25dfdcfe 100644 --- a/server/lib/consts.ts +++ b/server/lib/consts.ts @@ -2,7 +2,7 @@ import path from "path"; import { fileURLToPath } from "url"; // This is a placeholder value replaced by the build process -export const APP_VERSION = "1.11.0"; +export const APP_VERSION = "1.12.0"; export const __FILENAME = fileURLToPath(import.meta.url); export const __DIRNAME = path.dirname(__FILENAME); diff --git a/server/lib/readConfigFile.ts b/server/lib/readConfigFile.ts index 9aee8531..d37a03d8 100644 --- a/server/lib/readConfigFile.ts +++ b/server/lib/readConfigFile.ts @@ -50,7 +50,7 @@ export const configSchema = z .string() .nonempty("base_domain must not be empty") .transform((url) => url.toLowerCase()), - cert_resolver: z.string().optional().default("letsencrypt"), + cert_resolver: z.string().optional(), // null falls back to traefik.cert_resolver prefer_wildcard_cert: z.boolean().optional().default(false) }) ) diff --git a/server/lib/serverIpService.ts b/server/lib/serverIpService.ts index fb25c1c2..eb987e0f 100644 --- a/server/lib/serverIpService.ts +++ b/server/lib/serverIpService.ts @@ -3,9 +3,9 @@ import axios from "axios"; let serverIp: string | null = null; const services = [ + "https://checkip.amazonaws.com", "https://ifconfig.io/ip", "https://api.ipify.org", - "https://checkip.amazonaws.com" ]; export async function fetchServerIp() { diff --git a/server/private/routers/hybrid.ts b/server/private/routers/hybrid.ts index 1fc5d512..2b54ae9d 100644 --- a/server/private/routers/hybrid.ts +++ b/server/private/routers/hybrid.ts @@ -75,6 +75,7 @@ import { validateResourceSessionToken } from "@server/auth/sessions/resource"; import { checkExitNodeOrg, resolveExitNodes } from "#private/lib/exitNodes"; import { maxmindLookup } from "@server/db/maxmind"; import { verifyResourceAccessToken } from "@server/auth/verifyResourceAccessToken"; +import semver from "semver"; // Zod schemas for request validation const getResourceByDomainParamsSchema = z @@ -1070,11 +1071,20 @@ hybridRouter.get( ); } - const rules = await db + let rules = await db .select() .from(resourceRules) .where(eq(resourceRules.resourceId, resourceId)); + // backward compatibility: COUNTRY -> GEOIP + if ((remoteExitNode.version && semver.lt(remoteExitNode.version, "1.1.0")) || !remoteExitNode.version) { + for (const rule of rules) { + if (rule.match == "COUNTRY") { + rule.match = "GEOIP"; + } + } + } + return response<(typeof resourceRules.$inferSelect)[]>(res, { data: rules, success: true, diff --git a/server/routers/domain/createOrgDomain.ts b/server/routers/domain/createOrgDomain.ts index d40a0cb8..4c2451e3 100644 --- a/server/routers/domain/createOrgDomain.ts +++ b/server/routers/domain/createOrgDomain.ts @@ -286,7 +286,6 @@ export async function createOrgDomain( // Save NS records to database for (const nsValue of nsRecords) { recordsToInsert.push({ - id: generateId(15), domainId, recordType: "NS", baseDomain: baseDomain, @@ -309,7 +308,6 @@ export async function createOrgDomain( // Save CNAME records to database for (const cnameRecord of cnameRecords) { recordsToInsert.push({ - id: generateId(15), domainId, recordType: "CNAME", baseDomain: cnameRecord.baseDomain, @@ -332,7 +330,6 @@ export async function createOrgDomain( // Save A records to database for (const aRecord of aRecords) { recordsToInsert.push({ - id: generateId(15), domainId, recordType: "A", baseDomain: aRecord.baseDomain, diff --git a/server/routers/org/updateOrg.ts b/server/routers/org/updateOrg.ts index a2690bcd..a1739371 100644 --- a/server/routers/org/updateOrg.ts +++ b/server/routers/org/updateOrg.ts @@ -98,15 +98,16 @@ export async function updateOrg( parsedBody.data.passwordExpiryDays = undefined; } + const { tier } = await getOrgTierData(orgId); if ( - !isLicensed && + tier != TierId.STANDARD && parsedBody.data.settingsLogRetentionDaysRequest && parsedBody.data.settingsLogRetentionDaysRequest > 30 ) { return next( createHttpError( HttpCode.FORBIDDEN, - "You are not allowed to set log retention days greater than 30 because you are not subscribed to the Standard tier" + "You are not allowed to set log retention days greater than 30 with your current subscription" ) ); } diff --git a/server/setup/copyInConfig.ts b/server/setup/copyInConfig.ts index e003d089..dd829db4 100644 --- a/server/setup/copyInConfig.ts +++ b/server/setup/copyInConfig.ts @@ -1,4 +1,4 @@ -import { db } from "@server/db"; +import { db, dnsRecords } from "@server/db"; import { domains, exitNodes, orgDomains, orgs, resources } from "@server/db"; import config from "@server/lib/config"; import { eq, ne } from "drizzle-orm"; @@ -8,7 +8,10 @@ export async function copyInConfig() { const endpoint = config.getRawConfig().gerbil.base_endpoint; const listenPort = config.getRawConfig().gerbil.start_port; - if (!config.getRawConfig().flags?.disable_config_managed_domains && config.getRawConfig().domains) { + if ( + !config.getRawConfig().flags?.disable_config_managed_domains && + config.getRawConfig().domains + ) { await copyInDomains(); } @@ -39,7 +42,7 @@ async function copyInDomains() { domainId: key, baseDomain: value.base_domain.toLowerCase(), certResolver: value.cert_resolver || null, - preferWildcardCert: value.prefer_wildcard_cert || null, + preferWildcardCert: value.prefer_wildcard_cert || null }) ); @@ -56,31 +59,79 @@ async function copyInDomains() { if (!configDomainKeys.has(existingDomain.domainId)) { await trx .delete(domains) - .where(eq(domains.domainId, existingDomain.domainId)) - .execute(); + .where(eq(domains.domainId, existingDomain.domainId)); + await trx + .delete(dnsRecords) + .where(eq(dnsRecords.domainId, existingDomain.domainId)); } } - for (const { domainId, baseDomain, certResolver, preferWildcardCert } of configDomains) { + for (const { + domainId, + baseDomain, + certResolver, + preferWildcardCert + } of configDomains) { if (existingDomainKeys.has(domainId)) { await trx .update(domains) - .set({ baseDomain, verified: true, type: "wildcard", certResolver, preferWildcardCert }) - .where(eq(domains.domainId, domainId)) - .execute(); - } else { - await trx - .insert(domains) - .values({ - domainId, + .set({ baseDomain, - configManaged: true, - type: "wildcard", verified: true, + type: "wildcard", certResolver, preferWildcardCert }) - .execute(); + .where(eq(domains.domainId, domainId)); + + // delete the dns records and add them again to ensure they are correct + await trx + .delete(dnsRecords) + .where(eq(dnsRecords.domainId, domainId)); + + await trx.insert(dnsRecords).values([ + { + domainId, + recordType: "A", + baseDomain, + value: "Server IP Address", + verified: true + }, + { + domainId, + recordType: "A", + baseDomain, + value: "Server IP Address", + verified: true + } + ]); + } else { + await trx.insert(domains).values({ + domainId, + baseDomain, + configManaged: true, + type: "wildcard", + verified: true, + certResolver, + preferWildcardCert + }); + + await trx.insert(dnsRecords).values([ + { + domainId, + recordType: "A", + baseDomain, + value: "Server IP Address", + verified: true + }, + { + domainId, + recordType: "A", + baseDomain, + value: "Server IP Address", + verified: true + } + ]); } } diff --git a/server/setup/scriptsPg/1.12.0.ts b/server/setup/scriptsPg/1.12.0.ts index 98487cd8..7150a52c 100644 --- a/server/setup/scriptsPg/1.12.0.ts +++ b/server/setup/scriptsPg/1.12.0.ts @@ -44,7 +44,7 @@ export default async function migration() { await db.execute(sql` CREATE TABLE "dnsRecords" ( - "id" varchar PRIMARY KEY NOT NULL, + "id" serial PRIMARY KEY NOT NULL, "domainId" varchar NOT NULL, "recordType" varchar NOT NULL, "baseDomain" varchar, @@ -108,10 +108,10 @@ export default async function migration() { await db.execute(sql`ALTER TABLE "orgs" DROP COLUMN "settings";`); await db.execute(sql`COMMIT`); - console.log(`Updated resource rules match value from GEOIP to COUNTRY`); + console.log("Migrated database"); } catch (e) { await db.execute(sql`ROLLBACK`); - console.log("Unable to update resource rules match value"); + console.log("Unable to migrate database"); console.log(e); throw e; } diff --git a/server/setup/scriptsSqlite/1.12.0.ts b/server/setup/scriptsSqlite/1.12.0.ts index 393abdb6..8aa86724 100644 --- a/server/setup/scriptsSqlite/1.12.0.ts +++ b/server/setup/scriptsSqlite/1.12.0.ts @@ -72,7 +72,7 @@ export default async function migration() { db.prepare( ` CREATE TABLE 'dnsRecords' ( - 'id' text PRIMARY KEY NOT NULL, + 'id' integer PRIMARY KEY AUTOINCREMENT NOT NULL, 'domainId' text NOT NULL, 'recordType' text NOT NULL, 'baseDomain' text, diff --git a/src/components/DNSRecordsDataTable.tsx b/src/components/DNSRecordsDataTable.tsx index 0fe0d276..95d548a4 100644 --- a/src/components/DNSRecordsDataTable.tsx +++ b/src/components/DNSRecordsDataTable.tsx @@ -111,7 +111,7 @@ export function DNSRecordsDataTable({

{t("dnsRecord")}

{t("required")} - + )}
- @@ -282,12 +298,8 @@ export default function DomainsTable({ domains, orgId }: Props) { }} dialog={
-

- {t("domainQuestionRemove")} -

-

- {t("domainMessageRemove")} -

+

{t("domainQuestionRemove")}

+

{t("domainMessageRemove")}

} buttonText={t("domainConfirmDelete")}