import { useEffect, useState } from 'react'; import { Head, router } from '@inertiajs/react'; import axios from 'axios'; import InputError from '@/components/input-error'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Spinner } from '@/components/ui/spinner'; import AuthLayout from '@/layouts/auth-layout'; import { bufferToBase64, encrypt, exportKey, generateSalt, getAESKeyFromPBKDF, getKeyFromPassword, } from '@/lib/crypto'; import { storeKey } from '@/lib/key-storage'; import { dashboard } from '@/routes'; export default function SetupEncryption() { const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [storagePreference, setStoragePreference] = useState< 'session' | 'persistent' >('session'); const [processing, setProcessing] = useState(false); const [cryptoAvailable, setCryptoAvailable] = useState(true); const [errors, setErrors] = useState<{ password?: string; confirmPassword?: string; general?: string; }>({}); useEffect(() => { if (!window.crypto || !window.crypto.subtle) { setCryptoAvailable(false); setErrors({ general: 'Web Crypto API is not available. Please ensure you are accessing this page via HTTPS or localhost.', }); } }, []); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setErrors({}); if (password.length < 12) { setErrors({ password: 'Encryption password must be at least 12 characters', }); return; } if (password !== confirmPassword) { setErrors({ confirmPassword: 'Passwords do not match', }); return; } setProcessing(true); try { const salt = generateSalt(); const pbkdfKey = await getKeyFromPassword(password); const aesKey = await getAESKeyFromPBKDF(pbkdfKey, salt); const { encrypted, iv } = await encrypt('Hello, world', aesKey); const exportedKey = await exportKey(aesKey); await axios.post('/api/encryption/setup', { salt: bufferToBase64(salt), encrypted_content: encrypted, iv: iv, }); storeKey(exportedKey, storagePreference === 'persistent'); router.visit(dashboard().url); } catch (error) { console.error('Encryption setup error:', error); setErrors({ general: 'Failed to setup encryption. Please try again or contact support.', }); setProcessing(false); } } return (
setPassword(e.target.value)} placeholder="Enter a strong encryption password" disabled={processing} />

Use a strong password (minimum 12 characters). This password will encrypt your data.

setConfirmPassword(e.target.value)} placeholder="Confirm your encryption password" disabled={processing} />

Session storage clears when you close your browser. Persistent storage keeps your key until manually cleared.

{errors.general && (
{errors.general}
)}
); }