misc: added license checks

This commit is contained in:
Sheen Capadngan
2025-01-08 20:31:04 +08:00
parent 616b013b12
commit 2819c8519e
5 changed files with 40 additions and 4 deletions
@@ -48,6 +48,7 @@ export type TFeatureSet = {
samlSSO: false; samlSSO: false;
hsm: false; hsm: false;
oidcSSO: false; oidcSSO: false;
secretAccessInsights: false;
scim: false; scim: false;
ldap: false; ldap: false;
groups: false; groups: false;
+2 -1
View File
@@ -1028,7 +1028,8 @@ export const registerRoutes = async (
secretApprovalRequestDAL, secretApprovalRequestDAL,
secretApprovalRequestSecretDAL, secretApprovalRequestSecretDAL,
secretV2BridgeService, secretV2BridgeService,
secretApprovalRequestService secretApprovalRequestService,
licenseService
}); });
const secretSharingService = secretSharingServiceFactory({ const secretSharingService = secretSharingServiceFactory({
+11 -1
View File
@@ -11,6 +11,7 @@ import {
SecretsSchema, SecretsSchema,
SecretType SecretType
} from "@app/db/schemas"; } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service"; import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
@@ -114,6 +115,7 @@ type TSecretServiceFactoryDep = {
TSecretApprovalRequestSecretDALFactory, TSecretApprovalRequestSecretDALFactory,
"insertMany" | "insertApprovalSecretTags" "insertMany" | "insertApprovalSecretTags"
>; >;
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
}; };
export type TSecretServiceFactory = ReturnType<typeof secretServiceFactory>; export type TSecretServiceFactory = ReturnType<typeof secretServiceFactory>;
@@ -135,7 +137,8 @@ export const secretServiceFactory = ({
secretApprovalRequestDAL, secretApprovalRequestDAL,
secretApprovalRequestSecretDAL, secretApprovalRequestSecretDAL,
secretV2BridgeService, secretV2BridgeService,
secretApprovalRequestService secretApprovalRequestService,
licenseService
}: TSecretServiceFactoryDep) => { }: TSecretServiceFactoryDep) => {
const getSecretReference = async (projectId: string) => { const getSecretReference = async (projectId: string) => {
// if bot key missing means e2e still exist // if bot key missing means e2e still exist
@@ -1150,6 +1153,13 @@ export const secretServiceFactory = ({
const getSecretAccessList = async (dto: TGetSecretAccessListDTO) => { const getSecretAccessList = async (dto: TGetSecretAccessListDTO) => {
const { environment, secretPath, secretName, projectId } = dto; const { environment, secretPath, secretName, projectId } = dto;
const plan = await licenseService.getPlan(dto.actorOrgId);
if (!plan.secretAccessInsights) {
throw new BadRequestError({
message: "Failed to fetch secret access list due to plan restriction. Upgrade your plan."
});
}
const secret = await secretV2BridgeService.getSecretByName({ const secret = await secretV2BridgeService.getSecretByName({
actor: dto.actor, actor: dto.actor,
actorId: dto.actorId, actorId: dto.actorId,
@@ -23,6 +23,7 @@ export type SubscriptionPlan = {
workspacesUsed: number; workspacesUsed: number;
environmentLimit: number; environmentLimit: number;
samlSSO: boolean; samlSSO: boolean;
secretAccessInsights: boolean;
hsm: boolean; hsm: boolean;
oidcSSO: boolean; oidcSSO: boolean;
scim: boolean; scim: boolean;
@@ -15,6 +15,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { Link } from "@tanstack/react-router"; import { Link } from "@tanstack/react-router";
import { format } from "date-fns"; import { format } from "date-fns";
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
import { createNotification } from "@app/components/notifications"; import { createNotification } from "@app/components/notifications";
import { ProjectPermissionCan } from "@app/components/permissions"; import { ProjectPermissionCan } from "@app/components/permissions";
import { import {
@@ -41,7 +42,7 @@ import {
useProjectPermission, useProjectPermission,
useWorkspace useWorkspace
} from "@app/context"; } from "@app/context";
import { useToggle } from "@app/hooks"; import { usePopUp, useToggle } from "@app/hooks";
import { useGetSecretVersion } from "@app/hooks/api"; import { useGetSecretVersion } from "@app/hooks/api";
import { useGetSecretAccessList } from "@app/hooks/api/secrets/queries"; import { useGetSecretAccessList } from "@app/hooks/api/secrets/queries";
import { SecretV3RawSanitized, WsTag } from "@app/hooks/api/types"; import { SecretV3RawSanitized, WsTag } from "@app/hooks/api/types";
@@ -93,6 +94,10 @@ export const SecretDetailSidebar = ({
values: secret values: secret
}); });
const { handlePopUpToggle, popUp, handlePopUpOpen } = usePopUp([
"secretAccessUpgradePlan"
] as const);
const { permission } = useProjectPermission(); const { permission } = useProjectPermission();
const { currentWorkspace } = useWorkspace(); const { currentWorkspace } = useWorkspace();
@@ -200,6 +205,13 @@ export const SecretDetailSidebar = ({
} }
}} }}
/> />
<UpgradePlanModal
isOpen={popUp.secretAccessUpgradePlan.isOpen}
onOpenChange={(isUpgradeModalOpen) =>
handlePopUpToggle("secretAccessUpgradePlan", isUpgradeModalOpen)
}
text="Secret access analysis is only available on Infisical's Pro plan and above."
/>
<Drawer <Drawer
onOpenChange={(state) => { onOpenChange={(state) => {
if (isOpen && isDirty) { if (isOpen && isDirty) {
@@ -500,8 +512,19 @@ export const SecretDetailSidebar = ({
</div> </div>
<div className="dark mb-4 flex-grow text-sm text-bunker-300"> <div className="dark mb-4 flex-grow text-sm text-bunker-300">
<div className="mb-2">Access List</div> <div className="mb-2">Access List</div>
{isPending && (
<Button className="w-full px-2 py-1" variant="outline_bg" isDisabled>
Analyze Access
</Button>
)}
{!isPending && secretAccessList === undefined && ( {!isPending && secretAccessList === undefined && (
<Button className="w-full px-2 py-1" variant="outline_bg"> <Button
className="w-full px-2 py-1"
variant="outline_bg"
onClick={() => {
handlePopUpOpen("secretAccessUpgradePlan");
}}
>
Analyze Access Analyze Access
</Button> </Button>
)} )}