diff --git a/messages/en-US.json b/messages/en-US.json index 36d768d92..d3b3079ea 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -2580,6 +2580,7 @@ "billingModifyLicenses": "Modify License Subscription", "domainNotFound": "Domain Not Found", "domainNotFoundDescription": "This resource is disabled because the domain no longer exists our system. Please set a new domain for this resource.", + "rdirectDomainNotFoundDescription": "This redirect is disabled because the domain no longer exists our system. Please set a new domain for this redirect or its attached resource domain.", "failed": "Failed", "createNewOrgDescription": "Create a new organization", "organization": "Organization", diff --git a/server/db/queries/verifySessionQueries.ts b/server/db/queries/verifySessionQueries.ts index 101e43722..cf04d4b3f 100644 --- a/server/db/queries/verifySessionQueries.ts +++ b/server/db/queries/verifySessionQueries.ts @@ -40,7 +40,7 @@ import { domains } from "@server/db"; import { alias } from "@server/db"; -import { and, desc, eq, inArray, isNull, or, sql } from "drizzle-orm"; +import { and, desc, eq, inArray, isNull, not, or, sql } from "drizzle-orm"; import logger from "@server/logger"; export type ResourceWithAuth = { @@ -116,7 +116,13 @@ export async function getRedirectsByHost( eq(redirects.enabled, true), // Traefik drops resource-attached redirects along with a // disabled resource; do the same here. - or(isNull(redirects.resourceId), eq(resources.enabled, true)), + or( + isNull(redirects.resourceId), + and( + eq(resources.enabled, true), + not(isNull(resources.domainId)) + ) + ), inArray(redirectHost, candidates) ) ) diff --git a/server/lib/traefik/getTraefikConfig.ts b/server/lib/traefik/getTraefikConfig.ts index 93127346d..0e8dcae85 100644 --- a/server/lib/traefik/getTraefikConfig.ts +++ b/server/lib/traefik/getTraefikConfig.ts @@ -20,6 +20,7 @@ import { inArray, isNotNull, isNull, + not, or, sql } from "drizzle-orm"; @@ -367,7 +368,13 @@ export async function getTraefikConfig( .where( and( eq(redirects.enabled, true), - or(isNull(redirects.resourceId), eq(resources.enabled, true)) + or( + isNull(redirects.resourceId), + and( + eq(resources.enabled, true), + not(isNull(resources.domainId)) + ) + ) ) ) .orderBy(desc(redirects.priority), redirects.redirectId); // stable ordering diff --git a/server/private/lib/traefik/getTraefikConfig.ts b/server/private/lib/traefik/getTraefikConfig.ts index 18996b761..fc9160666 100644 --- a/server/private/lib/traefik/getTraefikConfig.ts +++ b/server/private/lib/traefik/getTraefikConfig.ts @@ -11,6 +11,10 @@ * This file is not licensed under the AGPLv3. */ +import regionalCache from "#private/lib/cache"; +import privateConfig from "#private/lib/config"; +import license from "#private/license/license"; +import { build } from "@server/build"; import { certificates, db, @@ -19,77 +23,70 @@ import { exitNodes, loginPage, redirects, - SiteResource, - targetHealthCheck -} from "@server/db"; -import { - and, - eq, - inArray, - or, - isNull, - ne, - isNotNull, - desc, - sql -} from "drizzle-orm"; -import logger from "@server/logger"; -import config from "@server/lib/config"; -import { - orgs, resources, - sites, siteNetworks, + SiteResource, siteResources, + sites, + targetHealthCheck, targets } from "@server/db"; -import { - sanitize, - encodePath, - validatePathRewriteConfig -} from "@server/lib/traefik/utils"; -import privateConfig from "#private/lib/config"; -import { applyPathRewriteMiddleware } from "@server/lib/traefik/middleware"; import { CertificateResult, getValidCertificatesForDomains } from "@server/lib/certificates"; -import { build } from "@server/build"; -import license from "#private/license/license"; -import regionalCache from "#private/lib/cache"; -import { ResourceWithTargets } from "@server/lib/traefik/types"; -import { buildWildcardTls } from "@server/lib/traefik/certResolver"; +import config from "@server/lib/config"; import { - buildHostRule, - appendPathMatch, - computeRoutePriority -} from "@server/lib/traefik/rule"; + AI_GATEWAY_CLIENT_IP_MIDDLEWARE_NAME, + AI_GATEWAY_TRUST_MIDDLEWARE_RESOURCE, + AI_GATEWAY_TRUST_MIDDLEWARE_SITE_RESOURCE, + buildAiGatewayClientIpMiddleware, + buildAiGatewayHostHeaderMiddleware, + buildAiGatewayRouterAndService, + buildAiGatewayTrustMiddlewares, + getAiGatewayHost +} from "@server/lib/traefik/aiGatewayMiddlewares"; +import { + buildBrowserGatewayConfig, + buildBrowserGatewayResourcesMap +} from "@server/lib/traefik/browserGateway"; +import { buildWildcardTls } from "@server/lib/traefik/certResolver"; +import { buildCustomHeadersMiddleware } from "@server/lib/traefik/headersMiddleware"; import { buildHttpLoadBalancerServers, buildStickySessionCookie, - buildTcpUdpLoadBalancerServers, - buildStickySessionIp + buildStickySessionIp, + buildTcpUdpLoadBalancerServers } from "@server/lib/traefik/loadBalancer"; -import { buildCustomHeadersMiddleware } from "@server/lib/traefik/headersMiddleware"; -import { - AI_GATEWAY_TRUST_MIDDLEWARE_RESOURCE, - AI_GATEWAY_TRUST_MIDDLEWARE_SITE_RESOURCE, - AI_GATEWAY_CLIENT_IP_MIDDLEWARE_NAME, - getAiGatewayHost, - buildAiGatewayTrustMiddlewares, - buildAiGatewayClientIpMiddleware, - buildAiGatewayHostHeaderMiddleware, - buildAiGatewayRouterAndService -} from "@server/lib/traefik/aiGatewayMiddlewares"; -import { - buildBrowserGatewayResourcesMap, - buildBrowserGatewayConfig -} from "@server/lib/traefik/browserGateway"; -import { buildSiteResourceAliasCertPlaceholders } from "@server/lib/traefik/siteResourceAlias"; +import { applyPathRewriteMiddleware } from "@server/lib/traefik/middleware"; import { buildRedirectConfig, RedirectRouteRow } from "@server/lib/traefik/redirect"; +import { + appendPathMatch, + buildHostRule, + computeRoutePriority +} from "@server/lib/traefik/rule"; +import { buildSiteResourceAliasCertPlaceholders } from "@server/lib/traefik/siteResourceAlias"; +import { ResourceWithTargets } from "@server/lib/traefik/types"; +import { + encodePath, + sanitize, + validatePathRewriteConfig +} from "@server/lib/traefik/utils"; +import logger from "@server/logger"; +import { + and, + desc, + eq, + inArray, + isNotNull, + isNull, + not, + or, + sql +} from "drizzle-orm"; const redirectHttpsMiddlewareName = "redirect-to-https"; const redirectToRootMiddlewareName = "redirect-to-root"; @@ -445,7 +442,13 @@ export async function getTraefikConfig( .where( and( eq(redirects.enabled, true), - or(isNull(redirects.resourceId), eq(resources.enabled, true)) + or( + isNull(redirects.resourceId), + and( + eq(resources.enabled, true), + not(isNull(resources.domainId)) + ) + ) ) ) .orderBy(desc(redirects.priority), redirects.redirectId); // stable ordering @@ -563,11 +566,6 @@ export async function getTraefikConfig( } }; - console.dir( - { resourcesMap, resourcesWithTargetsAndSites }, - { depth: null } - ); - // get the key and the resource for (const [, resource] of resourcesMap.entries()) { const targets = resource.targets;