From fbc106b5c1f03c0f3fa7abc435fca4cf84f28a95 Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Thu, 17 Nov 2022 10:06:37 +0800 Subject: [PATCH] Scaffold enc keys ui part 2 --- .../Vault/EncryptionKeysManagement.tsx | 75 +++++++++++++++---- studio/pages/project/[ref]/settings/vault.tsx | 2 +- studio/stores/project/VaultStore.ts | 30 ++++++-- 3 files changed, 87 insertions(+), 20 deletions(-) diff --git a/studio/components/interfaces/Settings/Vault/EncryptionKeysManagement.tsx b/studio/components/interfaces/Settings/Vault/EncryptionKeysManagement.tsx index 08ca7f372b7..810dd46b676 100644 --- a/studio/components/interfaces/Settings/Vault/EncryptionKeysManagement.tsx +++ b/studio/components/interfaces/Settings/Vault/EncryptionKeysManagement.tsx @@ -1,13 +1,27 @@ import { observer } from 'mobx-react-lite' -import { FC, Fragment, useEffect, useState } from 'react' -import { Input, IconSearch, Listbox, Button, Divider, Modal, Form, IconHelpCircle } from 'ui' +import { FC, Fragment, useState } from 'react' +import { + Input, + IconSearch, + Listbox, + Button, + Divider, + Modal, + Form, + IconHelpCircle, + IconTrash, + Badge, +} from 'ui' import EncryptionKeySelector from './EncryptionKeySelector' import InformationBox from 'components/ui/InformationBox' import { useStore } from 'hooks' +import dayjs from 'dayjs' -interface Props {} +interface Props { + onSelectRemove: (key: any) => void +} -const EncryptionKeysManagement: FC = ({}) => { +const EncryptionKeysManagement: FC = ({ onSelectRemove }) => { const { vault } = useStore() const [searchValue, setSearchValue] = useState('') @@ -15,7 +29,13 @@ const EncryptionKeysManagement: FC = ({}) => { const [showAddKeyModal, setShowAddKeyModal] = useState(false) const [selectedKeyToRemove, setSelectedKeyToRemove] = useState() - console.log('keys', vault.listKeys()) + const keys = searchValue + ? vault.listKeys( + (key: any) => + (key?.comment ?? '').toLowerCase().includes(searchValue.toLowerCase()) || + key.id.toLowerCase().includes(searchValue.toLowerCase()) + ) + : vault.listKeys() return ( <> @@ -48,22 +68,49 @@ const EncryptionKeysManagement: FC = ({}) => { {/* Table of secrets */} - {/*
- {secrets.map((secret, idx) => { +
+ {keys.map((key, idx) => { return ( - - - {idx !== mockSecrets.length - 1 && } + +
+
+

+ {key.comment || 'Unnamed'} +

+

+ {key.id} +

+
+
+ {key.status === 'default' && Default} +
+
+

+ Added on {dayjs(key.created).format('MMM D, YYYY')} +

+
+
+ {idx !== keys.length - 1 && }
) })} - {secrets.length === 0 && ( + {keys.length === 0 && ( <> {searchValue.length === 0 ? (
-

No secrets added yet

+

No encryption keys added yet

- The Vault allows you to store sensitive information like API keys + Encryption keys are created by the pgsodium extension and can be used to encrypt + your columns and secrets

) : ( @@ -76,7 +123,7 @@ const EncryptionKeysManagement: FC = ({}) => { )} )} -
*/} +
{ {/* Show encryption keys table if vault extension is enabled */} - + {}} /> {/* Show secrets table if vault extension is enabled */} diff --git a/studio/stores/project/VaultStore.ts b/studio/stores/project/VaultStore.ts index 4da6e993cba..125caf45bef 100644 --- a/studio/stores/project/VaultStore.ts +++ b/studio/stores/project/VaultStore.ts @@ -9,10 +9,20 @@ export interface IVaultStore { error: any load: () => void - listKeys: () => any[] - listSecrets: () => any[] + listKeys: (filter?: any) => EncryptionKey[] + listSecrets: () => Secret[] } +interface EncryptionKey { + id: string + key_id: number + comment: string + created: string + status: string +} + +interface Secret {} + export default class VaultStore implements IVaultStore { rootStore: IRootStore @@ -23,7 +33,7 @@ export default class VaultStore implements IVaultStore { LOADED: 'loaded', } - data: any = { keys: [], secrets: [] } + data: { keys: EncryptionKey[]; secrets: Secret[] } = { keys: [], secrets: [] } state = this.STATES.INITIAL error = null @@ -76,12 +86,22 @@ export default class VaultStore implements IVaultStore { } } + // Always return the default key as the first result listKeys(filter?: any) { const arr = this.data.keys.slice() + if (!!filter) { - return arr.filter(filter).sort((a: any, b: any) => b.key_id - a.key_id) + const filteredResults = arr.filter(filter).sort((a: any, b: any) => a.key_id - b.key_id) + const defaultKey = filteredResults.find((key) => key.status === 'default') as EncryptionKey + + if (defaultKey === undefined) return filteredResults + else return [defaultKey].concat(filteredResults.filter((key) => key.status !== 'default')) } else { - return arr.sort((a: any, b: any) => b.key_id - a.key_id) + const results = arr.sort((a: any, b: any) => a.key_id - b.key_id) + const defaultKey = results.find((key) => key.status === 'default') as EncryptionKey + + if (defaultKey === undefined) return results + return [defaultKey].concat(results.filter((key) => key.status !== 'default')) } }