Skip to content

Commit

Permalink
Connected version history to backend
Browse files Browse the repository at this point in the history
  • Loading branch information
vmatsiiako committed Dec 27, 2022
1 parent 2c63559 commit bb4d3ba
Show file tree
Hide file tree
Showing 5 changed files with 425 additions and 20 deletions.
1 change: 1 addition & 0 deletions frontend/components/dashboard/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ const SideBar = ({
isFull={true}
/>
</div> */}
<SecretVersionList secretId={data[0].id} />
<CommentField comment={data.filter(secret => secret.type == "shared")[0]?.comment} modifyComment={modifyComment} position={data[0].pos} />
</div>
<div className={`flex justify-start max-w-sm mt-4 px-4 mt-full mb-[4.7rem]`}>
Expand Down
6 changes: 4 additions & 2 deletions frontend/components/utilities/secrets/getSecretsForProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface SecretProps {
value: string;
type: 'personal' | 'shared';
comment: string;
id: string;
}

interface Props {
Expand Down Expand Up @@ -85,6 +86,7 @@ const getSecretsForProject = async ({
}

tempFileState.push({
id: secretPair._id,
key: plainTextKey,
value: plainTextValue,
type: secretPair.type,
Expand All @@ -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'],
Expand All @@ -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'],
Expand Down
40 changes: 40 additions & 0 deletions frontend/ee/api/secrets/GetSecretVersions.ts
Original file line number Diff line number Diff line change
@@ -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;
93 changes: 75 additions & 18 deletions frontend/ee/components/SecretVersionList.tsx
Original file line number Diff line number Diff line change
@@ -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: "[email protected]"
}, {
value: "Value2",
date: "Date2",
user: "[email protected]"
}]

/**
* @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<DecryptedSecretVersionListProps[]>([{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 <div className='w-full h-52 px-4 mt-4 text-sm text-bunker-300 overflow-x-none'>
<p className=''>Version History</p>
<div className='p-1 rounded-md bg-bunker-800 border border-mineshaft-500 overflow-x-none'>
<div className='h-48 overflow-y-scroll overflow-x-none'>
{versionData.map((version, index) =>
<div className='h-48 overflow-y-auto overflow-x-none'>
{secretVersions?.sort((a, b) => b.createdAt.localeCompare(a.createdAt))
.map((version: DecryptedSecretVersionListProps, index: number) =>
<div key={index} className='flex flex-row'>
<div className='pr-1 flex flex-col items-center'>
<div className='p-1'><FontAwesomeIcon icon={index == 0 ? faDotCircle : faCircle} /></div>
<div className='w-0 h-full border-l mt-1'></div>
</div>
<div className='flex flex-col w-full max-w-[calc(100%-2.3rem)]'>
<div className='pr-2 pt-1'>{version.date}</div>
<div className='pr-2 pt-1'>
{(new Date(version.createdAt)).toLocaleDateString('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
})}
</div>
<div className=''><p className='break-words'><span className='py-0.5 px-1 rounded-md bg-primary-200/10 mr-1.5'>Value:</span>{version.value}</p></div>
<div className=''><p className='break-words'><span className='py-0.5 px-1 rounded-md bg-primary-200/10 mr-1.5'>Updated by:</span>{version.user}</p></div>
{/* <div className=''><p className='break-words'><span className='py-0.5 px-1 rounded-md bg-primary-200/10 mr-1.5'>Updated by:</span>{version.user}</p></div> */}
</div>
</div>
)}
Expand Down
Loading

0 comments on commit bb4d3ba

Please sign in to comment.