Skip to content

Commit 25a7c9e

Browse files
authored
Prefix the user+device state key if needed (#4262)
* Prefix the user+device state key if needed No need to prefix it for rooms that use MSC3779. Otherwise, prefix it to bypass the auth rule for state events with keys starting with @. * Use RegExp.exec() method instead Sonar typescript:S6594 * Split nested ternary operator into method Sonar typescript:S3358 * Add test coverage
1 parent 78b6b87 commit 25a7c9e

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

spec/unit/matrixrtc/MatrixRTCSession.spec.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,42 @@ describe("MatrixRTCSession", () => {
399399
jest.useRealTimers();
400400
});
401401

402+
describe("non-legacy calls", () => {
403+
const activeFocusConfig = { type: "livekit", livekit_service_url: "https://active.url" };
404+
const activeFocus = { type: "livekit", focus_selection: "oldest_membership" };
405+
406+
function testJoin(useOwnedStateEvents: boolean): void {
407+
if (useOwnedStateEvents) {
408+
mockRoom.getVersion = jest.fn().mockReturnValue("org.matrix.msc3779.default");
409+
}
410+
411+
jest.useFakeTimers();
412+
sess!.joinRoomSession([activeFocusConfig], activeFocus, { useLegacyMemberEvents: false });
413+
expect(client.sendStateEvent).toHaveBeenCalledWith(
414+
mockRoom!.roomId,
415+
EventType.GroupCallMemberPrefix,
416+
{
417+
application: "m.call",
418+
scope: "m.room",
419+
call_id: "",
420+
device_id: "AAAAAAA",
421+
foci_preferred: [activeFocusConfig],
422+
focus_active: activeFocus,
423+
} satisfies SessionMembershipData,
424+
`${!useOwnedStateEvents ? "_" : ""}@alice:example.org_AAAAAAA`,
425+
);
426+
jest.useRealTimers();
427+
}
428+
429+
it("sends a membership event with session payload when joining a non-legacy call", () => {
430+
testJoin(false);
431+
});
432+
433+
it("does not prefix the state key with _ for rooms that support user-owned state events", () => {
434+
testJoin(true);
435+
});
436+
});
437+
402438
it("does nothing if join called when already joined", () => {
403439
sess!.joinRoomSession([mockFocus], mockFocus);
404440

spec/unit/matrixrtc/mocks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export function makeMockRoom(membershipData: MembershipData, localAge: number |
3030
getLiveTimeline: jest.fn().mockReturnValue({
3131
getState: jest.fn().mockReturnValue(roomState),
3232
}),
33+
getVersion: jest.fn().mockReturnValue("default"),
3334
} as unknown as Room;
3435
}
3536

src/matrixrtc/MatrixRTCSession.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ export class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, M
869869
this.room.roomId,
870870
EventType.GroupCallMemberPrefix,
871871
newContent,
872-
legacy ? localUserId : `${localUserId}_${localDeviceId}`,
872+
legacy ? localUserId : this.makeMembershipStateKey(localUserId, localDeviceId),
873873
);
874874
logger.info(`Sent updated call member event.`);
875875

@@ -899,6 +899,15 @@ export class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, M
899899
return false;
900900
}
901901

902+
private makeMembershipStateKey(localUserId: string, localDeviceId: string): string {
903+
const stateKey = `${localUserId}_${localDeviceId}`;
904+
if (/^org\.matrix\.msc3779\b/.exec(this.room.getVersion())) {
905+
return stateKey;
906+
} else {
907+
return `_${stateKey}`;
908+
}
909+
}
910+
902911
private onRotateKeyTimeout = (): void => {
903912
if (!this.manageMediaKeys) return;
904913

0 commit comments

Comments
 (0)