merge main

This commit is contained in:
Scott Wilson
2025-10-28 09:59:24 -07:00
165 changed files with 5524 additions and 3409 deletions
@@ -28,7 +28,8 @@ export const OrgGroupsSection = () => {
if (!subscription?.groups) {
handlePopUpOpen("upgradePlan", {
description:
"You can manage users more efficiently with groups if you upgrade your Infisical plan to an Enterprise license."
"You can manage users more efficiently with groups if you upgrade your Infisical plan to an Enterprise license.",
isEnterpriseFeature: true
});
} else {
handlePopUpOpen("group");
@@ -96,6 +97,7 @@ export const OrgGroupsSection = () => {
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
text={(popUp.upgradePlan?.data as { description: string })?.description}
/>
</div>
@@ -292,7 +292,8 @@ export const IdentityAuthMethodModalContent = ({
<UpgradePlanModal
isOpen={popUp?.upgradePlan?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can use IP allowlisting if you switch to Infisical's Pro plan."
text={`You can use ${popUp.upgradePlan.data?.featureName ?? "IP allowlisting"} if you switch to Infisical's ${popUp.upgradePlan.data?.isEnterpriseFeature ? "Enterprise" : "Pro"} plan.`}
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</>
);
@@ -147,7 +147,10 @@ const schema = z
export type FormData = z.infer<typeof schema>;
type Props = {
handlePopUpOpen: (popUpName: keyof UsePopUpState<["upgradePlan"]>) => void;
handlePopUpOpen: (
popUpName: keyof UsePopUpState<["upgradePlan"]>,
data?: { isEnterpriseFeature?: boolean; featureName?: string }
) => void;
handlePopUpToggle: (
popUpName: keyof UsePopUpState<["identityAuthMethod"]>,
state?: boolean
@@ -304,7 +307,10 @@ export const IdentityLdapAuthForm = ({
useEffect(() => {
if (!subscription?.ldap) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true,
featureName: "LDAP authentication"
});
handlePopUpToggle("identityAuthMethod", false);
}
}, [subscription, handlePopUpOpen, handlePopUpToggle]);
@@ -146,7 +146,7 @@ export const IdentitySection = withPermission(
if (!isMoreIdentitiesAllowed && !isEnterprise) {
handlePopUpOpen("upgradePlan", {
description:
"You can add more identities if you upgrade your Infisical plan."
"You can add more identities if you upgrade your Infisical Pro plan."
});
return;
}
@@ -179,7 +179,11 @@ export const IdentitySection = withPermission(
leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => {
if (subscription && !subscription.machineIdentityAuthTemplates) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true,
description:
"You can use Identity Auth Templates if you switch to Infisical's Enterprise plan."
});
return;
}
handlePopUpOpen("createTemplate");
@@ -249,7 +253,8 @@ export const IdentitySection = withPermission(
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can use Identity Auth Templates if you switch to Infisical's Enterprise plan."
text={popUp.upgradePlan.data?.description}
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
);
@@ -76,7 +76,7 @@ export const OrgMembersSection = () => {
if (!isMoreIdentitiesAllowed && !isEnterprise) {
handlePopUpOpen("upgradePlan", {
description: "You can add more members if you upgrade your Infisical plan."
description: "You can add more members if you switch to Infisical's Pro plan."
});
return;
}
@@ -133,7 +133,8 @@ export const OrgMembersTable = ({
if (isCustomRole && subscription && !subscription?.rbac) {
handlePopUpOpen("upgradePlan", {
description: "You can assign custom roles to members if you upgrade your Infisical plan."
description:
"You can assign custom roles to members if you switch to Infisical's Pro plan."
});
return;
}
@@ -105,7 +105,7 @@ export const OrgRoleTable = () => {
if (isCustomRole && subscription && !subscription?.rbac) {
handlePopUpOpen("upgradePlan", {
description:
"You can set the default org role to a custom role if you upgrade your Infisical plan."
"You can set the default org role to a custom role if you switch to Infisical's Pro plan."
});
return;
}
@@ -75,7 +75,9 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
type="button"
onClick={() =>
enterprise && !subscription.enterpriseAppConnections
? handlePopUpOpen("upgradePlan")
? handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
})
: onSelect(option.app)
}
className="group relative flex h-28 cursor-pointer flex-col items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-700 p-4 duration-200 hover:bg-mineshaft-600"
@@ -167,6 +169,7 @@ export const AppConnectionsSelect = ({ onSelect, projectType }: Props) => {
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can use every App Connection if you switch to Infisical's Enterprise plan."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
);
@@ -123,7 +123,7 @@ const LogsSectionComponent = ({
onOpenChange={(isOpen) => {
handlePopUpToggle("upgradePlan", isOpen);
}}
text="You can use audit logs if you switch to a paid Infisical plan."
text="You can use audit logs if you switch to Infisical's Pro plan."
/>
</div>
</div>
@@ -167,7 +167,7 @@ const LogsSectionComponent = ({
onOpenChange={(isOpen) => {
handlePopUpToggle("upgradePlan", isOpen);
}}
text="You can use audit logs if you switch to a paid Infisical plan."
text="You can use audit logs if you switch to Infisical's Pro plan."
/>
</div>
);
@@ -121,6 +121,7 @@ const Page = () => {
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text={(popUp.upgradePlan?.data as { description: string })?.description}
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
<DeleteActionModal
isOpen={popUp.deleteIdentity.isOpen}
@@ -92,7 +92,7 @@ export const ProjectsPage = () => {
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You have exceeded the number of projects allowed on the free plan."
text="You have exceeded the number of projects allowed on the free plan. You can upgrade to Infisical's Pro plan to add more projects."
/>
</div>
);
@@ -29,7 +29,9 @@ export const AuditLogStreamsTab = withPermission(
<Button
onClick={() => {
if (subscription && !subscription?.auditLogStreams) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
return;
}
handlePopUpOpen("auditLogStreamForm");
@@ -56,6 +58,7 @@ export const AuditLogStreamsTab = withPermission(
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can add audit log streams if you switch to Infisical's Enterprise plan."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
);
@@ -70,7 +70,9 @@ export const LogStreamProviderSelect = ({ onSelect }: Props) => {
type="button"
onClick={() => {
if (option.provider === LogProvider.QRadar) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
} else {
onSelect(option.provider);
}
@@ -110,6 +112,7 @@ export const LogStreamProviderSelect = ({ onSelect }: Props) => {
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="This audit log stream provider requires an enterprise license."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
);
@@ -180,7 +180,9 @@ const OrgConfigSection = ({
className="mt-2"
onClick={() => {
if (subscription && !subscription.kmip) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
return;
}
@@ -251,6 +253,7 @@ const OrgConfigSection = ({
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="KMIP requires an enterprise plan."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</>
);
@@ -27,6 +27,7 @@ type Props = {
kmsId?: string;
name?: string;
provider?: string;
isEnterpriseFeature?: boolean;
}
) => void;
subscription: SubscriptionPlan;
@@ -111,7 +112,9 @@ export const ExternalKmsItem = ({ kms, handlePopUpOpen, subscription }: Props) =
onClick={(e) => {
e.stopPropagation();
if (subscription && !subscription?.externalKms) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
return;
}
@@ -74,7 +74,9 @@ export const OrgEncryptionTab = withPermission(
<Button
onClick={() => {
if (subscription && !subscription?.externalKms) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
return;
}
handlePopUpOpen("addExternalKms");
@@ -124,6 +126,7 @@ export const OrgEncryptionTab = withPermission(
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can configure external KMS if you switch to Infisical's Enterprise plan."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
<AddExternalKmsForm
isOpen={popUp.addExternalKms.isOpen}
@@ -0,0 +1,72 @@
import { useState } from "react";
import { createNotification } from "@app/components/notifications";
import { OrgPermissionCan } from "@app/components/permissions";
import { Switch } from "@app/components/v2";
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import { useUpdateOrg } from "@app/hooks/api/organization/queries";
export const OrgProductSettingsTab = () => {
const { currentOrg } = useOrganization();
const { mutateAsync: updateOrg } = useUpdateOrg();
const [isLoading, setIsLoading] = useState(false);
const handleToggle = async (state: boolean) => {
setIsLoading(true);
try {
if (!currentOrg?.id) {
setIsLoading(false);
return;
}
await updateOrg({
orgId: currentOrg.id,
blockDuplicateSecretSyncDestinations: state
});
createNotification({
text: `Successfully ${state ? "enabled" : "disabled"} blocking duplicate secret sync destinations for this organization`,
type: "success"
});
} catch (err) {
console.error(err);
createNotification({
text: "Failed to update blocking duplicate secret sync destinations setting for this organization",
type: "error"
});
} finally {
setIsLoading(false);
}
};
return (
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-6">
<div className="mb-6">
<h2 className="text-xl font-medium text-mineshaft-100">Secrets Management</h2>
</div>
<div className="flex items-center justify-between">
<div>
<h3 className="mb-2 text-lg font-medium text-mineshaft-100">
Unique Secret Sync Destination Policy
</h3>
<p className="text-sm text-mineshaft-400">
When enabled, ensures each destination can only be used by one secret sync
configuration, preventing potential conflicts or overwrites.
</p>
</div>
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Settings}>
{(isAllowed) => (
<Switch
id="blockDuplicateSecretSyncDestinations"
isDisabled={!isAllowed || isLoading}
isChecked={currentOrg?.blockDuplicateSecretSyncDestinations ?? false}
onCheckedChange={(state) => handleToggle(state as boolean)}
/>
)}
</OrgPermissionCan>
</div>
</div>
);
};
@@ -0,0 +1 @@
export { OrgProductSettingsTab } from "./OrgProductSettingsTab";
@@ -111,7 +111,9 @@ export const OrgGithubSyncSection = () => {
onClick={() =>
subscription.githubOrgSync
? handlePopUpOpen("githubOrgSyncConfig")
: handlePopUpOpen("upgradePlan")
: handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
})
}
colorSchema="secondary"
isDisabled={!isAllowed}
@@ -203,6 +205,7 @@ export const OrgGithubSyncSection = () => {
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can use GitHub Organization Plan if you switch to Infisical's Enterprise plan."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
);
@@ -29,7 +29,9 @@ export const OrgScimSection = () => {
if (subscription?.scim) {
handlePopUpOpen("scimToken");
} else {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
}
};
@@ -37,7 +39,9 @@ export const OrgScimSection = () => {
try {
if (!currentOrg?.id) return;
if (!subscription?.scim) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
return;
}
@@ -90,7 +94,9 @@ export const OrgScimSection = () => {
if (subscription?.scim) {
handleEnableSCIMToggle(value);
} else {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
}
}}
isChecked={currentOrg?.scimEnabled ?? false}
@@ -112,6 +118,7 @@ export const OrgScimSection = () => {
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can use SCIM Provisioning if you switch to Infisical's Enterprise plan."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
);
@@ -34,7 +34,9 @@ export const OrgLDAPSection = (): JSX.Element => {
try {
if (!currentOrg?.id) return;
if (!subscription?.ldap) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
return;
}
@@ -78,7 +80,9 @@ export const OrgLDAPSection = (): JSX.Element => {
handlePopUpOpen("addLDAP");
} else {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
}
} catch (err) {
console.error(err);
@@ -87,7 +91,9 @@ export const OrgLDAPSection = (): JSX.Element => {
const openLDAPGroupMapModal = () => {
if (!subscription?.ldap) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
return;
}
@@ -186,6 +192,7 @@ export const OrgLDAPSection = (): JSX.Element => {
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can use LDAP authentication if you switch to Infisical's Enterprise plan."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
);
@@ -27,7 +27,7 @@ export const OrgSSOSection = (): JSX.Element => {
const { mutateAsync } = useUpdateSSOConfig();
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
"upgradePlan",
"upgradeEnterprisePlan",
// "upgradeEnterprisePlan",
"addSSO"
] as const);
@@ -38,7 +38,9 @@ export const OrgSSOSection = (): JSX.Element => {
if (!currentOrg?.id) return;
if (!subscription?.samlSSO) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
description: "You can use SAML SSO if you switch to Infisical's Pro plan."
});
return;
}
@@ -65,7 +67,11 @@ export const OrgSSOSection = (): JSX.Element => {
if (!currentOrg?.id) return;
if (!subscription?.samlSSO || !subscription?.groups) {
handlePopUpOpen("upgradeEnterprisePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true,
description:
"You can use SAML group mapping if you switch to Infisical's Enterprise plan."
});
return;
}
@@ -105,7 +111,9 @@ export const OrgSSOSection = (): JSX.Element => {
handlePopUpOpen("addSSO");
} else {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
description: "You can use SAML SSO if you switch to Infisical's Pro plan."
});
}
} catch (err) {
console.error(err);
@@ -234,12 +242,8 @@ export const OrgSSOSection = (): JSX.Element => {
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can use SAML SSO if you switch to Infisical's Pro plan."
/>
<UpgradePlanModal
isOpen={popUp.upgradeEnterprisePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradeEnterprisePlan", isOpen)}
text="You can use SAML group mapping if you switch to Infisical's Enterprise plan."
text={popUp.upgradePlan.data?.description}
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
);
@@ -93,7 +93,7 @@ export const OrgSsoTab = withPermission(
colorSchema="secondary"
onClick={() => {
if (!subscription?.samlSSO) {
handlePopUpOpen("upgradePlan", { feature: "SAML SSO", plan: "Pro" });
handlePopUpOpen("upgradePlan", { feature: "SAML SSO" });
return;
}
@@ -116,7 +116,7 @@ export const OrgSsoTab = withPermission(
colorSchema="secondary"
onClick={() => {
if (!subscription?.oidcSSO) {
handlePopUpOpen("upgradePlan", { feature: "OIDC SSO", plan: "Pro" });
handlePopUpOpen("upgradePlan", { feature: "OIDC SSO" });
return;
}
@@ -134,7 +134,10 @@ export const OrgSsoTab = withPermission(
colorSchema="secondary"
onClick={() => {
if (!subscription?.ldap) {
handlePopUpOpen("upgradePlan", { feature: "LDAP", plan: "Enterprise" });
handlePopUpOpen("upgradePlan", {
feature: "LDAP",
isEnterpriseFeature: true
});
return;
}
@@ -208,8 +211,13 @@ export const OrgSsoTab = withPermission(
text={`You can use ${
(popUp.upgradePlan.data as { feature: string })?.feature
} if you switch to Infisical's ${
(popUp.upgradePlan.data as { plan: string })?.plan
(popUp.upgradePlan.data as { isEnterpriseFeature: boolean })?.isEnterpriseFeature
? "Enterprise"
: "Pro"
} plan.`}
isEnterpriseFeature={
(popUp.upgradePlan.data as { isEnterpriseFeature: boolean })?.isEnterpriseFeature
}
/>
</>
);
@@ -10,6 +10,7 @@ import { ExternalMigrationsTab } from "../ExternalMigrationsTab";
import { KmipTab } from "../KmipTab/OrgKmipTab";
import { OrgEncryptionTab } from "../OrgEncryptionTab";
import { OrgGeneralTab } from "../OrgGeneralTab";
import { OrgProductSettingsTab } from "../OrgProductSettingsTab";
import { OrgProvisioningTab } from "../OrgProvisioningTab";
import { OrgSecurityTab } from "../OrgSecurityTab";
import { OrgSsoTab } from "../OrgSsoTab";
@@ -63,7 +64,12 @@ export const OrgTabGroup = () => {
key: "project-templates",
component: ProjectTemplatesTab
},
{ name: "KMIP", key: "kmip", component: KmipTab }
{ name: "KMIP", key: "kmip", component: KmipTab },
{
name: "Product Enforcements",
key: "product-enforcements",
component: OrgProductSettingsTab
}
];
const [selectedTab, setSelectedTab] = useState(search.selectedTab || tabs[0].key);
@@ -48,7 +48,9 @@ export const ProjectTemplatesSection = () => {
leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => {
if (!subscription?.projectTemplates) {
handlePopUpOpen("upgradePlan");
handlePopUpOpen("upgradePlan", {
isEnterpriseFeature: true
});
return;
}
@@ -72,6 +74,7 @@ export const ProjectTemplatesSection = () => {
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can create project templates if you switch to Infisical's Enterprise plan."
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
/>
</div>
</div>
@@ -1 +1,2 @@
export { OrgProductSettingsTab } from "./OrgProductSettingsTab";
export { OrgTabGroup } from "./OrgTabGroup";
@@ -149,7 +149,7 @@ export const UserOrgMembershipModal = ({ popUp, handlePopUpOpen, handlePopUpTogg
if (isCustomRole && subscription && !subscription?.rbac) {
handlePopUpOpen("upgradePlan", {
description:
"You can assign custom roles to members if you upgrade your Infisical plan."
"You can assign custom roles to members if you switch to Infisical's Pro plan."
});
return;
}