diff --git a/ee/packages/media-calls/src/internal/SignalProcessor.ts b/ee/packages/media-calls/src/internal/SignalProcessor.ts index 2c0a4bfdcf23f..fe267ee9bd884 100644 --- a/ee/packages/media-calls/src/internal/SignalProcessor.ts +++ b/ee/packages/media-calls/src/internal/SignalProcessor.ts @@ -86,8 +86,11 @@ export class GlobalSignalProcessor { const role = isCaller ? 'caller' : 'callee'; const callActor = call[role]; + // Hangup requests from different clients won't be coming from the signed client + const skipContractCheck = signal.type === 'hangup' && signal.reason === 'another-client'; + // Ignore signals from different sessions if the actor is already signed - if (callActor.contractId && callActor.contractId !== signal.contractId) { + if (!skipContractCheck && callActor.contractId && callActor.contractId !== signal.contractId) { return; } diff --git a/ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts b/ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts index 1178afe33ede5..1d805bd29d1ca 100644 --- a/ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts +++ b/ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts @@ -86,6 +86,7 @@ export class UserActorSignalProcessor { // 1. the signal came from the exact user session where the caller initiated the call // 2. the signal came from the exact user session where the callee accepted the call // 3. the call has not been accepted yet and the signal came from a valid session from the callee + // 4. It's a hangup request with reason = 'another-client' and the request came from any valid client of either user switch (signal.type) { case 'local-sdp': return this.saveLocalDescription(signal.sdp, signal.negotiationId); diff --git a/packages/media-signaling/src/definition/call/IClientMediaCall.ts b/packages/media-signaling/src/definition/call/IClientMediaCall.ts index 8e72491472168..4db58e8d07fb8 100644 --- a/packages/media-signaling/src/definition/call/IClientMediaCall.ts +++ b/packages/media-signaling/src/definition/call/IClientMediaCall.ts @@ -26,6 +26,7 @@ export type CallState = | 'renegotiating' // a webrtc connection had been established before, but a new one is being negotiated | 'hangup'; // call is over +// Changes to this list must be reflected on the enum for clientMediaSignalHangupSchema too export type CallHangupReason = | 'normal' // User explicitly hanged up | 'remote' // The client was told the call is over @@ -38,7 +39,8 @@ export type CallHangupReason = | 'media-error' // Hanging up because of an error setting up the media connection | 'input-error' // Something wrong with the audio input track on the client | 'error' // Hanging up because of an unidentified error - | 'unknown'; // One of the call's signed users reported they don't know this call + | 'unknown' // One of the call's signed users reported they don't know this call + | 'another-client'; // One of the call's users requested a hangup from a different client session than the one where the call is happening export type CallAnswer = | 'accept' // actor accepts the call diff --git a/packages/media-signaling/src/definition/signals/client/hangup.ts b/packages/media-signaling/src/definition/signals/client/hangup.ts index 0571f0bfd6c45..af4d38089cb3b 100644 --- a/packages/media-signaling/src/definition/signals/client/hangup.ts +++ b/packages/media-signaling/src/definition/signals/client/hangup.ts @@ -40,7 +40,10 @@ export const clientMediaSignalHangupSchema: JSONSchemaType