From 2d6230f19994cac347424525637771821a998775 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 27 Sep 2024 16:54:48 +0100 Subject: [PATCH] Rotate RTC key when a new member joins (#4422) --- spec/unit/matrixrtc/MatrixRTCSession.spec.ts | 21 +++++++++++++------- src/matrixrtc/MatrixRTCSession.ts | 6 +++--- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/spec/unit/matrixrtc/MatrixRTCSession.spec.ts b/spec/unit/matrixrtc/MatrixRTCSession.spec.ts index 31614010396..e3572b88d54 100644 --- a/spec/unit/matrixrtc/MatrixRTCSession.spec.ts +++ b/spec/unit/matrixrtc/MatrixRTCSession.spec.ts @@ -686,25 +686,27 @@ describe("MatrixRTCSession", () => { expect(client.cancelPendingEvent).toHaveBeenCalledWith(eventSentinel); }); - it("Re-sends key if a new member joins", async () => { + it("Rotates key if a new member joins", async () => { jest.useFakeTimers(); try { const mockRoom = makeMockRoom([membershipTemplate]); sess = MatrixRTCSession.roomSessionForRoom(client, mockRoom); - const keysSentPromise1 = new Promise((resolve) => { - sendEventMock.mockImplementation(resolve); + const keysSentPromise1 = new Promise((resolve) => { + sendEventMock.mockImplementation((_roomId, _evType, payload) => resolve(payload)); }); sess.joinRoomSession([mockFocus], mockFocus, { manageMediaKeys: true }); - await keysSentPromise1; + const firstKeysPayload = await keysSentPromise1; + expect(firstKeysPayload.keys).toHaveLength(1); + expect(firstKeysPayload.keys[0].index).toEqual(0); expect(sess!.statistics.counters.roomEventEncryptionKeysSent).toEqual(1); sendEventMock.mockClear(); jest.advanceTimersByTime(10000); - const keysSentPromise2 = new Promise((resolve) => { - sendEventMock.mockImplementation(resolve); + const keysSentPromise2 = new Promise((resolve) => { + sendEventMock.mockImplementation((_roomId, _evType, payload) => resolve(payload)); }); const onMembershipsChanged = jest.fn(); @@ -719,9 +721,14 @@ describe("MatrixRTCSession", () => { .mockReturnValue(makeMockRoomState([membershipTemplate, member2], mockRoom.roomId)); sess.onMembershipUpdate(); - await keysSentPromise2; + jest.advanceTimersByTime(10000); + + const secondKeysPayload = await keysSentPromise2; expect(sendEventMock).toHaveBeenCalled(); + expect(secondKeysPayload.keys).toHaveLength(1); + expect(secondKeysPayload.keys[0].index).toEqual(1); + expect(secondKeysPayload.keys[0].key).not.toEqual(firstKeysPayload.keys[0].key); expect(sess!.statistics.counters.roomEventEncryptionKeysSent).toEqual(2); } finally { jest.useRealTimers(); diff --git a/src/matrixrtc/MatrixRTCSession.ts b/src/matrixrtc/MatrixRTCSession.ts index 1cf486062f7..5a1d6e6e73d 100644 --- a/src/matrixrtc/MatrixRTCSession.ts +++ b/src/matrixrtc/MatrixRTCSession.ts @@ -776,8 +776,8 @@ export class MatrixRTCSession extends TypedEventEmitter !newFingerprints.has(x)) || Array.from(newFingerprints).some((x) => !oldFingerprints.has(x)); if (candidateUpdates) { - logger.debug(`Member(s) have updated/reconnected: re-sending keys`); + logger.debug(`Member(s) have updated/reconnected: re-sending keys to everyone`); this.requestKeyEventSend(); } }