clean up paid features check

This commit is contained in:
miloschwartz
2026-01-22 11:16:16 -08:00
committed by Owen Schwartz
parent 9a5bcb9099
commit 92331d7a33
10 changed files with 140 additions and 86 deletions

View File

@@ -4,13 +4,13 @@
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "vscode.json-language-features"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"

View File

@@ -31,7 +31,7 @@ import { pickPort } from "@server/routers/target/helpers";
import { resourcePassword } from "@server/db";
import { hashPassword } from "@server/auth/password";
import { isValidCIDR, isValidIP, isValidUrlGlobPattern } from "../validators";
import { isLicensedOrSubscribed } from "../isLicencedOrSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
import { build } from "@server/build";
export type ProxyResourcesResults = {
@@ -213,11 +213,7 @@ export async function updateProxyResources(
// Update existing resource
const isLicensed = await isLicensedOrSubscribed(orgId);
if (build == "enterprise" && !isLicensed) {
logger.warn(
"Server is not licensed! Clearing set maintenance screen values"
);
// null the maintenance mode fields if not licensed
if (!isLicensed) {
resourceData.maintenance = undefined;
}
@@ -653,11 +649,7 @@ export async function updateProxyResources(
}
const isLicensed = await isLicensedOrSubscribed(orgId);
if (build == "enterprise" && !isLicensed) {
logger.warn(
"Server is not licensed! Clearing set maintenance screen values"
);
// null the maintenance mode fields if not licensed
if (!isLicensed) {
resourceData.maintenance = undefined;
}

View File

@@ -14,7 +14,7 @@ import {
} from "@server/db";
import { getUniqueClientName } from "@server/db/names";
import { getNextAvailableClientSubnet } from "@server/lib/ip";
import { isLicensedOrSubscribed } from "@server/lib/isLicencedOrSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
import logger from "@server/logger";
import { sendTerminateClient } from "@server/routers/client/terminate";
import { and, eq, notInArray, type InferInsertModel } from "drizzle-orm";

View File

@@ -1,17 +1,3 @@
import { build } from "@server/build";
import license from "#dynamic/license/license";
import { getOrgTierData } from "#dynamic/lib/billing";
import { TierId } from "@server/lib/billing/tiers";
export async function isLicensedOrSubscribed(orgId: string): Promise<boolean> {
if (build === "enterprise") {
return await license.isUnlocked();
}
if (build === "saas") {
const { tier } = await getOrgTierData(orgId);
return tier === TierId.STANDARD;
}
return true;
return false;
}

View File

@@ -0,0 +1,30 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
import { build } from "@server/build";
import license from "#private/license/license";
import { getOrgTierData } from "#private/lib/billing";
import { TierId } from "@server/lib/billing/tiers";
export async function isLicensedOrSubscribed(orgId: string): Promise<boolean> {
if (build === "enterprise") {
return await license.isUnlocked();
}
if (build === "saas") {
const { tier } = await getOrgTierData(orgId);
return tier === TierId.STANDARD;
}
return false;
}

View File

@@ -12,7 +12,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { getUserDeviceName } from "@server/db/names";
import { build } from "@server/build";
import { isLicensedOrSubscribed } from "@server/lib/isLicencedOrSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
const getClientSchema = z.strictObject({
clientId: z
@@ -78,58 +78,108 @@ function getPlatformPostureData(
// Windows: Hard drive encryption, Firewall, Auto updates, TPM availability, Windows Antivirus status
if (normalizedPlatform === "windows") {
if (fingerprint.diskEncrypted !== null && fingerprint.diskEncrypted !== undefined) {
if (
fingerprint.diskEncrypted !== null &&
fingerprint.diskEncrypted !== undefined
) {
posture.diskEncrypted = fingerprint.diskEncrypted;
}
if (fingerprint.firewallEnabled !== null && fingerprint.firewallEnabled !== undefined) {
if (
fingerprint.firewallEnabled !== null &&
fingerprint.firewallEnabled !== undefined
) {
posture.firewallEnabled = fingerprint.firewallEnabled;
}
if (fingerprint.tpmAvailable !== null && fingerprint.tpmAvailable !== undefined) {
if (
fingerprint.tpmAvailable !== null &&
fingerprint.tpmAvailable !== undefined
) {
posture.tpmAvailable = fingerprint.tpmAvailable;
}
if (fingerprint.windowsAntivirusEnabled !== null && fingerprint.windowsAntivirusEnabled !== undefined) {
posture.windowsAntivirusEnabled = fingerprint.windowsAntivirusEnabled;
if (
fingerprint.windowsAntivirusEnabled !== null &&
fingerprint.windowsAntivirusEnabled !== undefined
) {
posture.windowsAntivirusEnabled =
fingerprint.windowsAntivirusEnabled;
}
}
// macOS: Hard drive encryption, Biometric configuration, Firewall, System Integrity Protection (SIP), Gatekeeper, Firewall stealth mode
else if (normalizedPlatform === "macos") {
if (fingerprint.diskEncrypted !== null && fingerprint.diskEncrypted !== undefined) {
if (
fingerprint.diskEncrypted !== null &&
fingerprint.diskEncrypted !== undefined
) {
posture.diskEncrypted = fingerprint.diskEncrypted;
}
if (fingerprint.biometricsEnabled !== null && fingerprint.biometricsEnabled !== undefined) {
if (
fingerprint.biometricsEnabled !== null &&
fingerprint.biometricsEnabled !== undefined
) {
posture.biometricsEnabled = fingerprint.biometricsEnabled;
}
if (fingerprint.firewallEnabled !== null && fingerprint.firewallEnabled !== undefined) {
if (
fingerprint.firewallEnabled !== null &&
fingerprint.firewallEnabled !== undefined
) {
posture.firewallEnabled = fingerprint.firewallEnabled;
}
if (fingerprint.macosSipEnabled !== null && fingerprint.macosSipEnabled !== undefined) {
if (
fingerprint.macosSipEnabled !== null &&
fingerprint.macosSipEnabled !== undefined
) {
posture.macosSipEnabled = fingerprint.macosSipEnabled;
}
if (fingerprint.macosGatekeeperEnabled !== null && fingerprint.macosGatekeeperEnabled !== undefined) {
if (
fingerprint.macosGatekeeperEnabled !== null &&
fingerprint.macosGatekeeperEnabled !== undefined
) {
posture.macosGatekeeperEnabled = fingerprint.macosGatekeeperEnabled;
}
if (fingerprint.macosFirewallStealthMode !== null && fingerprint.macosFirewallStealthMode !== undefined) {
posture.macosFirewallStealthMode = fingerprint.macosFirewallStealthMode;
if (
fingerprint.macosFirewallStealthMode !== null &&
fingerprint.macosFirewallStealthMode !== undefined
) {
posture.macosFirewallStealthMode =
fingerprint.macosFirewallStealthMode;
}
if (fingerprint.autoUpdatesEnabled !== null && fingerprint.autoUpdatesEnabled !== undefined) {
if (
fingerprint.autoUpdatesEnabled !== null &&
fingerprint.autoUpdatesEnabled !== undefined
) {
posture.autoUpdatesEnabled = fingerprint.autoUpdatesEnabled;
}
}
// Linux: Hard drive encryption, Firewall, AppArmor, SELinux, TPM availability
else if (normalizedPlatform === "linux") {
if (fingerprint.diskEncrypted !== null && fingerprint.diskEncrypted !== undefined) {
if (
fingerprint.diskEncrypted !== null &&
fingerprint.diskEncrypted !== undefined
) {
posture.diskEncrypted = fingerprint.diskEncrypted;
}
if (fingerprint.firewallEnabled !== null && fingerprint.firewallEnabled !== undefined) {
if (
fingerprint.firewallEnabled !== null &&
fingerprint.firewallEnabled !== undefined
) {
posture.firewallEnabled = fingerprint.firewallEnabled;
}
if (fingerprint.linuxAppArmorEnabled !== null && fingerprint.linuxAppArmorEnabled !== undefined) {
if (
fingerprint.linuxAppArmorEnabled !== null &&
fingerprint.linuxAppArmorEnabled !== undefined
) {
posture.linuxAppArmorEnabled = fingerprint.linuxAppArmorEnabled;
}
if (fingerprint.linuxSELinuxEnabled !== null && fingerprint.linuxSELinuxEnabled !== undefined) {
if (
fingerprint.linuxSELinuxEnabled !== null &&
fingerprint.linuxSELinuxEnabled !== undefined
) {
posture.linuxSELinuxEnabled = fingerprint.linuxSELinuxEnabled;
}
if (fingerprint.tpmAvailable !== null && fingerprint.tpmAvailable !== undefined) {
if (
fingerprint.tpmAvailable !== null &&
fingerprint.tpmAvailable !== undefined
) {
posture.tpmAvailable = fingerprint.tpmAvailable;
}
}
@@ -139,7 +189,10 @@ function getPlatformPostureData(
}
// Android: Screen lock, Biometric configuration, Hard drive encryption
else if (normalizedPlatform === "android") {
if (fingerprint.diskEncrypted !== null && fingerprint.diskEncrypted !== undefined) {
if (
fingerprint.diskEncrypted !== null &&
fingerprint.diskEncrypted !== undefined
) {
posture.diskEncrypted = fingerprint.diskEncrypted;
}
}
@@ -253,7 +306,6 @@ export async function getClient(
// Build posture data if available (platform-specific)
// Only return posture data if org is licensed/subscribed
let postureData: PostureData | null = null;
if (build !== "oss") {
const isOrgLicensed = await isLicensedOrSubscribed(
client.clients.orgId
);
@@ -263,7 +315,6 @@ export async function getClient(
client.currentFingerprint
);
}
}
const data: GetClientResponse = {
...client.clients,

View File

@@ -13,7 +13,7 @@ import { build } from "@server/build";
import { getOrgTierData } from "#dynamic/lib/billing";
import { TierId } from "@server/lib/billing/tiers";
import { cache } from "@server/lib/cache";
import { isLicensedOrSubscribed } from "@server/lib/isLicencedOrSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
const updateOrgParamsSchema = z.strictObject({
orgId: z.string()
@@ -89,7 +89,7 @@ export async function updateOrg(
const { orgId } = parsedParams.data;
const isLicensed = await isLicensedOrSubscribed(orgId);
if (build == "enterprise" && !isLicensed) {
if (!isLicensed) {
parsedBody.data.requireTwoFactor = undefined;
parsedBody.data.maxSessionLengthHours = undefined;
parsedBody.data.passwordExpiryDays = undefined;

View File

@@ -23,7 +23,7 @@ import { OpenAPITags } from "@server/openApi";
import { createCertificate } from "#dynamic/routers/certificates/createCertificate";
import { validateAndConstructDomain } from "@server/lib/domainUtils";
import { build } from "@server/build";
import { isLicensedOrSubscribed } from "@server/lib/isLicencedOrSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
const updateResourceParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive())
@@ -342,11 +342,7 @@ async function updateHttpResource(
}
const isLicensed = await isLicensedOrSubscribed(resource.orgId);
if (build == "enterprise" && !isLicensed) {
logger.warn(
"Server is not licensed! Clearing set maintenance screen values"
);
// null the maintenance mode fields if not licensed
if (!isLicensed) {
updateData.maintenanceModeEnabled = undefined;
updateData.maintenanceModeType = undefined;
updateData.maintenanceTitle = undefined;

View File

@@ -11,7 +11,7 @@ import { ActionsEnum } from "@server/auth/actions";
import { eq, and } from "drizzle-orm";
import { OpenAPITags, registry } from "@server/openApi";
import { build } from "@server/build";
import { isLicensedOrSubscribed } from "@server/lib/isLicencedOrSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
const createRoleParamsSchema = z.strictObject({
orgId: z.string()
@@ -101,7 +101,7 @@ export async function createRole(
}
const isLicensed = await isLicensedOrSubscribed(orgId);
if (build === "oss" || !isLicensed) {
if (!isLicensed) {
roleData.requireDeviceApproval = undefined;
}

View File

@@ -8,8 +8,7 @@ import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { build } from "@server/build";
import { isLicensedOrSubscribed } from "@server/lib/isLicencedOrSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
import { OpenAPITags, registry } from "@server/openApi";
const updateRoleParamsSchema = z.strictObject({
@@ -112,7 +111,7 @@ export async function updateRole(
}
const isLicensed = await isLicensedOrSubscribed(orgId);
if (build === "oss" || !isLicensed) {
if (!isLicensed) {
updateData.requireDeviceApproval = undefined;
}