Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 1 addition & 83 deletions spec/unit/matrixrtc/RTCEncryptionManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import { type ToDeviceKeyTransport } from "../../../src/matrixrtc/ToDeviceKeyTra
import { KeyTransportEvents, type KeyTransportEventsHandlerMap } from "../../../src/matrixrtc/IKeyTransport.ts";
import { membershipTemplate, mockCallMembership } from "./mocks.ts";
import { decodeBase64, TypedEventEmitter } from "../../../src";
import { RoomAndToDeviceTransport } from "../../../src/matrixrtc/RoomAndToDeviceKeyTransport.ts";
import { type RoomKeyTransport } from "../../../src/matrixrtc/RoomKeyTransport.ts";
import { logger, type Logger } from "../../../src/logger.ts";
import { logger } from "../../../src/logger.ts";
import { getParticipantId } from "../../../src/matrixrtc/utils.ts";

describe("RTCEncryptionManager", () => {
Expand Down Expand Up @@ -742,86 +740,6 @@ describe("RTCEncryptionManager", () => {
);
});

it("Should re-distribute key on transport switch", async () => {
const toDeviceEmitter = new TypedEventEmitter<KeyTransportEvents, KeyTransportEventsHandlerMap>();
const mockToDeviceTransport = {
start: jest.fn(),
stop: jest.fn(),
sendKey: jest.fn().mockResolvedValue(undefined),
on: toDeviceEmitter.on.bind(toDeviceEmitter),
off: toDeviceEmitter.off.bind(toDeviceEmitter),
emit: toDeviceEmitter.emit.bind(toDeviceEmitter),
setParentLogger: jest.fn(),
} as unknown as Mocked<ToDeviceKeyTransport>;

const roomEmitter = new TypedEventEmitter<KeyTransportEvents, KeyTransportEventsHandlerMap>();
const mockRoomTransport = {
start: jest.fn(),
stop: jest.fn(),
sendKey: jest.fn().mockResolvedValue(undefined),
on: roomEmitter.on.bind(roomEmitter),
off: roomEmitter.off.bind(roomEmitter),
emit: roomEmitter.emit.bind(roomEmitter),
setParentLogger: jest.fn(),
} as unknown as Mocked<RoomKeyTransport>;

const mockLogger = {
debug: jest.fn(),
warn: jest.fn(),
} as unknown as Mocked<Logger>;

const transport = new RoomAndToDeviceTransport(mockToDeviceTransport, mockRoomTransport, {
getChild: jest.fn().mockReturnValue(mockLogger),
} as unknown as Mocked<Logger>);

encryptionManager = new RTCEncryptionManager(
"@alice:example.org",
"DEVICE01",
getMembershipMock,
transport,
statistics,
onEncryptionKeysChanged,
);

const members = [
aCallMembership("@bob:example.org", "BOBDEVICE"),
aCallMembership("@bob:example.org", "BOBDEVICE2"),
aCallMembership("@carl:example.org", "CARLDEVICE"),
];
getMembershipMock.mockReturnValue(members);

// Let's join
encryptionManager.join(undefined);
encryptionManager.onMembershipsUpdate();
await jest.advanceTimersByTimeAsync(10);

// Should have sent the key to the toDevice transport
expect(mockToDeviceTransport.sendKey).toHaveBeenCalledTimes(1);
expect(mockRoomTransport.sendKey).not.toHaveBeenCalled();

// Simulate receiving a key by room transport
roomEmitter.emit(
KeyTransportEvents.ReceivedKeys,
"@bob:example.org",
"BOBDEVICE",
"AAAAAAAAAAA",
0 /* KeyId */,
0 /* Timestamp */,
);

await jest.runOnlyPendingTimersAsync();

// The key should have been re-distributed to the room transport
expect(mockRoomTransport.sendKey).toHaveBeenCalled();
expect(mockToDeviceTransport.sendKey).toHaveBeenCalledWith(
expect.any(String),
// It is the first key re-distributed
0,
// to all the members
members.map((m) => ({ userId: m.sender, deviceId: m.deviceId, membershipTs: m.createdTs() })),
);
});

function aCallMembership(userId: string, deviceId: string, ts: number = 1000): CallMembership {
return mockCallMembership(
{ ...membershipTemplate, user_id: userId, device_id: deviceId, created_ts: ts },
Expand Down
187 changes: 0 additions & 187 deletions spec/unit/matrixrtc/RoomAndToDeviceTransport.spec.ts

This file was deleted.

14 changes: 1 addition & 13 deletions src/matrixrtc/EncryptionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ import { type CallMembership } from "./CallMembership.ts";
import { type KeyTransportEventListener, KeyTransportEvents, type IKeyTransport } from "./IKeyTransport.ts";
import { isMyMembership, type ParticipantId, type Statistics } from "./types.ts";
import { getParticipantId } from "./utils.ts";
import {
type EnabledTransports,
RoomAndToDeviceEvents,
RoomAndToDeviceTransport,
} from "./RoomAndToDeviceKeyTransport.ts";

/**
* This interface is for testing and for making it possible to interchange the encryption manager.
Expand Down Expand Up @@ -119,10 +114,7 @@ export class EncryptionManager implements IEncryptionManager {
this.manageMediaKeys = this.joinConfig?.manageMediaKeys ?? this.manageMediaKeys;

this.transport.on(KeyTransportEvents.ReceivedKeys, this.onNewKeyReceived);
// Deprecate RoomKeyTransport: this can get removed.
if (this.transport instanceof RoomAndToDeviceTransport) {
this.transport.on(RoomAndToDeviceEvents.EnabledTransportsChanged, this.onTransportChanged);
}

this.transport.start();
if (this.joinConfig?.manageMediaKeys) {
this.makeNewSenderKey();
Expand Down Expand Up @@ -315,10 +307,6 @@ export class EncryptionManager implements IEncryptionManager {
}
};

private onTransportChanged: (enabled: EnabledTransports) => void = () => {
this.requestSendCurrentKey();
};

public onNewKeyReceived: KeyTransportEventListener = (userId, deviceId, keyBase64Encoded, index, timestamp) => {
this.logger.debug(`Received key over key transport ${userId}:${deviceId} at index ${index}`);
this.setEncryptionKey(userId, deviceId, index, keyBase64Encoded, timestamp);
Expand Down
25 changes: 3 additions & 22 deletions src/matrixrtc/MatrixRTCSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,10 @@ import { MembershipManager } from "./MembershipManager.ts";
import { EncryptionManager, type IEncryptionManager } from "./EncryptionManager.ts";
import { logDurationSync } from "../utils.ts";
import { type Statistics, type RTCNotificationType } from "./types.ts";
import { RoomKeyTransport } from "./RoomKeyTransport.ts";
import type { IMembershipManager } from "./IMembershipManager.ts";
import { RTCEncryptionManager } from "./RTCEncryptionManager.ts";
import {
RoomAndToDeviceEvents,
type RoomAndToDeviceEventsHandlerMap,
RoomAndToDeviceTransport,
} from "./RoomAndToDeviceKeyTransport.ts";
import { TypedReEmitter } from "../ReEmitter.ts";
import { ToDeviceKeyTransport } from "./ToDeviceKeyTransport.ts";
import { RoomKeyTransport } from "./RoomKeyTransport.ts";

export enum MatrixRTCSessionEvent {
// A member joined, left, or updated a property of their membership.
Expand Down Expand Up @@ -211,10 +205,7 @@ export type JoinSessionConfig = SessionConfig & MembershipConfig & EncryptionCon
* A MatrixRTCSession manages the membership & properties of a MatrixRTC session.
* This class doesn't deal with media at all, just membership & properties of a session.
*/
export class MatrixRTCSession extends TypedEventEmitter<
MatrixRTCSessionEvent | RoomAndToDeviceEvents,
MatrixRTCSessionEventHandlerMap & RoomAndToDeviceEventsHandlerMap
> {
export class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, MatrixRTCSessionEventHandlerMap> {
private membershipManager?: IMembershipManager;
private encryptionManager?: IEncryptionManager;
// The session Id of the call, this is the call_id of the call Member event.
Expand Down Expand Up @@ -403,10 +394,6 @@ export class MatrixRTCSession extends TypedEventEmitter<
const roomState = this.roomSubset.getLiveTimeline().getState(EventTimeline.FORWARDS);
roomState?.off(RoomStateEvent.Members, this.onRoomMemberUpdate);
}
private reEmitter = new TypedReEmitter<
MatrixRTCSessionEvent | RoomAndToDeviceEvents,
MatrixRTCSessionEventHandlerMap & RoomAndToDeviceEventsHandlerMap
>(this);

/**
* Announces this user and device as joined to the MatrixRTC session,
Expand Down Expand Up @@ -444,13 +431,7 @@ export class MatrixRTCSession extends TypedEventEmitter<
this.logger.info("Using to-device with room fallback transport for encryption keys");
const [uId, dId] = [this.client.getUserId()!, this.client.getDeviceId()!];
const [room, client, statistics] = [this.roomSubset, this.client, this.statistics];
// Deprecate RoomKeyTransport: only ToDeviceKeyTransport is needed once deprecated
const roomKeyTransport = new RoomKeyTransport(room, client, statistics);
const toDeviceTransport = new ToDeviceKeyTransport(uId, dId, room.roomId, client, statistics);
transport = new RoomAndToDeviceTransport(toDeviceTransport, roomKeyTransport, this.logger);

// Expose the changes so the ui can display the currently used transport.
this.reEmitter.reEmit(transport, [RoomAndToDeviceEvents.EnabledTransportsChanged]);
const transport = new ToDeviceKeyTransport(uId, dId, room.roomId, client, statistics);
this.encryptionManager = new RTCEncryptionManager(
this.client.getUserId()!,
this.client.getDeviceId()!,
Expand Down
Loading