130 lines
4.3 KiB
TypeScript
130 lines
4.3 KiB
TypeScript
import { useEncryptionKey } from '@/contexts/encryption-key-context';
|
|
import { cn } from '@/lib/utils';
|
|
import { __ } from '@/utils/i18n';
|
|
import { LockKeyhole, LockKeyholeOpen } from 'lucide-react';
|
|
import { useEffect, useState } from 'react';
|
|
import { Button } from './ui/button';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from './ui/dialog';
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipProvider,
|
|
TooltipTrigger,
|
|
} from './ui/tooltip';
|
|
import UnlockMessageDialog from './unlock-message-dialog';
|
|
|
|
export function EncryptionKeyButton() {
|
|
const {
|
|
isKeySet,
|
|
encryptedMessageData,
|
|
fetchEncryptedMessage,
|
|
clearEncryptionKey,
|
|
} = useEncryptionKey();
|
|
const [showUnlockDialog, setShowUnlockDialog] = useState(false);
|
|
const [showClearDialog, setShowClearDialog] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (!encryptedMessageData) {
|
|
fetchEncryptedMessage();
|
|
}
|
|
}, [encryptedMessageData, fetchEncryptedMessage]);
|
|
|
|
function handleClick() {
|
|
if (isKeySet) {
|
|
setShowClearDialog(true);
|
|
} else {
|
|
if (!encryptedMessageData) {
|
|
fetchEncryptedMessage();
|
|
}
|
|
setShowUnlockDialog(true);
|
|
}
|
|
}
|
|
|
|
function handleClearKey() {
|
|
clearEncryptionKey();
|
|
setShowClearDialog(false);
|
|
}
|
|
|
|
function handleUnlock() {
|
|
setShowUnlockDialog(false);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<TooltipProvider>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className={cn(
|
|
'h-8 w-8',
|
|
!isKeySet && 'unlock-button-pulse',
|
|
)}
|
|
onClick={handleClick}
|
|
aria-label={
|
|
isKeySet
|
|
? __('Lock encryption key')
|
|
: __('Unlock encryption key')
|
|
}
|
|
>
|
|
{isKeySet ? (
|
|
<LockKeyholeOpen className="h-5 w-5" />
|
|
) : (
|
|
<LockKeyhole className="h-5 w-5" />
|
|
)}
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
{isKeySet
|
|
? __('Click to lock encryption key')
|
|
: __('Click to unlock encryption key')}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
|
|
{encryptedMessageData && (
|
|
<UnlockMessageDialog
|
|
open={showUnlockDialog}
|
|
onOpenChange={setShowUnlockDialog}
|
|
onUnlock={handleUnlock}
|
|
encryptedContent={encryptedMessageData.encrypted_content}
|
|
iv={encryptedMessageData.iv}
|
|
salt={encryptedMessageData.salt}
|
|
/>
|
|
)}
|
|
|
|
<Dialog open={showClearDialog} onOpenChange={setShowClearDialog}>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>{__('Clear Encryption Key?')}</DialogTitle>
|
|
<DialogDescription>
|
|
{__(
|
|
"This will remove your encryption key from this browser session. You'll need to enter your password again to unlock encrypted content.",
|
|
)}
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<DialogFooter>
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => setShowClearDialog(false)}
|
|
>
|
|
{__('Cancel')}
|
|
</Button>
|
|
<Button onClick={handleClearKey}>
|
|
{__('Clear Key')}
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</>
|
|
);
|
|
}
|