diff --git a/frontend/components/dashboard/SideBar.tsx b/frontend/components/dashboard/SideBar.tsx index 454f0c6c6..03499b4d9 100644 --- a/frontend/components/dashboard/SideBar.tsx +++ b/frontend/components/dashboard/SideBar.tsx @@ -149,6 +149,7 @@ const SideBar = ({ isFull={true} /> */} + secret.type == "shared")[0]?.comment} modifyComment={modifyComment} position={data[0].pos} />
diff --git a/frontend/components/utilities/secrets/getSecretsForProject.ts b/frontend/components/utilities/secrets/getSecretsForProject.ts index de034323f..57f0e4a16 100644 --- a/frontend/components/utilities/secrets/getSecretsForProject.ts +++ b/frontend/components/utilities/secrets/getSecretsForProject.ts @@ -15,6 +15,7 @@ interface SecretProps { value: string; type: 'personal' | 'shared'; comment: string; + id: string; } interface Props { @@ -85,6 +86,7 @@ const getSecretsForProject = async ({ } tempFileState.push({ + id: secretPair._id, key: plainTextKey, value: plainTextValue, type: secretPair.type, @@ -97,7 +99,7 @@ const getSecretsForProject = async ({ setData( tempFileState.map((line, index) => { return { - id: guidGenerator(), + id: line['id'], pos: index, key: line['key'], value: line['value'], @@ -109,7 +111,7 @@ const getSecretsForProject = async ({ return tempFileState.map((line, index) => { return { - id: guidGenerator(), + id: line['id'], pos: index, key: line['key'], value: line['value'], diff --git a/frontend/ee/api/secrets/GetSecretVersions.ts b/frontend/ee/api/secrets/GetSecretVersions.ts new file mode 100644 index 000000000..8185234e6 --- /dev/null +++ b/frontend/ee/api/secrets/GetSecretVersions.ts @@ -0,0 +1,40 @@ +import SecurityClient from '~/utilities/SecurityClient'; + + +interface secretVersionProps { + secretId: string; + offset: number; + limit: number; +} + +/** + * This function fetches the versions of a specific secret + * @param {object} obj + * @param {string} obj.secretId - the id of a secret for which we are fetching the version history + * @param {number} obj.offset - the start of our query + * @param {number} obj.limit - how far our query goes + * @returns + */ +const getSecretVersions = async ({ secretId, offset, limit }: secretVersionProps) => { + return SecurityClient.fetchCall( + '/api/v1/secret/' + secretId + '/secret-versions?'+ + new URLSearchParams({ + offset: String(offset), + limit: String(limit) + }), + { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + } + ).then(async (res) => { + if (res && res.status == 200) { + return await res.json(); + } else { + console.log('Failed to get project secrets'); + } + }); +}; + +export default getSecretVersions; diff --git a/frontend/ee/components/SecretVersionList.tsx b/frontend/ee/components/SecretVersionList.tsx index a2147c2af..0bc8d6740 100644 --- a/frontend/ee/components/SecretVersionList.tsx +++ b/frontend/ee/components/SecretVersionList.tsx @@ -1,38 +1,95 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/router'; import { faCircle, faDotCircle } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import getSecretVersions from 'ee/api/secrets/GetSecretVersions'; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -interface SecretVersionListProps {} +import { decryptAssymmetric, decryptSymmetric } from '~/components/utilities/cryptography/crypto'; +import getLatestFileKey from '~/pages/api/workspace/getLatestFileKey'; + +interface DecryptedSecretVersionListProps { + createdAt: string; + value: string; +} + +interface EncrypetedSecretVersionListProps { + createdAt: string; + secretValueCiphertext: string; + secretValueIV: string; + secretValueTag: string; +} -const versionData = [{ - value: "Value1", - date: "Date1", - user: "vlad@infisical.com" -}, { - value: "Value2", - date: "Date2", - user: "tony@infisical.com" -}] /** - * @returns a list of the versions for a specific secret + * @returns a list of versions for a specific secret */ -const SecretVersionList = () => { +const SecretVersionList = ({ secretId }: { secretId: string; }) => { + const router = useRouter(); + const [secretVersions, setSecretVersions] = useState([{createdAt: "123", value: "124"}]); + + useEffect(() => { + const getSecretVersionHistory = async () => { + try { + const encryptedSecretVersions = await getSecretVersions({ secretId, offset: 0, limit: 10}); + const latestKey = await getLatestFileKey({ workspaceId: String(router.query.id) }) + + const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY'); + + let decryptedLatestKey: string; + if (latestKey) { + // assymmetrically decrypt symmetric key with local private key + decryptedLatestKey = decryptAssymmetric({ + ciphertext: latestKey.latestKey.encryptedKey, + nonce: latestKey.latestKey.nonce, + publicKey: latestKey.latestKey.sender.publicKey, + privateKey: String(PRIVATE_KEY) + }); + } + + const decryptedSecretVersions = encryptedSecretVersions.secretVersions.map((encryptedSecretVersion: EncrypetedSecretVersionListProps) => { + return { + createdAt: encryptedSecretVersion.createdAt, + value: decryptSymmetric({ + ciphertext: encryptedSecretVersion.secretValueCiphertext, + iv: encryptedSecretVersion.secretValueIV, + tag: encryptedSecretVersion.secretValueTag, + key: decryptedLatestKey + }) + } + }) + + setSecretVersions(decryptedSecretVersions); + } catch (error) { + console.log(error) + } + }; + getSecretVersionHistory(); + }, []); + return

Version History

-
- {versionData.map((version, index) => +
+ {secretVersions?.sort((a, b) => b.createdAt.localeCompare(a.createdAt)) + .map((version: DecryptedSecretVersionListProps, index: number) =>
-
{version.date}
+
+ {(new Date(version.createdAt)).toLocaleDateString('en-US', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + })} +

Value:{version.value}

-

Updated by:{version.user}

+ {/*

Updated by:{version.user}

*/}
)} diff --git a/frontend/public/images/invitation-expired.svg b/frontend/public/images/invitation-expired.svg new file mode 100644 index 000000000..0daf7eda4 --- /dev/null +++ b/frontend/public/images/invitation-expired.svg @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +