You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Move roomList out of MatrixClient, into legacy Crypto (#3944)
* 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
This commit is contained in:
@ -356,7 +356,6 @@ describe("Crypto", function () {
|
|||||||
|
|
||||||
let crypto: Crypto;
|
let crypto: Crypto;
|
||||||
let mockBaseApis: MatrixClient;
|
let mockBaseApis: MatrixClient;
|
||||||
let mockRoomList: RoomList;
|
|
||||||
|
|
||||||
let fakeEmitter: EventEmitter;
|
let fakeEmitter: EventEmitter;
|
||||||
|
|
||||||
@ -390,19 +389,10 @@ describe("Crypto", function () {
|
|||||||
isGuest: jest.fn(),
|
isGuest: jest.fn(),
|
||||||
emit: jest.fn(),
|
emit: jest.fn(),
|
||||||
} as unknown as MatrixClient;
|
} as unknown as MatrixClient;
|
||||||
mockRoomList = {} as unknown as RoomList;
|
|
||||||
|
|
||||||
fakeEmitter = new EventEmitter();
|
fakeEmitter = new EventEmitter();
|
||||||
|
|
||||||
crypto = new Crypto(
|
crypto = new Crypto(mockBaseApis, "@alice:home.server", "FLIBBLE", clientStore, cryptoStore, []);
|
||||||
mockBaseApis,
|
|
||||||
"@alice:home.server",
|
|
||||||
"FLIBBLE",
|
|
||||||
clientStore,
|
|
||||||
cryptoStore,
|
|
||||||
mockRoomList,
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
crypto.registerEventHandlers(fakeEmitter as any);
|
crypto.registerEventHandlers(fakeEmitter as any);
|
||||||
await crypto.init();
|
await crypto.init();
|
||||||
});
|
});
|
||||||
@ -1341,15 +1331,9 @@ describe("Crypto", function () {
|
|||||||
setRoomEncryption: jest.fn().mockResolvedValue(undefined),
|
setRoomEncryption: jest.fn().mockResolvedValue(undefined),
|
||||||
} as unknown as RoomList;
|
} as unknown as RoomList;
|
||||||
|
|
||||||
crypto = new Crypto(
|
crypto = new Crypto(mockClient, "@alice:home.server", "FLIBBLE", clientStore, cryptoStore, []);
|
||||||
mockClient,
|
// @ts-ignore we are injecting a mock into a private property
|
||||||
"@alice:home.server",
|
crypto.roomList = mockRoomList;
|
||||||
"FLIBBLE",
|
|
||||||
clientStore,
|
|
||||||
cryptoStore,
|
|
||||||
mockRoomList,
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set the algorithm if called for a known room", async () => {
|
it("should set the algorithm if called for a known room", async () => {
|
||||||
|
@ -51,7 +51,7 @@ import { decodeBase64, encodeBase64 } from "./base64";
|
|||||||
import { IExportedDevice as IExportedOlmDevice } from "./crypto/OlmDevice";
|
import { IExportedDevice as IExportedOlmDevice } from "./crypto/OlmDevice";
|
||||||
import { IOlmDevice } from "./crypto/algorithms/megolm";
|
import { IOlmDevice } from "./crypto/algorithms/megolm";
|
||||||
import { TypedReEmitter } from "./ReEmitter";
|
import { TypedReEmitter } from "./ReEmitter";
|
||||||
import { IRoomEncryption, RoomList } from "./crypto/RoomList";
|
import { IRoomEncryption } from "./crypto/RoomList";
|
||||||
import { logger, Logger } from "./logger";
|
import { logger, Logger } from "./logger";
|
||||||
import { SERVICE_TYPES } from "./service-types";
|
import { SERVICE_TYPES } from "./service-types";
|
||||||
import {
|
import {
|
||||||
@ -1272,7 +1272,6 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
protected cryptoStore?: CryptoStore;
|
protected cryptoStore?: CryptoStore;
|
||||||
protected verificationMethods?: VerificationMethod[];
|
protected verificationMethods?: VerificationMethod[];
|
||||||
protected fallbackICEServerAllowed = false;
|
protected fallbackICEServerAllowed = false;
|
||||||
protected roomList: RoomList;
|
|
||||||
protected syncApi?: SlidingSyncSdk | SyncApi;
|
protected syncApi?: SlidingSyncSdk | SyncApi;
|
||||||
public roomNameGenerator?: ICreateClientOpts["roomNameGenerator"];
|
public roomNameGenerator?: ICreateClientOpts["roomNameGenerator"];
|
||||||
public pushRules?: IPushRules;
|
public pushRules?: IPushRules;
|
||||||
@ -1428,10 +1427,6 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
|
|
||||||
this.livekitServiceURL = opts.livekitServiceURL;
|
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.roomNameGenerator = opts.roomNameGenerator;
|
||||||
|
|
||||||
this.toDeviceMessageQueue = new ToDeviceMessageQueue(this);
|
this.toDeviceMessageQueue = new ToDeviceMessageQueue(this);
|
||||||
@ -2233,10 +2228,6 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
this.logger.debug("Crypto: Starting up crypto store...");
|
this.logger.debug("Crypto: Starting up crypto store...");
|
||||||
await this.cryptoStore.startup();
|
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();
|
const userId = this.getUserId();
|
||||||
if (userId === null) {
|
if (userId === null) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -2251,15 +2242,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const crypto = new Crypto(
|
const crypto = new Crypto(this, userId, this.deviceId, this.store, this.cryptoStore, this.verificationMethods!);
|
||||||
this,
|
|
||||||
userId,
|
|
||||||
this.deviceId,
|
|
||||||
this.store,
|
|
||||||
this.cryptoStore,
|
|
||||||
this.roomList,
|
|
||||||
this.verificationMethods!,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.reEmitter.reEmit(crypto, [
|
this.reEmitter.reEmit(crypto, [
|
||||||
CryptoEvent.KeyBackupFailed,
|
CryptoEvent.KeyBackupFailed,
|
||||||
@ -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
|
// 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
|
// the server is hiding it from us. Check the store to see if it was
|
||||||
// previously encrypted.
|
// previously encrypted.
|
||||||
return this.roomList.isRoomEncrypted(roomId);
|
return this.crypto?.isRoomEncrypted(roomId) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4019,7 +4002,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
throw new Error("End-to-end encryption disabled");
|
throw new Error("End-to-end encryption disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
const roomEncryption = this.roomList.getRoomEncryption(roomId);
|
const roomEncryption = this.crypto?.getRoomEncryption(roomId);
|
||||||
if (!roomEncryption) {
|
if (!roomEncryption) {
|
||||||
// unknown room, or unencrypted room
|
// unknown room, or unencrypted room
|
||||||
this.logger.error("Unknown room. Not sharing decryption keys");
|
this.logger.error("Unknown room. Not sharing decryption keys");
|
||||||
|
@ -29,6 +29,13 @@ export interface IRoomEncryption {
|
|||||||
}
|
}
|
||||||
/* eslint-enable camelcase */
|
/* 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 {
|
export class RoomList {
|
||||||
// Object of roomId -> room e2e info object (body of the m.room.encryption event)
|
// Object of roomId -> room e2e info object (body of the m.room.encryption event)
|
||||||
private roomEncryption: Record<string, IRoomEncryption> = {};
|
private roomEncryption: Record<string, IRoomEncryption> = {};
|
||||||
@ -43,7 +50,7 @@ export class RoomList {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRoomEncryption(roomId: string): IRoomEncryption {
|
public getRoomEncryption(roomId: string): IRoomEncryption | null {
|
||||||
return this.roomEncryption[roomId] || null;
|
return this.roomEncryption[roomId] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ import {
|
|||||||
IUploadKeySignaturesResponse,
|
IUploadKeySignaturesResponse,
|
||||||
MatrixClient,
|
MatrixClient,
|
||||||
} from "../client";
|
} from "../client";
|
||||||
import type { IRoomEncryption, RoomList } from "./RoomList";
|
import { IRoomEncryption, RoomList } from "./RoomList";
|
||||||
import { IKeyBackupInfo } from "./keybackup";
|
import { IKeyBackupInfo } from "./keybackup";
|
||||||
import { ISyncStateData } from "../sync";
|
import { ISyncStateData } from "../sync";
|
||||||
import { CryptoStore } from "./store/base";
|
import { CryptoStore } from "./store/base";
|
||||||
@ -385,6 +385,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
|
|||||||
public readonly dehydrationManager: DehydrationManager;
|
public readonly dehydrationManager: DehydrationManager;
|
||||||
public readonly secretStorage: LegacySecretStorage;
|
public readonly secretStorage: LegacySecretStorage;
|
||||||
|
|
||||||
|
private readonly roomList: RoomList;
|
||||||
private readonly reEmitter: TypedReEmitter<CryptoEvent, CryptoEventHandlerMap>;
|
private readonly reEmitter: TypedReEmitter<CryptoEvent, CryptoEventHandlerMap>;
|
||||||
private readonly verificationMethods: Map<VerificationMethod, typeof VerificationBase>;
|
private readonly verificationMethods: Map<VerificationMethod, typeof VerificationBase>;
|
||||||
public readonly supportedAlgorithms: string[];
|
public readonly supportedAlgorithms: string[];
|
||||||
@ -473,10 +474,13 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
|
|||||||
private readonly deviceId: string,
|
private readonly deviceId: string,
|
||||||
private readonly clientStore: IStore,
|
private readonly clientStore: IStore,
|
||||||
public readonly cryptoStore: CryptoStore,
|
public readonly cryptoStore: CryptoStore,
|
||||||
private readonly roomList: RoomList,
|
|
||||||
verificationMethods: Array<VerificationMethod | (typeof VerificationBase & { NAME: string })>,
|
verificationMethods: Array<VerificationMethod | (typeof VerificationBase & { NAME: string })>,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
logger.debug("Crypto: initialising roomlist...");
|
||||||
|
this.roomList = new RoomList(cryptoStore);
|
||||||
|
|
||||||
this.reEmitter = new TypedReEmitter(this);
|
this.reEmitter = new TypedReEmitter(this);
|
||||||
|
|
||||||
if (verificationMethods) {
|
if (verificationMethods) {
|
||||||
@ -626,6 +630,9 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
|
|||||||
// (this is important for key backups & things)
|
// (this is important for key backups & things)
|
||||||
this.deviceList.startTrackingDeviceList(this.userId);
|
this.deviceList.startTrackingDeviceList(this.userId);
|
||||||
|
|
||||||
|
logger.debug("Crypto: initialising roomlist...");
|
||||||
|
await this.roomList.init();
|
||||||
|
|
||||||
logger.log("Crypto: checking for key backup...");
|
logger.log("Crypto: checking for key backup...");
|
||||||
this.backupManager.checkAndStart();
|
this.backupManager.checkAndStart();
|
||||||
}
|
}
|
||||||
@ -4244,6 +4251,22 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
|
|||||||
obj.signatures = recursiveMapToObject(sigs);
|
obj.signatures = recursiveMapToObject(sigs);
|
||||||
if (unsigned !== undefined) obj.unsigned = unsigned;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user