fix(federation): address code review findings for FED-009

- Resolve homeUserId from DB in sendFederatedCallStart/End (not raw userId)
- Clear existing timeout in createFederatedCall before overwriting
- Clear federatedCallToken/Url in leaveVoice and handleForceDisconnect
- Remove unnecessary `as any` cast in relay processor
This commit is contained in:
Jannis Braun
2026-03-31 23:58:27 +02:00
parent 274b6a0b2f
commit 626fbfdba8
4 changed files with 16 additions and 3 deletions
+1 -1
View File
@@ -3092,7 +3092,7 @@ function processDmCallStartEvent(
callerName: callerStub.displayName ?? callerStub.username, callerName: callerStub.displayName ?? callerStub.username,
livekitUrl: event.call!.livekitUrl, livekitUrl: event.call!.livekitUrl,
livekitToken: token, livekitToken: token,
} as any); });
} }
accepted.push(event.messageId); accepted.push(event.messageId);
+9 -2
View File
@@ -1765,7 +1765,7 @@ async function sendFederatedCallStart(
livekitUrl, livekitUrl,
tokens, tokens,
caller: { caller: {
homeUserId: callerId, homeUserId: members.find(m => m.userId === callerId)?.homeUserId || callerId,
homeInstance: ourOrigin, homeInstance: ourOrigin,
displayName: callerName, displayName: callerName,
}, },
@@ -1852,6 +1852,13 @@ async function sendFederatedCallEnd(dmChannelId: string, endedByUserId: string):
} }
if (targets.size === 0) return; if (targets.size === 0) return;
// Resolve actual homeUserId from DB
const endUser = db.select({ homeUserId: schema.users.homeUserId })
.from(schema.users)
.where(eq(schema.users.id, endedByUserId))
.get();
const resolvedHomeUserId = endUser?.homeUserId || endedByUserId;
const event = { const event = {
eventType: 'dm_call_end' as const, eventType: 'dm_call_end' as const,
messageId: generateSnowflake(), messageId: generateSnowflake(),
@@ -1859,7 +1866,7 @@ async function sendFederatedCallEnd(dmChannelId: string, endedByUserId: string):
timestamp: Date.now(), timestamp: Date.now(),
federatedId: channel.federatedId, federatedId: channel.federatedId,
call: { call: {
endedBy: { homeUserId: endedByUserId, homeInstance: ourOrigin }, endedBy: { homeUserId: resolvedHomeUserId, homeInstance: ourOrigin },
}, },
}; };
+2
View File
@@ -445,6 +445,8 @@ class ConnectionManager {
/** Register a federated call received via S2S. Adds 60s ringing timeout. */ /** Register a federated call received via S2S. Adds 60s ringing timeout. */
createFederatedCall(entry: FederatedCallEntry): void { createFederatedCall(entry: FederatedCallEntry): void {
// Clear any existing entry + timeout to avoid leaked timers
this.clearFederatedCall(entry.dmChannelId);
this.federatedCalls.set(entry.dmChannelId, entry); this.federatedCalls.set(entry.dmChannelId, entry);
// 60s ringing timeout — mirrors host behavior // 60s ringing timeout — mirrors host behavior
+4
View File
@@ -482,6 +482,8 @@ export const useVoiceStore = create<VoiceState>()(
focusedParticipantId: null, focusedParticipantId: null,
activeDmCall: null, activeDmCall: null,
outgoingCall: null, outgoingCall: null,
federatedCallToken: null,
federatedCallUrl: null,
deafenedUserIds: new Set(), deafenedUserIds: new Set(),
participantMutes: new Map(), participantMutes: new Map(),
streamVolumes: new Map(), streamVolumes: new Map(),
@@ -517,6 +519,8 @@ export const useVoiceStore = create<VoiceState>()(
focusedParticipantId: null, focusedParticipantId: null,
activeDmCall: null, activeDmCall: null,
outgoingCall: null, outgoingCall: null,
federatedCallToken: null,
federatedCallUrl: null,
deafenedUserIds: new Set(), deafenedUserIds: new Set(),
participantMutes: new Map(), participantMutes: new Map(),
streamVolumes: new Map(), streamVolumes: new Map(),