mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 04:26:33 +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 { SAProjectLevelPermissionsTable } from './components/SAProjectLevelPermissionsTable';
|
||||||
import {
|
import {
|
||||||
CopyServiceAccountIDSection,
|
CopyServiceAccountPublicKeySection,
|
||||||
ServiceAccountNameChangeSection} from './components';
|
ServiceAccountNameChangeSection
|
||||||
|
} from './components';
|
||||||
|
|
||||||
export const CreateServiceAccountPage = () => {
|
export const CreateServiceAccountPage = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -29,7 +30,7 @@ export const CreateServiceAccountPage = () => {
|
|||||||
serviceAccountId={serviceAccountId}
|
serviceAccountId={serviceAccountId}
|
||||||
/>
|
/>
|
||||||
<div className="mt-8">
|
<div className="mt-8">
|
||||||
<CopyServiceAccountIDSection
|
<CopyServiceAccountPublicKeySection
|
||||||
serviceAccountId={serviceAccountId}
|
serviceAccountId={serviceAccountId}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+53
@@ -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 />
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export { CopyServiceAccountPublicKeySection } from './CopyServiceAccountPublicKeySection';
|
||||||
+2
-1
@@ -40,7 +40,8 @@ import {
|
|||||||
useDeleteServiceAccountProjectLevelPermission,
|
useDeleteServiceAccountProjectLevelPermission,
|
||||||
useGetServiceAccountById,
|
useGetServiceAccountById,
|
||||||
useGetServiceAccountProjectLevelPermissions,
|
useGetServiceAccountProjectLevelPermissions,
|
||||||
useGetUserWorkspaces} from '@app/hooks/api';
|
useGetUserWorkspaces
|
||||||
|
} from '@app/hooks/api';
|
||||||
import getLatestFileKey from '@app/pages/api/workspace/getLatestFileKey';
|
import getLatestFileKey from '@app/pages/api/workspace/getLatestFileKey';
|
||||||
|
|
||||||
const createProjectLevelPermissionSchema = yup.object({
|
const createProjectLevelPermissionSchema = yup.object({
|
||||||
|
|||||||
+1
-1
@@ -58,7 +58,7 @@ export const ServiceAccountNameChangeSection = ({
|
|||||||
onSubmit={handleSubmit(onFormSubmit)}
|
onSubmit={handleSubmit(onFormSubmit)}
|
||||||
className="rounded-md bg-white/5 p-6"
|
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">
|
<div className="mb-2 w-full max-w-lg">
|
||||||
{!isServiceAccountLoading && (
|
{!isServiceAccountLoading && (
|
||||||
<Controller
|
<Controller
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export { CopyServiceAccountIDSection } from './CopyServiceAccountIDSection';
|
export { CopyServiceAccountIDSection } from './CopyServiceAccountIDSection';
|
||||||
|
export { CopyServiceAccountPublicKeySection } from './CopyServiceAccountPublicKeySection';
|
||||||
export { SAProjectLevelPermissionsTable } from './SAProjectLevelPermissionsTable';
|
export { SAProjectLevelPermissionsTable } from './SAProjectLevelPermissionsTable';
|
||||||
export { ServiceAccountNameChangeSection } from './ServiceAccountNameChangeSection';
|
export { ServiceAccountNameChangeSection } from './ServiceAccountNameChangeSection';
|
||||||
+27
-1
@@ -65,8 +65,10 @@ export const OrgServiceAccountsTable = () => {
|
|||||||
const orgId = currentOrg?._id || '';
|
const orgId = currentOrg?._id || '';
|
||||||
const [step, setStep] = useState(0);
|
const [step, setStep] = useState(0);
|
||||||
const [isAccessKeyCopied, setIsAccessKeyCopied] = useToggle(false);
|
const [isAccessKeyCopied, setIsAccessKeyCopied] = useToggle(false);
|
||||||
|
const [isPublicKeyCopied, setIsPublicKeyCopied] = useToggle(false);
|
||||||
const [isPrivateKeyCopied, setIsPrivateKeyCopied] = useToggle(false);
|
const [isPrivateKeyCopied, setIsPrivateKeyCopied] = useToggle(false);
|
||||||
const [accessKey, setAccessKey] = useState('');
|
const [accessKey, setAccessKey] = useState('');
|
||||||
|
const [publicKey, setPublicKey] = useState('');
|
||||||
const [privateKey, setPrivateKey] = useState('');
|
const [privateKey, setPrivateKey] = useState('');
|
||||||
const [searchServiceAccountFilter, setSearchServiceAccountFilter] = useState('');
|
const [searchServiceAccountFilter, setSearchServiceAccountFilter] = useState('');
|
||||||
const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
|
const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
|
||||||
@@ -85,12 +87,16 @@ export const OrgServiceAccountsTable = () => {
|
|||||||
timer = setTimeout(() => setIsAccessKeyCopied.off(), 2000);
|
timer = setTimeout(() => setIsAccessKeyCopied.off(), 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPublicKeyCopied) {
|
||||||
|
timer = setTimeout(() => setIsPublicKeyCopied.off(), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
if (isPrivateKeyCopied) {
|
if (isPrivateKeyCopied) {
|
||||||
timer = setTimeout(() => setIsPrivateKeyCopied.off(), 2000);
|
timer = setTimeout(() => setIsPrivateKeyCopied.off(), 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [isAccessKeyCopied, isPrivateKeyCopied]);
|
}, [isAccessKeyCopied, isPublicKeyCopied, isPrivateKeyCopied]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -103,6 +109,7 @@ export const OrgServiceAccountsTable = () => {
|
|||||||
if (!currentOrg?._id) return;
|
if (!currentOrg?._id) return;
|
||||||
|
|
||||||
const keyPair = generateKeyPair();
|
const keyPair = generateKeyPair();
|
||||||
|
setPublicKey(keyPair.publicKey);
|
||||||
setPrivateKey(keyPair.privateKey);
|
setPrivateKey(keyPair.privateKey);
|
||||||
|
|
||||||
const serviceAccountDetails = await createServiceAccount.mutateAsync({
|
const serviceAccountDetails = await createServiceAccount.mutateAsync({
|
||||||
@@ -216,6 +223,24 @@ export const OrgServiceAccountsTable = () => {
|
|||||||
</span>
|
</span>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</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>
|
<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]">
|
<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>
|
<p className="mr-4 break-all">{privateKey}</p>
|
||||||
@@ -234,6 +259,7 @@ export const OrgServiceAccountsTable = () => {
|
|||||||
</span>
|
</span>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user