Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: misc cleanup for secret history optimization #411

Merged
merged 6 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions frontend/components/environments/secrets/HistoryDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { relativeTimeFromDates } from '@/utils/time'
import clsx from 'clsx'
import { GetSecretHistory } from '@/graphql/queries/secrets/getSecretHistory.gql'
import { useState, Fragment, useEffect, useContext } from 'react'
import { FaHistory, FaTimes, FaKey } from 'react-icons/fa'
import { FaHistory, FaKey, FaRobot, FaTimes } from 'react-icons/fa'
import { SecretPropertyDiffs } from './SecretPropertyDiffs'
import { Button } from '../../common/Button'
import { Dialog, Transition } from '@headlessui/react'
Expand Down Expand Up @@ -86,23 +86,21 @@ export const HistoryDialog = ({

const { publicKey, privateKey } = await envKeyring(seed)

console.log('decrupting', data.secrets[0].id)

const decryptedSecret = await decryptSecretHistory(data.secrets[0], {
privateKey,
publicKey,
salt: '',
})

setClientSecret(decryptedSecret)
console.log('Decrypted secret:', decryptedSecret)
}
} catch (error) {
console.error('Error fetching or decrypting secret history:', error)
}
}

if (keyring && isOpen) fetchAndDecryptHistory()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [keyring, isOpen, secret, getHistory])

const getEventTypeColor = (eventType: ApiSecretEventEventTypeChoices) => {
Expand All @@ -119,6 +117,32 @@ export const HistoryDialog = ({
if (eventType === ApiSecretEventEventTypeChoices.D) return 'Deleted'
}

const eventCreatedBy = (log: SecretEventType) => {
if (log.user)
return (
<div className="flex items-center gap-1 text-sm">
<Avatar imagePath={log.user?.avatarUrl!} size="sm" />
{log.user.fullName || log.user.email}
</div>
)
else if (log.serviceToken)
return (
<div className="flex items-center gap-1 text-sm">
<FaKey /> {log.serviceToken ? log.serviceToken.name : 'Service token'}
</div>
)
else if (log.serviceAccount)
return (
<div className="flex items-center gap-1 text-sm">
<div className="rounded-full flex items-center bg-neutral-500/40 justify-center size-6">
<FaRobot className=" text-zinc-900 dark:text-zinc-100" />
</div>{' '}
{log.serviceAccount.name}
{log.serviceAccountToken && ` (${log.serviceAccountToken.name})`}
</div>
)
}

const secretHistory = clientSecret?.history

return (
Expand Down Expand Up @@ -193,17 +217,16 @@ export const HistoryDialog = ({
<div className="text-zinc-800 dark:text-zinc-200 font-semibold">
{getEventTypeText(historyItem!.eventType)}
</div>
<div className="text-neutral-500 text-sm">
<div
className="text-neutral-500 text-sm"
title={new Date(historyItem!.timestamp).toLocaleTimeString()}
>
{relativeTimeFromDates(new Date(historyItem!.timestamp))}
</div>{' '}
<div className="text-sm flex items-center gap-2 text-neutral-500">
{historyItem!.user && (
<div className="flex items-center gap-1 text-sm">
by{' '}
<Avatar imagePath={historyItem!.user.avatarUrl!} size="sm" />
{historyItem?.user.fullName || historyItem?.user.email}
</div>
)}
</div>
<span className="text-neutral-500 text-sm">by</span>

<div className="text-zinc-900 dark:text-zinc-100">
{eventCreatedBy(historyItem!)}
</div>
</div>
{index > 0 && (
Expand All @@ -212,6 +235,7 @@ export const HistoryDialog = ({
historyItem={historyItem!}
index={index}
handlePropertyChange={handlePropertyChange}
onRestore={closeModal}
/>
)}
</div>
Expand Down
34 changes: 21 additions & 13 deletions frontend/components/environments/secrets/SecretPropertyDiffs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ import { FaRedoAlt, FaUndoAlt } from 'react-icons/fa'
import { Button } from '../../common/Button'
import { Tag } from '../Tag'

export const SecretPropertyDiffs = (props: {
export const SecretPropertyDiffs = ({
secret,
historyItem,
index,
handlePropertyChange,
onRestore,
}: {
secret: SecretType
historyItem: SecretEventType
index: number
handlePropertyChange: Function
onRestore: Function
}) => {
const { secret, historyItem, index, handlePropertyChange } = props

const previousItem = secret.history![index - 1]!

const getAddedTags = () => {
Expand All @@ -30,6 +35,7 @@ export const SecretPropertyDiffs = (props: {

const handleRestoreValue = (value: string) => {
handlePropertyChange(secret.id, 'value', value)
onRestore()
}

return (
Expand All @@ -51,19 +57,21 @@ export const SecretPropertyDiffs = (props: {
<div className="flex items-center gap-2">
<span className="text-neutral-500 mr-2">VALUE:</span>
</div>
<div className="flex flex-col">
<div className="flex flex-col w-full">
<div className="flex-1 items-end gap-4 justify-between bg-red-200 dark:bg-red-950">
<div>
<s className=" text-red-500 ph-no-capture">{previousItem.value}</s>
</div>
<Button
variant="outline"
onClick={() => handleRestoreValue(previousItem.value)}
title="Restore this value"
>
<FaRedoAlt className="shrink-0" />
<span className="font-sans text-xs">Restore</span>
</Button>
<div className="flex items-center justify-end p-1">
<Button
variant="outline"
onClick={() => handleRestoreValue(previousItem.value)}
title="Restore this value"
>
<FaRedoAlt className="shrink-0 text-2xs" />
<span className="font-sans text-2xs">Restore</span>
</Button>
</div>
</div>
<span className="bg-emerald-100 dark:bg-emerald-950 text-emerald-500 ph-no-capture">
{historyItem!.value}
Expand All @@ -83,7 +91,7 @@ export const SecretPropertyDiffs = (props: {
</span>
</div>
)}

{historyItem!.path !== previousItem.path && (
<div className="pl-3 font-mono break-all">
<span className="text-neutral-500 mr-2">PATH:</span>
Expand Down
Loading