mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Add public key to service account creation modal
This commit is contained in:
@@ -4,8 +4,9 @@ import NavHeader from '@app/components/navigation/NavHeader';
|
||||
|
||||
import { SAProjectLevelPermissionsTable } from './components/SAProjectLevelPermissionsTable';
|
||||
import {
|
||||
CopyServiceAccountIDSection,
|
||||
ServiceAccountNameChangeSection} from './components';
|
||||
CopyServiceAccountPublicKeySection,
|
||||
ServiceAccountNameChangeSection
|
||||
} from './components';
|
||||
|
||||
export const CreateServiceAccountPage = () => {
|
||||
const router = useRouter();
|
||||
@@ -29,7 +30,7 @@ export const CreateServiceAccountPage = () => {
|
||||
serviceAccountId={serviceAccountId}
|
||||
/>
|
||||
<div className="mt-8">
|
||||
<CopyServiceAccountIDSection
|
||||
<CopyServiceAccountPublicKeySection
|
||||
serviceAccountId={serviceAccountId}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { useEffect } from 'react';
|
||||
import { faCheck, faCopy } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
import { IconButton } from '@app/components/v2';
|
||||
import { useToggle } from '@app/hooks';
|
||||
import { useGetServiceAccountById } from '@app/hooks/api';
|
||||
|
||||
type Props = {
|
||||
serviceAccountId: string;
|
||||
}
|
||||
|
||||
export const CopyServiceAccountPublicKeySection = ({ serviceAccountId }: Props): JSX.Element => {
|
||||
const { data: serviceAccount } = useGetServiceAccountById(serviceAccountId);
|
||||
const [isServiceAccountIdCopied, setIsServiceAccountIdCopied] = useToggle(false);
|
||||
|
||||
useEffect(() => {
|
||||
let timer: NodeJS.Timeout;
|
||||
|
||||
if (isServiceAccountIdCopied) {
|
||||
timer = setTimeout(() => setIsServiceAccountIdCopied.off(), 2000);
|
||||
}
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [isServiceAccountIdCopied]);
|
||||
|
||||
const copyServiceAccountIdToClipboard = () => {
|
||||
if (!serviceAccount) return;
|
||||
|
||||
navigator.clipboard.writeText(serviceAccount.publicKey);
|
||||
setIsServiceAccountIdCopied.on();
|
||||
};
|
||||
|
||||
return serviceAccount ? (
|
||||
<div className="flex w-full flex-col items-start rounded-md bg-white/5 px-6 p-6">
|
||||
<p className="text-xl font-semibold">Public Key</p>
|
||||
<div className="mt-4 flex items-center justify-end rounded-md bg-white/[0.07] text-base text-gray-400 p-2">
|
||||
<p className="mr-4 break-all">{serviceAccount.publicKey}</p>
|
||||
<IconButton
|
||||
ariaLabel="copy icon"
|
||||
colorSchema="secondary"
|
||||
className="group relative"
|
||||
onClick={() => copyServiceAccountIdToClipboard()}
|
||||
>
|
||||
<FontAwesomeIcon icon={isServiceAccountIdCopied ? faCheck : faCopy} />
|
||||
<span className="absolute -left-8 -top-20 hidden w-28 translate-y-full rounded-md bg-bunker-800 py-2 pl-3 text-center text-sm text-gray-400 group-hover:flex group-hover:animate-fadeIn">
|
||||
Copy
|
||||
</span>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
) : <div />
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { CopyServiceAccountPublicKeySection } from './CopyServiceAccountPublicKeySection';
|
||||
@@ -40,7 +40,8 @@ import {
|
||||
useDeleteServiceAccountProjectLevelPermission,
|
||||
useGetServiceAccountById,
|
||||
useGetServiceAccountProjectLevelPermissions,
|
||||
useGetUserWorkspaces} from '@app/hooks/api';
|
||||
useGetUserWorkspaces
|
||||
} from '@app/hooks/api';
|
||||
import getLatestFileKey from '@app/pages/api/workspace/getLatestFileKey';
|
||||
|
||||
const createProjectLevelPermissionSchema = yup.object({
|
||||
|
||||
@@ -58,7 +58,7 @@ export const ServiceAccountNameChangeSection = ({
|
||||
onSubmit={handleSubmit(onFormSubmit)}
|
||||
className="rounded-md bg-white/5 p-6"
|
||||
>
|
||||
<p className="mb-4 text-xl font-semibold">Service Account Name</p>
|
||||
<p className="mb-4 text-xl font-semibold">Name</p>
|
||||
<div className="mb-2 w-full max-w-lg">
|
||||
{!isServiceAccountLoading && (
|
||||
<Controller
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export { CopyServiceAccountIDSection } from './CopyServiceAccountIDSection';
|
||||
export { CopyServiceAccountPublicKeySection } from './CopyServiceAccountPublicKeySection';
|
||||
export { SAProjectLevelPermissionsTable } from './SAProjectLevelPermissionsTable';
|
||||
export { ServiceAccountNameChangeSection } from './ServiceAccountNameChangeSection';
|
||||
@@ -65,8 +65,10 @@ export const OrgServiceAccountsTable = () => {
|
||||
const orgId = currentOrg?._id || '';
|
||||
const [step, setStep] = useState(0);
|
||||
const [isAccessKeyCopied, setIsAccessKeyCopied] = useToggle(false);
|
||||
const [isPublicKeyCopied, setIsPublicKeyCopied] = useToggle(false);
|
||||
const [isPrivateKeyCopied, setIsPrivateKeyCopied] = useToggle(false);
|
||||
const [accessKey, setAccessKey] = useState('');
|
||||
const [publicKey, setPublicKey] = useState('');
|
||||
const [privateKey, setPrivateKey] = useState('');
|
||||
const [searchServiceAccountFilter, setSearchServiceAccountFilter] = useState('');
|
||||
const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
|
||||
@@ -85,12 +87,16 @@ export const OrgServiceAccountsTable = () => {
|
||||
timer = setTimeout(() => setIsAccessKeyCopied.off(), 2000);
|
||||
}
|
||||
|
||||
if (isPublicKeyCopied) {
|
||||
timer = setTimeout(() => setIsPublicKeyCopied.off(), 2000);
|
||||
}
|
||||
|
||||
if (isPrivateKeyCopied) {
|
||||
timer = setTimeout(() => setIsPrivateKeyCopied.off(), 2000);
|
||||
}
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [isAccessKeyCopied, isPrivateKeyCopied]);
|
||||
}, [isAccessKeyCopied, isPublicKeyCopied, isPrivateKeyCopied]);
|
||||
|
||||
const {
|
||||
control,
|
||||
@@ -103,6 +109,7 @@ export const OrgServiceAccountsTable = () => {
|
||||
if (!currentOrg?._id) return;
|
||||
|
||||
const keyPair = generateKeyPair();
|
||||
setPublicKey(keyPair.publicKey);
|
||||
setPrivateKey(keyPair.privateKey);
|
||||
|
||||
const serviceAccountDetails = await createServiceAccount.mutateAsync({
|
||||
@@ -216,6 +223,24 @@ export const OrgServiceAccountsTable = () => {
|
||||
</span>
|
||||
</IconButton>
|
||||
</div>
|
||||
<p className="mt-4">Public Key</p>
|
||||
<div className="flex items-center justify-end rounded-md p-2 text-base text-gray-400 bg-white/[0.07]">
|
||||
<p className="mr-4 break-all">{publicKey}</p>
|
||||
<IconButton
|
||||
ariaLabel="copy icon"
|
||||
colorSchema="secondary"
|
||||
className="group relative"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(publicKey);
|
||||
setIsPublicKeyCopied.on();
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon icon={isPublicKeyCopied ? faCheck : faCopy} />
|
||||
<span className="absolute -left-8 -top-20 hidden w-28 translate-y-full rounded-md bg-bunker-800 py-2 pl-3 text-center text-sm text-gray-400 group-hover:flex group-hover:animate-fadeIn">
|
||||
Copy
|
||||
</span>
|
||||
</IconButton>
|
||||
</div>
|
||||
<p className="mt-4">Private Key</p>
|
||||
<div className="flex items-center justify-end rounded-md p-2 text-base text-gray-400 bg-white/[0.07]">
|
||||
<p className="mr-4 break-all">{privateKey}</p>
|
||||
@@ -234,6 +259,7 @@ export const OrgServiceAccountsTable = () => {
|
||||
</span>
|
||||
</IconButton>
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user