From 11a69fe92a45ce22634c2f672cbad96cbd99d533 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:01:19 +0100 Subject: [PATCH] fix: cache federated user identity from WS ready to fix server mute/deafen getMyUserIdForOrigin relied on instanceStore resolver which could return the home user ID during connection errors. Cache the authoritative user ID directly from the WS ready payload, ensuring effective-state computations use the correct federated identity. --- packages/web/src/hooks/useWebSocket.ts | 7 ++++++- packages/web/src/stores/spaceStore.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/web/src/hooks/useWebSocket.ts b/packages/web/src/hooks/useWebSocket.ts index 24598a5a..8da872b5 100644 --- a/packages/web/src/hooks/useWebSocket.ts +++ b/packages/web/src/hooks/useWebSocket.ts @@ -1,6 +1,6 @@ import React, { useEffect, useRef } from 'react'; import { useAuthStore } from '../stores/authStore'; -import { useSpaceStore, getChannelOrigin, getMyUserIdForOrigin } from '../stores/spaceStore'; +import { useSpaceStore, getChannelOrigin, getMyUserIdForOrigin, setMyUserIdForOrigin } from '../stores/spaceStore'; import { useChatStore } from '../stores/chatStore'; import { useVoiceStore } from '../stores/voiceStore'; import { useSocialStore } from '../stores/socialStore'; @@ -109,6 +109,11 @@ function handleEvent(origin: string, event: ServerEvent): void { populateFromReady(origin, event.spaces, event.folders, event.dmChannels); + // Cache authoritative identity for this origin (federation-safe) + if (!isHome) { + setMyUserIdForOrigin(origin, event.user.id); + } + // Mark remote instance as connected in instanceStore if (!isHome) { import('../stores/instanceStore').then(({ useInstanceStore }) => { diff --git a/packages/web/src/stores/spaceStore.ts b/packages/web/src/stores/spaceStore.ts index 8af956be..97986178 100644 --- a/packages/web/src/stores/spaceStore.ts +++ b/packages/web/src/stores/spaceStore.ts @@ -592,6 +592,14 @@ export function setUserIdForOriginResolver(resolver: (origin: string) => string _getUserIdForOrigin = resolver; } +// Direct identity cache populated from WS ready events. +// Bypasses the instanceStore resolver for reliable federation support. +const _myUserIdByOrigin = new Map(); + +export function setMyUserIdForOrigin(origin: string, userId: string): void { + _myUserIdByOrigin.set(origin, userId); +} + /** * Returns the local user's ID on a given instance origin. * '' or falsy = home instance (returns authStore user ID). @@ -599,5 +607,9 @@ export function setUserIdForOriginResolver(resolver: (origin: string) => string */ export function getMyUserIdForOrigin(origin: string): string | undefined { if (!origin) return useAuthStore.getState().user?.id; + // Direct cache (populated from WS ready) takes priority — always correct + const cached = _myUserIdByOrigin.get(origin); + if (cached) return cached; + // Fallback to instanceStore resolver (may have placeholder user during connection) return _getUserIdForOrigin?.(origin); }