refactor(desktop): AuthContext exposes userKeyState instead of device record

Replaces the per-device DeviceRecord lookup with a per-user discriminated
union (loading | needs-setup | needs-unlock | unlocked). Heartbeat block
deleted (telemetry no longer device-bound); webPush keyed by install-id.
This commit is contained in:
byGalax
2026-05-15 22:52:41 +02:00
parent 2c586351fc
commit 20216b37c6
8 changed files with 128 additions and 84 deletions
+12 -6
View File
@@ -4,6 +4,7 @@ import { Outlet } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import { startConversationKeySync } from '../lib/conversationKeySync';
import { startDeviceApprovalListener } from '../lib/deviceApproval';
import { ensureInstallId } from '../lib/installId';
import { ensureNotificationPermission } from '../lib/osNotify';
import { cachedUserKey } from '../lib/userIdentity';
import { BackupPromptBanner } from './BackupPromptBanner';
@@ -12,7 +13,7 @@ import { DeviceApprovalBanner } from './DeviceApprovalBanner';
import { Sidebar } from './Sidebar';
export function AppShell() {
const { session, device } = useAuth();
const { session } = useAuth();
useEffect(() => {
// Prompt once per authenticated shell mount. Module-level guard prevents
// re-asking if the user already responded this session.
@@ -20,20 +21,25 @@ export function AppShell() {
}, []);
useEffect(() => {
if (!session?.user.id || !device?.id) return;
if (!session?.user.id) return;
const userId = session.user.id;
const deviceId = device.id;
const stopKeySync = startConversationKeySync(userId, deviceId);
// Per-install id replaces the per-device record now that crypto is
// user-keyed. The legacy conv-key-sync and device-approval subsystems
// still take a "deviceId" argument for telemetry / row identity; passing
// the install id keeps those wires intact until they are themselves
// reworked in later tasks (Task 16/17/19 territory).
const installId = ensureInstallId();
const stopKeySync = startConversationKeySync(userId, installId);
const stopApproval = startDeviceApprovalListener({
ownUserId: userId,
ownDeviceId: deviceId,
ownDeviceId: installId,
getPriv: () => cachedUserKey(userId),
});
return () => {
stopKeySync();
stopApproval();
};
}, [session?.user.id, device?.id]);
}, [session?.user.id]);
return (
<div className="relative flex min-h-screen overflow-hidden bg-surface text-fg">