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); }