mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
fix(secrets-permissions): UI fix for users with edit permissions but not read secret value permission
This commit is contained in:
@@ -87,6 +87,7 @@ export const SecretEditRow = ({
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const [isDeleting, setIsDeleting] = useToggle();
|
||||
const [isSecretBlurFocus, setIsSecretBlurFocus] = useToggle(false);
|
||||
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
||||
|
||||
const toggleModal = useCallback(() => {
|
||||
@@ -124,7 +125,14 @@ export const SecretEditRow = ({
|
||||
);
|
||||
}
|
||||
}
|
||||
reset({ value });
|
||||
if (secretValueHidden) {
|
||||
setTimeout(() => {
|
||||
reset({ value: defaultValue || null });
|
||||
}, 0);
|
||||
setIsSecretBlurFocus.off();
|
||||
} else {
|
||||
reset({ value });
|
||||
}
|
||||
};
|
||||
|
||||
const canReadSecretValue = hasSecretReadValueOrDescribePermission(
|
||||
@@ -132,6 +140,22 @@ export const SecretEditRow = ({
|
||||
ProjectPermissionSecretActions.ReadValue
|
||||
);
|
||||
|
||||
const canEditSecretValue = permission.can(
|
||||
ProjectPermissionSecretActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: ["*"]
|
||||
})
|
||||
);
|
||||
|
||||
const handleSecretBlurClick = () => {
|
||||
if (canEditSecretValue) {
|
||||
setIsSecretBlurFocus.toggle();
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteSecret = useCallback(async () => {
|
||||
setIsDeleting.on();
|
||||
setIsModalOpen(false);
|
||||
@@ -155,8 +179,17 @@ export const SecretEditRow = ({
|
||||
/>
|
||||
|
||||
<div className="flex-grow border-r border-r-mineshaft-600 pl-1 pr-2">
|
||||
{secretValueHidden ? (
|
||||
<Blur tooltipText="You do not have permission to read the value of this secret." />
|
||||
{secretValueHidden && !isSecretBlurFocus ? (
|
||||
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
||||
<div
|
||||
className="flex flex-grow"
|
||||
onClick={handleSecretBlurClick}
|
||||
onBlur={() => setIsSecretBlurFocus.off()}
|
||||
>
|
||||
<Blur
|
||||
tooltipText={`You do not have permission to read the value of this secret.${canEditSecretValue ? " But you have permission to edit it." : ""}`}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<Controller
|
||||
disabled={isImportedSecret && !defaultValue}
|
||||
@@ -172,6 +205,7 @@ export const SecretEditRow = ({
|
||||
secretPath={secretPath}
|
||||
environment={environment}
|
||||
isImport={isImportedSecret}
|
||||
defaultValue={secretValueHidden ? "" : undefined}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { subject } from "@casl/ability";
|
||||
import { faCircle } from "@fortawesome/free-regular-svg-icons";
|
||||
import {
|
||||
faAngleDown,
|
||||
@@ -14,6 +15,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { Button, Checkbox, TableContainer, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { useProjectPermission } from "@app/context";
|
||||
import {
|
||||
ProjectPermissionSecretActions,
|
||||
ProjectPermissionSub
|
||||
} from "@app/context/ProjectPermissionContext/types";
|
||||
import { useToggle } from "@app/hooks";
|
||||
import { SecretType, SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
@@ -64,6 +70,28 @@ export const SecretOverviewTableRow = ({
|
||||
const totalCols = environments.length + 1; // secret key row
|
||||
const [isSecretVisible, setIsSecretVisible] = useToggle();
|
||||
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const getDefaultValue = (
|
||||
secret: SecretV3RawSanitized | undefined,
|
||||
importedSecret: { secret?: SecretV3RawSanitized } | undefined
|
||||
) => {
|
||||
const canEditSecretValue = permission.can(
|
||||
ProjectPermissionSecretActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment: secret?.env || "",
|
||||
secretPath: secret?.path || "",
|
||||
secretName: secret?.key || "",
|
||||
secretTags: ["*"]
|
||||
})
|
||||
);
|
||||
|
||||
if (secret?.secretValueHidden) {
|
||||
return canEditSecretValue ? "<hidden-by-infisical>" : "";
|
||||
}
|
||||
return secret?.valueOverride || secret?.value || importedSecret?.secret?.value || "";
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tr isHoverable isSelectable onClick={() => setIsFormExpanded.toggle()} className="group">
|
||||
@@ -228,13 +256,7 @@ export const SecretOverviewTableRow = ({
|
||||
isVisible={isSecretVisible}
|
||||
secretName={secretKey}
|
||||
secretValueHidden={secret?.secretValueHidden || false}
|
||||
defaultValue={
|
||||
secret?.secretValueHidden
|
||||
? ""
|
||||
: secret?.valueOverride ||
|
||||
secret?.value ||
|
||||
importedSecret?.secret?.value
|
||||
}
|
||||
defaultValue={getDefaultValue(secret, importedSecret)}
|
||||
secretId={secret?.id}
|
||||
isOverride={Boolean(secret?.valueOverride)}
|
||||
isImportedSecret={isImportedSecret}
|
||||
|
||||
@@ -94,6 +94,24 @@ export const SecretItem = memo(
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { permission } = useProjectPermission();
|
||||
const { isRotatedSecret } = secret;
|
||||
const [isSecretBlurFocus, setIsSecretBlurFocus] = useToggle(false);
|
||||
|
||||
const canEditSecretValue = permission.can(
|
||||
ProjectPermissionSecretActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secret.key,
|
||||
secretTags: ["*"]
|
||||
})
|
||||
);
|
||||
|
||||
const getDefaultValue = () => {
|
||||
if (secret.secretValueHidden) {
|
||||
return canEditSecretValue ? "<hidden-by-infisical>" : "";
|
||||
}
|
||||
return secret.valueOverride || secret.value || "";
|
||||
};
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
@@ -108,11 +126,11 @@ export const SecretItem = memo(
|
||||
} = useForm<TFormSchema>({
|
||||
defaultValues: {
|
||||
...secret,
|
||||
value: secret.secretValueHidden ? "" : secret.value
|
||||
value: getDefaultValue()
|
||||
},
|
||||
values: {
|
||||
...secret,
|
||||
value: secret.secretValueHidden ? "" : secret.value
|
||||
value: getDefaultValue()
|
||||
},
|
||||
resolver: zodResolver(formSchema)
|
||||
});
|
||||
@@ -154,6 +172,7 @@ export const SecretItem = memo(
|
||||
secretTags: selectedTagSlugs
|
||||
})
|
||||
);
|
||||
|
||||
const { secretValueHidden } = secret;
|
||||
|
||||
const [isSecValueCopied, setIsSecValueCopied] = useToggle(false);
|
||||
@@ -169,6 +188,12 @@ export const SecretItem = memo(
|
||||
overrideAction === SecretActionType.Created || overrideAction === SecretActionType.Modified;
|
||||
const hasTagsApplied = Boolean(fields.length);
|
||||
|
||||
const handleSecretBlurClick = () => {
|
||||
if (canEditSecretValue) {
|
||||
setIsSecretBlurFocus.toggle();
|
||||
}
|
||||
};
|
||||
|
||||
const handleOverrideClick = () => {
|
||||
if (isOverriden) {
|
||||
// override need not be flagged delete if it was never saved in server
|
||||
@@ -301,8 +326,17 @@ export const SecretItem = memo(
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
) : secretValueHidden ? (
|
||||
<Blur tooltipText="You do not have permission to read the value of this secret." />
|
||||
) : secretValueHidden && !isSecretBlurFocus ? (
|
||||
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
||||
<div
|
||||
className="flex flex-grow"
|
||||
onClick={handleSecretBlurClick}
|
||||
onBlur={() => setIsSecretBlurFocus.off()}
|
||||
>
|
||||
<Blur
|
||||
tooltipText={`You do not have permission to read the value of this secret.${canEditSecretValue ? " But you have permission to edit it." : ""}`}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<Controller
|
||||
name="value"
|
||||
@@ -316,7 +350,7 @@ export const SecretItem = memo(
|
||||
environment={environment}
|
||||
secretPath={secretPath}
|
||||
{...field}
|
||||
defaultValue={secretValueHidden ? "" : undefined}
|
||||
defaultValue={secretValueHidden ? "<hidden-by-infisical>" : undefined}
|
||||
containerClassName="py-1.5 rounded-md transition-all"
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user