import { enableEncryption, revealWorkspaceKey, setWorkspaceKey } from '@yaakapp-internal/crypto'; import type { WorkspaceMeta } from '@yaakapp-internal/models'; import classNames from 'classnames'; import { useAtomValue } from 'jotai/index'; import { useEffect, useState } from 'react'; import { activeWorkspaceAtom, activeWorkspaceMetaAtom } from '../hooks/useActiveWorkspace'; import { createFastMutation } from '../hooks/useFastMutation'; import { useStateWithDeps } from '../hooks/useStateWithDeps'; import { CopyIconButton } from './CopyIconButton'; import { Banner } from './core/Banner'; import type { ButtonProps } from './core/Button'; import { Button } from './core/Button'; import { IconButton } from './core/IconButton'; import { IconTooltip } from './core/IconTooltip'; import { Label } from './core/Label'; import { PlainInput } from './core/PlainInput'; import { HStack, VStack } from './core/Stacks'; import { EncryptionHelp } from './EncryptionHelp'; interface Props { size?: ButtonProps['size']; expanded?: boolean; onDone?: () => void; onEnabledEncryption?: () => void; } export function WorkspaceEncryptionSetting({ size, expanded, onDone, onEnabledEncryption }: Props) { const [justEnabledEncryption, setJustEnabledEncryption] = useState(false); const workspace = useAtomValue(activeWorkspaceAtom); const workspaceMeta = useAtomValue(activeWorkspaceMetaAtom); if (workspace == null || workspaceMeta == null) { return null; } if (workspace.encryptionKeyChallenge && workspaceMeta.encryptionKey == null) { return ( { onDone?.(); onEnabledEncryption?.(); }} /> ); } if (workspaceMeta.encryptionKey) { const keyRevealer = ( ); return ( {justEnabledEncryption && ( {helpAfterEncryption} )} {keyRevealer} {onDone && ( )} ); } return (
{expanded ? ( ) : ( )}
); } const setWorkspaceKeyMut = createFastMutation({ mutationKey: ['set-workspace-key'], mutationFn: setWorkspaceKey, }); function EnterWorkspaceKey({ workspaceMeta, onEnabled, }: { workspaceMeta: WorkspaceMeta; onEnabled?: () => void; }) { const [key, setKey] = useState(''); return ( This workspace contains encrypted values but no key is configured. Please enter the workspace key to access the encrypted data. { e.preventDefault(); setWorkspaceKeyMut.mutate( { workspaceId: workspaceMeta.workspaceId, key: key.trim(), }, { onSuccess: onEnabled }, ); }} > ); } function KeyRevealer({ workspaceId, defaultShow = false, disableLabel = false, }: { workspaceId: string; defaultShow?: boolean; disableLabel?: boolean; }) { const [key, setKey] = useState(null); const [show, setShow] = useStateWithDeps(defaultShow, [defaultShow]); useEffect(() => { revealWorkspaceKey(workspaceId).then(setKey); }, [setKey, workspaceId]); if (key == null) return null; return (
{!disableLabel && ( workspace encryption key{' '} )} {key && } {key && } setShow((v) => !v)} />
); } function HighlightedKey({ keyText, show }: { keyText: string; show: boolean }) { return ( {show ? ( keyText.split('').map((c, i) => { return ( {c} ); }) ) : (
•••••••••••••••••••••
)}
); } const helpAfterEncryption = (

this key is used for any encryption used for this workspace. It is stored securely using your OS keychain, but it is recommended to back it up. If you share this workspace with others, you'll need to send them this key to access any encrypted values.

);