mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-20 22:17:52 +00:00
Merge branch 'main' into ENG-4006
This commit is contained in:
@@ -7,16 +7,15 @@ import {
|
||||
faTrash,
|
||||
faUsers,
|
||||
faUserXmark,
|
||||
faWarning,
|
||||
faXmark
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { AlertTriangleIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Checkbox,
|
||||
DeleteActionModal,
|
||||
@@ -38,6 +37,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useSubscription, useUser } from "@app/context";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
@@ -451,7 +451,7 @@ export const ServerAdminsTable = () => {
|
||||
const email = user.email ?? user.username;
|
||||
return (
|
||||
<li key={user.id}>
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center gap-x-1">
|
||||
<p>
|
||||
{user.firstName || user.lastName ? (
|
||||
<>
|
||||
@@ -464,15 +464,10 @@ export const ServerAdminsTable = () => {
|
||||
</p>
|
||||
{userId === user.id && (
|
||||
<Tooltip content="Are you sure you want to remove yourself from this instance?">
|
||||
<div className="inline-block">
|
||||
<Badge
|
||||
variant="primary"
|
||||
className="mt-[0.05rem] ml-1 inline-flex w-min items-center gap-1.5 whitespace-nowrap"
|
||||
>
|
||||
<FontAwesomeIcon icon={faWarning} />
|
||||
<span>Deleting Yourself</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="danger">
|
||||
<AlertTriangleIcon />
|
||||
Deleting Yourself
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { faRotate } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { RefreshCwIcon } from "lucide-react";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Badge, Button, DeleteActionModal } from "@app/components/v2";
|
||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useUser } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useInvalidateCache } from "@app/hooks/api";
|
||||
@@ -62,11 +62,8 @@ export const CachingPageForm = () => {
|
||||
<div className="mb-2 flex items-center gap-3">
|
||||
<span className="text-xl font-medium text-mineshaft-100">Secrets Cache</span>
|
||||
{isInvalidating && (
|
||||
<Badge
|
||||
variant="danger"
|
||||
className="flex h-5 w-min items-center gap-1.5 whitespace-nowrap"
|
||||
>
|
||||
<FontAwesomeIcon icon={faRotate} className="animate-spin" />
|
||||
<Badge variant="danger">
|
||||
<RefreshCwIcon className="animate-spin" />
|
||||
Invalidating Cache
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { useCallback } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { InfoIcon } from "lucide-react";
|
||||
import { z } from "zod";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Badge, Button, FormControl, Select, SelectItem, Tooltip } from "@app/components/v2";
|
||||
import { Button, FormControl, Select, SelectItem, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useServerConfig, useSubscription } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import {
|
||||
@@ -54,6 +54,7 @@ export const EncryptionPageForm = () => {
|
||||
|
||||
if (!subscription.hsm) {
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
isEnterpriseFeature: true,
|
||||
description: "Hardware Security Module's (HSM's), are only available on Enterprise plans."
|
||||
});
|
||||
return;
|
||||
@@ -132,12 +133,10 @@ export const EncryptionPageForm = () => {
|
||||
|
||||
{config.fipsEnabled && (
|
||||
<Tooltip content="FIPS mode of operation is enabled for your instance. All cryptographic operations within the FIPS boundaries are validated to be FIPS compliant.">
|
||||
<div>
|
||||
<Badge className="flex items-center gap-2" variant="primary">
|
||||
FIPS Mode: Enabled
|
||||
<FontAwesomeIcon icon={faInfoCircle} />
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="info">
|
||||
FIPS Mode: Enabled
|
||||
<InfoIcon />
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
@@ -146,6 +145,7 @@ export const EncryptionPageForm = () => {
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
text={(popUp.upgradePlan?.data as { description: string })?.description}
|
||||
isEnterpriseFeature={popUp.upgradePlan?.data?.isEnterpriseFeature}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Control, Controller, useForm, useWatch } from "react-hook-form";
|
||||
import {
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faChevronRight,
|
||||
faExclamationTriangle,
|
||||
faMagnifyingGlass
|
||||
@@ -14,6 +12,7 @@ import { z } from "zod";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Input, SecretInput, Tooltip } from "@app/components/v2";
|
||||
import { HighlightText } from "@app/components/v2/HighlightText";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { useGetEnvOverrides, useUpdateServerConfig } from "@app/hooks/api";
|
||||
|
||||
type TForm = Record<string, string>;
|
||||
@@ -213,22 +212,9 @@ export const EnvironmentPageForm = () => {
|
||||
>
|
||||
<div className="flex w-full flex-row items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-start gap-1">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Overrides</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/self-hosting/configuration/envars#environment-variable-overrides"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.32rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/self-hosting/configuration/envars#environment-variable-overrides" />
|
||||
</div>
|
||||
<p className="text-sm text-bunker-300">
|
||||
Override specific environment variables. After saving, it may take up to 5 minutes for
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
faXmark
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { ServerCogIcon } from "lucide-react";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
Badge,
|
||||
DeleteActionModal,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
THead,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
PreferenceKey,
|
||||
@@ -110,7 +111,8 @@ const IdentityPanelTable = ({
|
||||
<Td>
|
||||
{name}
|
||||
{isInstanceAdmin && (
|
||||
<Badge variant="primary" className="ml-2">
|
||||
<Badge variant="info" className="ml-2">
|
||||
<ServerCogIcon />
|
||||
Server Admin
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
faArrowDown,
|
||||
faArrowUp,
|
||||
faBuilding,
|
||||
faCircleQuestion,
|
||||
faEllipsisV,
|
||||
faEnvelope,
|
||||
faEye,
|
||||
@@ -19,11 +18,11 @@ import {
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { CircleQuestionMarkIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DeleteActionModal,
|
||||
DropdownMenu,
|
||||
@@ -46,6 +45,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useUser } from "@app/context";
|
||||
import { OrgMembershipRole } from "@app/helpers/roles";
|
||||
import {
|
||||
@@ -295,15 +295,17 @@ const ViewMembersModalContent = ({
|
||||
)}
|
||||
</div>
|
||||
</Td>
|
||||
<Td className="max-w-0">
|
||||
<Badge className="flex w-fit max-w-full items-center gap-x-1 bg-mineshaft-400/50 whitespace-nowrap text-bunker-200">
|
||||
<p className="truncate capitalize">{member.role.replace("-", " ")}</p>
|
||||
{Boolean(member.roleId) && (
|
||||
<Tooltip content="This member has a custom role assigned.">
|
||||
<FontAwesomeIcon icon={faCircleQuestion} className="w-3" />
|
||||
</Tooltip>
|
||||
)}
|
||||
</Badge>
|
||||
<Td>
|
||||
<div className="flex max-w-32">
|
||||
<Tooltip
|
||||
content={member.roleId ? "This member has a custom role assigned." : ""}
|
||||
>
|
||||
<Badge isTruncatable variant="neutral">
|
||||
<span className="capitalize">{member.role.replace("-", " ")}</span>
|
||||
{Boolean(member.roleId) && <CircleQuestionMarkIcon />}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</Td>
|
||||
<Td>
|
||||
<div className="flex justify-end">
|
||||
|
||||
@@ -9,16 +9,15 @@ import {
|
||||
faUsers,
|
||||
faUserShield,
|
||||
faUserXmark,
|
||||
faWarning,
|
||||
faXmark
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { AlertTriangleIcon, UserCogIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Checkbox,
|
||||
DeleteActionModal,
|
||||
@@ -41,6 +40,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useSubscription, useUser } from "@app/context";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
@@ -218,7 +218,8 @@ const UserPanelTable = ({
|
||||
{name ?? <span className="text-mineshaft-400">Not Set</span>}
|
||||
</p>
|
||||
{superAdmin && (
|
||||
<Badge variant="primary" className="ml-2 whitespace-nowrap">
|
||||
<Badge variant="info" className="ml-2">
|
||||
<UserCogIcon />
|
||||
Server Admin
|
||||
</Badge>
|
||||
)}
|
||||
@@ -548,7 +549,7 @@ export const UserIdentitiesTable = () => {
|
||||
const email = user.email ?? user.username;
|
||||
return (
|
||||
<li key={user.id}>
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center gap-x-1">
|
||||
<p>
|
||||
{user.firstName || user.lastName ? (
|
||||
<>
|
||||
@@ -561,15 +562,10 @@ export const UserIdentitiesTable = () => {
|
||||
</p>
|
||||
{userId === user.id && (
|
||||
<Tooltip content="Are you sure you want to remove yourself from this instance?">
|
||||
<div className="inline-block">
|
||||
<Badge
|
||||
variant="primary"
|
||||
className="mt-[0.05rem] ml-1 inline-flex w-min items-center gap-1.5 whitespace-nowrap"
|
||||
>
|
||||
<FontAwesomeIcon icon={faWarning} />
|
||||
<span>Deleting Yourself</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="danger">
|
||||
<AlertTriangleIcon />
|
||||
Deleting Yourself
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -7,7 +7,6 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
THead,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { useGetCaCerts } from "@app/hooks/api";
|
||||
|
||||
@@ -60,7 +60,7 @@ export const CaCertificatesTable = ({ caId }: Props) => {
|
||||
<div className="flex items-center">
|
||||
CA Certificate {caCert.version}
|
||||
{isLastItem && (
|
||||
<Badge variant="success" className="ml-4">
|
||||
<Badge variant="info" className="ml-4">
|
||||
Current
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { CaStatus, CaType, useListCasByTypeAndProjectId } from "@app/hooks/api";
|
||||
import {
|
||||
|
||||
+1
-1
@@ -10,7 +10,6 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -26,6 +25,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { CaStatus, CaType, useListExternalCasByProjectId } from "@app/hooks/api";
|
||||
import { caStatusToNameMap, getCaStatusBadgeVariant } from "@app/hooks/api/ca/constants";
|
||||
|
||||
+1
@@ -104,6 +104,7 @@ export const CertificateTemplatesSection = ({ caId }: Props) => {
|
||||
<UpgradePlanModal
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
|
||||
text="Managing template enrollment options for EST is only available on Infisical's Enterprise plan."
|
||||
/>
|
||||
</div>
|
||||
|
||||
+4
-1
@@ -36,6 +36,7 @@ type Props = {
|
||||
data?: {
|
||||
id?: string;
|
||||
name?: string;
|
||||
isEnterpriseFeature?: boolean;
|
||||
}
|
||||
) => void;
|
||||
};
|
||||
@@ -90,7 +91,9 @@ export const CertificateTemplatesTable = ({ handlePopUpOpen, caId }: Props) => {
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
if (!subscription?.pkiEst) {
|
||||
handlePopUpOpen("upgradePlan");
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
isEnterpriseFeature: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,17 @@ import {
|
||||
faEllipsis,
|
||||
faEye,
|
||||
faFileExport,
|
||||
faQuestionCircle,
|
||||
faRedo,
|
||||
faTrash
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { format } from "date-fns";
|
||||
import { CircleQuestionMarkIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -33,6 +32,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionCertificateActions,
|
||||
ProjectPermissionSub,
|
||||
@@ -58,7 +58,7 @@ const isExpiringWithinOneDay = (notAfter: string): boolean => {
|
||||
|
||||
const getAutoRenewalInfo = (certificate: TCertificate) => {
|
||||
if (certificate.renewedByCertificateId) {
|
||||
return { text: "Renewed", variant: "instance" as const };
|
||||
return { text: "Renewed", variant: "neutral" as const };
|
||||
}
|
||||
|
||||
const isRevoked = certificate.status === CertStatus.REVOKED;
|
||||
@@ -69,7 +69,7 @@ const getAutoRenewalInfo = (certificate: TCertificate) => {
|
||||
if (isRevoked) {
|
||||
return {
|
||||
text: "Not Available",
|
||||
variant: "instance" as const,
|
||||
variant: "neutral" as const,
|
||||
tooltip: "Renewal is not available for revoked certificates"
|
||||
};
|
||||
}
|
||||
@@ -77,7 +77,7 @@ const getAutoRenewalInfo = (certificate: TCertificate) => {
|
||||
if (isExpired) {
|
||||
return {
|
||||
text: "Not Available",
|
||||
variant: "instance" as const,
|
||||
variant: "neutral" as const,
|
||||
tooltip: "Renewal is not available for expired certificates"
|
||||
};
|
||||
}
|
||||
@@ -85,7 +85,7 @@ const getAutoRenewalInfo = (certificate: TCertificate) => {
|
||||
if (hasNoProfile) {
|
||||
return {
|
||||
text: "Not Available",
|
||||
variant: "instance" as const,
|
||||
variant: "neutral" as const,
|
||||
tooltip: "Renewal requires a certificate profile"
|
||||
};
|
||||
}
|
||||
@@ -93,7 +93,7 @@ const getAutoRenewalInfo = (certificate: TCertificate) => {
|
||||
if (certificate.hasPrivateKey === false) {
|
||||
return {
|
||||
text: "Not Available",
|
||||
variant: "instance" as const,
|
||||
variant: "neutral" as const,
|
||||
tooltip: "Renewal is not available for certificates with externally generated private keys"
|
||||
};
|
||||
}
|
||||
@@ -101,7 +101,7 @@ const getAutoRenewalInfo = (certificate: TCertificate) => {
|
||||
if (isExpiringWithinDay) {
|
||||
return {
|
||||
text: "Not Available",
|
||||
variant: "instance" as const,
|
||||
variant: "neutral" as const,
|
||||
tooltip: "Auto-renewal is not available for certificates expiring within 24 hours"
|
||||
};
|
||||
}
|
||||
@@ -115,7 +115,7 @@ const getAutoRenewalInfo = (certificate: TCertificate) => {
|
||||
}
|
||||
|
||||
if (!certificate.renewBeforeDays) {
|
||||
return { text: "Auto-Renewal Disabled", variant: "primary" as const };
|
||||
return { text: "Auto-Renewal Disabled", variant: "warning" as const };
|
||||
}
|
||||
|
||||
const notAfterDate = new Date(certificate.notAfter);
|
||||
@@ -133,11 +133,11 @@ const getAutoRenewalInfo = (certificate: TCertificate) => {
|
||||
);
|
||||
|
||||
if (daysUntilRenewal === 0) {
|
||||
return { text: "Renews today", variant: "primary" as const };
|
||||
return { text: "Renews today", variant: "warning" as const };
|
||||
}
|
||||
|
||||
if (daysUntilRenewal <= 7) {
|
||||
return { text: `Renews in ${daysUntilRenewal}d`, variant: "primary" as const };
|
||||
return { text: `Renews in ${daysUntilRenewal}d`, variant: "warning" as const };
|
||||
}
|
||||
|
||||
return { text: `Renews in ${daysUntilRenewal}d`, variant: "success" as const };
|
||||
@@ -279,16 +279,12 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => {
|
||||
{autoRenewalInfo &&
|
||||
(autoRenewalInfo.tooltip ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant={autoRenewalInfo.variant}>
|
||||
{autoRenewalInfo.text}
|
||||
<Tooltip content={autoRenewalInfo.tooltip}>
|
||||
<FontAwesomeIcon
|
||||
icon={faQuestionCircle}
|
||||
className="ml-1 cursor-help text-red-400 hover:text-red-300"
|
||||
size="sm"
|
||||
/>
|
||||
</Tooltip>
|
||||
</Badge>
|
||||
<Tooltip content={autoRenewalInfo.tooltip}>
|
||||
<Badge variant={autoRenewalInfo.variant}>
|
||||
{autoRenewalInfo.text}
|
||||
<CircleQuestionMarkIcon />
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</div>
|
||||
) : (
|
||||
<Badge variant={autoRenewalInfo.variant}>{autoRenewalInfo.text}</Badge>
|
||||
|
||||
+2
-2
@@ -5,13 +5,13 @@ export const getCertValidUntilBadgeDetails = (notAfter: string) => {
|
||||
const notAfterDate = new Date(notAfter).getTime();
|
||||
const diffInMs = notAfterDate - currentDate;
|
||||
|
||||
let variant: "success" | "primary" | "danger" = "success";
|
||||
let variant: "success" | "warning" | "danger" = "success";
|
||||
let label = "Healthy";
|
||||
|
||||
if (diffInMs > ms("60d")) {
|
||||
variant = "success";
|
||||
} else if (diffInMs > ms("30d")) {
|
||||
variant = "primary";
|
||||
variant = "warning";
|
||||
} else {
|
||||
variant = "danger";
|
||||
}
|
||||
|
||||
+7
-12
@@ -1,7 +1,6 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { subject } from "@casl/ability";
|
||||
import {
|
||||
faBan,
|
||||
faCalendarCheck,
|
||||
faCheck,
|
||||
faCopy,
|
||||
@@ -19,6 +18,7 @@ import {
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { format } from "date-fns";
|
||||
import { BanIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
PkiSyncStatusBadge
|
||||
} from "@app/components/pki-syncs";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -39,6 +38,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionPkiSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -172,10 +172,7 @@ export const PkiSyncRow = ({
|
||||
<Td>
|
||||
<Tooltip content="The PKI subscriber for this sync has been deleted. Configure a new source or remove this sync.">
|
||||
<div className="w-min">
|
||||
<Badge
|
||||
className="flex h-5 w-min items-center gap-1.5 whitespace-nowrap"
|
||||
variant="primary"
|
||||
>
|
||||
<Badge variant="warning">
|
||||
<FontAwesomeIcon icon={faTriangleExclamation} />
|
||||
<span>Source Deleted</span>
|
||||
</Badge>
|
||||
@@ -234,12 +231,10 @@ export const PkiSyncRow = ({
|
||||
className="text-xs"
|
||||
content="Auto-Sync is disabled. Certificate changes in the PKI subscriber will not be automatically synced to the destination."
|
||||
>
|
||||
<div>
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faBan} />
|
||||
{!syncStatus && "Auto-Sync Disabled"}
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<BanIcon />
|
||||
{!syncStatus && "Auto-Sync Disabled"}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
{syncOption?.canImportCertificates && <PkiSyncImportStatusBadge mini pkiSync={pkiSync} />}
|
||||
|
||||
+6
-16
@@ -1,11 +1,12 @@
|
||||
import { useCallback, useEffect, useMemo } from "react";
|
||||
import { faArrowUpRightFromSquare, faBookOpen, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { CreatePkiSyncModal } from "@app/components/pki-syncs";
|
||||
import { Button, Spinner } from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { ProjectPermissionPkiSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -64,21 +65,10 @@ export const PkiSyncsTab = () => {
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-start gap-1">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Certificate Syncs</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/integrations/pki-syncs/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.32rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Certificate Syncs</p>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/pki/certificate-syncs/overview" />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-bunker-300">
|
||||
Use App Connections to sync certificates to third-party services.
|
||||
|
||||
+2
-2
@@ -7,7 +7,6 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -24,6 +23,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionPkiSubscriberActions,
|
||||
ProjectPermissionSub,
|
||||
@@ -93,7 +93,7 @@ export const PkiSubscriberCertificatesTable = ({ subscriberName, handlePopUpOpen
|
||||
}
|
||||
|
||||
if (daysUntilExpiry < 30) {
|
||||
return <Badge variant="primary">Expiring Soon</Badge>;
|
||||
return <Badge variant="warning">Expiring Soon</Badge>;
|
||||
}
|
||||
|
||||
return <Badge variant="success">Valid</Badge>;
|
||||
|
||||
+1
-1
@@ -11,7 +11,6 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -27,6 +26,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionPkiSubscriberActions,
|
||||
ProjectPermissionSub,
|
||||
|
||||
+9
-14
@@ -1,7 +1,6 @@
|
||||
import { useCallback } from "react";
|
||||
import { subject } from "@casl/ability";
|
||||
import {
|
||||
faBan,
|
||||
faCheck,
|
||||
faCopy,
|
||||
faDownload,
|
||||
@@ -15,6 +14,7 @@ import {
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { BanIcon, RefreshCwIcon } from "lucide-react";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
PkiSyncRemoveStatusBadge
|
||||
} from "@app/components/pki-syncs";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -35,6 +34,7 @@ import {
|
||||
IconButton,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionPkiSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -136,24 +136,19 @@ export const PkiSyncActionTriggers = ({ pkiSync }: Props) => {
|
||||
{syncOption?.canImportCertificates && <PkiSyncImportStatusBadge pkiSync={pkiSync} />}
|
||||
<PkiSyncRemoveStatusBadge pkiSync={pkiSync} />
|
||||
{pkiSync.isAutoSyncEnabled ? (
|
||||
<Badge
|
||||
variant="success"
|
||||
className="flex h-5 w-min items-center gap-1.5 whitespace-nowrap"
|
||||
>
|
||||
<FontAwesomeIcon icon={faRotate} />
|
||||
<span>Auto-Sync Enabled</span>
|
||||
<Badge variant="info">
|
||||
<RefreshCwIcon />
|
||||
Auto-Sync Enabled
|
||||
</Badge>
|
||||
) : (
|
||||
<Tooltip
|
||||
className="text-xs"
|
||||
content="Auto-Sync is disabled. Certificate changes in the PKI subscriber will not be automatically synced to the destination."
|
||||
>
|
||||
<div>
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faBan} />
|
||||
<span>Auto-Sync Disabled</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<BanIcon />
|
||||
Auto-Sync Disabled
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
<div>
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { GenericFieldLabel } from "@app/components/secret-syncs";
|
||||
import { Badge, IconButton } from "@app/components/v2";
|
||||
import { IconButton } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionPkiSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { TPkiSync } from "@app/hooks/api/pkiSyncs";
|
||||
|
||||
+8
-11
@@ -1,10 +1,12 @@
|
||||
/* eslint-disable jsx-a11y/label-has-associated-control */
|
||||
import { subject } from "@casl/ability";
|
||||
import { faEdit, faTriangleExclamation } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faEdit } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { AlertTriangleIcon } from "lucide-react";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Badge, IconButton, Tooltip } from "@app/components/v2";
|
||||
import { IconButton, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionPkiSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { TPkiSync } from "@app/hooks/api/pkiSyncs";
|
||||
@@ -36,15 +38,10 @@ export const PkiSyncSourceSection = ({ pkiSync, onEditSource }: Props) => {
|
||||
<div>
|
||||
{!subscriberId && (
|
||||
<Tooltip content="The PKI subscriber for this sync has been deleted. Configure a new source or remove this sync.">
|
||||
<div className="mr-1 inline-block w-min">
|
||||
<Badge
|
||||
className="flex h-5 w-min items-center gap-1.5 whitespace-nowrap"
|
||||
variant="primary"
|
||||
>
|
||||
<FontAwesomeIcon icon={faTriangleExclamation} />
|
||||
<span>Source Deleted</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="danger" className="mr-1">
|
||||
<AlertTriangleIcon />
|
||||
Source Deleted
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
<ProjectPermissionCan I={ProjectPermissionPkiSyncActions.Edit} a={permissionSubject}>
|
||||
|
||||
@@ -203,7 +203,9 @@ export const PkiTemplateListPage = () => {
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (!subscription.pkiEst) {
|
||||
handlePopUpOpen("estUpgradePlan");
|
||||
handlePopUpOpen("estUpgradePlan", {
|
||||
isEnterpriseFeature: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
handlePopUpOpen("enrollmentOptions", {
|
||||
@@ -296,6 +298,7 @@ export const PkiTemplateListPage = () => {
|
||||
isOpen={popUp.estUpgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("estUpgradePlan", isOpen)}
|
||||
text="You can only configure template enrollment methods if you switch to Infisical's Enterprise plan."
|
||||
isEnterpriseFeature={popUp.estUpgradePlan.data?.isEnterpriseFeature}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
+8
-24
@@ -12,7 +12,6 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -21,6 +20,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useProjectPermission } from "@app/context";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
@@ -45,42 +45,26 @@ const MetricsBadges = ({
|
||||
};
|
||||
}) => {
|
||||
if (!metrics) {
|
||||
return (
|
||||
<Badge variant="primary" className="text-xs">
|
||||
No metrics
|
||||
</Badge>
|
||||
);
|
||||
return <Badge variant="warning">No metrics</Badge>;
|
||||
}
|
||||
|
||||
if (metrics.totalCertificates === 0) {
|
||||
return (
|
||||
<Badge variant="primary" className="text-xs">
|
||||
No certificates
|
||||
</Badge>
|
||||
);
|
||||
return <Badge variant="warning">No certificates</Badge>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{metrics.activeCertificates > 0 && (
|
||||
<Badge variant="success" className="text-xs">
|
||||
{metrics.activeCertificates} active
|
||||
</Badge>
|
||||
<Badge variant="success">{metrics.activeCertificates} active</Badge>
|
||||
)}
|
||||
{metrics.expiringCertificates > 0 && (
|
||||
<Badge variant="primary" className="text-xs">
|
||||
{metrics.expiringCertificates} expiring
|
||||
</Badge>
|
||||
<Badge variant="warning">{metrics.expiringCertificates} expiring</Badge>
|
||||
)}
|
||||
{metrics.expiredCertificates > 0 && (
|
||||
<Badge variant="danger" className="text-xs">
|
||||
{metrics.expiredCertificates} expired
|
||||
</Badge>
|
||||
<Badge variant="danger">{metrics.expiredCertificates} expired</Badge>
|
||||
)}
|
||||
{metrics.revokedCertificates > 0 && (
|
||||
<Badge variant="danger" className="text-xs">
|
||||
{metrics.revokedCertificates} revoked
|
||||
</Badge>
|
||||
<Badge variant="danger">{metrics.revokedCertificates} revoked</Badge>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
@@ -135,7 +119,7 @@ export const ProfileRow = ({ profile, onEditProfile, onDeleteProfile }: Props) =
|
||||
const getEnrollmentTypeBadge = (enrollmentType: string) => {
|
||||
const config = {
|
||||
api: { variant: "success" as const, label: "API" },
|
||||
est: { variant: "primary" as const, label: "EST" }
|
||||
est: { variant: "warning" as const, label: "EST" }
|
||||
} as const;
|
||||
|
||||
const configKey = Object.keys(config).includes(enrollmentType)
|
||||
|
||||
@@ -170,7 +170,9 @@ export const KmipClientTable = () => {
|
||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||
onClick={() => {
|
||||
if (subscription && !subscription.kmip) {
|
||||
handlePopUpOpen("upgradePlan");
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
isEnterpriseFeature: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -343,6 +345,7 @@ export const KmipClientTable = () => {
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
text="KMIP requires an enterprise plan."
|
||||
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
@@ -23,7 +23,6 @@ import { motion } from "framer-motion";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -44,7 +43,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { BadgeProps } from "@app/components/v2/Badge/Badge";
|
||||
import { Badge, TBadgeProps } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionCmekActions,
|
||||
@@ -72,7 +71,7 @@ import { DeleteCmekModal } from "./DeleteCmekModal";
|
||||
|
||||
const getStatusBadgeProps = (
|
||||
isDisabled: boolean
|
||||
): { variant: BadgeProps["variant"]; label: string } => {
|
||||
): { variant: TBadgeProps["variant"]; label: string } => {
|
||||
if (isDisabled) {
|
||||
return {
|
||||
variant: "danger",
|
||||
|
||||
@@ -7,7 +7,6 @@ import { z } from "zod";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { decodeBase64 } from "@app/components/utilities/cryptography/crypto";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
FormControl,
|
||||
Modal,
|
||||
@@ -19,6 +18,7 @@ import {
|
||||
TextArea,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { SigningAlgorithm, TCmek, useCmekVerify } from "@app/hooks/api/cmeks";
|
||||
import { isBase64 } from "@app/lib/fn/base64";
|
||||
|
||||
@@ -112,30 +112,22 @@ const VerifyForm = ({ cmek }: FormProps) => {
|
||||
<div className="mb-6 flex flex-col gap-2">
|
||||
<div className="flex items-center justify-between space-x-2">
|
||||
<span className="text-sm opacity-60">Signature Status:</span>
|
||||
<Badge variant={signatureValid ? "success" : "danger"}>
|
||||
<Tooltip
|
||||
content={
|
||||
signatureValid
|
||||
? "The signature is valid. signature was created using the same signing algorithm and key as the one used to sign the data."
|
||||
: "The signature is invalid. The signature was not created using the same signing algorithm and key as the one used to sign the data. The data and signature may have been tampered with."
|
||||
}
|
||||
>
|
||||
{signatureValid ? (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<p>Valid</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<p>Invalid</p>
|
||||
</div>
|
||||
)}
|
||||
</Tooltip>
|
||||
</Badge>
|
||||
<Tooltip
|
||||
content={
|
||||
signatureValid
|
||||
? "The signature is valid. signature was created using the same signing algorithm and key as the one used to sign the data."
|
||||
: "The signature is invalid. The signature was not created using the same signing algorithm and key as the one used to sign the data. The data and signature may have been tampered with."
|
||||
}
|
||||
>
|
||||
<Badge variant={signatureValid ? "success" : "danger"}>
|
||||
{signatureValid ? "Valid" : "Invalid"}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="text-sm opacity-60">Signing Algorithm:</span>
|
||||
<Badge variant="primary">{signingAlgorithm}</Badge>
|
||||
<Badge variant="info">{signingAlgorithm}</Badge>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<span className="text-sm opacity-60">Signature:</span>{" "}
|
||||
|
||||
+8
-2
@@ -5,6 +5,7 @@ import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { OrgPermissionGroupActions, OrgPermissionSubjects, useSubscription } from "@app/context";
|
||||
import { useDeleteGroup } from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
@@ -27,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");
|
||||
@@ -57,7 +59,10 @@ export const OrgGroupsSection = () => {
|
||||
return (
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Groups</p>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Groups</p>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/groups" />
|
||||
</div>
|
||||
<OrgPermissionCan I={OrgPermissionGroupActions.Create} a={OrgPermissionSubjects.Groups}>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -92,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>
|
||||
|
||||
+5
-3
@@ -4,7 +4,8 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { Badge, FormControl, Select, SelectItem, Tooltip } from "@app/components/v2";
|
||||
import { FormControl, Select, SelectItem, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
@@ -277,7 +278,7 @@ export const IdentityAuthMethodModalContent = ({
|
||||
>
|
||||
{label}{" "}
|
||||
{alreadyConfigured && !isSelectedAuthAlreadyConfigured && (
|
||||
<Badge>Configured</Badge>
|
||||
<Badge variant="info">Configured</Badge>
|
||||
)}
|
||||
</SelectItem>
|
||||
</Tooltip>
|
||||
@@ -291,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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
+25
-13
@@ -22,11 +22,12 @@ import {
|
||||
TextArea,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { useOrganization, useSubscription } from "@app/context";
|
||||
import { useOrganization, useOrgPermission, useSubscription } from "@app/context";
|
||||
import {
|
||||
OrgGatewayPermissionActions,
|
||||
OrgPermissionSubjects
|
||||
} from "@app/context/OrgPermissionContext/types";
|
||||
import { OrgMembershipRole } from "@app/helpers/roles";
|
||||
import {
|
||||
gatewaysQueryKeys,
|
||||
useAddIdentityKubernetesAuth,
|
||||
@@ -129,6 +130,8 @@ export const IdentityKubernetesAuthForm = ({
|
||||
] as const);
|
||||
const { data: vaultConfigs = [] } = useGetVaultExternalMigrationConfigs();
|
||||
const hasVaultConnection = vaultConfigs.some((config) => config.connectionId);
|
||||
const { hasOrgRole } = useOrgPermission();
|
||||
const isOrgAdmin = hasOrgRole(OrgMembershipRole.Admin);
|
||||
|
||||
const {
|
||||
control,
|
||||
@@ -409,20 +412,29 @@ export const IdentityKubernetesAuthForm = ({
|
||||
<FontAwesomeIcon icon={faInfoCircle} className="mt-0.5 text-primary" />
|
||||
<span className="text-mineshaft-200">Load values from HashiCorp Vault</span>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline_bg"
|
||||
size="xs"
|
||||
leftIcon={
|
||||
<img
|
||||
src="/images/integrations/Vault.png"
|
||||
alt="HashiCorp Vault"
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
<Tooltip
|
||||
content={
|
||||
!isOrgAdmin
|
||||
? "Only organization admins can import configurations from HashiCorp Vault"
|
||||
: undefined
|
||||
}
|
||||
onClick={() => handleImportPopUpToggle("importFromVault", true)}
|
||||
>
|
||||
Load from Vault
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline_bg"
|
||||
size="xs"
|
||||
leftIcon={
|
||||
<img
|
||||
src="/images/integrations/Vault.png"
|
||||
alt="HashiCorp Vault"
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
}
|
||||
onClick={() => handleImportPopUpToggle("importFromVault", true)}
|
||||
isDisabled={!isOrgAdmin}
|
||||
>
|
||||
Load from Vault
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex w-full items-center gap-2">
|
||||
|
||||
+8
-2
@@ -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]);
|
||||
|
||||
+14
-39
@@ -1,15 +1,11 @@
|
||||
import {
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faLink,
|
||||
faPlus
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { faLink, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { Button, DeleteActionModal, Modal, ModalContent } from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
OrgPermissionIdentityActions,
|
||||
OrgPermissionSubjects,
|
||||
@@ -113,22 +109,9 @@ export const IdentitySection = withPermission(
|
||||
<div>
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex w-full items-center gap-4">
|
||||
<div className="flex flex-1 items-center gap-1">
|
||||
<div className="flex flex-1 items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Identities</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/identities/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.16rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/identities/machine-identities" />
|
||||
</div>
|
||||
{isSubOrganization && (
|
||||
<OrgPermissionCan
|
||||
@@ -163,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;
|
||||
}
|
||||
@@ -181,22 +164,9 @@ export const IdentitySection = withPermission(
|
||||
{/* Identity Auth Templates Section */}
|
||||
<div className="mt-4 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Identity Auth Templates</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/identities/auth-templates"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.16rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/identities/auth-templates" />
|
||||
</div>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionMachineIdentityAuthTemplateActions.CreateTemplates}
|
||||
@@ -209,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");
|
||||
@@ -279,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>
|
||||
);
|
||||
|
||||
+12
-13
@@ -1,13 +1,13 @@
|
||||
import { useState } from "react";
|
||||
import { faBan, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { BanIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DeleteActionModal,
|
||||
EmailServiceSetupModal,
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
ModalContent,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge, DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
@@ -75,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;
|
||||
}
|
||||
@@ -207,7 +208,10 @@ export const OrgMembersSection = () => {
|
||||
</div>
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Users</p>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Users</p>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/identities/user-identities" />
|
||||
</div>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Member}>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -303,15 +307,10 @@ export const OrgMembersSection = () => {
|
||||
</p>
|
||||
{userId === member.user.id && (
|
||||
<Tooltip content="You cannot remove yourself from this organization">
|
||||
<div className="inline-block">
|
||||
<Badge
|
||||
variant="danger"
|
||||
className="mt-[0.05rem] ml-1 inline-flex w-min items-center gap-1.5 whitespace-nowrap"
|
||||
>
|
||||
<FontAwesomeIcon icon={faBan} />
|
||||
<span>Ignored</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="danger" className="ml-2">
|
||||
<BanIcon />
|
||||
Ignored
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
+11
-10
@@ -11,19 +11,18 @@ import {
|
||||
faMagnifyingGlass,
|
||||
faSearch,
|
||||
faUsers,
|
||||
faUserShield,
|
||||
faUserSlash,
|
||||
faUserXmark
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { UserCogIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { LastLoginSection } from "@app/components/organization/LastLoginSection";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Checkbox,
|
||||
DropdownMenu,
|
||||
@@ -50,6 +49,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
@@ -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;
|
||||
}
|
||||
@@ -519,17 +520,17 @@ export const OrgMembersTable = ({
|
||||
<Td
|
||||
className={twMerge("group max-w-0", isActive ? "" : "text-mineshaft-400")}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="truncate">
|
||||
{name ?? <span className="text-mineshaft-400">Not Set</span>}
|
||||
</p>
|
||||
{u.superAdmin && (
|
||||
<Badge variant="primary" className="ml-2 w-min whitespace-nowrap">
|
||||
<span className="mr-1 hidden xl:inline">Server Admin</span>
|
||||
<Tooltip content="Server Admin">
|
||||
<FontAwesomeIcon className="xl:hidden" icon={faUserShield} />
|
||||
</Tooltip>
|
||||
</Badge>
|
||||
<Tooltip content="Server Admin">
|
||||
<Badge variant="info">
|
||||
<UserCogIcon />
|
||||
<span className="hidden xl:inline">Server Admin</span>
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
{lastLoginAuthMethod && lastLoginTime && (
|
||||
<Tooltip
|
||||
|
||||
+24
-14
@@ -14,13 +14,13 @@ import {
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { ServerIcon, WrenchIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DeleteActionModal,
|
||||
DropdownMenu,
|
||||
@@ -41,13 +41,14 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge, DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
useOrganization,
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { isCustomOrgRole, isCustomProjectRole } from "@app/helpers/roles";
|
||||
import { isCustomOrgRole } from "@app/helpers/roles";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
PreferenceKey,
|
||||
@@ -104,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;
|
||||
}
|
||||
@@ -200,9 +201,12 @@ export const OrgRoleTable = () => {
|
||||
return (
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<p className="text-xl font-medium text-mineshaft-100">
|
||||
{isSubOrganization ? "Sub-" : ""}Organization Roles
|
||||
</p>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">
|
||||
{isSubOrganization ? "Sub-" : ""}Organization Roles
|
||||
</p>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/organization#roles-and-access-control" />
|
||||
</div>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Role}>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -295,17 +299,13 @@ export const OrgRoleTable = () => {
|
||||
}
|
||||
>
|
||||
<Td className="max-w-md">
|
||||
<div className="flex">
|
||||
<div className="flex gap-x-1.5">
|
||||
<p className="overflow-hidden text-ellipsis whitespace-nowrap">{name}</p>
|
||||
{isDefaultOrgRole && (
|
||||
<Tooltip
|
||||
content={`Members joining your organization will be assigned the ${name} role unless otherwise specified.`}
|
||||
>
|
||||
<div>
|
||||
<Badge variant="success" className="ml-1">
|
||||
Default
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="info">Default</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
@@ -314,8 +314,18 @@ export const OrgRoleTable = () => {
|
||||
{slug}
|
||||
</Td>
|
||||
<Td>
|
||||
<Badge className="w-min bg-mineshaft-400/50 whitespace-nowrap text-bunker-200">
|
||||
{isCustomProjectRole(slug) ? "Custom" : "Default"}
|
||||
<Badge variant="ghost">
|
||||
{isCustomOrgRole(slug) ? (
|
||||
<>
|
||||
<WrenchIcon />
|
||||
Custom
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ServerIcon />
|
||||
Platform
|
||||
</>
|
||||
)}
|
||||
</Badge>
|
||||
</Td>
|
||||
<Td>
|
||||
|
||||
+4
-16
@@ -1,6 +1,6 @@
|
||||
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { APP_CONNECTION_MAP } from "@app/helpers/appConnections";
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
|
||||
@@ -29,23 +29,11 @@ export const AppConnectionHeader = ({ app, isConnected, onBack }: Props) => {
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center text-mineshaft-300">
|
||||
<div className="flex items-center gap-x-2 text-mineshaft-300">
|
||||
{appDetails.name}
|
||||
<a
|
||||
<DocumentationLinkBadge
|
||||
href={`https://infisical.com/docs/integrations/app-connections/${app}`}
|
||||
target="_blank"
|
||||
className="mb-1 ml-1"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1 mb-[0.03rem] text-[12px]" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
/>
|
||||
</div>
|
||||
<p className="text-sm leading-4 text-mineshaft-400">
|
||||
{isConnected ? `${appDetails.name} Connection` : `Connect to ${appDetails.name}`}
|
||||
|
||||
+4
-1
@@ -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>
|
||||
);
|
||||
|
||||
+5
-5
@@ -8,18 +8,17 @@ import {
|
||||
faEdit,
|
||||
faEllipsisV,
|
||||
faInfoCircle,
|
||||
faServer,
|
||||
faTable,
|
||||
faTrash
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { Link } from "@tanstack/react-router";
|
||||
import { ServerIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { VariablePermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -29,6 +28,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { OrgPermissionSubjects, ProjectPermissionSub } from "@app/context";
|
||||
import { OrgPermissionAppConnectionActions } from "@app/context/OrgPermissionContext/types";
|
||||
import { ProjectPermissionAppConnectionActions } from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -157,9 +157,9 @@ export const AppConnectionRow = ({
|
||||
{isPlatformManagedCredentials && (
|
||||
<Tooltip side="left" content="This connection's credentials are managed by Infisical.">
|
||||
<div>
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 whitespace-nowrap">
|
||||
<FontAwesomeIcon icon={faServer} />
|
||||
<span>Platform Managed Credentials</span>
|
||||
<Badge variant="info">
|
||||
<ServerIcon />
|
||||
Platform Managed Credentials
|
||||
</Badge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
+3
-17
@@ -2,8 +2,6 @@ import { useMemo, useState } from "react";
|
||||
import {
|
||||
faArrowDown,
|
||||
faArrowUp,
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faCheckCircle,
|
||||
faFilter,
|
||||
faMagnifyingGlass,
|
||||
@@ -34,6 +32,7 @@ import {
|
||||
THead,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { OrgPermissionSubjects, ProjectPermissionSub } from "@app/context";
|
||||
import { OrgPermissionAppConnectionActions } from "@app/context/OrgPermissionContext/types";
|
||||
import { ProjectPermissionAppConnectionActions } from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -212,22 +211,9 @@ export const AppConnectionsTable = ({ projectId, projectType }: Props) => {
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">App Connections</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/integrations/app-connections/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.12rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/integrations/app-connections/overview" />
|
||||
</div>
|
||||
<p className="text-sm text-bunker-300">
|
||||
Create and configure connections with third-party apps for re-use across your project
|
||||
|
||||
@@ -8,7 +8,6 @@ import { AnimatePresence, motion } from "framer-motion";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -20,6 +19,7 @@ import {
|
||||
Select,
|
||||
SelectItem
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useOrganization } from "@app/context";
|
||||
import { useGetUserProjects } from "@app/hooks/api";
|
||||
import {
|
||||
@@ -124,7 +124,7 @@ export const LogsFilter = ({ presets, setFilter, filter, project }: Props) => {
|
||||
<Button variant="outline_bg" colorSchema="primary" className="relative">
|
||||
<FontAwesomeIcon icon={faFilterCircleXmark} />
|
||||
{activeFilterCount > 0 && (
|
||||
<Badge className="absolute right-0 bottom-0" variant="primary">
|
||||
<Badge className="absolute -top-2 -right-2" variant="info">
|
||||
{activeFilterCount}
|
||||
</Badge>
|
||||
)}
|
||||
@@ -137,7 +137,7 @@ export const LogsFilter = ({ presets, setFilter, filter, project }: Props) => {
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<span>Filters</span>
|
||||
<Badge className="px-1.5 py-0.5" variant="primary">
|
||||
<Badge isSquare variant="info">
|
||||
{activeFilterCount}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import ms from "ms";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
OrgPermissionAuditLogsActions,
|
||||
OrgPermissionSubjects,
|
||||
@@ -76,22 +75,9 @@ const LogsSectionComponent = ({
|
||||
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex flex-wrap items-center justify-between gap-y-2">
|
||||
<div>
|
||||
<div className="flex items-center gap-1 whitespace-nowrap">
|
||||
<div className="flex items-center gap-x-2 whitespace-nowrap">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Audit History</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/audit-logs"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.1rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/audit-logs" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2 lg:justify-end">
|
||||
@@ -137,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>
|
||||
@@ -181,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}
|
||||
|
||||
+16
-21
@@ -1,7 +1,8 @@
|
||||
import { faBan, faEye } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faBan } from "@fortawesome/free-solid-svg-icons";
|
||||
import { EyeIcon } from "lucide-react";
|
||||
|
||||
import { Badge, EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useGetIdentityJwtAuth } from "@app/hooks/api";
|
||||
import { IdentityJwtConfigurationType } from "@app/hooks/api/identities/enums";
|
||||
import { IdentityJwtAuthForm } from "@app/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityJwtAuthForm";
|
||||
@@ -78,12 +79,10 @@ export const ViewIdentityJwtAuthContent = ({
|
||||
<p className="rounded-sm bg-mineshaft-600 p-2 break-words">{data.jwksCaCert}</p>
|
||||
}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</IdentityAuthFieldDisplay>
|
||||
@@ -103,12 +102,10 @@ export const ViewIdentityJwtAuthContent = ({
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<div className="inline-block w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Key {index + 1}</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Key {index + 1}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
@@ -138,12 +135,10 @@ export const ViewIdentityJwtAuthContent = ({
|
||||
</pre>
|
||||
}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</IdentityAuthFieldDisplay>
|
||||
|
||||
+12
-15
@@ -1,9 +1,10 @@
|
||||
import { useMemo } from "react";
|
||||
import { faBan, faEye } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faBan } from "@fortawesome/free-solid-svg-icons";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { EyeIcon } from "lucide-react";
|
||||
|
||||
import { Badge, EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { gatewaysQueryKeys, useGetIdentityKubernetesAuth } from "@app/hooks/api";
|
||||
import { IdentityKubernetesAuthForm } from "@app/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityKubernetesAuthForm";
|
||||
|
||||
@@ -89,12 +90,10 @@ export const ViewIdentityKubernetesAuthContent = ({
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<p className="text-base leading-4 text-bunker-400 italic">Not set</p>
|
||||
@@ -122,12 +121,10 @@ export const ViewIdentityKubernetesAuthContent = ({
|
||||
className="max-w-xl p-2"
|
||||
content={<p className="rounded-sm bg-mineshaft-600 p-2 break-words">{data.caCert}</p>}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</IdentityAuthFieldDisplay>
|
||||
|
||||
+12
-15
@@ -1,7 +1,8 @@
|
||||
import { faBan, faEye } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faBan } from "@fortawesome/free-solid-svg-icons";
|
||||
import { EyeIcon } from "lucide-react";
|
||||
|
||||
import { Badge, EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useClearIdentityLdapAuthLockouts, useGetIdentityLdapAuth } from "@app/hooks/api";
|
||||
import { IdentityLdapAuthForm } from "@app/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityLdapAuthForm";
|
||||
import { ViewIdentityContentWrapper } from "@app/pages/organization/IdentityDetailsByIDPage/components/ViewIdentityAuthModal/ViewIdentityContentWrapper";
|
||||
@@ -72,12 +73,10 @@ export const ViewIdentityLdapAuthContent = ({
|
||||
className="max-w-xl p-2"
|
||||
content={<p className="rounded-sm bg-mineshaft-600 p-2 break-words">{data.bindPass}</p>}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</IdentityAuthFieldDisplay>
|
||||
<IdentityAuthFieldDisplay label="Search Base / DN">
|
||||
@@ -95,12 +94,10 @@ export const ViewIdentityLdapAuthContent = ({
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</IdentityAuthFieldDisplay>
|
||||
|
||||
+16
-21
@@ -1,7 +1,8 @@
|
||||
import { faBan, faEye } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faBan } from "@fortawesome/free-solid-svg-icons";
|
||||
import { EyeIcon } from "lucide-react";
|
||||
|
||||
import { Badge, EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useGetIdentityOidcAuth } from "@app/hooks/api";
|
||||
import { IdentityOidcAuthForm } from "@app/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm";
|
||||
import { ViewIdentityContentWrapper } from "@app/pages/organization/IdentityDetailsByIDPage/components/ViewIdentityAuthModal/ViewIdentityContentWrapper";
|
||||
@@ -73,12 +74,10 @@ export const ViewIdentityOidcAuthContent = ({
|
||||
className="max-w-xl p-2"
|
||||
content={<p className="rounded-sm bg-mineshaft-600 p-2 break-words">{data.caCert}</p>}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</IdentityAuthFieldDisplay>
|
||||
@@ -102,12 +101,10 @@ export const ViewIdentityOidcAuthContent = ({
|
||||
</pre>
|
||||
}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</IdentityAuthFieldDisplay>
|
||||
@@ -122,12 +119,10 @@ export const ViewIdentityOidcAuthContent = ({
|
||||
</pre>
|
||||
}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</IdentityAuthFieldDisplay>
|
||||
|
||||
+8
-9
@@ -1,7 +1,8 @@
|
||||
import { faBan, faEye } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faBan } from "@fortawesome/free-solid-svg-icons";
|
||||
import { EyeIcon } from "lucide-react";
|
||||
|
||||
import { Badge, EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { EmptyState, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useGetIdentityTlsCertAuth } from "@app/hooks/api";
|
||||
import { IdentityTlsCertAuthForm } from "@app/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityTlsCertAuthForm";
|
||||
|
||||
@@ -71,12 +72,10 @@ export const ViewIdentityTlsCertAuthContent = ({
|
||||
<p className="rounded-sm bg-mineshaft-600 p-2 break-words">{data.caCertificate}</p>
|
||||
}
|
||||
>
|
||||
<div className="w-min">
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
<span>Reveal</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<EyeIcon />
|
||||
Reveal
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</IdentityAuthFieldDisplay>
|
||||
<IdentityAuthFieldDisplay className="col-span-2" label="Allowed Common Names">
|
||||
|
||||
+3
-17
@@ -1,7 +1,5 @@
|
||||
import { useState } from "react";
|
||||
import {
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faCopy,
|
||||
faDoorClosed,
|
||||
faEdit,
|
||||
@@ -39,6 +37,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
OrgGatewayPermissionActions,
|
||||
OrgPermissionSubjects
|
||||
@@ -106,22 +105,9 @@ export const GatewayTab = withPermission(
|
||||
return (
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<div className="flex grow items-center gap-2">
|
||||
<div className="flex grow items-center gap-x-2">
|
||||
<h3 className="text-lg font-medium text-mineshaft-100">Gateways</h3>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/gateways/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="inline-block rounded-md bg-yellow/20 px-1.5 py-0.5 text-sm font-normal text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/gateways/overview" />
|
||||
<div className="flex grow" />
|
||||
<Button
|
||||
variant="outline_bg"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faCopy,
|
||||
faDoorClosed,
|
||||
faEllipsisV,
|
||||
@@ -37,6 +35,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import {
|
||||
OrgPermissionSubjects,
|
||||
@@ -116,22 +115,9 @@ export const RelayTab = withPermission(
|
||||
return (
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<div className="flex grow items-center gap-2">
|
||||
<div className="flex grow items-center gap-x-2">
|
||||
<h3 className="text-lg font-medium text-mineshaft-100">Relays</h3>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/gateways/relay-deployment"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="inline-block rounded-md bg-yellow/20 px-1.5 py-0.5 text-sm font-normal text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/gateways/relay-deployment" />
|
||||
<div className="flex grow" />
|
||||
<Button
|
||||
variant="outline_bg"
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useState } from "react";
|
||||
import {
|
||||
faArrowDownAZ,
|
||||
faBorderAll,
|
||||
faCheck,
|
||||
faCheckCircle,
|
||||
faFolderOpen,
|
||||
faList,
|
||||
@@ -11,13 +10,13 @@ import {
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { RequestProjectAccessModal } from "@app/components/projects/RequestProjectAccessModal";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -31,6 +30,7 @@ import {
|
||||
Skeleton,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { OrgPermissionAdminConsoleAction } from "@app/context/OrgPermissionContext/types";
|
||||
import { getProjectHomePage, getProjectLottieIcon, getProjectTitle } from "@app/helpers/project";
|
||||
@@ -308,9 +308,9 @@ export const AllProjectView = ({
|
||||
</div>
|
||||
</div>
|
||||
{workspace.isMember ? (
|
||||
<Badge className="flex items-center" variant="success">
|
||||
<FontAwesomeIcon icon={faCheck} className="mr-1" />
|
||||
<span>Joined</span>
|
||||
<Badge variant="info">
|
||||
<CheckIcon />
|
||||
Joined
|
||||
</Badge>
|
||||
) : (
|
||||
<OrgPermissionCan
|
||||
|
||||
+14
-17
@@ -3,7 +3,8 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { format } from "date-fns";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Badge, IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import {
|
||||
SecretSharingAccessType,
|
||||
TSharedSecret,
|
||||
@@ -35,27 +36,23 @@ export const RequestedSecretsRow = ({
|
||||
{isExpired && !row.encryptedSecret ? (
|
||||
<Badge variant="danger">Expired</Badge>
|
||||
) : (
|
||||
<Badge variant={row.encryptedSecret ? "success" : "primary"}>
|
||||
<Badge variant={row.encryptedSecret ? "success" : "warning"}>
|
||||
{row.encryptedSecret ? "Secret Provided" : "Pending Secret"}
|
||||
</Badge>
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
<Badge variant="primary">
|
||||
<Tooltip
|
||||
content={
|
||||
row.accessType === SecretSharingAccessType.Anyone
|
||||
? "Anyone can input the secret."
|
||||
: "Only members of the organization can input the secret."
|
||||
}
|
||||
>
|
||||
<div>
|
||||
{row.accessType === SecretSharingAccessType.Anyone
|
||||
? "Anyone"
|
||||
: "Organization Members"}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Badge>
|
||||
<Tooltip
|
||||
content={
|
||||
row.accessType === SecretSharingAccessType.Anyone
|
||||
? "Anyone can input the secret."
|
||||
: "Only members of the organization can input the secret."
|
||||
}
|
||||
>
|
||||
<Badge variant="info">
|
||||
{row.accessType === SecretSharingAccessType.Anyone ? "Anyone" : "Organization Members"}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</Td>
|
||||
<Td>{`${format(new Date(row.createdAt), "yyyy-MM-dd - HH:mm a")}`}</Td>
|
||||
<Td>{row.expiresAt ? format(new Date(row.expiresAt), "yyyy-MM-dd - HH:mm a") : "-"}</Td>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { format } from "date-fns";
|
||||
|
||||
import { IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v2/Badge";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { TSharedSecret } from "@app/hooks/api/secretSharing";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
|
||||
+4
-1
@@ -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>
|
||||
);
|
||||
|
||||
+3
-14
@@ -1,6 +1,6 @@
|
||||
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { AUDIT_LOG_STREAM_PROVIDER_MAP } from "@app/helpers/auditLogStreams";
|
||||
import { LogProvider } from "@app/hooks/api/auditLogStreams/enums";
|
||||
|
||||
@@ -34,20 +34,9 @@ export const AuditLogStreamHeader = ({ provider, logStreamExists, onBack }: Prop
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<div className="mb-1 flex items-center text-mineshaft-300">
|
||||
<div className="mb-1 flex items-center gap-x-2 text-mineshaft-300">
|
||||
{providerDetails.name}
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/audit-log-streams/audit-log-streams#example-providers"
|
||||
target="_blank"
|
||||
className="ml-1"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1 mb-px text-xs" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="mb-px ml-1 text-[10px]" />
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/audit-log-streams/audit-log-streams#example-providers" />
|
||||
</div>
|
||||
<p className="text-sm leading-4 text-mineshaft-400">
|
||||
{logStreamExists
|
||||
|
||||
+4
-1
@@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
+3
-2
@@ -2,7 +2,8 @@ import { Controller, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Badge, Button, FormControl, Input, Select, SelectItem } from "@app/components/v2";
|
||||
import { Button, FormControl, Input, Select, SelectItem } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useOrganization } from "@app/context";
|
||||
import { useAddExternalKms, useUpdateExternalKms } from "@app/hooks/api";
|
||||
import {
|
||||
@@ -244,7 +245,7 @@ export const AwsKmsForm = ({ onCompleted, onCancel, kms }: Props) => {
|
||||
>
|
||||
{AWS_REGIONS.map((awsRegion) => (
|
||||
<SelectItem value={awsRegion.slug} key={`kms-aws-region-${awsRegion.slug}`}>
|
||||
{awsRegion.name} <Badge variant="success">{awsRegion.slug}</Badge>
|
||||
{awsRegion.name} <Badge variant="neutral">{awsRegion.slug}</Badge>
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
+4
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -3,7 +3,8 @@ import { Controller, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Badge, Button, FilterableSelect, FormControl, Input } from "@app/components/v2";
|
||||
import { Button, FilterableSelect, FormControl, Input } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useOrganization } from "@app/context";
|
||||
import {
|
||||
useAddExternalKms,
|
||||
@@ -71,7 +72,7 @@ const GCP_REGIONS = [
|
||||
const formatOptionLabel = ({ value, label }: { value: string; label: string }) => (
|
||||
<div className="flex w-full flex-row items-center justify-between">
|
||||
<span>{label}</span>
|
||||
<Badge variant="success">{value}</Badge>
|
||||
<Badge variant="neutral">{value}</Badge>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
+4
-1
@@ -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}
|
||||
|
||||
+4
-1
@@ -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>
|
||||
);
|
||||
|
||||
+10
-3
@@ -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>
|
||||
);
|
||||
|
||||
+10
-3
@@ -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>
|
||||
);
|
||||
|
||||
+14
-10
@@ -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
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
+3
-18
@@ -1,5 +1,4 @@
|
||||
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
|
||||
type ProviderDetails = {
|
||||
label: string;
|
||||
@@ -24,23 +23,9 @@ export const SSOModalHeader = ({ providerDetails, isConnected }: Props) => {
|
||||
className="h-12 w-12 rounded-md bg-bunker-500 p-2"
|
||||
/>
|
||||
<div>
|
||||
<div className="flex items-center text-mineshaft-300">
|
||||
<div className="flex items-center gap-x-2 text-mineshaft-300">
|
||||
{providerDetails.label}
|
||||
<a
|
||||
href={`${docsBaseUrl}/${providerDetails.docsUrl}`}
|
||||
target="_blank"
|
||||
className="mb-1 ml-1"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1 mb-[0.03rem] text-[12px]" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href={`${docsBaseUrl}/${providerDetails.docsUrl}`} />
|
||||
</div>
|
||||
<p className="text-sm leading-4 text-mineshaft-400">
|
||||
{isConnected
|
||||
|
||||
+2
-2
@@ -7,7 +7,6 @@ import { twMerge } from "tailwind-merge";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DeleteActionModal,
|
||||
DropdownMenu,
|
||||
@@ -24,6 +23,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
||||
import { withPermission } from "@app/hoc";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
@@ -48,7 +48,7 @@ const renderStatus = (status: WorkflowIntegrationStatus) => {
|
||||
}
|
||||
|
||||
if (status === WorkflowIntegrationStatus.Pending) {
|
||||
return <Badge variant="primary">Pending</Badge>;
|
||||
return <Badge variant="warning">Pending</Badge>;
|
||||
}
|
||||
|
||||
return <Badge variant="danger">Failed</Badge>;
|
||||
|
||||
+8
-17
@@ -1,10 +1,11 @@
|
||||
import { useState } from "react";
|
||||
import { faArrowUpRightFromSquare, faBookOpen, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { Button } from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects, useSubscription } from "@app/context";
|
||||
import { TProjectTemplate } from "@app/hooks/api/projectTemplates";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
@@ -33,22 +34,9 @@ export const ProjectTemplatesSection = () => {
|
||||
project setup
|
||||
</p>
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-start">
|
||||
<div className="mb-4 flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Project Templates</p>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://infisical.com/docs/documentation/platform/project-templates"
|
||||
>
|
||||
<div className="mt-[0.32rem] ml-2 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/project-templates" />
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Create}
|
||||
a={OrgPermissionSubjects.ProjectTemplates}
|
||||
@@ -60,7 +48,9 @@ export const ProjectTemplatesSection = () => {
|
||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||
onClick={() => {
|
||||
if (!subscription?.projectTemplates) {
|
||||
handlePopUpOpen("upgradePlan");
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
isEnterpriseFeature: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -84,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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import { useCallback } from "react";
|
||||
import {
|
||||
faBoxOpen,
|
||||
faCheck,
|
||||
faCopy,
|
||||
faEdit,
|
||||
faEllipsisV,
|
||||
faFolder,
|
||||
faRightToBracket,
|
||||
faRotate,
|
||||
faTrash
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { formatDistance } from "date-fns";
|
||||
import { FolderIcon, PackageOpenIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -29,6 +27,7 @@ import {
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { HighlightText } from "@app/components/v2/HighlightText";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionPamAccountActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { useToggle } from "@app/hooks";
|
||||
@@ -88,15 +87,15 @@ export const PamAccountRow = ({
|
||||
<span>
|
||||
<HighlightText text={name} highlight={search} />
|
||||
</span>
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-bunker-300/20 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faBoxOpen} />
|
||||
<Badge variant="neutral">
|
||||
<PackageOpenIcon />
|
||||
<span>
|
||||
<HighlightText text={account.resource.name} highlight={search} />
|
||||
</span>
|
||||
</Badge>
|
||||
{isFlatView && accountPath && (
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-bunker-300/20 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faFolder} />
|
||||
<Badge variant="neutral">
|
||||
<FolderIcon />
|
||||
<span>
|
||||
<HighlightText text={accountPath} highlight={search} />
|
||||
</span>
|
||||
@@ -108,14 +107,7 @@ export const PamAccountRow = ({
|
||||
isDisabled={!account.lastRotationMessage}
|
||||
content={account.lastRotationMessage}
|
||||
>
|
||||
<Badge
|
||||
className={twMerge(
|
||||
"flex h-5 w-min items-center gap-1.5 whitespace-nowrap",
|
||||
account.rotationStatus === "failed"
|
||||
? "bg-red/20 text-red"
|
||||
: "bg-green/20 text-green"
|
||||
)}
|
||||
>
|
||||
<Badge variant={account.rotationStatus === "failed" ? "danger" : "success"}>
|
||||
<FontAwesomeIcon icon={faRotate} />
|
||||
<span>Rotated {formatDistance(new Date(), account.lastRotatedAt)} ago</span>
|
||||
</Badge>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { Badge } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { PAM_RESOURCE_TYPE_MAP, PamResourceType } from "@app/hooks/api/pam";
|
||||
|
||||
export const PamResourceOption = ({
|
||||
@@ -27,7 +27,7 @@ export const PamResourceOption = ({
|
||||
<>
|
||||
<p className="truncate">{children}</p>
|
||||
<div className="mr-auto ml-2">
|
||||
<Badge className="flex h-5 items-center gap-1 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<Badge variant="neutral">
|
||||
<img
|
||||
alt={`${name} logo`}
|
||||
src={`/images/integrations/${image}`}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -15,6 +14,7 @@ import {
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { HighlightText } from "@app/components/v2/HighlightText";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { PAM_RESOURCE_TYPE_MAP, TPamResource } from "@app/hooks/api/pam";
|
||||
|
||||
@@ -40,7 +40,7 @@ export const PamResourceRow = ({ resource, onUpdate, onDelete, search }: Props)
|
||||
<span>
|
||||
<HighlightText text={name} highlight={search} />
|
||||
</span>
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<Badge variant="neutral">
|
||||
<span>
|
||||
<HighlightText text={resourceTypeName} highlight={search} />
|
||||
</span>
|
||||
|
||||
@@ -54,10 +54,10 @@ export const ResourceTypeSelect = ({ onSelect }: Props) => {
|
||||
|
||||
const handleResourceSelect = (resource: PamResourceType) => {
|
||||
if (!subscription.pam) {
|
||||
handlePopUpOpen(
|
||||
"upgradePlan",
|
||||
"PAM (Privileged Access Management) requires an enterprise plan."
|
||||
);
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
description: "PAM (Privileged Access Management) requires an enterprise plan.",
|
||||
isEnterpriseFeature: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,10 +67,11 @@ export const ResourceTypeSelect = ({ onSelect }: Props) => {
|
||||
resource === PamResourceType.SSH ||
|
||||
resource === PamResourceType.Kubernetes
|
||||
) {
|
||||
handlePopUpOpen(
|
||||
"upgradePlan",
|
||||
"This resource type requires a special license add-on to be enabled in your enterprise plan."
|
||||
);
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
description:
|
||||
"This resource type requires a special license add-on to be enabled in your enterprise plan.",
|
||||
isEnterpriseFeature: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -179,7 +180,8 @@ export const ResourceTypeSelect = ({ onSelect }: Props) => {
|
||||
<UpgradePlanModal
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
text={popUp.upgradePlan.data || ""}
|
||||
text={popUp.upgradePlan.data?.description}
|
||||
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { faBoxOpen, faCheck, faCopy, faUser } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faCheck, faCopy, faUser } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { PackageOpenIcon } from "lucide-react";
|
||||
|
||||
import { Badge, IconButton, Tooltip } from "@app/components/v2";
|
||||
import { IconButton, Tooltip } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useTimedReset } from "@app/hooks";
|
||||
import { PAM_RESOURCE_TYPE_MAP, TPamSession } from "@app/hooks/api/pam";
|
||||
|
||||
@@ -76,8 +78,8 @@ export const PamSessionDetailsSection = ({
|
||||
className="size-4"
|
||||
/>
|
||||
<p>{accountName}</p>
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-yellow/20 whitespace-nowrap text-yellow">
|
||||
<FontAwesomeIcon icon={faBoxOpen} />
|
||||
<Badge variant="neutral">
|
||||
<PackageOpenIcon />
|
||||
{resourceName}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
@@ -1,45 +1,38 @@
|
||||
import {
|
||||
faBan,
|
||||
faCircle,
|
||||
faGavel,
|
||||
faHourglass,
|
||||
IconDefinition
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
ActivityIcon,
|
||||
BanIcon,
|
||||
ChevronsLeftRightEllipsisIcon,
|
||||
GavelIcon,
|
||||
LucideIcon
|
||||
} from "lucide-react";
|
||||
|
||||
import { Badge } from "@app/components/v2";
|
||||
import { Badge, TBadgeProps } from "@app/components/v3";
|
||||
import { PamSessionStatus } from "@app/hooks/api/pam";
|
||||
|
||||
interface StatusConfig {
|
||||
bgColor: string;
|
||||
textColor: string;
|
||||
icon: IconDefinition;
|
||||
iconClassName?: string;
|
||||
variant: TBadgeProps["variant"];
|
||||
icon: LucideIcon;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const PAM_SESSION_STATUS_CONFIG: Record<PamSessionStatus, StatusConfig> = {
|
||||
[PamSessionStatus.Active]: {
|
||||
bgColor: "bg-green/20",
|
||||
textColor: "text-green",
|
||||
icon: faCircle,
|
||||
iconClassName: "size-2 animate-pulse"
|
||||
variant: "success",
|
||||
icon: ActivityIcon,
|
||||
className: "animate-pulse"
|
||||
},
|
||||
[PamSessionStatus.Terminated]: {
|
||||
bgColor: "bg-red/20",
|
||||
textColor: "text-red",
|
||||
icon: faGavel
|
||||
variant: "danger",
|
||||
icon: GavelIcon
|
||||
},
|
||||
[PamSessionStatus.Starting]: {
|
||||
bgColor: "bg-yellow/20",
|
||||
textColor: "text-yellow",
|
||||
icon: faHourglass,
|
||||
iconClassName: "animate-spin"
|
||||
variant: "info",
|
||||
icon: ChevronsLeftRightEllipsisIcon,
|
||||
className: "animate-pulse"
|
||||
},
|
||||
[PamSessionStatus.Ended]: {
|
||||
bgColor: "bg-bunker-300/20",
|
||||
textColor: "text-bunker-300",
|
||||
icon: faBan
|
||||
variant: "neutral",
|
||||
icon: BanIcon
|
||||
}
|
||||
};
|
||||
|
||||
@@ -48,15 +41,11 @@ export const PamSessionStatusBadge = ({ status }: { status: PamSessionStatus })
|
||||
|
||||
const displayName = status[0].toUpperCase() + status.slice(1);
|
||||
|
||||
const Icon = config.icon;
|
||||
|
||||
return (
|
||||
<Badge
|
||||
className={twMerge(
|
||||
"flex h-5 w-min items-center gap-1.5 whitespace-nowrap",
|
||||
config.bgColor,
|
||||
config.textColor
|
||||
)}
|
||||
>
|
||||
<FontAwesomeIcon icon={config.icon} className={config.iconClassName} />
|
||||
<Badge variant={config.variant} className={config.className}>
|
||||
<Icon />
|
||||
{displayName}
|
||||
</Badge>
|
||||
);
|
||||
|
||||
+10
-2
@@ -5,6 +5,7 @@ import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
@@ -33,7 +34,8 @@ export const GroupsSection = () => {
|
||||
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 switch to Infisical's Enterprise plan.",
|
||||
isEnterpriseFeature: true
|
||||
});
|
||||
} else {
|
||||
handlePopUpOpen("group");
|
||||
@@ -68,7 +70,10 @@ export const GroupsSection = () => {
|
||||
return (
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<p className="text-xl font-medium text-mineshaft-100">User Groups</p>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">User Groups</p>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/groups#user-groups" />
|
||||
</div>
|
||||
<ProjectPermissionCan I={ProjectPermissionActions.Create} a={ProjectPermissionSub.Groups}>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -100,6 +105,9 @@ export const GroupsSection = () => {
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
text={(popUp.upgradePlan?.data as { description: string })?.description}
|
||||
isEnterpriseFeature={
|
||||
(popUp.upgradePlan?.data as { isEnterpriseFeature: boolean })?.isEnterpriseFeature
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
+3
-17
@@ -2,8 +2,6 @@ import { subject } from "@casl/ability";
|
||||
import {
|
||||
faArrowDown,
|
||||
faArrowUp,
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faCircleXmark,
|
||||
faClock,
|
||||
faEllipsisV,
|
||||
@@ -44,6 +42,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { getProjectBaseURL } from "@app/helpers/project";
|
||||
import { formatProjectRoleName } from "@app/helpers/roles";
|
||||
@@ -159,22 +158,9 @@ export const IdentityTab = withProjectPermission(
|
||||
return (
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Identities</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/identities/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.16rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/identities/machine-identities" />
|
||||
</div>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
|
||||
+4
-5
@@ -2,7 +2,6 @@ import { useMemo } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { components, OptionProps } from "react-select";
|
||||
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
|
||||
import { faGlobe } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Link } from "@tanstack/react-router";
|
||||
@@ -10,7 +9,6 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
FilterableSelect,
|
||||
FormControl,
|
||||
@@ -19,6 +17,7 @@ import {
|
||||
ModalContent,
|
||||
Spinner
|
||||
} from "@app/components/v2";
|
||||
import { Badge, OrgIcon } from "@app/components/v3";
|
||||
import { useOrganization, useProject } from "@app/context";
|
||||
import {
|
||||
useAddIdentityToWorkspace,
|
||||
@@ -50,9 +49,9 @@ const Option = ({
|
||||
<div className="flex flex-row items-center justify-between">
|
||||
<p className="truncate">{children}</p>
|
||||
{props.data.isManagedByRootOrg && (
|
||||
<Badge variant="org" className="ml-auto cursor-pointer">
|
||||
<FontAwesomeIcon icon={faGlobe} />
|
||||
Managed by Root Org
|
||||
<Badge variant="org" className="ml-auto">
|
||||
<OrgIcon />
|
||||
Organization
|
||||
</Badge>
|
||||
)}
|
||||
{isSelected && (
|
||||
|
||||
+5
-1
@@ -5,6 +5,7 @@ import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
@@ -57,7 +58,10 @@ export const MembersSection = () => {
|
||||
return (
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Users</p>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Users</p>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/identities/user-identities" />
|
||||
</div>
|
||||
<ProjectPermissionCan I={ProjectPermissionActions.Create} a={ProjectPermissionSub.Member}>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
|
||||
+18
-4
@@ -13,12 +13,12 @@ import {
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { ServerIcon, WrenchIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DeleteActionModal,
|
||||
DropdownMenu,
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge, DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { getProjectBaseURL } from "@app/helpers/project";
|
||||
import { isCustomProjectRole } from "@app/helpers/roles";
|
||||
@@ -167,7 +168,10 @@ export const ProjectRoleList = () => {
|
||||
return (
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex justify-between">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Project Roles</p>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Project Roles</p>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/access-controls/role-based-access-controls#project-level-access-controls" />
|
||||
</div>
|
||||
<ProjectPermissionCan I={ProjectPermissionActions.Create} a={ProjectPermissionSub.Role}>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -261,8 +265,18 @@ export const ProjectRoleList = () => {
|
||||
<Td>{name}</Td>
|
||||
<Td>{slug}</Td>
|
||||
<Td>
|
||||
<Badge className="w-min bg-mineshaft-400/50 whitespace-nowrap text-bunker-200">
|
||||
{isCustomProjectRole(slug) ? "Custom" : "Default"}
|
||||
<Badge variant="ghost">
|
||||
{isCustomProjectRole(slug) ? (
|
||||
<>
|
||||
<WrenchIcon />
|
||||
Custom
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ServerIcon />
|
||||
Platform
|
||||
</>
|
||||
)}
|
||||
</Badge>
|
||||
</Td>
|
||||
<Td>
|
||||
|
||||
+4
-16
@@ -1,10 +1,11 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { faArrowUpRightFromSquare, faBookOpen, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { withProjectPermission } from "@app/hoc";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
@@ -50,22 +51,9 @@ export const ServiceTokenSection = withProjectPermission(
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Service Tokens</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/token"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.16rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/token" />
|
||||
</div>
|
||||
<p className="text-sm text-bunker-300">
|
||||
{t("section.token.service-tokens-description")}
|
||||
|
||||
@@ -191,7 +191,7 @@ export const Page = () => {
|
||||
onOpenUpgradeModal={() =>
|
||||
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."
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
+2
-4
@@ -60,7 +60,7 @@ type TRoleForm = z.infer<typeof roleFormSchema>;
|
||||
|
||||
type Props = {
|
||||
projectMember: TWorkspaceUser;
|
||||
onOpenUpgradeModal: (title: string) => void;
|
||||
onOpenUpgradeModal: () => void;
|
||||
};
|
||||
|
||||
export const MemberRoleModify = ({ projectMember, onOpenUpgradeModal }: Props) => {
|
||||
@@ -122,9 +122,7 @@ export const MemberRoleModify = ({ projectMember, onOpenUpgradeModal }: Props) =
|
||||
);
|
||||
|
||||
if (hasCustomRoleSelected && subscription && !subscription?.rbac) {
|
||||
onOpenUpgradeModal(
|
||||
"You can assign custom roles to members if you upgrade your Infisical plan."
|
||||
);
|
||||
onOpenUpgradeModal();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -42,7 +42,8 @@ export const AuditLogsRetentionSection = () => {
|
||||
try {
|
||||
if (!subscription?.auditLogs) {
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
description: "You can only configure audit logs retention if you upgrade your plan."
|
||||
description:
|
||||
"You can only configure audit logs retention if you switch to Infisical's Pro plan."
|
||||
});
|
||||
|
||||
return;
|
||||
@@ -51,7 +52,7 @@ export const AuditLogsRetentionSection = () => {
|
||||
if (subscription && auditLogsRetentionDays > subscription?.auditLogsRetentionDays) {
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
description:
|
||||
"To update your audit logs retention period to a higher value, upgrade your plan."
|
||||
"To update your audit logs retention period to a higher value, switch to Infisical's Pro plan."
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
+3
-2
@@ -14,7 +14,8 @@ import { format } from "date-fns";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Badge, IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { TCloudIntegration } from "@app/hooks/api/integrations/types";
|
||||
import { TIntegration } from "@app/hooks/api/types";
|
||||
@@ -103,7 +104,7 @@ export const IntegrationRow = ({
|
||||
<Td>
|
||||
{" "}
|
||||
{typeof integration.isSynced !== "boolean" ? (
|
||||
<Badge variant="primary" key={integration.id}>
|
||||
<Badge variant="info" key={integration.id}>
|
||||
Pending Sync
|
||||
</Badge>
|
||||
) : (
|
||||
|
||||
+7
-12
@@ -13,12 +13,12 @@ import {
|
||||
faToggleOff,
|
||||
faToggleOn,
|
||||
faTrash,
|
||||
faTriangleExclamation,
|
||||
faXmark
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { format } from "date-fns";
|
||||
import { AlertTriangleIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
SecretSyncStatusBadge
|
||||
} from "@app/components/secret-syncs";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -39,6 +38,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -173,15 +173,10 @@ export const SecretSyncRow = ({
|
||||
) : (
|
||||
<Td>
|
||||
<Tooltip content="The source location for this sync has been deleted. Configure a new source or remove this sync.">
|
||||
<div className="w-min">
|
||||
<Badge
|
||||
className="flex h-5 w-min items-center gap-1.5 whitespace-nowrap"
|
||||
variant="primary"
|
||||
>
|
||||
<FontAwesomeIcon icon={faTriangleExclamation} />
|
||||
<span>Source Folder Deleted</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="danger">
|
||||
<AlertTriangleIcon />
|
||||
<span>Source Folder Deleted</span>
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</Td>
|
||||
)}
|
||||
@@ -237,7 +232,7 @@ export const SecretSyncRow = ({
|
||||
content="Auto-Sync is disabled. Changes to the source location will not be automatically synced to the destination."
|
||||
>
|
||||
<div>
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<Badge variant="neutral">
|
||||
<FontAwesomeIcon icon={faBan} />
|
||||
{!syncStatus && "Auto-Sync Disabled"}
|
||||
</Badge>
|
||||
|
||||
+4
-16
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { faArrowUpRightFromSquare, faBookOpen, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { CreateSecretSyncModal } from "@app/components/secret-syncs";
|
||||
import { TSecretSyncForm } from "@app/components/secret-syncs/forms/schemas";
|
||||
import { Button, Spinner } from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -91,22 +92,9 @@ export const SecretSyncsTab = () => {
|
||||
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-start gap-1">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<p className="text-lg font-medium text-mineshaft-100">Secret Syncs</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/integrations/secret-syncs/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.32rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/integrations/secret-syncs/overview" />
|
||||
</div>
|
||||
<p className="text-sm text-bunker-300">
|
||||
Use App Connections to sync secrets to third-party services.
|
||||
|
||||
@@ -277,7 +277,11 @@ export const OverviewPage = () => {
|
||||
});
|
||||
|
||||
const isFilteredByResources = Object.values(filter).some(Boolean);
|
||||
const { isPending: isOverviewLoading, data: overview } = useGetProjectSecretsOverview(
|
||||
const {
|
||||
isPending: isOverviewLoading,
|
||||
data: overview,
|
||||
isFetching: isOverviewFetching
|
||||
} = useGetProjectSecretsOverview(
|
||||
{
|
||||
projectId,
|
||||
environments: visibleEnvs.map((env) => env.slug),
|
||||
@@ -631,6 +635,8 @@ export const OverviewPage = () => {
|
||||
};
|
||||
|
||||
const handleFolderClick = (path: string) => {
|
||||
if (isOverviewFetching) return;
|
||||
|
||||
// store for breadcrumb nav to restore previously used filters
|
||||
setFilterHistory((prev) => {
|
||||
const curr = new Map(prev);
|
||||
@@ -1173,7 +1179,9 @@ export const OverviewPage = () => {
|
||||
return;
|
||||
}
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
isEnterpriseFeature: true
|
||||
isEnterpriseFeature: true,
|
||||
description:
|
||||
"You can add dynamic secrets if you switch to Infisical's Enterprise plan."
|
||||
});
|
||||
}}
|
||||
isDisabled={userAvailableDynamicSecretEnvs.length === 0}
|
||||
@@ -1197,7 +1205,10 @@ export const OverviewPage = () => {
|
||||
handlePopUpClose("misc");
|
||||
return;
|
||||
}
|
||||
handlePopUpOpen("upgradePlan");
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
description:
|
||||
"You can add secret rotations if you switch to Infisical's Pro plan."
|
||||
});
|
||||
}}
|
||||
isDisabled={userAvailableSecretRotationEnvs.length === 0}
|
||||
variant="outline_bg"
|
||||
@@ -1682,11 +1693,7 @@ export const OverviewPage = () => {
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
|
||||
text={
|
||||
subscription.slug === null
|
||||
? "You can perform this action under an Enterprise license"
|
||||
: "You can perform this action if you switch to Infisical's Enterprise plan"
|
||||
}
|
||||
text={popUp.upgradePlan.data?.description}
|
||||
/>
|
||||
)}
|
||||
<CreateSecretRotationV2Modal
|
||||
|
||||
+7
-10
@@ -11,11 +11,13 @@ import {
|
||||
faXmark
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { SecretRotationV2StatusBadge } from "@app/components/secret-rotations-v2/SecretRotationV2StatusBadge";
|
||||
import { Badge, IconButton, TableContainer, Tag, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { IconButton, TableContainer, Tag, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionSecretRotationActions,
|
||||
ProjectPermissionSub
|
||||
@@ -70,15 +72,10 @@ export const SecretOverviewSecretRotationRow = ({
|
||||
<div className="flex-1">{secretRotationName}</div>
|
||||
{statuses?.some((status) => status === SecretRotationStatus.Failed) && (
|
||||
<Tooltip className="max-w-sm" content="One or more secrets failed to rotate.">
|
||||
<div>
|
||||
<Badge
|
||||
variant="danger"
|
||||
className="flex h-5 w-min items-center gap-1 whitespace-nowrap"
|
||||
>
|
||||
<FontAwesomeIcon icon={faXmark} />
|
||||
<span>Rotation Failed</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="danger">
|
||||
<XIcon />
|
||||
Rotation Failed
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
+8
-9
@@ -1,20 +1,18 @@
|
||||
import {
|
||||
faCheck,
|
||||
faChevronRight,
|
||||
faCode,
|
||||
faCopy,
|
||||
faEye,
|
||||
faFolder,
|
||||
faKey,
|
||||
faTags
|
||||
faKey
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { CurlyBracesIcon, TagsIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
@@ -25,6 +23,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useProject } from "@app/context";
|
||||
import { reverseTruncate } from "@app/helpers/reverseTruncate";
|
||||
import { useTimedReset } from "@app/hooks";
|
||||
@@ -135,15 +134,15 @@ export const QuickSearchSecretItem = ({
|
||||
<Td>
|
||||
<div className="flex w-full items-center justify-end gap-4">
|
||||
{tagMatch && (
|
||||
<Badge variant="primary" className="flex items-center gap-1 whitespace-nowrap">
|
||||
<FontAwesomeIcon size="xs" icon={faTags} />
|
||||
<Badge variant="neutral">
|
||||
<TagsIcon />
|
||||
{tagMatch.slug}
|
||||
</Badge>
|
||||
)}
|
||||
{metadataMatch && !tagMatch && (
|
||||
<Badge variant="primary" className="flex items-center gap-1 whitespace-nowrap">
|
||||
<FontAwesomeIcon size="xs" icon={faCode} />
|
||||
<p className="truncate">Metadata Match</p>
|
||||
<Badge variant="neutral">
|
||||
<CurlyBracesIcon />
|
||||
Metadata
|
||||
</Badge>
|
||||
)}
|
||||
{isSingleEnv ? (
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Helmet } from "react-helmet";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v2/Badge";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { useProject } from "@app/context";
|
||||
import { useGetAccessRequestsCount, useGetSecretApprovalRequestCount } from "@app/hooks/api";
|
||||
import { ProjectType } from "@app/hooks/api/projects/types";
|
||||
@@ -50,13 +50,17 @@ export const SecretApprovalsPage = () => {
|
||||
<Tab variant="project" value={TabSection.SecretApprovalRequests}>
|
||||
Change Requests
|
||||
{Boolean(secretApprovalReqCount?.open) && (
|
||||
<Badge className="ml-2">{secretApprovalReqCount?.open}</Badge>
|
||||
<Badge variant="warning" isSquare className="ml-2">
|
||||
{secretApprovalReqCount?.open}
|
||||
</Badge>
|
||||
)}
|
||||
</Tab>
|
||||
<Tab variant="project" value={TabSection.ResourceApprovalRequests}>
|
||||
Access Requests
|
||||
{Boolean(accessApprovalRequestCount?.pendingCount) && (
|
||||
<Badge className="ml-2">{accessApprovalRequestCount?.pendingCount}</Badge>
|
||||
<Badge variant="warning" isSquare className="ml-2">
|
||||
{accessApprovalRequestCount?.pendingCount}
|
||||
</Badge>
|
||||
)}
|
||||
</Tab>
|
||||
<Tab variant="project" value={TabSection.Policies}>
|
||||
|
||||
+28
-48
@@ -2,23 +2,18 @@
|
||||
/* eslint-disable react/jsx-no-useless-fragment */
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import {
|
||||
faArrowUpRightFromSquare,
|
||||
faBan,
|
||||
faBookOpen,
|
||||
faCheck,
|
||||
faCheckCircle,
|
||||
faChevronDown,
|
||||
faClipboardCheck,
|
||||
faLock,
|
||||
faMagnifyingGlass,
|
||||
faPlus,
|
||||
faSearch,
|
||||
faStopwatch,
|
||||
faUser,
|
||||
IconDefinition
|
||||
faUser
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { format, formatDistance } from "date-fns";
|
||||
import { BanIcon, CheckIcon, ClipboardCheckIcon, LucideIcon, TimerIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
@@ -34,7 +29,7 @@ import {
|
||||
Pagination,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v2/Badge";
|
||||
import { Badge, DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionMemberActions,
|
||||
ProjectPermissionSub,
|
||||
@@ -207,12 +202,12 @@ export const AccessApprovalRequest = ({
|
||||
|
||||
let displayData: {
|
||||
label: string;
|
||||
type: "primary" | "danger" | "success";
|
||||
type: "warning" | "danger" | "success";
|
||||
tooltipContent?: string;
|
||||
icon: IconDefinition | null;
|
||||
icon: LucideIcon | null;
|
||||
} = {
|
||||
label: "",
|
||||
type: "primary",
|
||||
type: "warning",
|
||||
icon: null
|
||||
};
|
||||
|
||||
@@ -225,7 +220,7 @@ export const AccessApprovalRequest = ({
|
||||
displayData = {
|
||||
label: "Access Expired",
|
||||
type: "danger",
|
||||
icon: faStopwatch,
|
||||
icon: TimerIcon,
|
||||
tooltipContent: request.privilege?.temporaryAccessEndTime
|
||||
? `Expired ${format(request.privilege.temporaryAccessEndTime, "M/d/yyyy h:mm aa")}`
|
||||
: undefined
|
||||
@@ -234,27 +229,27 @@ export const AccessApprovalRequest = ({
|
||||
displayData = {
|
||||
label: "Access Granted",
|
||||
type: "success",
|
||||
icon: faCheck,
|
||||
icon: CheckIcon,
|
||||
tooltipContent: `Granted ${format(request.updatedAt, "M/d/yyyy h:mm aa")}`
|
||||
};
|
||||
else if (isRejectedByAnyone)
|
||||
displayData = {
|
||||
label: "Rejected",
|
||||
type: "danger",
|
||||
icon: faBan,
|
||||
icon: BanIcon,
|
||||
tooltipContent: `Rejected ${format(request.updatedAt, "M/d/yyyy h:mm aa")}`
|
||||
};
|
||||
else if (userReviewStatus === ApprovalStatus.APPROVED) {
|
||||
displayData = {
|
||||
label: "Pending Additional Reviews",
|
||||
type: "primary",
|
||||
icon: faClipboardCheck
|
||||
type: "warning",
|
||||
icon: ClipboardCheckIcon
|
||||
};
|
||||
} else if (!isReviewedByUser)
|
||||
displayData = {
|
||||
label: "Review Required",
|
||||
type: "primary",
|
||||
icon: faClipboardCheck
|
||||
type: "warning",
|
||||
icon: ClipboardCheckIcon
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -301,22 +296,9 @@ export const AccessApprovalRequest = ({
|
||||
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-start gap-1">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Access Requests</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/access-controls/access-requests"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.32rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/access-controls/access-requests" />
|
||||
</div>
|
||||
<p className="text-sm text-bunker-300">
|
||||
Request and review access to secrets in sensitive environments and folders
|
||||
@@ -329,7 +311,10 @@ export const AccessApprovalRequest = ({
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (subscription && !subscription?.secretApproval) {
|
||||
handlePopUpOpen("upgradePlan");
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
description:
|
||||
"You can use request access feature if you switch to Infisical's Pro plan."
|
||||
});
|
||||
return;
|
||||
}
|
||||
handlePopUpOpen("requestAccess");
|
||||
@@ -473,6 +458,8 @@ export const AccessApprovalRequest = ({
|
||||
filteredRequests?.slice(offset, perPage * page).map((request) => {
|
||||
const details = generateRequestDetails(request);
|
||||
|
||||
const StatusIcon = details.displayData.icon;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={request.id}
|
||||
@@ -486,7 +473,7 @@ export const AccessApprovalRequest = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex flex-1 items-center justify-between">
|
||||
<div className="flex w-full flex-col justify-between">
|
||||
<div className="mb-1 flex w-full items-center">
|
||||
<FontAwesomeIcon
|
||||
@@ -510,7 +497,7 @@ export const AccessApprovalRequest = ({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex shrink-0 items-center gap-3">
|
||||
{request.requestedByUserId === user.id && (
|
||||
<div className="flex items-center gap-1.5 text-xs whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faUser} size="sm" />
|
||||
@@ -518,17 +505,10 @@ export const AccessApprovalRequest = ({
|
||||
</div>
|
||||
)}
|
||||
<Tooltip content={details.displayData.tooltipContent}>
|
||||
<div>
|
||||
<Badge
|
||||
className="flex items-center gap-1.5 whitespace-nowrap"
|
||||
variant={details.displayData.type}
|
||||
>
|
||||
{details.displayData.icon && (
|
||||
<FontAwesomeIcon icon={details.displayData.icon} />
|
||||
)}
|
||||
<span>{details.displayData.label}</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant={details.displayData.type}>
|
||||
{StatusIcon && <StatusIcon />}
|
||||
{details.displayData.label}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
@@ -593,7 +573,7 @@ export const AccessApprovalRequest = ({
|
||||
)}
|
||||
|
||||
<UpgradePlanModal
|
||||
text="You need to upgrade your plan to access this feature"
|
||||
text={popUp.upgradePlan.data?.description}
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={() => handlePopUpClose("upgradePlan")}
|
||||
/>
|
||||
|
||||
+19
-37
@@ -9,6 +9,7 @@ import {
|
||||
faUserSlash
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { BanIcon, CheckIcon, HourglassIcon } from "lucide-react";
|
||||
import ms from "ms";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
@@ -24,7 +25,7 @@ import {
|
||||
ModalContent,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v2/Badge";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionActions, useProject, useUser } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useListWorkspaceGroups, useReviewAccessRequest } from "@app/hooks/api";
|
||||
@@ -42,13 +43,13 @@ import { EditAccessRequestModal } from "@app/pages/secret-manager/SecretApproval
|
||||
const getReviewedStatusSymbol = (status?: ApprovalStatus, isOrgMembershipActive?: boolean) => {
|
||||
if (status === ApprovalStatus.APPROVED)
|
||||
return (
|
||||
<Badge variant="success" className="flex h-4 items-center justify-center">
|
||||
<Badge variant="success">
|
||||
<FontAwesomeIcon icon={faCheck} size="xs" />
|
||||
</Badge>
|
||||
);
|
||||
if (status === ApprovalStatus.REJECTED)
|
||||
return (
|
||||
<Badge variant="danger" className="flex h-4 items-center justify-center">
|
||||
<Badge variant="danger">
|
||||
<FontAwesomeIcon icon={faBan} size="xs" />
|
||||
</Badge>
|
||||
);
|
||||
@@ -58,13 +59,13 @@ const getReviewedStatusSymbol = (status?: ApprovalStatus, isOrgMembershipActive?
|
||||
// Can't do a tooltip here because nested tooltips doesn't work properly as of yet.
|
||||
// TODO(daniel): Fix nested tooltips in the future.
|
||||
|
||||
<Badge className="flex h-4 items-center justify-center bg-mineshaft-400/50 text-bunker-300">
|
||||
<Badge variant="neutral">
|
||||
<FontAwesomeIcon size="xs" icon={faUserSlash} />
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Badge variant="primary" className="flex h-4 items-center justify-center">
|
||||
<Badge variant="warning">
|
||||
<FontAwesomeIcon icon={faHourglass} size="xs" />
|
||||
</Badge>
|
||||
);
|
||||
@@ -346,9 +347,7 @@ export const ReviewAccessRequestModal = ({
|
||||
<span>Approvers</span>
|
||||
{approverSequence.isMyReviewInThisSequence &&
|
||||
request.status === ApprovalStatus.PENDING && (
|
||||
<Badge variant="primary" className="h-min">
|
||||
Awaiting Your Review
|
||||
</Badge>
|
||||
<Badge variant="warning">Awaiting Your Review</Badge>
|
||||
)}
|
||||
</div>
|
||||
<div className="max-h-[40vh] thin-scrollbar overflow-y-auto rounded-sm py-2">
|
||||
@@ -364,43 +363,28 @@ export const ReviewAccessRequestModal = ({
|
||||
let BadgeComponent: ReactNode = null;
|
||||
if (approver.hasRejected) {
|
||||
StepComponent = (
|
||||
<Badge
|
||||
variant="danger"
|
||||
className="flex h-6 min-w-6 items-center justify-center"
|
||||
>
|
||||
<FontAwesomeIcon icon={faBan} />
|
||||
<Badge isSquare variant="danger">
|
||||
<BanIcon />
|
||||
</Badge>
|
||||
);
|
||||
BadgeComponent = <Badge variant="danger">Rejected</Badge>;
|
||||
} else if (approver.hasApproved) {
|
||||
StepComponent = (
|
||||
<Badge
|
||||
variant="success"
|
||||
className="flex h-6 min-w-6 items-center justify-center"
|
||||
>
|
||||
<FontAwesomeIcon icon={faCheck} />
|
||||
<Badge isSquare variant="success">
|
||||
<CheckIcon />
|
||||
</Badge>
|
||||
);
|
||||
BadgeComponent = <Badge variant="success">Approved</Badge>;
|
||||
} else if (isPending) {
|
||||
StepComponent = (
|
||||
<Badge
|
||||
variant="primary"
|
||||
className="flex h-6 min-w-6 items-center justify-center"
|
||||
>
|
||||
<FontAwesomeIcon icon={faHourglass} />
|
||||
<Badge isSquare variant="warning">
|
||||
<HourglassIcon />
|
||||
</Badge>
|
||||
);
|
||||
BadgeComponent = <Badge variant="primary">Pending</Badge>;
|
||||
BadgeComponent = <Badge variant="warning">Pending</Badge>;
|
||||
} else {
|
||||
StepComponent = (
|
||||
<Badge
|
||||
className={
|
||||
isInactive
|
||||
? "py-auto my-auto flex h-6 min-w-6 items-center justify-center gap-1.5 bg-mineshaft-400/50 text-center whitespace-nowrap text-bunker-200"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
<Badge isSquare variant="neutral">
|
||||
<span>{index + 1}</span>
|
||||
</Badge>
|
||||
);
|
||||
@@ -447,12 +431,10 @@ export const ReviewAccessRequestModal = ({
|
||||
{member.user.username}
|
||||
<span className="text-xs">
|
||||
<Tooltip content="This user has been deactivated and no longer has an active organization membership.">
|
||||
<div>
|
||||
<Badge className="pointer-events-none mr-auto ml-1 flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faBan} />
|
||||
Inactive
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge variant="neutral">
|
||||
<BanIcon />
|
||||
Inactive
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
+4
-18
@@ -2,8 +2,6 @@ import { useMemo, useState } from "react";
|
||||
import {
|
||||
faArrowDown,
|
||||
faArrowUp,
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faCheckCircle,
|
||||
faFileShield,
|
||||
faFilter,
|
||||
@@ -36,6 +34,7 @@ import {
|
||||
THead,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionSub,
|
||||
TProjectPermission,
|
||||
@@ -243,22 +242,9 @@ export const ApprovalPolicyList = ({ projectId }: IProps) => {
|
||||
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-start gap-1">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Policies</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/pr-workflows"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.32rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/pr-workflows" />
|
||||
</div>
|
||||
<p className="text-sm text-bunker-300">
|
||||
Implement granular policies for access requests and secrets management
|
||||
@@ -505,7 +491,7 @@ export const ApprovalPolicyList = ({ projectId }: IProps) => {
|
||||
<UpgradePlanModal
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
text="You can add secret approval policy if you switch to Infisical's Enterprise plan."
|
||||
text="You can add secret approval policy if you switch to Infisical's Pro plan."
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
+9
-12
@@ -1,6 +1,5 @@
|
||||
import { useMemo } from "react";
|
||||
import {
|
||||
faBan,
|
||||
faClipboardCheck,
|
||||
faEdit,
|
||||
faEllipsisV,
|
||||
@@ -9,6 +8,7 @@ import {
|
||||
faUserGroup
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { BanIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v2/Badge";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { getMemberLabel } from "@app/helpers/members";
|
||||
@@ -100,6 +100,8 @@ export const ApprovalPolicyRow = ({
|
||||
});
|
||||
}, [policy, members, groups]);
|
||||
|
||||
const { variant, Icon } = policyDetails[policy.policyType];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tr
|
||||
@@ -116,13 +118,8 @@ export const ApprovalPolicyRow = ({
|
||||
<Td>{policy.environments.map((env) => env.name).join(", ")}</Td>
|
||||
<Td>{policy.secretPath || "*"}</Td>
|
||||
<Td>
|
||||
<Badge
|
||||
className={twMerge(
|
||||
policyDetails[policy.policyType].className,
|
||||
"flex w-min items-center gap-1.5 whitespace-nowrap"
|
||||
)}
|
||||
>
|
||||
<FontAwesomeIcon icon={policyDetails[policy.policyType].icon} />
|
||||
<Badge variant={variant}>
|
||||
<Icon />
|
||||
<span>{policyDetails[policy.policyType].name}</span>
|
||||
</Badge>
|
||||
</Td>
|
||||
@@ -196,7 +193,7 @@ export const ApprovalPolicyRow = ({
|
||||
className={twMerge("grow border-mineshaft-600", index !== 0 && "border-r")}
|
||||
/>
|
||||
{labels.length > 1 && (
|
||||
<Badge className="my-auto flex h-5 w-min min-w-5 items-center justify-center gap-1.5 bg-mineshaft-400/50 text-center whitespace-nowrap text-bunker-200">
|
||||
<Badge variant="neutral">
|
||||
<span>{index + 1}</span>
|
||||
</Badge>
|
||||
)}
|
||||
@@ -225,8 +222,8 @@ export const ApprovalPolicyRow = ({
|
||||
<span className="text-xs">
|
||||
<Tooltip content="This user has been deactivated and no longer has an active organization membership.">
|
||||
<div>
|
||||
<Badge className="pointer-events-none mr-auto ml-1 flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faBan} />
|
||||
<Badge variant="neutral">
|
||||
<BanIcon />
|
||||
Inactive
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
import { components, OptionProps } from "react-select";
|
||||
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
|
||||
import { faBan } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { BanIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { Badge } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import { BypasserType } from "@app/hooks/api/accessApproval/types";
|
||||
import { ApproverType } from "@app/hooks/api/secretApproval/types";
|
||||
|
||||
@@ -26,8 +26,8 @@ export const PolicyMemberOption = ({
|
||||
{children}
|
||||
</p>
|
||||
{!props.data.isOrgMembershipActive && (
|
||||
<Badge className="pointer-events-none mr-auto ml-1 flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
|
||||
<FontAwesomeIcon icon={faBan} />
|
||||
<Badge className="ml-auto" variant="neutral">
|
||||
<BanIcon />
|
||||
Inactive
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
+17
-27
@@ -1,23 +1,19 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faCheck,
|
||||
faCheckCircle,
|
||||
faChevronDown,
|
||||
faCodeBranch,
|
||||
faCodeMerge,
|
||||
faMagnifyingGlass,
|
||||
faSearch,
|
||||
faXmark
|
||||
faSearch
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useSearch } from "@tanstack/react-router";
|
||||
import { format, formatDistance } from "date-fns";
|
||||
import { GitMergeIcon, XIcon } from "lucide-react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -30,6 +26,7 @@ import {
|
||||
Skeleton,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge, DocumentationLinkBadge } from "@app/components/v3";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import {
|
||||
ProjectPermissionMemberActions,
|
||||
@@ -139,22 +136,9 @@ export const SecretApprovalRequest = () => {
|
||||
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-start gap-1">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<p className="text-xl font-medium text-mineshaft-100">Change Requests</p>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/pr-workflows"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="mt-[0.32rem] ml-1 inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/pr-workflows" />
|
||||
</div>
|
||||
<p className="text-sm text-bunker-300">Review pending and closed change requests</p>
|
||||
</div>
|
||||
@@ -329,12 +313,18 @@ export const SecretApprovalRequest = () => {
|
||||
{status === "close" && (
|
||||
<Tooltip content={updatedAt ? format(new Date(updatedAt), "M/dd/yyyy h:mm a") : ""}>
|
||||
<div className="my-auto ml-auto">
|
||||
<Badge
|
||||
variant={hasMerged ? "success" : "danger"}
|
||||
className="flex h-min items-center gap-1"
|
||||
>
|
||||
<FontAwesomeIcon icon={hasMerged ? faCodeMerge : faXmark} />
|
||||
{hasMerged ? "Merged" : "Rejected"}
|
||||
<Badge variant={hasMerged ? "success" : "danger"}>
|
||||
{hasMerged ? (
|
||||
<>
|
||||
<GitMergeIcon />
|
||||
Merged
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<XIcon />
|
||||
Rejected
|
||||
</>
|
||||
)}
|
||||
</Badge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
+46
-29
@@ -33,7 +33,6 @@ import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { CreateSecretRotationV2Modal } from "@app/components/secret-rotations-v2";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
DeleteActionModal,
|
||||
DropdownMenu,
|
||||
@@ -51,10 +50,12 @@ import {
|
||||
ModalContent,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v3";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionDynamicSecretActions,
|
||||
ProjectPermissionSub,
|
||||
useOrgPermission,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useSubscription
|
||||
@@ -64,6 +65,7 @@ import {
|
||||
ProjectPermissionSecretActions,
|
||||
ProjectPermissionSecretRotationActions
|
||||
} from "@app/context/ProjectPermissionContext/types";
|
||||
import { OrgMembershipRole } from "@app/helpers/roles";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import {
|
||||
useCreateFolder,
|
||||
@@ -203,6 +205,8 @@ export const ActionBar = ({
|
||||
const { permission } = useProjectPermission();
|
||||
const { data: vaultConfigs = [] } = useGetVaultExternalMigrationConfigs();
|
||||
const hasVaultConnection = vaultConfigs.some((config) => config.connectionId);
|
||||
const { hasOrgRole } = useOrgPermission();
|
||||
const isOrgAdmin = hasOrgRole(OrgMembershipRole.Admin);
|
||||
|
||||
const handleFolderCreate = async (folderName: string, description: string | null) => {
|
||||
try {
|
||||
@@ -825,7 +829,9 @@ export const ActionBar = ({
|
||||
>
|
||||
<div className="flex w-full justify-between">
|
||||
<span>Tags</span>
|
||||
{Boolean(filteredTags) && <Badge>{filteredTags} Applied</Badge>}
|
||||
{Boolean(filteredTags) && (
|
||||
<Badge variant="info">{filteredTags} Applied</Badge>
|
||||
)}
|
||||
</div>
|
||||
</DropdownSubMenuTrigger>
|
||||
<DropdownSubMenuContent className="max-h-80 thin-scrollbar overflow-y-auto rounded-l-none">
|
||||
@@ -905,7 +911,9 @@ export const ActionBar = ({
|
||||
return;
|
||||
}
|
||||
|
||||
handlePopUpOpen("upgradePlan");
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
feature: "PIT Recovery"
|
||||
});
|
||||
}}
|
||||
leftIcon={<FontAwesomeIcon icon={faCodeCommit} />}
|
||||
isLoading={isSnapshotCountLoading}
|
||||
@@ -1020,6 +1028,7 @@ export const ActionBar = ({
|
||||
return;
|
||||
}
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
feature: "Dynamic Secrets",
|
||||
isEnterpriseFeature: true
|
||||
});
|
||||
}}
|
||||
@@ -1048,7 +1057,9 @@ export const ActionBar = ({
|
||||
handlePopUpClose("misc");
|
||||
return;
|
||||
}
|
||||
handlePopUpOpen("upgradePlan");
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
feature: "Secret Rotation"
|
||||
});
|
||||
}}
|
||||
variant="outline_bg"
|
||||
className="h-10 text-left"
|
||||
@@ -1116,25 +1127,33 @@ export const ActionBar = ({
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
leftIcon={
|
||||
<img
|
||||
src="/images/integrations/Vault.png"
|
||||
alt="HashiCorp Vault"
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
<Tooltip
|
||||
content={
|
||||
!isOrgAdmin
|
||||
? "Only organization admins can import secrets from HashiCorp Vault"
|
||||
: undefined
|
||||
}
|
||||
onClick={() => {
|
||||
handlePopUpOpen("importFromVault");
|
||||
handlePopUpClose("misc");
|
||||
}}
|
||||
isDisabled={!isAllowed}
|
||||
variant="outline_bg"
|
||||
className="h-10 text-left"
|
||||
isFullWidth
|
||||
>
|
||||
Add from HashiCorp Vault
|
||||
</Button>
|
||||
<Button
|
||||
leftIcon={
|
||||
<img
|
||||
src="/images/integrations/Vault.png"
|
||||
alt="HashiCorp Vault"
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
handlePopUpOpen("importFromVault");
|
||||
handlePopUpClose("misc");
|
||||
}}
|
||||
isDisabled={!isAllowed || !isOrgAdmin}
|
||||
variant="outline_bg"
|
||||
className="h-10 text-left"
|
||||
isFullWidth
|
||||
>
|
||||
Add from HashiCorp Vault
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</ProjectPermissionCan>
|
||||
)}
|
||||
@@ -1214,7 +1233,11 @@ export const ActionBar = ({
|
||||
environment={environment}
|
||||
secretPath={secretPath}
|
||||
projectId={projectId}
|
||||
onUpgradePlan={() => handlePopUpOpen("upgradePlan")}
|
||||
onUpgradePlan={() =>
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
feature: "Secret Imports"
|
||||
})
|
||||
}
|
||||
isOpen={popUp.addSecretImport.isOpen}
|
||||
onClose={() => handlePopUpClose("addSecretImport")}
|
||||
onTogglePopUp={(isOpen) => handlePopUpToggle("addSecretImport", isOpen)}
|
||||
@@ -1277,13 +1300,7 @@ export const ActionBar = ({
|
||||
isOpen={popUp.upgradePlan.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
isEnterpriseFeature={popUp.upgradePlan.data?.isEnterpriseFeature}
|
||||
text={
|
||||
subscription.slug === null
|
||||
? "You can perform this action under an Enterprise license"
|
||||
: `You can perform this action if you switch to Infisical's ${
|
||||
popUp.upgradePlan.data?.isEnterpriseFeature ? "Enterprise" : "Pro"
|
||||
} plan`
|
||||
}
|
||||
text={`You can use ${popUp.upgradePlan.data?.feature} if you switch to Infisical's ${popUp.upgradePlan.data?.isEnterpriseFeature ? "Enterprise" : "Pro"} plan.`}
|
||||
/>
|
||||
)}
|
||||
<Modal
|
||||
|
||||
+4
-6
@@ -36,9 +36,8 @@ const formSchema = z.object({
|
||||
const valMs = ms(val);
|
||||
if (valMs < 60 * 1000)
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be a greater than 1min" });
|
||||
// a day
|
||||
if (valMs > 24 * 60 * 60 * 1000)
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
|
||||
if (valMs > ms("10y"))
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than 10 years" });
|
||||
}),
|
||||
maxTTL: z
|
||||
.string()
|
||||
@@ -48,9 +47,8 @@ const formSchema = z.object({
|
||||
const valMs = ms(val);
|
||||
if (valMs < 60 * 1000)
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be a greater than 1min" });
|
||||
// a day
|
||||
if (valMs > 24 * 60 * 60 * 1000)
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
|
||||
if (valMs > ms("10y"))
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than 10 years" });
|
||||
}),
|
||||
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
|
||||
environment: z.object({ name: z.string(), slug: z.string() }),
|
||||
|
||||
+4
-6
@@ -95,9 +95,8 @@ const formSchema = z.object({
|
||||
const valMs = ms(val);
|
||||
if (valMs < 60 * 1000)
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be a greater than 1min" });
|
||||
// a day
|
||||
if (valMs > 24 * 60 * 60 * 1000)
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
|
||||
if (valMs > ms("10y"))
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than 10 years" });
|
||||
}),
|
||||
maxTTL: z
|
||||
.string()
|
||||
@@ -107,9 +106,8 @@ const formSchema = z.object({
|
||||
const valMs = ms(val);
|
||||
if (valMs < 60 * 1000)
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be a greater than 1min" });
|
||||
// a day
|
||||
if (valMs > 24 * 60 * 60 * 1000)
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
|
||||
if (valMs > ms("10y"))
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than 10 years" });
|
||||
}),
|
||||
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
|
||||
environment: z.object({ name: z.string(), slug: z.string() }),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user