Skip to content
Open
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 @@ -782,86 +780,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: 7 additions & 18 deletions src/matrixrtc/MatrixRTCSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,15 @@ import {
type IRTCNotificationContent,
type ICallNotifyContent,
} from "./types.ts";
import { RoomKeyTransport } from "./RoomKeyTransport.ts";
import {
MembershipManagerEvent,
type MembershipManagerEventHandlerMap,
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";
import { TypedReEmitter } from "../ReEmitter.ts";

/**
* Events emitted by MatrixRTCSession
Expand Down Expand Up @@ -229,8 +224,8 @@ export type JoinSessionConfig = SessionConfig & MembershipConfig & EncryptionCon
* This class doesn't deal with media at all, just membership & properties of a session.
*/
export class MatrixRTCSession extends TypedEventEmitter<
MatrixRTCSessionEvent | RoomAndToDeviceEvents | MembershipManagerEvent,
MatrixRTCSessionEventHandlerMap & RoomAndToDeviceEventsHandlerMap & MembershipManagerEventHandlerMap
MatrixRTCSessionEvent | MembershipManagerEvent,
MatrixRTCSessionEventHandlerMap & MembershipManagerEventHandlerMap
> {
private membershipManager?: IMembershipManager;
private encryptionManager?: IEncryptionManager;
Expand Down Expand Up @@ -473,8 +468,8 @@ export class MatrixRTCSession extends TypedEventEmitter<
roomState?.off(RoomStateEvent.Members, this.onRoomMemberUpdate);
}
private reEmitter = new TypedReEmitter<
MatrixRTCSessionEvent | RoomAndToDeviceEvents | MembershipManagerEvent,
MatrixRTCSessionEventHandlerMap & RoomAndToDeviceEventsHandlerMap & MembershipManagerEventHandlerMap
MatrixRTCSessionEvent | MembershipManagerEvent,
MatrixRTCSessionEventHandlerMap & MembershipManagerEventHandlerMap
>(this);

/**
Expand Down Expand Up @@ -518,13 +513,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