fix(messages): gate on server key state, not just local unlock

The Messages UI trusted only the per-device IndexedDB key, so if the server's
key record was gone (deleted, DB-restored, admin-reset) while a stale private
key lingered in the browser, the app looked 'unlocked' but no one could be
messaged and no setup was offered. Add useKeyState (server 'configured' AND
local unlock): show setup when the server has no key (setup overwrites the stale
local key), unlock when it has one this device hasn't opened, ready otherwise.
ChatThread is now self-contained. Also fix the header title on the Messages and
Notifications pages (was falling through to 'Channel manager').
This commit is contained in:
npeter83 2026-06-25 22:58:29 +02:00
parent 8392037e5f
commit 963afa33a6
5 changed files with 42 additions and 29 deletions

View file

@ -3,7 +3,6 @@ import { useTranslation } from "react-i18next";
import { useQueryClient } from "@tanstack/react-query";
import { ChevronDown, ChevronUp, X } from "lucide-react";
import { closeChat, initDock, notifyIncoming, toggleMinimize, useDockChats, type DockChat } from "../lib/chatDock";
import { useUnlocked } from "../lib/messaging";
import { onMessage } from "../lib/messagesSocket";
import * as e2ee from "../lib/e2ee";
import Avatar from "./Avatar";
@ -15,7 +14,6 @@ import ChatThread from "./ChatThread";
export default function ChatDock({ meId }: { meId: number }) {
const qc = useQueryClient();
const chats = useDockChats();
const unlocked = useUnlocked();
// Restore the per-device unlocked key and the persisted dock windows once, app-wide.
useEffect(() => {
@ -45,13 +43,13 @@ export default function ChatDock({ meId }: { meId: number }) {
return (
<div className="fixed bottom-0 right-0 z-40 flex flex-row-reverse items-end gap-3 p-4 pointer-events-none">
{chats.map((c) => (
<ChatWindow key={c.partnerId} chat={c} meId={meId} unlocked={unlocked} />
<ChatWindow key={c.partnerId} chat={c} meId={meId} />
))}
</div>
);
}
function ChatWindow({ chat, meId, unlocked }: { chat: DockChat; meId: number; unlocked: boolean }) {
function ChatWindow({ chat, meId }: { chat: DockChat; meId: number }) {
const { t } = useTranslation();
const [flashing, setFlashing] = useState(false);
@ -95,7 +93,7 @@ function ChatWindow({ chat, meId, unlocked }: { chat: DockChat; meId: number; un
</div>
{!chat.minimized && (
<div className="flex flex-col h-96">
<ChatThread meId={meId} partnerId={chat.partnerId} isSystem={false} unlocked={unlocked} />
<ChatThread meId={meId} partnerId={chat.partnerId} isSystem={false} />
</div>
)}
</div>