mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-17 09:49:55 +02:00
Make sure things are paywalled in the blueprints
This commit is contained in:
@@ -23,6 +23,8 @@ import logger from "@server/logger";
|
|||||||
import { defaultRoleAllowedActions } from "@server/routers/role/createRole";
|
import { defaultRoleAllowedActions } from "@server/routers/role/createRole";
|
||||||
import { getNextAvailableAliasAddress } from "../ip";
|
import { getNextAvailableAliasAddress } from "../ip";
|
||||||
import { createCertificate } from "#dynamic/routers/certificates/createCertificate";
|
import { createCertificate } from "#dynamic/routers/certificates/createCertificate";
|
||||||
|
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
||||||
|
import { tierMatrix } from "../billing/tierMatrix";
|
||||||
|
|
||||||
async function getDomainForSiteResource(
|
async function getDomainForSiteResource(
|
||||||
siteResourceId: number | undefined,
|
siteResourceId: number | undefined,
|
||||||
@@ -114,6 +116,30 @@ export async function updateClientResources(
|
|||||||
for (const [resourceNiceId, resourceData] of Object.entries(
|
for (const [resourceNiceId, resourceData] of Object.entries(
|
||||||
config["client-resources"]
|
config["client-resources"]
|
||||||
)) {
|
)) {
|
||||||
|
if (resourceData.mode === "http") {
|
||||||
|
const hasHttpFeature = await isLicensedOrSubscribed(
|
||||||
|
orgId,
|
||||||
|
tierMatrix.advancedPrivateResources
|
||||||
|
);
|
||||||
|
if (!hasHttpFeature) {
|
||||||
|
throw new Error(
|
||||||
|
"HTTP private resources are not included in your current plan. Please upgrade."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceData.mode === "ssh") {
|
||||||
|
const hasSshFeature = await isLicensedOrSubscribed(
|
||||||
|
orgId,
|
||||||
|
tierMatrix.advancedPrivateResources
|
||||||
|
);
|
||||||
|
if (!hasSshFeature) {
|
||||||
|
throw new Error(
|
||||||
|
"SSH private resources are not included in your current plan. Please upgrade."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const [existingResource] = await trx
|
const [existingResource] = await trx
|
||||||
.select()
|
.select()
|
||||||
.from(siteResources)
|
.from(siteResources)
|
||||||
@@ -366,7 +392,9 @@ export async function updateClientResources(
|
|||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
existingRoles.push(created);
|
existingRoles.push(created);
|
||||||
logger.info(`Auto-created role "${name}" in org ${orgId} from blueprint`);
|
logger.info(
|
||||||
|
`Auto-created role "${name}" in org ${orgId} from blueprint`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const roleIds = existingRoles.map((role) => role.roleId);
|
const roleIds = existingRoles.map((role) => role.roleId);
|
||||||
@@ -510,7 +538,9 @@ export async function updateClientResources(
|
|||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
existingRoles.push(created);
|
existingRoles.push(created);
|
||||||
logger.info(`Auto-created role "${name}" in org ${orgId} from blueprint`);
|
logger.info(
|
||||||
|
`Auto-created role "${name}" in org ${orgId} from blueprint`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const roleIds = existingRoles.map((role) => role.roleId);
|
const roleIds = existingRoles.map((role) => role.roleId);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
|||||||
import { fireHealthCheckUnknownAlert } from "@server/lib/alerts";
|
import { fireHealthCheckUnknownAlert } from "@server/lib/alerts";
|
||||||
import { tierMatrix } from "../billing/tierMatrix";
|
import { tierMatrix } from "../billing/tierMatrix";
|
||||||
import { defaultRoleAllowedActions } from "@server/routers/role/createRole";
|
import { defaultRoleAllowedActions } from "@server/routers/role/createRole";
|
||||||
|
import { build } from "@server/build";
|
||||||
|
|
||||||
export type ProxyResourcesResults = {
|
export type ProxyResourcesResults = {
|
||||||
proxyResource: Resource;
|
proxyResource: Resource;
|
||||||
@@ -222,17 +223,59 @@ export async function updateProxyResources(
|
|||||||
headers = JSON.stringify(resourceData.headers);
|
headers = JSON.stringify(resourceData.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (["ssh", "rdp", "vnc"].includes(resourceData.mode || "")) {
|
||||||
|
const isLicensed = await isLicensedOrSubscribed(
|
||||||
|
orgId,
|
||||||
|
tierMatrix.advancedPublicResources
|
||||||
|
);
|
||||||
|
if (!isLicensed) {
|
||||||
|
throw new Error(
|
||||||
|
"Your current subscription does not support browser gateway resources. Please upgrade to access this feature."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceData.policy) {
|
||||||
|
const isLicensed = await isLicensedOrSubscribed(
|
||||||
|
orgId,
|
||||||
|
tierMatrix.resourcePolicies
|
||||||
|
);
|
||||||
|
if (!isLicensed) {
|
||||||
|
throw new Error(
|
||||||
|
"Your current subscription does not support shared resource policies. Please upgrade to access this feature."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (existingResource) {
|
if (existingResource) {
|
||||||
let domain;
|
let domain;
|
||||||
if (
|
if (
|
||||||
["http", "ssh", "rdp", "vnc"].includes(resourceData.mode || "")
|
["http", "ssh", "rdp", "vnc"].includes(resourceData.mode || "")
|
||||||
) {
|
) {
|
||||||
|
if (resourceData["full-domain"]?.startsWith("*.")) {
|
||||||
|
const isLicensed = await isLicensedOrSubscribed(
|
||||||
|
orgId,
|
||||||
|
tierMatrix.wildcardSubdomain
|
||||||
|
);
|
||||||
|
if (!isLicensed) {
|
||||||
|
throw new Error(
|
||||||
|
"Wildcard subdomains are not supported on your current plan. Please upgrade to access this feature."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
domain = await getDomain(
|
domain = await getDomain(
|
||||||
existingResource.resourceId,
|
existingResource.resourceId,
|
||||||
resourceData["full-domain"]!,
|
resourceData["full-domain"]!,
|
||||||
orgId,
|
orgId,
|
||||||
trx
|
trx
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await enforceDomainNamespacePaywall(
|
||||||
|
orgId,
|
||||||
|
domain.domainId,
|
||||||
|
trx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the only key in the resource is targets, if so, skip the update
|
// check if the only key in the resource is targets, if so, skip the update
|
||||||
@@ -906,12 +949,30 @@ export async function updateProxyResources(
|
|||||||
if (
|
if (
|
||||||
["http", "ssh", "rdp", "vnc"].includes(resourceData.mode || "")
|
["http", "ssh", "rdp", "vnc"].includes(resourceData.mode || "")
|
||||||
) {
|
) {
|
||||||
|
if (resourceData["full-domain"]?.startsWith("*.")) {
|
||||||
|
const isLicensed = await isLicensedOrSubscribed(
|
||||||
|
orgId,
|
||||||
|
tierMatrix.wildcardSubdomain
|
||||||
|
);
|
||||||
|
if (!isLicensed) {
|
||||||
|
throw new Error(
|
||||||
|
"Wildcard subdomains are not supported on your current plan. Please upgrade to access this feature."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
domain = await getDomain(
|
domain = await getDomain(
|
||||||
undefined,
|
undefined,
|
||||||
resourceData["full-domain"]!,
|
resourceData["full-domain"]!,
|
||||||
orgId,
|
orgId,
|
||||||
trx
|
trx
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await enforceDomainNamespacePaywall(
|
||||||
|
orgId,
|
||||||
|
domain.domainId,
|
||||||
|
trx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isLicensed = await isLicensedOrSubscribed(
|
const isLicensed = await isLicensedOrSubscribed(
|
||||||
@@ -1866,6 +1927,37 @@ function checkIfTargetChanged(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function enforceDomainNamespacePaywall(
|
||||||
|
orgId: string,
|
||||||
|
domainId: string,
|
||||||
|
trx: Transaction
|
||||||
|
) {
|
||||||
|
if (build !== "saas") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasDomainNamespaceAccess = await isLicensedOrSubscribed(
|
||||||
|
orgId,
|
||||||
|
tierMatrix.domainNamespaces
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasDomainNamespaceAccess) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [namespaceDomain] = await trx
|
||||||
|
.select()
|
||||||
|
.from(domainNamespaces)
|
||||||
|
.where(eq(domainNamespaces.domainId, domainId))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (namespaceDomain) {
|
||||||
|
throw new Error(
|
||||||
|
"Your current subscription does not support custom domain namespaces. Please upgrade to access this feature."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function getDomain(
|
export async function getDomain(
|
||||||
resourceId: number | undefined,
|
resourceId: number | undefined,
|
||||||
fullDomain: string,
|
fullDomain: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user