Properly paywall the new resource types

This commit is contained in:
Owen
2026-06-02 18:06:42 -07:00
parent 128db20755
commit f2f56dc6c2
17 changed files with 312 additions and 115 deletions

View File

@@ -31,7 +31,7 @@ import {
} from "@server/lib/domainUtils";
import { isSubscribed } from "#dynamic/lib/isSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
import { TierFeature, tierMatrix } from "@server/lib/billing/tierMatrix";
import {
getUniqueResourceName,
getUniqueResourcePolicyName
@@ -342,6 +342,21 @@ async function createHttpResource(
}
}
if (
["ssh", "rdp", "vnc"].includes(mode!) &&
!isLicensedOrSubscribed(
orgId!,
tierMatrix[TierFeature.AdvancedPublicResources]
)
) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"Your current subscription does not support browser gateway resources. Please upgrade to access this feature."
)
);
}
// Validate domain and construct full domain
const domainResult = await validateAndConstructDomain(
domainId,

View File

@@ -123,23 +123,40 @@ export async function createRole(
);
}
const isLicensedDeviceApprovals = await isLicensedOrSubscribed(orgId, tierMatrix.deviceApprovals);
const isLicensedDeviceApprovals = await isLicensedOrSubscribed(
orgId,
tierMatrix.deviceApprovals
);
if (!isLicensedDeviceApprovals) {
roleData.requireDeviceApproval = undefined;
}
const isLicensedSshPam = await isLicensedOrSubscribed(orgId, tierMatrix.sshPam);
const isLicensedSshPam = await isLicensedOrSubscribed(
orgId,
tierMatrix.advancedPrivateResources
);
const roleInsertValues: Record<string, unknown> = {
name: roleData.name,
orgId
};
if (roleData.description !== undefined) roleInsertValues.description = roleData.description;
if (roleData.requireDeviceApproval !== undefined) roleInsertValues.requireDeviceApproval = roleData.requireDeviceApproval;
if (roleData.description !== undefined)
roleInsertValues.description = roleData.description;
if (roleData.requireDeviceApproval !== undefined)
roleInsertValues.requireDeviceApproval =
roleData.requireDeviceApproval;
if (isLicensedSshPam) {
if (roleData.sshSudoMode !== undefined) roleInsertValues.sshSudoMode = roleData.sshSudoMode;
if (roleData.sshSudoCommands !== undefined) roleInsertValues.sshSudoCommands = JSON.stringify(roleData.sshSudoCommands);
if (roleData.sshCreateHomeDir !== undefined) roleInsertValues.sshCreateHomeDir = roleData.sshCreateHomeDir;
if (roleData.sshUnixGroups !== undefined) roleInsertValues.sshUnixGroups = JSON.stringify(roleData.sshUnixGroups);
if (roleData.sshSudoMode !== undefined)
roleInsertValues.sshSudoMode = roleData.sshSudoMode;
if (roleData.sshSudoCommands !== undefined)
roleInsertValues.sshSudoCommands = JSON.stringify(
roleData.sshSudoCommands
);
if (roleData.sshCreateHomeDir !== undefined)
roleInsertValues.sshCreateHomeDir = roleData.sshCreateHomeDir;
if (roleData.sshUnixGroups !== undefined)
roleInsertValues.sshUnixGroups = JSON.stringify(
roleData.sshUnixGroups
);
}
await db.transaction(async (trx) => {

View File

@@ -134,12 +134,18 @@ export async function updateRole(
);
}
const isLicensedDeviceApprovals = await isLicensedOrSubscribed(orgId, tierMatrix.deviceApprovals);
const isLicensedDeviceApprovals = await isLicensedOrSubscribed(
orgId,
tierMatrix.deviceApprovals
);
if (!isLicensedDeviceApprovals) {
updateData.requireDeviceApproval = undefined;
}
const isLicensedSshPam = await isLicensedOrSubscribed(orgId, tierMatrix.sshPam);
const isLicensedSshPam = await isLicensedOrSubscribed(
orgId,
tierMatrix.advancedPrivateResources
);
if (!isLicensedSshPam) {
delete updateData.sshSudoMode;
delete updateData.sshSudoCommands;
@@ -147,10 +153,14 @@ export async function updateRole(
delete updateData.sshUnixGroups;
} else {
if (Array.isArray(updateData.sshSudoCommands)) {
updateData.sshSudoCommands = JSON.stringify(updateData.sshSudoCommands);
updateData.sshSudoCommands = JSON.stringify(
updateData.sshSudoCommands
);
}
if (Array.isArray(updateData.sshUnixGroups)) {
updateData.sshUnixGroups = JSON.stringify(updateData.sshUnixGroups);
updateData.sshUnixGroups = JSON.stringify(
updateData.sshUnixGroups
);
}
}

View File

@@ -293,7 +293,7 @@ export async function createSiteResource(
if (mode == "http") {
const hasHttpFeature = await isLicensedOrSubscribed(
orgId,
tierMatrix[TierFeature.HTTPPrivateResources]
tierMatrix[TierFeature.AdvancedPrivateResources]
);
if (!hasHttpFeature) {
return next(
@@ -425,9 +425,18 @@ export async function createSiteResource(
const isLicensedSshPam = await isLicensedOrSubscribed(
orgId,
tierMatrix.sshPam
tierMatrix.advancedPrivateResources
);
if (mode == "ssh" && !isLicensedSshPam) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"SSH private resources are not included in your current plan. Please upgrade."
)
);
}
let updatedNiceId = niceId;
if (!niceId) {
updatedNiceId = await getUniqueSiteResourceName(orgId);

View File

@@ -314,7 +314,7 @@ export async function updateSiteResource(
if (mode == "http") {
const hasHttpFeature = await isLicensedOrSubscribed(
existingSiteResource.orgId,
tierMatrix[TierFeature.HTTPPrivateResources]
tierMatrix[TierFeature.AdvancedPrivateResources]
);
if (!hasHttpFeature) {
return next(
@@ -328,7 +328,7 @@ export async function updateSiteResource(
const isLicensedSshPam = await isLicensedOrSubscribed(
existingSiteResource.orgId,
tierMatrix.sshPam
tierMatrix.advancedPrivateResources
);
const [org] = await db