mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 17:30:06 +00:00
feat: updated frontend project permission logic
This commit is contained in:
@@ -79,8 +79,23 @@ export const SecretMainPage = () => {
|
||||
const secretPath = (router.query.secretPath as string) || "/";
|
||||
const canReadSecret = permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: "*",
|
||||
secretTags: ["*"]
|
||||
})
|
||||
);
|
||||
const canReadSecretImports = permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.SecretImports, { environment, secretPath })
|
||||
);
|
||||
|
||||
const canReadDynamicSecret = permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath })
|
||||
);
|
||||
|
||||
const canDoReadRollback = permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionSub.SecretRollback
|
||||
@@ -91,8 +106,8 @@ export const SecretMainPage = () => {
|
||||
searchFilter: (router.query.searchFilter as string) || "",
|
||||
include: {
|
||||
[RowType.Folder]: true,
|
||||
[RowType.Import]: canReadSecret,
|
||||
[RowType.DynamicSecret]: canReadSecret,
|
||||
[RowType.Import]: canReadSecretImports,
|
||||
[RowType.DynamicSecret]: canReadDynamicSecret,
|
||||
[RowType.Secret]: canReadSecret
|
||||
}
|
||||
};
|
||||
@@ -107,12 +122,12 @@ export const SecretMainPage = () => {
|
||||
...prev,
|
||||
include: {
|
||||
[RowType.Folder]: true,
|
||||
[RowType.Import]: canReadSecret,
|
||||
[RowType.DynamicSecret]: canReadSecret,
|
||||
[RowType.Import]: canReadSecretImports,
|
||||
[RowType.DynamicSecret]: canReadDynamicSecret,
|
||||
[RowType.Secret]: canReadSecret
|
||||
}
|
||||
}));
|
||||
}, [canReadSecret]);
|
||||
}, [canReadSecret, canReadSecretImports, canReadDynamicSecret]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
@@ -141,9 +156,9 @@ export const SecretMainPage = () => {
|
||||
orderBy,
|
||||
search: debouncedSearchFilter,
|
||||
orderDirection,
|
||||
includeImports: canReadSecret && filter.include.import,
|
||||
includeImports: canReadSecretImports && filter.include.import,
|
||||
includeFolders: filter.include.folder,
|
||||
includeDynamicSecrets: canReadSecret && filter.include.dynamic,
|
||||
includeDynamicSecrets: canReadDynamicSecret && filter.include.dynamic,
|
||||
includeSecrets: canReadSecret && filter.include.secret,
|
||||
tags: filter.tags
|
||||
});
|
||||
@@ -362,7 +377,7 @@ export const SecretMainPage = () => {
|
||||
<div className="flex-grow px-4 py-2">Value</div>
|
||||
</div>
|
||||
)}
|
||||
{canReadSecret && imports?.length && (
|
||||
{canReadSecretImports && imports?.length && (
|
||||
<SecretImportListView
|
||||
searchTerm={debouncedSearchFilter}
|
||||
secretImports={imports}
|
||||
@@ -382,7 +397,7 @@ export const SecretMainPage = () => {
|
||||
onNavigateToFolder={handleResetFilter}
|
||||
/>
|
||||
)}
|
||||
{canReadSecret && dynamicSecrets?.length && (
|
||||
{canReadDynamicSecret && dynamicSecrets?.length && (
|
||||
<DynamicSecretListView
|
||||
environment={environment}
|
||||
projectSlug={projectSlug}
|
||||
@@ -401,7 +416,10 @@ export const SecretMainPage = () => {
|
||||
isProtectedBranch={isProtectedBranch}
|
||||
/>
|
||||
)}
|
||||
{!canReadSecret && folders?.length === 0 && <PermissionDeniedBanner />}
|
||||
{!canReadSecret &&
|
||||
!canReadDynamicSecret &&
|
||||
!canReadSecretImports &&
|
||||
folders?.length === 0 && <PermissionDeniedBanner />}
|
||||
</div>
|
||||
</div>
|
||||
{!isDetailsLoading && totalCount > 0 && (
|
||||
|
||||
@@ -45,12 +45,7 @@ import {
|
||||
Tooltip,
|
||||
UpgradePlanModal
|
||||
} from "@app/components/v2";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useSubscription } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useCreateFolder, useDeleteSecretBatch, useMoveSecrets } from "@app/hooks/api";
|
||||
import { fetchProjectSecrets } from "@app/hooks/api/secrets/queries";
|
||||
@@ -125,12 +120,6 @@ export const ActionBar = ({
|
||||
const { reset: resetSelectedSecret } = useSelectedSecretActions();
|
||||
const isMultiSelectActive = Boolean(Object.keys(selectedSecrets).length);
|
||||
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const shouldCheckFolderPermission = permission.rules.some((rule) =>
|
||||
(rule.subject as ProjectPermissionSub[]).includes(ProjectPermissionSub.SecretFolders)
|
||||
);
|
||||
|
||||
const handleFolderCreate = async (folderName: string) => {
|
||||
try {
|
||||
await createFolder({
|
||||
@@ -438,7 +427,12 @@ export const ActionBar = ({
|
||||
<div className="flex items-center">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: "*",
|
||||
secretTags: ["*"]
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -469,12 +463,7 @@ export const ActionBar = ({
|
||||
<div className="flex flex-col space-y-1 p-1.5">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={subject(
|
||||
shouldCheckFolderPermission
|
||||
? ProjectPermissionSub.SecretFolders
|
||||
: ProjectPermissionSub.Secrets,
|
||||
{ environment, secretPath }
|
||||
)}
|
||||
a={subject(ProjectPermissionSub.SecretFolders, { environment, secretPath })}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -494,7 +483,12 @@ export const ActionBar = ({
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: "*",
|
||||
secretTags: ["*"]
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -518,7 +512,10 @@ export const ActionBar = ({
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.SecretImports, {
|
||||
environment,
|
||||
secretPath
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -558,7 +555,12 @@ export const ActionBar = ({
|
||||
</div>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: "*",
|
||||
secretTags: ["*"]
|
||||
})}
|
||||
renderTooltip
|
||||
allowedLabel="Move"
|
||||
>
|
||||
@@ -577,7 +579,12 @@ export const ActionBar = ({
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: "*",
|
||||
secretTags: ["*"]
|
||||
})}
|
||||
renderTooltip
|
||||
allowedLabel="Delete"
|
||||
>
|
||||
|
||||
+6
-4
@@ -60,7 +60,6 @@ export const DynamicSecretLease = ({
|
||||
path: secretPath,
|
||||
dynamicSecretName
|
||||
});
|
||||
|
||||
|
||||
const deleteDynamicSecretLease = useRevokeDynamicSecretLease();
|
||||
|
||||
@@ -141,7 +140,7 @@ export const DynamicSecretLease = ({
|
||||
<div className="flex items-center space-x-4">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath })}
|
||||
renderTooltip
|
||||
allowedLabel="Renew"
|
||||
>
|
||||
@@ -160,7 +159,7 @@ export const DynamicSecretLease = ({
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath })}
|
||||
renderTooltip
|
||||
allowedLabel="Delete"
|
||||
>
|
||||
@@ -180,7 +179,10 @@ export const DynamicSecretLease = ({
|
||||
{status === DynamicSecretLeaseStatus.FailedDeletion && (
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.DynamicSecrets, {
|
||||
environment,
|
||||
secretPath
|
||||
})}
|
||||
renderTooltip
|
||||
allowedLabel="Force Delete. This action will remove the secret from internal storage, but it will remain in external systems."
|
||||
>
|
||||
|
||||
+2
-2
@@ -166,7 +166,7 @@ export const DynamicSecretListView = ({
|
||||
<div className="flex items-center space-x-4 border-l border-mineshaft-600 px-3 py-3">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath })}
|
||||
renderTooltip
|
||||
allowedLabel="Edit"
|
||||
>
|
||||
@@ -188,7 +188,7 @@ export const DynamicSecretListView = ({
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath })}
|
||||
renderTooltip
|
||||
allowedLabel="Delete"
|
||||
>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { DeleteActionModal, IconButton, Modal, ModalContent } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProjectPermission } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useDeleteFolder, useUpdateFolder } from "@app/hooks/api";
|
||||
import { TSecretFolder } from "@app/hooks/api/secretFolders/types";
|
||||
@@ -33,11 +33,6 @@ export const FolderListView = ({
|
||||
"deleteFolder"
|
||||
] as const);
|
||||
const router = useRouter();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const shouldCheckFolderPermission = permission.rules.some((rule) =>
|
||||
(rule.subject as ProjectPermissionSub[]).includes(ProjectPermissionSub.SecretFolders)
|
||||
);
|
||||
|
||||
const { mutateAsync: updateFolder } = useUpdateFolder();
|
||||
const { mutateAsync: deleteFolder } = useDeleteFolder();
|
||||
@@ -126,12 +121,7 @@ export const FolderListView = ({
|
||||
<div className="flex items-center space-x-4 border-l border-mineshaft-600 px-3 py-3">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(
|
||||
shouldCheckFolderPermission
|
||||
? ProjectPermissionSub.SecretFolders
|
||||
: ProjectPermissionSub.Secrets,
|
||||
{ environment, secretPath }
|
||||
)}
|
||||
a={subject(ProjectPermissionSub.SecretFolders, { environment, secretPath })}
|
||||
renderTooltip
|
||||
allowedLabel="Edit"
|
||||
>
|
||||
@@ -150,12 +140,7 @@ export const FolderListView = ({
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(
|
||||
shouldCheckFolderPermission
|
||||
? ProjectPermissionSub.SecretFolders
|
||||
: ProjectPermissionSub.Secrets,
|
||||
{ environment, secretPath }
|
||||
)}
|
||||
a={subject(ProjectPermissionSub.SecretFolders, { environment, secretPath })}
|
||||
renderTooltip
|
||||
allowedLabel="Delete"
|
||||
>
|
||||
|
||||
+6
-1
@@ -142,7 +142,12 @@ export const CopySecretsFromBoard = ({
|
||||
<div>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: "*",
|
||||
secretTags: ["*"]
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
|
||||
@@ -250,7 +250,12 @@ export const SecretDropzone = ({
|
||||
</div>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: "*",
|
||||
secretTags: ["*"]
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<input
|
||||
@@ -287,7 +292,12 @@ export const SecretDropzone = ({
|
||||
{!isSmaller && (
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: "*",
|
||||
secretTags: ["*"]
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
|
||||
+7
-4
@@ -67,7 +67,7 @@ export const SecretImportItem = ({
|
||||
isReplicationExpand,
|
||||
importedSecrets = [],
|
||||
searchTerm = "",
|
||||
secretPath,
|
||||
secretPath = "/",
|
||||
environment,
|
||||
secretImport,
|
||||
onExpandReplicateSecrets: onExpandReplicate
|
||||
@@ -209,7 +209,7 @@ export const SecretImportItem = ({
|
||||
{isReplication && (
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.SecretImports, { environment, secretPath })}
|
||||
renderTooltip
|
||||
allowedLabel="Resync replicated secrets"
|
||||
>
|
||||
@@ -235,7 +235,10 @@ export const SecretImportItem = ({
|
||||
<div className="flex items-center space-x-4 border-l border-mineshaft-600 px-4 py-2">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.SecretImports, {
|
||||
environment,
|
||||
secretPath: secretPath || "/"
|
||||
})}
|
||||
renderTooltip
|
||||
allowedLabel="Change order"
|
||||
>
|
||||
@@ -256,7 +259,7 @@ export const SecretImportItem = ({
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.SecretImports, { environment, secretPath })}
|
||||
renderTooltip
|
||||
allowedLabel="Delete"
|
||||
>
|
||||
|
||||
+57
-15
@@ -85,15 +85,6 @@ export const SecretDetailSidebar = ({
|
||||
values: secret
|
||||
});
|
||||
const { permission } = useProjectPermission();
|
||||
const cannotEditSecret = permission.cannot(
|
||||
ProjectPermissionActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||
);
|
||||
const isReadOnly =
|
||||
permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||
) && cannotEditSecret;
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
@@ -104,6 +95,27 @@ export const SecretDetailSidebar = ({
|
||||
(prev, curr) => ({ ...prev, [curr.id]: true }),
|
||||
{}
|
||||
);
|
||||
const selectTagSlugs = selectedTags.map((i) => i.slug);
|
||||
|
||||
const cannotEditSecret = permission.cannot(
|
||||
ProjectPermissionActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: selectTagSlugs
|
||||
})
|
||||
);
|
||||
const isReadOnly =
|
||||
permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: selectTagSlugs
|
||||
})
|
||||
) && cannotEditSecret;
|
||||
|
||||
const overrideAction = watch("overrideAction");
|
||||
const isOverridden =
|
||||
@@ -194,7 +206,12 @@ export const SecretDetailSidebar = ({
|
||||
</FormControl>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: selectTagSlugs
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Controller
|
||||
@@ -221,7 +238,12 @@ export const SecretDetailSidebar = ({
|
||||
<div className="mb-2 border-b border-mineshaft-600 pb-4">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: selectTagSlugs
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Switch
|
||||
@@ -277,7 +299,12 @@ export const SecretDetailSidebar = ({
|
||||
<DropdownMenu>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: selectTagSlugs
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuTrigger asChild>
|
||||
@@ -388,7 +415,12 @@ export const SecretDetailSidebar = ({
|
||||
render={({ field: { value, onChange, onBlur } }) => (
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: selectTagSlugs
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Switch
|
||||
@@ -450,7 +482,12 @@ export const SecretDetailSidebar = ({
|
||||
<div className="flex items-center space-x-4">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: selectTagSlugs
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -465,7 +502,12 @@ export const SecretDetailSidebar = ({
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: selectTagSlugs
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button colorSchema="danger" isDisabled={!isAllowed} onClick={onDeleteSecret}>
|
||||
|
||||
@@ -81,15 +81,6 @@ export const SecretItem = memo(
|
||||
}: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { permission } = useProjectPermission();
|
||||
const isReadOnly =
|
||||
permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||
) &&
|
||||
permission.cannot(
|
||||
ProjectPermissionActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||
);
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
@@ -107,6 +98,8 @@ export const SecretItem = memo(
|
||||
resolver: zodResolver(formSchema)
|
||||
});
|
||||
|
||||
const secretName = watch("key");
|
||||
|
||||
const secretReminderRepeatDays = watch("reminderRepeatDays");
|
||||
const secretReminderNote = watch("reminderNote");
|
||||
|
||||
@@ -118,11 +111,33 @@ export const SecretItem = memo(
|
||||
(prev, curr) => ({ ...prev, [curr.id]: true }),
|
||||
{}
|
||||
);
|
||||
const selectedTagSlugs = selectedTags.map((i) => i.slug);
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "tags"
|
||||
});
|
||||
|
||||
const isReadOnly =
|
||||
permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: selectedTagSlugs
|
||||
})
|
||||
) &&
|
||||
permission.cannot(
|
||||
ProjectPermissionActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: selectedTagSlugs
|
||||
})
|
||||
);
|
||||
|
||||
const [isSecValueCopied, setIsSecValueCopied] = useToggle(false);
|
||||
const [createReminderFormOpen, setCreateReminderFormOpen] = useToggle(false);
|
||||
useEffect(() => {
|
||||
@@ -309,7 +324,12 @@ export const SecretItem = memo(
|
||||
<DropdownMenu>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: selectedTagSlugs
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuTrigger asChild disabled={!isAllowed}>
|
||||
@@ -384,7 +404,12 @@ export const SecretItem = memo(
|
||||
</DropdownMenu>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: selectedTagSlugs
|
||||
})}
|
||||
renderTooltip
|
||||
allowedLabel="Override"
|
||||
>
|
||||
@@ -440,7 +465,12 @@ export const SecretItem = memo(
|
||||
<Popover>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: selectedTagSlugs
|
||||
})}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<PopoverTrigger asChild disabled={!isAllowed}>
|
||||
@@ -519,7 +549,12 @@ export const SecretItem = memo(
|
||||
</Tooltip>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||
a={subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: selectedTagSlugs
|
||||
})}
|
||||
renderTooltip
|
||||
allowedLabel="Delete"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user