Skip to content

Commit

Permalink
Move roomList out of MatrixClient, into legacy Crypto (#3944)
Browse files Browse the repository at this point in the history
* Comment explaining the purpose of RoomList

* Fix incorrect return type declaration on RoomList.getRoomEncryption

* Move RoomList out of MatrixClient, into legacy Crypto

* Initialise RoomList inside Crypto.init to allow us to await it
  • Loading branch information
andybalaam authored Dec 11, 2023
1 parent 13c7e0e commit b03dc6a
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 44 deletions.
24 changes: 4 additions & 20 deletions spec/unit/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,6 @@ describe("Crypto", function () {

let crypto: Crypto;
let mockBaseApis: MatrixClient;
let mockRoomList: RoomList;

let fakeEmitter: EventEmitter;

Expand Down Expand Up @@ -390,19 +389,10 @@ describe("Crypto", function () {
isGuest: jest.fn(),
emit: jest.fn(),
} as unknown as MatrixClient;
mockRoomList = {} as unknown as RoomList;

fakeEmitter = new EventEmitter();

crypto = new Crypto(
mockBaseApis,
"@alice:home.server",
"FLIBBLE",
clientStore,
cryptoStore,
mockRoomList,
[],
);
crypto = new Crypto(mockBaseApis, "@alice:home.server", "FLIBBLE", clientStore, cryptoStore, []);
crypto.registerEventHandlers(fakeEmitter as any);
await crypto.init();
});
Expand Down Expand Up @@ -1341,15 +1331,9 @@ describe("Crypto", function () {
setRoomEncryption: jest.fn().mockResolvedValue(undefined),
} as unknown as RoomList;

crypto = new Crypto(
mockClient,
"@alice:home.server",
"FLIBBLE",
clientStore,
cryptoStore,
mockRoomList,
[],
);
crypto = new Crypto(mockClient, "@alice:home.server", "FLIBBLE", clientStore, cryptoStore, []);
// @ts-ignore we are injecting a mock into a private property
crypto.roomList = mockRoomList;
});

it("should set the algorithm if called for a known room", async () => {
Expand Down
25 changes: 4 additions & 21 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import { decodeBase64, encodeBase64 } from "./base64";
import { IExportedDevice as IExportedOlmDevice } from "./crypto/OlmDevice";
import { IOlmDevice } from "./crypto/algorithms/megolm";
import { TypedReEmitter } from "./ReEmitter";
import { IRoomEncryption, RoomList } from "./crypto/RoomList";
import { IRoomEncryption } from "./crypto/RoomList";
import { logger, Logger } from "./logger";
import { SERVICE_TYPES } from "./service-types";
import {
Expand Down Expand Up @@ -1272,7 +1272,6 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
protected cryptoStore?: CryptoStore;
protected verificationMethods?: VerificationMethod[];
protected fallbackICEServerAllowed = false;
protected roomList: RoomList;
protected syncApi?: SlidingSyncSdk | SyncApi;
public roomNameGenerator?: ICreateClientOpts["roomNameGenerator"];
public pushRules?: IPushRules;
Expand Down Expand Up @@ -1428,10 +1427,6 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa

this.livekitServiceURL = opts.livekitServiceURL;

// List of which rooms have encryption enabled: separate from crypto because
// we still want to know which rooms are encrypted even if crypto is disabled:
// we don't want to start sending unencrypted events to them.
this.roomList = new RoomList(this.cryptoStore);
this.roomNameGenerator = opts.roomNameGenerator;

this.toDeviceMessageQueue = new ToDeviceMessageQueue(this);
Expand Down Expand Up @@ -2233,10 +2228,6 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
this.logger.debug("Crypto: Starting up crypto store...");
await this.cryptoStore.startup();

// initialise the list of encrypted rooms (whether or not crypto is enabled)
this.logger.debug("Crypto: initialising roomlist...");
await this.roomList.init();

const userId = this.getUserId();
if (userId === null) {
throw new Error(
Expand All @@ -2251,15 +2242,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
);
}

const crypto = new Crypto(
this,
userId,
this.deviceId,
this.store,
this.cryptoStore,
this.roomList,
this.verificationMethods!,
);
const crypto = new Crypto(this, userId, this.deviceId, this.store, this.cryptoStore, this.verificationMethods!);

this.reEmitter.reEmit(crypto, [
CryptoEvent.KeyBackupFailed,
Expand Down Expand Up @@ -3283,7 +3266,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// we don't have an m.room.encrypted event, but that might be because
// the server is hiding it from us. Check the store to see if it was
// previously encrypted.
return this.roomList.isRoomEncrypted(roomId);
return this.crypto?.isRoomEncrypted(roomId) ?? false;
}

/**
Expand Down Expand Up @@ -4019,7 +4002,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
throw new Error("End-to-end encryption disabled");
}

const roomEncryption = this.roomList.getRoomEncryption(roomId);
const roomEncryption = this.crypto?.getRoomEncryption(roomId);
if (!roomEncryption) {
// unknown room, or unencrypted room
this.logger.error("Unknown room. Not sharing decryption keys");
Expand Down
9 changes: 8 additions & 1 deletion src/crypto/RoomList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ export interface IRoomEncryption {
}
/* eslint-enable camelcase */

/**
* Information about the encryption settings of rooms. Loads this information
* from the supplied crypto store when `init()` is called, and saves it to the
* crypto store whenever it is updated via `setRoomEncryption()`. Can supply
* full information about a room's encryption via `getRoomEncryption()`, or just
* answer whether or not a room has encryption via `isRoomEncrypted`.
*/
export class RoomList {
// Object of roomId -> room e2e info object (body of the m.room.encryption event)
private roomEncryption: Record<string, IRoomEncryption> = {};
Expand All @@ -43,7 +50,7 @@ export class RoomList {
});
}

public getRoomEncryption(roomId: string): IRoomEncryption {
public getRoomEncryption(roomId: string): IRoomEncryption | null {
return this.roomEncryption[roomId] || null;
}

Expand Down
27 changes: 25 additions & 2 deletions src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import {
IUploadKeySignaturesResponse,
MatrixClient,
} from "../client";
import type { IRoomEncryption, RoomList } from "./RoomList";
import { IRoomEncryption, RoomList } from "./RoomList";
import { IKeyBackupInfo } from "./keybackup";
import { ISyncStateData } from "../sync";
import { CryptoStore } from "./store/base";
Expand Down Expand Up @@ -385,6 +385,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
public readonly dehydrationManager: DehydrationManager;
public readonly secretStorage: LegacySecretStorage;

private readonly roomList: RoomList;
private readonly reEmitter: TypedReEmitter<CryptoEvent, CryptoEventHandlerMap>;
private readonly verificationMethods: Map<VerificationMethod, typeof VerificationBase>;
public readonly supportedAlgorithms: string[];
Expand Down Expand Up @@ -473,10 +474,13 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
private readonly deviceId: string,
private readonly clientStore: IStore,
public readonly cryptoStore: CryptoStore,
private readonly roomList: RoomList,
verificationMethods: Array<VerificationMethod | (typeof VerificationBase & { NAME: string })>,
) {
super();

logger.debug("Crypto: initialising roomlist...");
this.roomList = new RoomList(cryptoStore);

this.reEmitter = new TypedReEmitter(this);

if (verificationMethods) {
Expand Down Expand Up @@ -626,6 +630,9 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
// (this is important for key backups & things)
this.deviceList.startTrackingDeviceList(this.userId);

logger.debug("Crypto: initialising roomlist...");
await this.roomList.init();

logger.log("Crypto: checking for key backup...");
this.backupManager.checkAndStart();
}
Expand Down Expand Up @@ -4244,6 +4251,22 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
obj.signatures = recursiveMapToObject(sigs);
if (unsigned !== undefined) obj.unsigned = unsigned;
}

/**
* @returns true if the room with the supplied ID is encrypted. False if the
* room is not encrypted, or is unknown to us.
*/
public isRoomEncrypted(roomId: string): boolean {
return this.roomList.isRoomEncrypted(roomId);
}

/**
* @returns information about the encryption on the room with the supplied
* ID, or null if the room is not encrypted or unknown to us.
*/
public getRoomEncryption(roomId: string): IRoomEncryption | null {
return this.roomList.getRoomEncryption(roomId);
}
}

/**
Expand Down

0 comments on commit b03dc6a

Please sign in to comment.