mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 21:28:18 +00:00
Merge pull request #1512 from akhilmhdh/fix/delay-audit-log
feat(server): changed license service to use redis cache keystore
This commit is contained in:
Generated
-20
@@ -47,7 +47,6 @@
|
|||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"mysql2": "^3.9.1",
|
"mysql2": "^3.9.1",
|
||||||
"nanoid": "^5.0.4",
|
"nanoid": "^5.0.4",
|
||||||
"node-cache": "^5.1.2",
|
|
||||||
"nodemailer": "^6.9.9",
|
"nodemailer": "^6.9.9",
|
||||||
"ora": "^7.0.1",
|
"ora": "^7.0.1",
|
||||||
"passport-github": "^1.1.0",
|
"passport-github": "^1.1.0",
|
||||||
@@ -5706,14 +5705,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/clone": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cluster-key-slot": {
|
"node_modules/cluster-key-slot": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
|
||||||
@@ -9258,17 +9249,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
|
||||||
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
|
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
|
||||||
},
|
},
|
||||||
"node_modules/node-cache": {
|
|
||||||
"version": "5.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz",
|
|
||||||
"integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==",
|
|
||||||
"dependencies": {
|
|
||||||
"clone": "2.x"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
|||||||
@@ -108,7 +108,6 @@
|
|||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"mysql2": "^3.9.1",
|
"mysql2": "^3.9.1",
|
||||||
"nanoid": "^5.0.4",
|
"nanoid": "^5.0.4",
|
||||||
"node-cache": "^5.1.2",
|
|
||||||
"nodemailer": "^6.9.9",
|
"nodemailer": "^6.9.9",
|
||||||
"ora": "^7.0.1",
|
"ora": "^7.0.1",
|
||||||
"passport-github": "^1.1.0",
|
"passport-github": "^1.1.0",
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
// TODO(akhilmhdh): With tony find out the api structure and fill it here
|
// TODO(akhilmhdh): With tony find out the api structure and fill it here
|
||||||
|
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import NodeCache from "node-cache";
|
|
||||||
|
|
||||||
|
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
@@ -39,6 +39,7 @@ type TLicenseServiceFactoryDep = {
|
|||||||
orgDAL: Pick<TOrgDALFactory, "findOrgById">;
|
orgDAL: Pick<TOrgDALFactory, "findOrgById">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||||
licenseDAL: TLicenseDALFactory;
|
licenseDAL: TLicenseDALFactory;
|
||||||
|
keyStore: Pick<TKeyStoreFactory, "setItemWithExpiry" | "getItem" | "deleteItem">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TLicenseServiceFactory = ReturnType<typeof licenseServiceFactory>;
|
export type TLicenseServiceFactory = ReturnType<typeof licenseServiceFactory>;
|
||||||
@@ -46,12 +47,18 @@ export type TLicenseServiceFactory = ReturnType<typeof licenseServiceFactory>;
|
|||||||
const LICENSE_SERVER_CLOUD_LOGIN = "/api/auth/v1/license-server-login";
|
const LICENSE_SERVER_CLOUD_LOGIN = "/api/auth/v1/license-server-login";
|
||||||
const LICENSE_SERVER_ON_PREM_LOGIN = "/api/auth/v1/license-login";
|
const LICENSE_SERVER_ON_PREM_LOGIN = "/api/auth/v1/license-login";
|
||||||
|
|
||||||
const FEATURE_CACHE_KEY = (orgId: string, projectId?: string) => `${orgId}-${projectId || ""}`;
|
const LICENSE_SERVER_CLOUD_PLAN_TTL = 60; // 60s
|
||||||
export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }: TLicenseServiceFactoryDep) => {
|
const FEATURE_CACHE_KEY = (orgId: string) => `infisical-cloud-plan-${orgId}`;
|
||||||
|
|
||||||
|
export const licenseServiceFactory = ({
|
||||||
|
orgDAL,
|
||||||
|
permissionService,
|
||||||
|
licenseDAL,
|
||||||
|
keyStore
|
||||||
|
}: TLicenseServiceFactoryDep) => {
|
||||||
let isValidLicense = false;
|
let isValidLicense = false;
|
||||||
let instanceType = InstanceType.OnPrem;
|
let instanceType = InstanceType.OnPrem;
|
||||||
let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures();
|
let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures();
|
||||||
const featureStore = new NodeCache({ stdTTL: 60 });
|
|
||||||
|
|
||||||
const appCfg = getConfig();
|
const appCfg = getConfig();
|
||||||
const licenseServerCloudApi = setupLicenceRequestWithStore(
|
const licenseServerCloudApi = setupLicenceRequestWithStore(
|
||||||
@@ -75,6 +82,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
|
|||||||
isValidLicense = true;
|
isValidLicense = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appCfg.LICENSE_KEY) {
|
if (appCfg.LICENSE_KEY) {
|
||||||
const token = await licenseServerOnPremApi.refreshLicence();
|
const token = await licenseServerOnPremApi.refreshLicence();
|
||||||
if (token) {
|
if (token) {
|
||||||
@@ -100,22 +108,21 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
|
|||||||
logger.info(`getPlan: attempting to fetch plan for [orgId=${orgId}] [projectId=${projectId}]`);
|
logger.info(`getPlan: attempting to fetch plan for [orgId=${orgId}] [projectId=${projectId}]`);
|
||||||
try {
|
try {
|
||||||
if (instanceType === InstanceType.Cloud) {
|
if (instanceType === InstanceType.Cloud) {
|
||||||
const cachedPlan = featureStore.get<TFeatureSet>(FEATURE_CACHE_KEY(orgId, projectId));
|
const cachedPlan = await keyStore.getItem(FEATURE_CACHE_KEY(orgId));
|
||||||
if (cachedPlan) return cachedPlan;
|
if (cachedPlan) return JSON.parse(cachedPlan) as TFeatureSet;
|
||||||
|
|
||||||
const org = await orgDAL.findOrgById(orgId);
|
const org = await orgDAL.findOrgById(orgId);
|
||||||
if (!org) throw new BadRequestError({ message: "Org not found" });
|
if (!org) throw new BadRequestError({ message: "Org not found" });
|
||||||
const {
|
const {
|
||||||
data: { currentPlan }
|
data: { currentPlan }
|
||||||
} = await licenseServerCloudApi.request.get<{ currentPlan: TFeatureSet }>(
|
} = await licenseServerCloudApi.request.get<{ currentPlan: TFeatureSet }>(
|
||||||
`/api/license-server/v1/customers/${org.customerId}/cloud-plan`,
|
`/api/license-server/v1/customers/${org.customerId}/cloud-plan`
|
||||||
{
|
);
|
||||||
params: {
|
await keyStore.setItemWithExpiry(
|
||||||
workspaceId: projectId
|
FEATURE_CACHE_KEY(org.id),
|
||||||
}
|
LICENSE_SERVER_CLOUD_PLAN_TTL,
|
||||||
}
|
JSON.stringify(currentPlan)
|
||||||
);
|
);
|
||||||
featureStore.set(FEATURE_CACHE_KEY(org.id, projectId), currentPlan);
|
|
||||||
return currentPlan;
|
return currentPlan;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -128,10 +135,10 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
|
|||||||
return onPremFeatures;
|
return onPremFeatures;
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshPlan = async (orgId: string, projectId?: string) => {
|
const refreshPlan = async (orgId: string) => {
|
||||||
if (instanceType === InstanceType.Cloud) {
|
if (instanceType === InstanceType.Cloud) {
|
||||||
featureStore.del(FEATURE_CACHE_KEY(orgId, projectId));
|
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
|
||||||
await getPlan(orgId, projectId);
|
await getPlan(orgId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,7 +173,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
|
|||||||
quantity: count
|
quantity: count
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
featureStore.del(orgId);
|
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
|
||||||
} else if (instanceType === InstanceType.EnterpriseOnPrem) {
|
} else if (instanceType === InstanceType.EnterpriseOnPrem) {
|
||||||
const usedSeats = await licenseDAL.countOfOrgMembers(null);
|
const usedSeats = await licenseDAL.countOfOrgMembers(null);
|
||||||
await licenseServerOnPremApi.request.patch(`/api/license/v1/license`, { usedSeats });
|
await licenseServerOnPremApi.request.patch(`/api/license/v1/license`, { usedSeats });
|
||||||
@@ -215,7 +222,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
|
|||||||
`/api/license-server/v1/customers/${organization.customerId}/session/trial`,
|
`/api/license-server/v1/customers/${organization.customerId}/session/trial`,
|
||||||
{ success_url }
|
{ success_url }
|
||||||
);
|
);
|
||||||
featureStore.del(FEATURE_CACHE_KEY(orgId));
|
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
|
||||||
return { url };
|
return { url };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ export const registerRoutes = async (
|
|||||||
projectRoleDAL,
|
projectRoleDAL,
|
||||||
serviceTokenDAL
|
serviceTokenDAL
|
||||||
});
|
});
|
||||||
const licenseService = licenseServiceFactory({ permissionService, orgDAL, licenseDAL });
|
const licenseService = licenseServiceFactory({ permissionService, orgDAL, licenseDAL, keyStore });
|
||||||
const trustedIpService = trustedIpServiceFactory({
|
const trustedIpService = trustedIpServiceFactory({
|
||||||
licenseService,
|
licenseService,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
|
|||||||
Reference in New Issue
Block a user