feat: move feature to org level

This commit is contained in:
ShubhamPalriwala
2024-05-28 23:40:50 +05:30
parent 3b40f37f50
commit f85a35fde8
16 changed files with 71 additions and 105 deletions

View File

@@ -19,6 +19,7 @@ export enum OrgPermissionSubjects {
Groups = "groups",
Billing = "billing",
SecretScanning = "secret-scanning",
SecretSharing = "secret-sharing",
Identity = "identity"
}
@@ -34,6 +35,7 @@ export type OrgPermissionSet =
| [OrgPermissionActions, OrgPermissionSubjects.Ldap]
| [OrgPermissionActions, OrgPermissionSubjects.Groups]
| [OrgPermissionActions, OrgPermissionSubjects.SecretScanning]
| [OrgPermissionActions, OrgPermissionSubjects.SecretSharing]
| [OrgPermissionActions, OrgPermissionSubjects.Billing]
| [OrgPermissionActions, OrgPermissionSubjects.Identity];

View File

@@ -20,11 +20,11 @@ export const useDeleteSharedSecret = () => {
return useMutation<
TSharedSecret,
{ message: string },
{ sharedSecretId: string; workspaceId: string }
{ sharedSecretId: string }
>({
mutationFn: async ({ sharedSecretId, workspaceId }: TDeleteSharedSecretRequest) => {
mutationFn: async ({ sharedSecretId }: TDeleteSharedSecretRequest) => {
const { data } = await apiRequest.delete<TSharedSecret>(
`/api/v1/secret-sharing/${workspaceId}/${sharedSecretId}`
`/api/v1/secret-sharing/${sharedSecretId}`
);
return data;
},

View File

@@ -4,12 +4,12 @@ import { apiRequest } from "@app/config/request";
import { TSharedSecret, TViewSharedSecretResponse } from "./types";
export const useGetSharedSecrets = (workspaceId: string) => {
export const useGetSharedSecrets = () => {
return useQuery({
queryKey: ["sharedSecrets"],
queryFn: async () => {
const { data } = await apiRequest.get<TSharedSecret[]>(
`/api/v1/secret-sharing/${workspaceId}`
"/api/v1/secret-sharing/"
);
return data;
}

View File

@@ -12,7 +12,6 @@ export type TCreateSharedSecretRequest = {
name: string;
signedValue: string;
expiresAt: Date;
workspaceId: string;
};
export type TViewSharedSecretResponse = {
@@ -23,5 +22,4 @@ export type TViewSharedSecretResponse = {
export type TDeleteSharedSecretRequest = {
sharedSecretId: string;
workspaceId: string;
};

View File

@@ -531,18 +531,6 @@ export const AppLayout = ({ children }: LayoutProps) => {
</MenuItem>
</a>
</Link>
<Link href={`/project/${currentWorkspace?.id}/secret-sharing`} passHref>
<a>
<MenuItem
isSelected={
router.asPath === `/project/${currentWorkspace?.id}/secret-sharing`
}
icon="system-outline-90-lock-closed"
>
Secret Sharing
</MenuItem>
</a>
</Link>
<Link href={`/integrations/${currentWorkspace?.id}`} passHref>
<a>
<MenuItem
@@ -642,6 +630,18 @@ export const AppLayout = ({ children }: LayoutProps) => {
</MenuItem>
</a>
</Link>
<Link href={`/org/${currentOrg?.id}/secret-sharing`} passHref>
<a>
<MenuItem
isSelected={
router.asPath === `/org/${currentOrg?.id}/secret-sharing`
}
icon="system-outline-90-lock-closed"
>
Secret Sharing
</MenuItem>
</a>
</Link>
{(window.location.origin.includes("https://app.infisical.com") ||
window.location.origin.includes("https://gamma.infisical.com")) && (
<Link href={`/org/${currentOrg?.id}/billing`} passHref>

View File

@@ -22,7 +22,7 @@ import {
Select,
SelectItem
} from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { useOrganization } from "@app/context";
import { useToggle } from "@app/hooks";
import { useCreateSharedSecret } from "@app/hooks/api/secretSharing";
import { UsePopUpState } from "@app/hooks/usePopUp";
@@ -87,7 +87,7 @@ export const AddShareSecretModal = ({ popUp, handlePopUpToggle }: Props) => {
resolver: yupResolver(schema)
});
const createSharedSecret = useCreateSharedSecret();
const { currentWorkspace } = useWorkspace();
const { currentOrg } = useOrganization();
const [newSharedSecret, setnewSharedSecret] = useState("");
const [isUrlCopied, setIsUrlCopied] = useToggle(false);
const hasSharedSecret = Boolean(newSharedSecret);
@@ -108,7 +108,7 @@ export const AddShareSecretModal = ({ popUp, handlePopUpToggle }: Props) => {
const onFormSubmit = async ({ name, value, expiresInValue, expiresInUnit }: FormData) => {
try {
if (!currentWorkspace?.id) return;
if (!currentOrg?.id) return;
const signingKeyPair = generateSignKeyPair();
const signedMessage = signAssymmetric({
@@ -128,7 +128,6 @@ export const AddShareSecretModal = ({ popUp, handlePopUpToggle }: Props) => {
name,
signedValue: signedMessage,
expiresAt,
workspaceId: currentWorkspace.id
});
setnewSharedSecret(
`${window.location.origin}/shared/secret/${id}?key=${encodeURIComponent(

View File

@@ -3,10 +3,10 @@ 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 { OrgPermissionCan } from "@app/components/permissions";
import { Button, Checkbox, DeleteActionModal } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { withProjectPermission } from "@app/hoc";
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
import { withPermission } from "@app/hoc";
import { usePopUp } from "@app/hooks";
import { useDeleteSharedSecret } from "@app/hooks/api/secretSharing";
@@ -15,9 +15,8 @@ import { ShareSecretsTable } from "./ShareSecretsTable";
type DeleteModalData = { name: string; id: string };
export const ShareSecretSection = withProjectPermission(
export const ShareSecretSection = withPermission(
() => {
const { currentWorkspace } = useWorkspace();
const deleteSharedSecret = useDeleteSharedSecret();
const [showExpiredSharedSecrets, setShowExpiredSharedSecrets] = useState(false);
@@ -28,10 +27,8 @@ export const ShareSecretSection = withProjectPermission(
const onDeleteApproved = async () => {
try {
if (!currentWorkspace?.id) return;
deleteSharedSecret.mutateAsync({
sharedSecretId: (popUp?.deleteSharedSecretConfirmation?.data as DeleteModalData)?.id,
workspaceId: currentWorkspace.id
});
createNotification({
text: "Successfully deleted shared secret",
@@ -52,9 +49,9 @@ export const ShareSecretSection = withProjectPermission(
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="mb-2 flex justify-between">
<p className="text-xl font-semibold text-mineshaft-100">Shared Secrets</p>
<ProjectPermissionCan
I={ProjectPermissionActions.Create}
a={ProjectPermissionSub.SecretSharing}
<OrgPermissionCan
I={OrgPermissionActions.Create}
a={OrgPermissionSubjects.SecretSharing}
>
{(isAllowed) => (
<Button
@@ -68,7 +65,7 @@ export const ShareSecretSection = withProjectPermission(
Share Secret
</Button>
)}
</ProjectPermissionCan>
</OrgPermissionCan>
</div>
<div className="mb-8 flex items-center justify-between">
<p className="flex-grow text-gray-400">
@@ -93,9 +90,8 @@ export const ShareSecretSection = withProjectPermission(
<AddShareSecretModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
<DeleteActionModal
isOpen={popUp.deleteSharedSecretConfirmation.isOpen}
title={`Delete ${
(popUp?.deleteSharedSecretConfirmation?.data as DeleteModalData)?.name || " "
} shared secret?`}
title={`Delete ${(popUp?.deleteSharedSecretConfirmation?.data as DeleteModalData)?.name || " "
} shared secret?`}
onChange={(isOpen) => handlePopUpToggle("deleteSharedSecretConfirmation", isOpen)}
deleteKey={(popUp?.deleteSharedSecretConfirmation?.data as DeleteModalData)?.name}
onClose={() => handlePopUpClose("deleteSharedSecretConfirmation")}
@@ -104,5 +100,5 @@ export const ShareSecretSection = withProjectPermission(
</div>
);
},
{ action: ProjectPermissionActions.Read, subject: ProjectPermissionSub.SecretSharing }
{ action: OrgPermissionActions.Read, subject: OrgPermissionSubjects.SecretSharing }
);

View File

@@ -2,9 +2,9 @@ import { useEffect, useState } from "react";
import { faTrashCan } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { ProjectPermissionCan } from "@app/components/permissions";
import { OrgPermissionCan } from "@app/components/permissions";
import { IconButton, Td, Tr } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
import { TSharedSecret } from "@app/hooks/api/secretSharing";
import { UsePopUpState } from "@app/hooks/usePopUp";
@@ -110,9 +110,9 @@ export const ShareSecretsRow = ({
<p className="text-xs text-gray-500">{formatDate(row.expiresAt)}</p>
</Td>
<Td>
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={ProjectPermissionSub.SecretSharing}
<OrgPermissionCan
I={OrgPermissionActions.Delete}
a={OrgPermissionSubjects.SecretSharing}
>
{(isAllowed) => (
<IconButton
@@ -129,7 +129,7 @@ export const ShareSecretsRow = ({
<FontAwesomeIcon icon={faTrashCan} />
</IconButton>
)}
</ProjectPermissionCan>
</OrgPermissionCan>
</Td>
</Tr>
);

View File

@@ -12,7 +12,6 @@ import {
THead,
Tr
} from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { TSharedSecret, useGetSharedSecrets } from "@app/hooks/api/secretSharing";
import { UsePopUpState } from "@app/hooks/usePopUp";
@@ -34,9 +33,7 @@ type Props = {
export const ShareSecretsTable = ({ handlePopUpOpen, showExpiredSharedSecrets }: Props) => {
const [tableData, setTableData] = useState<TSharedSecret[]>([]);
const { currentWorkspace } = useWorkspace();
const workspaceId = currentWorkspace?.id || "";
const { isLoading, data = [] } = useGetSharedSecrets(workspaceId);
const { isLoading, data = [] } = useGetSharedSecrets();
useEffect(() => {
if (!isLoading) {