Remove encryption UI from Chat page, use plaintext messages
This commit is contained in:
+8
-124
@@ -7,9 +7,8 @@ import { Input } from '@/components/ui/input';
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
import { useChatStore } from '@/stores/chat-store';
|
||||
import { useFriendsStore } from '@/stores/friends-store';
|
||||
import { getCurrentPrivateKey, hasStoredKey, setupEncryption, unlockEncryption } from '@/lib/crypto';
|
||||
import { toast } from 'sonner';
|
||||
import { ArrowLeft, Send, Lock, AlertTriangle, Loader2 } from 'lucide-react';
|
||||
import { ArrowLeft, Send, Loader2 } from 'lucide-react';
|
||||
|
||||
export default function Chat() {
|
||||
const { friendId } = useParams<{ friendId: string }>();
|
||||
@@ -31,11 +30,6 @@ export default function Chat() {
|
||||
|
||||
const [input, setInput] = useState('');
|
||||
const [sending, setSending] = useState(false);
|
||||
const [encryptionReady, setEncryptionReady] = useState(false);
|
||||
const [needsSetup, setNeedsSetup] = useState(false);
|
||||
const [needsUnlock, setNeedsUnlock] = useState(false);
|
||||
const [password, setPassword] = useState('');
|
||||
const [settingUp, setSettingUp] = useState(false);
|
||||
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||
@@ -48,84 +42,28 @@ export default function Chat() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check encryption state
|
||||
checkEncryptionState();
|
||||
|
||||
return () => {
|
||||
clearChat();
|
||||
};
|
||||
}, [user, navigate, clearChat]);
|
||||
|
||||
useEffect(() => {
|
||||
if (encryptionReady && friendId) {
|
||||
if (friendId) {
|
||||
connect();
|
||||
openConversation(friendId);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (encryptionReady) disconnect();
|
||||
clearChat();
|
||||
disconnect();
|
||||
};
|
||||
}, [encryptionReady, friendId, connect, disconnect, openConversation]);
|
||||
}, [user, friendId, navigate, connect, disconnect, openConversation, clearChat]);
|
||||
|
||||
useEffect(() => {
|
||||
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
}, [messages]);
|
||||
|
||||
async function checkEncryptionState() {
|
||||
if (getCurrentPrivateKey()) {
|
||||
setEncryptionReady(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const hasKey = await hasStoredKey();
|
||||
if (hasKey) {
|
||||
setNeedsUnlock(true);
|
||||
} else {
|
||||
setNeedsSetup(true);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSetup() {
|
||||
if (!password) return;
|
||||
setSettingUp(true);
|
||||
try {
|
||||
await setupEncryption(password);
|
||||
setEncryptionReady(true);
|
||||
setNeedsSetup(false);
|
||||
toast.success('Encryption keys generated!');
|
||||
} catch {
|
||||
toast.error('Failed to set up encryption');
|
||||
} finally {
|
||||
setSettingUp(false);
|
||||
setPassword('');
|
||||
}
|
||||
}
|
||||
|
||||
async function handleUnlock() {
|
||||
if (!password) return;
|
||||
setSettingUp(true);
|
||||
try {
|
||||
const success = await unlockEncryption(password);
|
||||
if (success) {
|
||||
setEncryptionReady(true);
|
||||
setNeedsUnlock(false);
|
||||
} else {
|
||||
toast.error('Incorrect password');
|
||||
}
|
||||
} catch {
|
||||
toast.error('Failed to unlock encryption');
|
||||
} finally {
|
||||
setSettingUp(false);
|
||||
setPassword('');
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSend(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
if (!input.trim() || !friendId || sending) return;
|
||||
|
||||
setSending(true);
|
||||
try {
|
||||
await sendMessage(friendId, input.trim());
|
||||
sendMessage(friendId, input.trim());
|
||||
setInput('');
|
||||
} catch {
|
||||
toast.error('Failed to send message');
|
||||
@@ -144,50 +82,6 @@ export default function Chat() {
|
||||
|
||||
if (!user) return null;
|
||||
|
||||
// Encryption setup/unlock screens
|
||||
if (needsSetup || needsUnlock) {
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className="mx-auto max-w-sm space-y-6 pt-12">
|
||||
<div className="text-center">
|
||||
<Lock className="mx-auto mb-4 h-12 w-12 text-muted-foreground" />
|
||||
<h2 className="text-xl font-bold">
|
||||
{needsSetup ? 'Set Up Encrypted Chat' : 'Unlock Encrypted Chat'}
|
||||
</h2>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
{needsSetup
|
||||
? 'Enter your account password to generate encryption keys. Messages are encrypted end-to-end.'
|
||||
: 'Enter your password to decrypt your messages.'}
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
if (needsSetup) { handleSetup(); } else { handleUnlock(); }
|
||||
}}
|
||||
className="space-y-4"
|
||||
>
|
||||
<Input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<Button type="submit" className="w-full" disabled={settingUp || !password}>
|
||||
{settingUp && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||||
{needsSetup ? 'Generate Keys' : 'Unlock'}
|
||||
</Button>
|
||||
</form>
|
||||
{needsSetup && (
|
||||
<p className="text-xs text-muted-foreground text-center">
|
||||
If you clear browser data, old messages become unreadable. You can regenerate keys but won't be able to decrypt past messages.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className="flex h-[calc(100vh-8rem)] flex-col">
|
||||
@@ -209,9 +103,6 @@ export default function Chat() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<span className="ml-auto" aria-label="End-to-end encrypted">
|
||||
<Lock className="h-4 w-4 text-green-500" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Messages */}
|
||||
@@ -246,14 +137,7 @@ export default function Chat() {
|
||||
: 'bg-muted text-foreground'
|
||||
}`}
|
||||
>
|
||||
{msg.decryptionFailed ? (
|
||||
<div className="flex items-center gap-1 text-xs opacity-70">
|
||||
<AlertTriangle className="h-3 w-3" />
|
||||
Cannot decrypt message
|
||||
</div>
|
||||
) : (
|
||||
<p className="whitespace-pre-wrap break-words">{msg.content}</p>
|
||||
)}
|
||||
<p className="whitespace-pre-wrap break-words">{msg.content}</p>
|
||||
<p className={`mt-1 text-[10px] ${isMine ? 'text-primary-foreground/60' : 'text-muted-foreground'}`}>
|
||||
{new Date(msg.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user