feat(client): getOwnerInstanceForDm — route owner-only DM ops to current owner instance

This commit is contained in:
Jannis Braun
2026-05-10 19:39:13 +02:00
parent 063ed2dd64
commit 22c3fd6d50
3 changed files with 131 additions and 0 deletions
+23
View File
@@ -10,6 +10,7 @@ import {
resolveUserIdFromInstances,
getCachedUserIdForOrigin,
clearMyUserIdCache,
setOwnerInstanceForDmResolver,
} from '../utils/crossStoreResolvers';
import { useAuthStore } from './authStore';
import { useChatStore } from './chatStore';
@@ -1137,6 +1138,28 @@ export function getChannelOrigin(channelId: string): string {
return useSpaceStore.getState().channelOriginMap.get(channelId) ?? '';
}
/**
* Returns the owner's home-instance origin for a group DM, or '' for the
* local home instance. Used to route owner-only API calls (rename, icon,
* kick, transfer) so the federation event's sourceInstance equals the
* channel's ownerHomeInstance — required by receiver authority checks.
*
* Distinct from getChannelOrigin: that function returns the channel's
* pinned serving origin (where the client's WS connection mirrors the
* channel), which can differ from the owner's home instance after a
* manual transfer.
*
* The resolver itself lives in `utils/crossStoreResolvers.ts` so that
* `api/client.ts` can call it without creating a value-cycle on spaceStore;
* spaceStore registers the resolver below at module load.
*/
export function getOwnerInstanceForDm(channelId: string): string {
const dm = useSpaceStore.getState().dmChannels.find(d => d.id === channelId);
return dm?.ownerHomeInstance ?? '';
}
setOwnerInstanceForDmResolver(getOwnerInstanceForDm);
/**
* Resolves a raw DM channel ID to its primary `dmChannels` entry ID.
*