mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-20 17:00:56 +00:00
Merge branch 'main' into ENG-3674
This commit is contained in:
+11
-1
@@ -1,5 +1,7 @@
|
||||
import { useEffect } from "react";
|
||||
import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { Button } from "@app/components/v2";
|
||||
@@ -15,13 +17,15 @@ import {
|
||||
useGetOrgPlanBillingInfo,
|
||||
useGetOrgTrialUrl
|
||||
} from "@app/hooks/api";
|
||||
import { subscriptionQueryKeys } from "@app/hooks/api/subscriptions/queries";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
|
||||
import { ManagePlansModal } from "./ManagePlansModal";
|
||||
|
||||
export const PreviewSection = () => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { subscription } = useSubscription();
|
||||
const { subscription } = useSubscription(true);
|
||||
const queryClient = useQueryClient();
|
||||
const { data, isPending } = useGetOrgPlanBillingInfo(currentOrg?.id ?? "");
|
||||
const getOrgTrialUrl = useGetOrgTrialUrl();
|
||||
const createCustomerPortalSession = useCreateCustomerPortalSession();
|
||||
@@ -37,6 +41,12 @@ export const PreviewSection = () => {
|
||||
return formattedTotal;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: subscriptionQueryKeys.getOrgSubsription(currentOrg?.id ?? "")
|
||||
});
|
||||
}, []);
|
||||
|
||||
const formatDate = (date: number) => {
|
||||
const createdDate = new Date(date * 1000);
|
||||
const day: number = createdDate.getDate();
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { format, formatRelative } from "date-fns";
|
||||
import { formatRelative } from "date-fns";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
@@ -48,13 +48,14 @@ import {
|
||||
import { withPermission } from "@app/hoc";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { gatewaysQueryKeys, useDeleteGatewayById } from "@app/hooks/api/gateways";
|
||||
import { useDeleteGatewayV2ById } from "@app/hooks/api/gateways-v2";
|
||||
|
||||
import { EditGatewayDetailsModal } from "./components/EditGatewayDetailsModal";
|
||||
|
||||
export const GatewayListPage = withPermission(
|
||||
() => {
|
||||
const [search, setSearch] = useState("");
|
||||
const { data: gateways, isPending: isGatewayLoading } = useQuery(gatewaysQueryKeys.list());
|
||||
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
|
||||
|
||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([
|
||||
"deleteGateway",
|
||||
@@ -62,16 +63,20 @@ export const GatewayListPage = withPermission(
|
||||
] as const);
|
||||
|
||||
const deleteGatewayById = useDeleteGatewayById();
|
||||
const deleteGatewayV2ById = useDeleteGatewayV2ById();
|
||||
|
||||
const handleDeleteGateway = async () => {
|
||||
await deleteGatewayById.mutateAsync((popUp.deleteGateway.data as { id: string }).id, {
|
||||
onSuccess: () => {
|
||||
handlePopUpToggle("deleteGateway");
|
||||
createNotification({
|
||||
type: "success",
|
||||
text: "Successfully delete gateway"
|
||||
});
|
||||
}
|
||||
const data = popUp.deleteGateway.data as { id: string; isV1: boolean };
|
||||
if (data.isV1) {
|
||||
await deleteGatewayById.mutateAsync(data.id);
|
||||
} else {
|
||||
await deleteGatewayV2ById.mutateAsync(data.id);
|
||||
}
|
||||
|
||||
handlePopUpToggle("deleteGateway");
|
||||
createNotification({
|
||||
type: "success",
|
||||
text: "Successfully deleted gateway"
|
||||
});
|
||||
};
|
||||
|
||||
@@ -127,7 +132,6 @@ export const GatewayListPage = withPermission(
|
||||
<THead>
|
||||
<Tr>
|
||||
<Th className="w-1/3">Name</Th>
|
||||
<Th>Cert Issued At</Th>
|
||||
<Th>Identity</Th>
|
||||
<Th>
|
||||
Health Check
|
||||
@@ -143,13 +147,19 @@ export const GatewayListPage = withPermission(
|
||||
</Tr>
|
||||
</THead>
|
||||
<TBody>
|
||||
{isGatewayLoading && (
|
||||
{isGatewaysLoading && (
|
||||
<TableSkeleton innerKey="gateway-table" columns={4} key="gateway-table" />
|
||||
)}
|
||||
{filteredGateway?.map((el) => (
|
||||
<Tr key={el.id}>
|
||||
<Td>{el.name}</Td>
|
||||
<Td>{format(new Date(el.issuedAt), "yyyy-MM-dd hh:mm:ss aaa")}</Td>
|
||||
<Td>
|
||||
<div className="flex items-center gap-2">
|
||||
<span>{el.name}</span>
|
||||
<span className="rounded bg-mineshaft-700 px-1.5 py-0.5 text-xs text-mineshaft-400">
|
||||
Gateway v{el.isV1 ? "1" : "2"}
|
||||
</span>
|
||||
</div>
|
||||
</Td>
|
||||
<Td>{el.identity.name}</Td>
|
||||
<Td>
|
||||
{el.heartbeat
|
||||
@@ -176,20 +186,22 @@ export const GatewayListPage = withPermission(
|
||||
>
|
||||
Copy ID
|
||||
</DropdownMenuItem>
|
||||
<OrgPermissionCan
|
||||
I={OrgGatewayPermissionActions.EditGateways}
|
||||
a={OrgPermissionSubjects.Gateway}
|
||||
>
|
||||
{(isAllowed: boolean) => (
|
||||
<DropdownMenuItem
|
||||
isDisabled={!isAllowed}
|
||||
icon={<FontAwesomeIcon icon={faEdit} />}
|
||||
onClick={() => handlePopUpOpen("editDetails", el)}
|
||||
>
|
||||
Edit Details
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
{el.isV1 && (
|
||||
<OrgPermissionCan
|
||||
I={OrgGatewayPermissionActions.EditGateways}
|
||||
a={OrgPermissionSubjects.Gateway}
|
||||
>
|
||||
{(isAllowed: boolean) => (
|
||||
<DropdownMenuItem
|
||||
isDisabled={!isAllowed}
|
||||
icon={<FontAwesomeIcon icon={faEdit} />}
|
||||
onClick={() => handlePopUpOpen("editDetails", el)}
|
||||
>
|
||||
Edit Details
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
)}
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionAppConnectionActions.Delete}
|
||||
a={OrgPermissionSubjects.AppConnections}
|
||||
@@ -224,7 +236,7 @@ export const GatewayListPage = withPermission(
|
||||
/>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
{!isGatewayLoading && !filteredGateway?.length && (
|
||||
{!isGatewaysLoading && !filteredGateway?.length && (
|
||||
<EmptyState
|
||||
title={
|
||||
gateways?.length
|
||||
@@ -251,8 +263,5 @@ export const GatewayListPage = withPermission(
|
||||
</div>
|
||||
);
|
||||
},
|
||||
{
|
||||
action: OrgPermissionAppConnectionActions.Read,
|
||||
subject: OrgPermissionSubjects.AppConnections
|
||||
}
|
||||
{ action: OrgGatewayPermissionActions.ListGateways, subject: OrgPermissionSubjects.Gateway }
|
||||
);
|
||||
|
||||
+53
-17
@@ -24,11 +24,17 @@ enum EnforceAuthType {
|
||||
export const OrgGeneralAuthSection = ({
|
||||
isSamlConfigured,
|
||||
isOidcConfigured,
|
||||
isGoogleConfigured
|
||||
isGoogleConfigured,
|
||||
isSamlActive,
|
||||
isOidcActive,
|
||||
isLdapActive
|
||||
}: {
|
||||
isSamlConfigured: boolean;
|
||||
isOidcConfigured: boolean;
|
||||
isGoogleConfigured: boolean;
|
||||
isSamlActive: boolean;
|
||||
isOidcActive: boolean;
|
||||
isLdapActive: boolean;
|
||||
}) => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { subscription } = useSubscription();
|
||||
@@ -126,6 +132,15 @@ export const OrgGeneralAuthSection = ({
|
||||
}
|
||||
};
|
||||
|
||||
const isGoogleOAuthEnforced = currentOrg.googleSsoAuthEnforced;
|
||||
|
||||
const getActiveSsoLabel = () => {
|
||||
if (isSamlActive) return "SAML";
|
||||
if (isOidcActive) return "OIDC";
|
||||
if (isLdapActive) return "LDAP";
|
||||
return "";
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-6">
|
||||
<div>
|
||||
@@ -135,7 +150,7 @@ export const OrgGeneralAuthSection = ({
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 py-4">
|
||||
<div className={twMerge("mt-4", !isSamlConfigured && "hidden")}>
|
||||
<div className={twMerge("mt-4", (!isSamlConfigured || isGoogleOAuthEnforced) && "hidden")}>
|
||||
<div className="mb-2 flex justify-between">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-md text-mineshaft-100">Enforce SAML SSO</span>
|
||||
@@ -160,7 +175,7 @@ export const OrgGeneralAuthSection = ({
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={twMerge("mt-4", !isOidcConfigured && "hidden")}>
|
||||
<div className={twMerge("mt-4", (!isOidcConfigured || isGoogleOAuthEnforced) && "hidden")}>
|
||||
<div className="mb-2 flex justify-between">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-md text-mineshaft-100">Enforce OIDC SSO</span>
|
||||
@@ -188,26 +203,47 @@ export const OrgGeneralAuthSection = ({
|
||||
<div className={twMerge("mt-2", !isGoogleConfigured && "hidden")}>
|
||||
<div className="mb-2 flex justify-between">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-md text-mineshaft-100">Enforce Google SSO</span>
|
||||
<span className="text-md text-mineshaft-100">Enforce Google OAuth</span>
|
||||
</div>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Sso}>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.Sso}
|
||||
tooltipProps={{
|
||||
className: "max-w-sm",
|
||||
side: "left"
|
||||
}}
|
||||
allowedLabel={
|
||||
isOidcActive || isSamlActive || isLdapActive
|
||||
? `You cannot enforce Google OAuth while ${getActiveSsoLabel()} SSO is enabled. Disable ${getActiveSsoLabel()} SSO to enforce Google OAuth.`
|
||||
: undefined
|
||||
}
|
||||
renderTooltip={isOidcActive || isSamlActive || isLdapActive}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Switch
|
||||
id="enforce-google-sso"
|
||||
onCheckedChange={(value) =>
|
||||
handleEnforceOrgAuthToggle(value, EnforceAuthType.GOOGLE)
|
||||
}
|
||||
isChecked={currentOrg?.googleSsoAuthEnforced ?? false}
|
||||
isDisabled={!isAllowed || currentOrg?.authEnforced}
|
||||
/>
|
||||
<div>
|
||||
<Switch
|
||||
id="enforce-google-sso"
|
||||
onCheckedChange={(value) =>
|
||||
handleEnforceOrgAuthToggle(value, EnforceAuthType.GOOGLE)
|
||||
}
|
||||
isChecked={currentOrg?.googleSsoAuthEnforced ?? false}
|
||||
isDisabled={
|
||||
!isAllowed ||
|
||||
currentOrg?.authEnforced ||
|
||||
isOidcActive ||
|
||||
isSamlActive ||
|
||||
isLdapActive
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</div>
|
||||
<p className="text-sm text-mineshaft-300">
|
||||
Enforce users to authenticate via Google OAuth SSO to access this organization.
|
||||
Enforce users to authenticate via Google OAuth to access this organization.
|
||||
<br />
|
||||
When this is enabled your organization members will only be able to login with Google
|
||||
SSO (not Google SAML).
|
||||
OAuth (not Google SAML).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -267,8 +303,8 @@ export const OrgGeneralAuthSection = ({
|
||||
</div>
|
||||
<p className="text-sm text-mineshaft-300">
|
||||
<span>
|
||||
Allow organization admins to bypass SAML enforcement when SSO is unavailable,
|
||||
misconfigured, or inaccessible.
|
||||
Allow organization admins to bypass SSO login enforcement when your SSO provider is
|
||||
unavailable, misconfigured, or inaccessible.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
+26
-9
@@ -94,6 +94,8 @@ export const OrgLDAPSection = (): JSX.Element => {
|
||||
handlePopUpOpen("ldapGroupMap");
|
||||
};
|
||||
|
||||
const isGoogleOAuthEnabled = currentOrg.googleSsoAuthEnforced;
|
||||
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<div className="py-4">
|
||||
@@ -116,16 +118,31 @@ export const OrgLDAPSection = (): JSX.Element => {
|
||||
<div className="pt-4">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<h2 className="text-md text-mineshaft-100">Enable LDAP</h2>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Ldap}>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.Ldap}
|
||||
tooltipProps={{
|
||||
className: "max-w-sm",
|
||||
side: "left"
|
||||
}}
|
||||
allowedLabel={
|
||||
isGoogleOAuthEnabled
|
||||
? "You cannot enable LDAP SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable LDAP SSO."
|
||||
: undefined
|
||||
}
|
||||
renderTooltip={isGoogleOAuthEnabled}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Switch
|
||||
id="enable-saml-sso"
|
||||
onCheckedChange={(value) => handleLDAPToggle(value)}
|
||||
isChecked={data ? data.isActive : false}
|
||||
isDisabled={!isAllowed}
|
||||
>
|
||||
Enable
|
||||
</Switch>
|
||||
<div>
|
||||
<Switch
|
||||
id="enable-ldap-sso"
|
||||
onCheckedChange={(value) => handleLDAPToggle(value)}
|
||||
isChecked={data ? data.isActive : false}
|
||||
isDisabled={!isAllowed || isGoogleOAuthEnabled}
|
||||
>
|
||||
Enable
|
||||
</Switch>
|
||||
</div>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</div>
|
||||
|
||||
+24
-7
@@ -83,6 +83,8 @@ export const OrgOIDCSection = (): JSX.Element => {
|
||||
}
|
||||
};
|
||||
|
||||
const isGoogleOAuthEnabled = currentOrg.googleSsoAuthEnforced;
|
||||
|
||||
return (
|
||||
<div className="mb-4 rounded-lg border-mineshaft-600 bg-mineshaft-900">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
@@ -106,14 +108,29 @@ export const OrgOIDCSection = (): JSX.Element => {
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<h2 className="text-md text-mineshaft-100">Enable OIDC</h2>
|
||||
{!isPending && (
|
||||
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Sso}>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.Sso}
|
||||
tooltipProps={{
|
||||
className: "max-w-sm",
|
||||
side: "left"
|
||||
}}
|
||||
allowedLabel={
|
||||
isGoogleOAuthEnabled
|
||||
? "You cannot enable OIDC SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable OIDC SSO."
|
||||
: undefined
|
||||
}
|
||||
renderTooltip={isGoogleOAuthEnabled}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Switch
|
||||
id="enable-oidc-sso"
|
||||
onCheckedChange={(value) => handleOIDCToggle(value)}
|
||||
isChecked={data ? data.isActive : false}
|
||||
isDisabled={!isAllowed}
|
||||
/>
|
||||
<div>
|
||||
<Switch
|
||||
id="enable-oidc-sso"
|
||||
onCheckedChange={(value) => handleOIDCToggle(value)}
|
||||
isChecked={data ? data.isActive : false}
|
||||
isDisabled={!isAllowed || isGoogleOAuthEnabled}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
)}
|
||||
|
||||
+24
-7
@@ -78,6 +78,8 @@ export const OrgSSOSection = (): JSX.Element => {
|
||||
}
|
||||
};
|
||||
|
||||
const isGoogleOAuthEnabled = currentOrg.googleSsoAuthEnforced;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
@@ -99,14 +101,29 @@ export const OrgSSOSection = (): JSX.Element => {
|
||||
<div className="mb-2 flex items-center justify-between pt-4">
|
||||
<h2 className="text-md text-mineshaft-100">Enable SAML</h2>
|
||||
{!isPending && (
|
||||
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Sso}>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.Sso}
|
||||
tooltipProps={{
|
||||
className: "max-w-sm",
|
||||
side: "left"
|
||||
}}
|
||||
allowedLabel={
|
||||
isGoogleOAuthEnabled
|
||||
? "You cannot enable SAML SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable SAML SSO."
|
||||
: undefined
|
||||
}
|
||||
renderTooltip={isGoogleOAuthEnabled}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Switch
|
||||
id="enable-saml-sso"
|
||||
onCheckedChange={(value) => handleSamlSSOToggle(value)}
|
||||
isChecked={data ? data.isActive : false}
|
||||
isDisabled={!isAllowed}
|
||||
/>
|
||||
<div>
|
||||
<Switch
|
||||
id="enable-saml-sso"
|
||||
onCheckedChange={(value) => handleSamlSSOToggle(value)}
|
||||
isChecked={data ? data.isActive : false}
|
||||
isDisabled={!isAllowed || isGoogleOAuthEnabled}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
)}
|
||||
|
||||
@@ -184,6 +184,9 @@ export const OrgSsoTab = withPermission(
|
||||
isSamlConfigured={isSamlConfigured}
|
||||
isOidcConfigured={isOidcConfigured}
|
||||
isGoogleConfigured={isGoogleConfigured}
|
||||
isSamlActive={Boolean(samlConfig?.isActive)}
|
||||
isOidcActive={Boolean(oidcConfig?.isActive)}
|
||||
isLdapActive={Boolean(ldapConfig?.isActive)}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user