diff --git a/frontend/src/pages/pam/PamResourcesPage/components/PamResourceForm/shared/SqlRotateAccountFields.tsx b/frontend/src/pages/pam/PamResourcesPage/components/PamResourceForm/shared/SqlRotateAccountFields.tsx index e7e9023dd..d3f11ed60 100644 --- a/frontend/src/pages/pam/PamResourcesPage/components/PamResourceForm/shared/SqlRotateAccountFields.tsx +++ b/frontend/src/pages/pam/PamResourcesPage/components/PamResourceForm/shared/SqlRotateAccountFields.tsx @@ -1,38 +1,74 @@ import { useEffect, useState } from "react"; import { Controller, useFormContext, useWatch } from "react-hook-form"; -import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, - FormControl, - Input -} from "@app/components/v2"; +import { FormControl, Input, Switch } from "@app/components/v2"; import { UNCHANGED_PASSWORD_SENTINEL } from "@app/hooks/api/pam/constants"; export const SqlRotateAccountFields = ({ isUpdate }: { isUpdate: boolean }) => { - const { control } = useFormContext(); + const { control, setValue, getValues } = useFormContext(); const [showPassword, setShowPassword] = useState(false); const password = useWatch({ control, name: "credentials.password" }); + const rotationUsername = useWatch({ control, name: "rotationAccountCredentials.username" }); + const rotationPassword = useWatch({ control, name: "rotationAccountCredentials.password" }); + + const [enabled, setEnabled] = useState(false); + const [wasRotationPasswordSentinelInitially, setWasRotationPasswordSentinelInitially] = + useState(false); + + useEffect(() => { + const initialRotationPass = getValues("rotationAccountCredentials.password"); + if (initialRotationPass === UNCHANGED_PASSWORD_SENTINEL) { + setWasRotationPasswordSentinelInitially(true); + } + }, [getValues]); + useEffect(() => { if (password === UNCHANGED_PASSWORD_SENTINEL) { setShowPassword(false); } }, [password]); + useEffect(() => { + const isUsernamePopulated = rotationUsername && rotationUsername !== ""; + const isPasswordPopulated = + rotationPassword && + rotationPassword !== "" && + rotationPassword !== UNCHANGED_PASSWORD_SENTINEL; + + if (isUsernamePopulated || isPasswordPopulated) { + setEnabled(true); + } + }, [rotationUsername, rotationPassword]); + return ( - - - -
Rotation Account
-
- -

- Credentials of the privileged account which will be used for rotating other accounts - under this resource -

+
+ { + setEnabled(value); + if (value) { + setValue("rotationAccountCredentials.username", "", { + shouldDirty: true + }); + setValue("rotationAccountCredentials.password", "", { + shouldDirty: true + }); + } else { + setValue("rotationAccountCredentials", null, { + shouldDirty: true + }); + } + }} + isChecked={enabled} + containerClassName="flex-row-reverse w-fit" + className="ml-0" + > +

Credential Rotation

+
+ + {enabled && ( + <>
{ isError={Boolean(error?.message)} label="Username" > - +
+ +
)} /> @@ -58,29 +96,40 @@ export const SqlRotateAccountFields = ({ isUpdate }: { isUpdate: boolean }) => { isError={Boolean(error?.message)} label="Password" > - { - if (isUpdate && field.value === UNCHANGED_PASSWORD_SENTINEL) { - field.onChange(""); - } - setShowPassword(true); - }} - onBlur={() => { - if (isUpdate && field.value === "") { - field.onChange(UNCHANGED_PASSWORD_SENTINEL); - } - setShowPassword(false); - }} - /> +
+ { + if (isUpdate && field.value === UNCHANGED_PASSWORD_SENTINEL) { + field.onChange(""); + } + setShowPassword(true); + }} + onBlur={() => { + if ( + isUpdate && + field.value === "" && + wasRotationPasswordSentinelInitially + ) { + field.onChange(UNCHANGED_PASSWORD_SENTINEL); + } + setShowPassword(false); + }} + /> +
)} />
- - - + +

+ Credentials of the privileged account which will be used for rotating other accounts + under this resource +

+ + )} +
); };