From 0850a28d20159e101c799fe2f7e15ba88d8407f5 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Feb 2026 19:52:28 -0800 Subject: [PATCH] Add more tier matrix checks --- server/lib/billing/tierMatrix.ts | 4 ++-- server/lib/blueprints/proxyResources.ts | 1 - server/routers/badger/verifySession.ts | 22 +++++++++++++++++----- server/routers/idp/generateOidcUrl.ts | 6 +++++- server/routers/resource/updateResource.ts | 3 ++- server/routers/role/createRole.ts | 3 ++- server/routers/role/updateRole.ts | 3 ++- server/routers/user/createOrgUser.ts | 6 +++++- 8 files changed, 35 insertions(+), 13 deletions(-) diff --git a/server/lib/billing/tierMatrix.ts b/server/lib/billing/tierMatrix.ts index ad1f33c4..bc5cb950 100644 --- a/server/lib/billing/tierMatrix.ts +++ b/server/lib/billing/tierMatrix.ts @@ -2,7 +2,7 @@ import { Tier } from "@server/types/Tiers"; export enum TierFeature { OrgOidc = "orgOidc", - CustomAuthenticationDomain = "customAuthenticationDomain", + LoginPageDomain = "loginPageDomain", DeviceApprovals = "deviceApprovals", LoginPageBranding = "loginPageBranding", LogExport = "logExport", @@ -18,7 +18,7 @@ export enum TierFeature { export const tierMatrix: Record = { [TierFeature.OrgOidc]: ["tier1", "tier2", "tier3", "enterprise"], - [TierFeature.CustomAuthenticationDomain]: [ + [TierFeature.LoginPageDomain]: [ "tier1", "tier2", "tier3", diff --git a/server/lib/blueprints/proxyResources.ts b/server/lib/blueprints/proxyResources.ts index 93ddfdfb..55a7712b 100644 --- a/server/lib/blueprints/proxyResources.ts +++ b/server/lib/blueprints/proxyResources.ts @@ -33,7 +33,6 @@ import { hashPassword } from "@server/auth/password"; import { isValidCIDR, isValidIP, isValidUrlGlobPattern } from "../validators"; import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed"; import { tierMatrix } from "../billing/tierMatrix"; -import { t } from "@faker-js/faker/dist/airline-DF6RqYmq"; export type ProxyResourcesResults = { proxyResource: Resource; diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index fa81b6f9..828960d1 100644 --- a/server/routers/badger/verifySession.ts +++ b/server/routers/badger/verifySession.ts @@ -17,7 +17,7 @@ import { ResourceHeaderAuthExtendedCompatibility, ResourcePassword, ResourcePincode, - ResourceRule, + ResourceRule } from "@server/db"; import config from "@server/lib/config"; import { isIpInCidr, stripPortFromHost } from "@server/lib/ip"; @@ -40,6 +40,7 @@ import { logRequestAudit } from "./logRequestAudit"; import cache from "@server/lib/cache"; import { APP_VERSION } from "@server/lib/consts"; import { isSubscribed } from "#private/lib/isSubscribed"; +import { tierMatrix } from "@server/lib/billing/tierMatrix"; const verifyResourceSessionSchema = z.object({ sessions: z.record(z.string(), z.string()).optional(), @@ -796,7 +797,10 @@ async function notAllowed( ) { let loginPage: LoginPage | null = null; if (orgId) { - const subscribed = await isSubscribed(orgId); + const subscribed = await isSubscribed( + orgId, + tierMatrix.loginPageDomain + ); if (subscribed) { loginPage = await getOrgLoginPage(orgId); } @@ -850,7 +854,7 @@ async function headerAuthChallenged( ) { let loginPage: LoginPage | null = null; if (orgId) { - const subscribed = await isSubscribed(orgId); + const subscribed = await isSubscribed(orgId, tierMatrix.loginPageDomain); if (subscribed) { loginPage = await getOrgLoginPage(orgId); } @@ -1037,7 +1041,11 @@ export function isPathAllowed(pattern: string, path: string): boolean { const MAX_RECURSION_DEPTH = 100; // Recursive function to try different wildcard matches - function matchSegments(patternIndex: number, pathIndex: number, depth: number = 0): boolean { + function matchSegments( + patternIndex: number, + pathIndex: number, + depth: number = 0 + ): boolean { // Check recursion depth limit if (depth > MAX_RECURSION_DEPTH) { logger.warn( @@ -1123,7 +1131,11 @@ export function isPathAllowed(pattern: string, path: string): boolean { logger.debug( `${indent}Segment with wildcard matches: "${currentPatternPart}" matches "${currentPathPart}"` ); - return matchSegments(patternIndex + 1, pathIndex + 1, depth + 1); + return matchSegments( + patternIndex + 1, + pathIndex + 1, + depth + 1 + ); } logger.debug( diff --git a/server/routers/idp/generateOidcUrl.ts b/server/routers/idp/generateOidcUrl.ts index 46f34ef5..646dc2c4 100644 --- a/server/routers/idp/generateOidcUrl.ts +++ b/server/routers/idp/generateOidcUrl.ts @@ -15,6 +15,7 @@ import config from "@server/lib/config"; import { decrypt } from "@server/lib/crypto"; import { build } from "@server/build"; import { isSubscribed } from "#dynamic/lib/isSubscribed"; +import { tierMatrix } from "@server/lib/billing/tierMatrix"; const paramsSchema = z .object({ @@ -112,7 +113,10 @@ export async function generateOidcUrl( } if (build === "saas") { - const subscribed = await isSubscribed(orgId); + const subscribed = await isSubscribed( + orgId, + tierMatrix.orgOidc + ); if (!subscribed) { return next( createHttpError( diff --git a/server/routers/resource/updateResource.ts b/server/routers/resource/updateResource.ts index 62a466d7..79b59a2a 100644 --- a/server/routers/resource/updateResource.ts +++ b/server/routers/resource/updateResource.ts @@ -24,6 +24,7 @@ import { createCertificate } from "#dynamic/routers/certificates/createCertifica import { validateAndConstructDomain } from "@server/lib/domainUtils"; import { build } from "@server/build"; import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed"; +import { tierMatrix } from "@server/lib/billing/tierMatrix"; const updateResourceParamsSchema = z.strictObject({ resourceId: z.string().transform(Number).pipe(z.int().positive()) @@ -341,7 +342,7 @@ async function updateHttpResource( headers = null; } - const isLicensed = await isLicensedOrSubscribed(resource.orgId); + const isLicensed = await isLicensedOrSubscribed(resource.orgId, tierMatrix.maintencePage); if (!isLicensed) { updateData.maintenanceModeEnabled = undefined; updateData.maintenanceModeType = undefined; diff --git a/server/routers/role/createRole.ts b/server/routers/role/createRole.ts index 666eb756..edb8f1bd 100644 --- a/server/routers/role/createRole.ts +++ b/server/routers/role/createRole.ts @@ -12,6 +12,7 @@ import { eq, and } from "drizzle-orm"; import { OpenAPITags, registry } from "@server/openApi"; import { build } from "@server/build"; import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed"; +import { tierMatrix } from "@server/lib/billing/tierMatrix"; const createRoleParamsSchema = z.strictObject({ orgId: z.string() @@ -100,7 +101,7 @@ export async function createRole( ); } - const isLicensed = await isLicensedOrSubscribed(orgId); + const isLicensed = await isLicensedOrSubscribed(orgId, tierMatrix.deviceApprovals); if (!isLicensed) { roleData.requireDeviceApproval = undefined; } diff --git a/server/routers/role/updateRole.ts b/server/routers/role/updateRole.ts index 6724d622..51a33e32 100644 --- a/server/routers/role/updateRole.ts +++ b/server/routers/role/updateRole.ts @@ -10,6 +10,7 @@ import logger from "@server/logger"; import { fromError } from "zod-validation-error"; import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed"; import { OpenAPITags, registry } from "@server/openApi"; +import { tierMatrix } from "@server/lib/billing/tierMatrix"; const updateRoleParamsSchema = z.strictObject({ roleId: z.string().transform(Number).pipe(z.int().positive()) @@ -110,7 +111,7 @@ export async function updateRole( ); } - const isLicensed = await isLicensedOrSubscribed(orgId); + const isLicensed = await isLicensedOrSubscribed(orgId, tierMatrix.deviceApprovals); if (!isLicensed) { updateData.requireDeviceApproval = undefined; } diff --git a/server/routers/user/createOrgUser.ts b/server/routers/user/createOrgUser.ts index cd57943b..cac912f9 100644 --- a/server/routers/user/createOrgUser.ts +++ b/server/routers/user/createOrgUser.ts @@ -15,6 +15,7 @@ import { FeatureId } from "@server/lib/billing"; import { build } from "@server/build"; import { calculateUserClientsForOrgs } from "@server/lib/calculateUserClientsForOrgs"; import { isSubscribed } from "#dynamic/lib/isSubscribed"; +import { tierMatrix } from "@server/lib/billing/tierMatrix"; const paramsSchema = z.strictObject({ orgId: z.string().nonempty() @@ -127,7 +128,10 @@ export async function createOrgUser( ); } else if (type === "oidc") { if (build === "saas") { - const subscribed = await isSubscribed(orgId); + const subscribed = await isSubscribed( + orgId, + tierMatrix.orgOidc + ); if (subscribed) { return next( createHttpError(