diff options
Diffstat (limited to 'includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto')
7 files changed, 0 insertions, 774 deletions
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/KeyClaimManager.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/KeyClaimManager.ts deleted file mode 100644 index 9df8f89..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/KeyClaimManager.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { OlmMachine, UserId } from "@matrix-org/matrix-sdk-crypto-js"; - -import { OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; - -/** - * KeyClaimManager: linearises calls to OlmMachine.getMissingSessions to avoid races - * - * We have one of these per `RustCrypto` (and hence per `MatrixClient`). - */ -export class KeyClaimManager { - private currentClaimPromise: Promise<void>; - private stopped = false; - - public constructor( - private readonly olmMachine: OlmMachine, - private readonly outgoingRequestProcessor: OutgoingRequestProcessor, - ) { - this.currentClaimPromise = Promise.resolve(); - } - - /** - * Tell the KeyClaimManager to immediately stop processing requests. - * - * Any further calls, and any still in the queue, will fail with an error. - */ - public stop(): void { - this.stopped = true; - } - - /** - * Given a list of users, attempt to ensure that we have Olm Sessions active with each of their devices - * - * If we don't have an active olm session, we will claim a one-time key and start one. - * - * @param userList - list of userIDs to claim - */ - public ensureSessionsForUsers(userList: Array<UserId>): Promise<void> { - // The Rust-SDK requires that we only have one getMissingSessions process in flight at once. This little dance - // ensures that, by only having one call to ensureSessionsForUsersInner active at once (and making them - // queue up in order). - const prom = this.currentClaimPromise - .catch(() => { - // any errors in the previous claim will have been reported already, so there is nothing to do here. - // we just throw away the error and start anew. - }) - .then(() => this.ensureSessionsForUsersInner(userList)); - this.currentClaimPromise = prom; - return prom; - } - - private async ensureSessionsForUsersInner(userList: Array<UserId>): Promise<void> { - // bail out quickly if we've been stopped. - if (this.stopped) { - throw new Error(`Cannot ensure Olm sessions: shutting down`); - } - const claimRequest = await this.olmMachine.getMissingSessions(userList); - if (claimRequest) { - await this.outgoingRequestProcessor.makeOutgoingRequest(claimRequest); - } - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/OutgoingRequestProcessor.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/OutgoingRequestProcessor.ts deleted file mode 100644 index 7ac9a21..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/OutgoingRequestProcessor.ts +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { - OlmMachine, - KeysBackupRequest, - KeysClaimRequest, - KeysQueryRequest, - KeysUploadRequest, - RoomMessageRequest, - SignatureUploadRequest, - ToDeviceRequest, -} from "@matrix-org/matrix-sdk-crypto-js"; - -import { logger } from "../logger"; -import { IHttpOpts, MatrixHttpApi, Method } from "../http-api"; -import { QueryDict } from "../utils"; - -/** - * Common interface for all the request types returned by `OlmMachine.outgoingRequests`. - */ -export interface OutgoingRequest { - readonly id: string | undefined; - readonly type: number; -} - -/** - * OutgoingRequestManager: turns `OutgoingRequest`s from the rust sdk into HTTP requests - * - * We have one of these per `RustCrypto` (and hence per `MatrixClient`), not that it does anything terribly complicated. - * It's responsible for: - * - * * holding the reference to the `MatrixHttpApi` - * * turning `OutgoingRequest`s from the rust backend into HTTP requests, and sending them - * * sending the results of such requests back to the rust backend. - */ -export class OutgoingRequestProcessor { - public constructor( - private readonly olmMachine: OlmMachine, - private readonly http: MatrixHttpApi<IHttpOpts & { onlyData: true }>, - ) {} - - public async makeOutgoingRequest(msg: OutgoingRequest): Promise<void> { - let resp: string; - - /* refer https://docs.rs/matrix-sdk-crypto/0.6.0/matrix_sdk_crypto/requests/enum.OutgoingRequests.html - * for the complete list of request types - */ - if (msg instanceof KeysUploadRequest) { - resp = await this.rawJsonRequest(Method.Post, "/_matrix/client/v3/keys/upload", {}, msg.body); - } else if (msg instanceof KeysQueryRequest) { - resp = await this.rawJsonRequest(Method.Post, "/_matrix/client/v3/keys/query", {}, msg.body); - } else if (msg instanceof KeysClaimRequest) { - resp = await this.rawJsonRequest(Method.Post, "/_matrix/client/v3/keys/claim", {}, msg.body); - } else if (msg instanceof SignatureUploadRequest) { - resp = await this.rawJsonRequest(Method.Post, "/_matrix/client/v3/keys/signatures/upload", {}, msg.body); - } else if (msg instanceof KeysBackupRequest) { - resp = await this.rawJsonRequest(Method.Put, "/_matrix/client/v3/room_keys/keys", {}, msg.body); - } else if (msg instanceof ToDeviceRequest) { - const path = - `/_matrix/client/v3/sendToDevice/${encodeURIComponent(msg.event_type)}/` + - encodeURIComponent(msg.txn_id); - resp = await this.rawJsonRequest(Method.Put, path, {}, msg.body); - } else if (msg instanceof RoomMessageRequest) { - const path = - `/_matrix/client/v3/room/${encodeURIComponent(msg.room_id)}/send/` + - `${encodeURIComponent(msg.event_type)}/${encodeURIComponent(msg.txn_id)}`; - resp = await this.rawJsonRequest(Method.Put, path, {}, msg.body); - } else { - logger.warn("Unsupported outgoing message", Object.getPrototypeOf(msg)); - resp = ""; - } - - if (msg.id) { - await this.olmMachine.markRequestAsSent(msg.id, msg.type, resp); - } - } - - private async rawJsonRequest(method: Method, path: string, queryParams: QueryDict, body: string): Promise<string> { - const opts = { - // inhibit the JSON stringification and parsing within HttpApi. - json: false, - - // nevertheless, we are sending, and accept, JSON. - headers: { - "Content-Type": "application/json", - "Accept": "application/json", - }, - - // we use the full prefix - prefix: "", - }; - - try { - const response = await this.http.authedRequest<string>(method, path, queryParams, body, opts); - logger.info(`rust-crypto: successfully made HTTP request: ${method} ${path}`); - return response; - } catch (e) { - logger.warn(`rust-crypto: error making HTTP request: ${method} ${path}: ${e}`); - throw e; - } - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/RoomEncryptor.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/RoomEncryptor.ts deleted file mode 100644 index 1649a69..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/RoomEncryptor.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { EncryptionSettings, OlmMachine, RoomId, UserId } from "@matrix-org/matrix-sdk-crypto-js"; - -import { EventType } from "../@types/event"; -import { IContent, MatrixEvent } from "../models/event"; -import { Room } from "../models/room"; -import { logger, PrefixedLogger } from "../logger"; -import { KeyClaimManager } from "./KeyClaimManager"; -import { RoomMember } from "../models/room-member"; -import { OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; - -/** - * RoomEncryptor: responsible for encrypting messages to a given room - */ -export class RoomEncryptor { - private readonly prefixedLogger: PrefixedLogger; - - /** - * @param olmMachine - The rust-sdk's OlmMachine - * @param keyClaimManager - Our KeyClaimManager, which manages the queue of one-time-key claim requests - * @param room - The room we want to encrypt for - * @param encryptionSettings - body of the m.room.encryption event currently in force in this room - */ - public constructor( - private readonly olmMachine: OlmMachine, - private readonly keyClaimManager: KeyClaimManager, - private readonly outgoingRequestProcessor: OutgoingRequestProcessor, - private readonly room: Room, - private encryptionSettings: IContent, - ) { - this.prefixedLogger = logger.withPrefix(`[${room.roomId} encryption]`); - } - - /** - * Handle a new `m.room.encryption` event in this room - * - * @param config - The content of the encryption event - */ - public onCryptoEvent(config: IContent): void { - if (JSON.stringify(this.encryptionSettings) != JSON.stringify(config)) { - this.prefixedLogger.error(`Ignoring m.room.encryption event which requests a change of config`); - } - } - - /** - * Handle a new `m.room.member` event in this room - * - * @param member - new membership state - */ - public onRoomMembership(member: RoomMember): void { - this.prefixedLogger.debug(`${member.membership} event for ${member.userId}`); - - if ( - member.membership == "join" || - (member.membership == "invite" && this.room.shouldEncryptForInvitedMembers()) - ) { - // make sure we are tracking the deviceList for this user - this.prefixedLogger.debug(`starting to track devices for: ${member.userId}`); - this.olmMachine.updateTrackedUsers([new UserId(member.userId)]); - } - - // TODO: handle leaves (including our own) - } - - /** - * Prepare to encrypt events in this room. - * - * This ensures that we have a megolm session ready to use and that we have shared its key with all the devices - * in the room. - */ - public async ensureEncryptionSession(): Promise<void> { - if (this.encryptionSettings.algorithm !== "m.megolm.v1.aes-sha2") { - throw new Error( - `Cannot encrypt in ${this.room.roomId} for unsupported algorithm '${this.encryptionSettings.algorithm}'`, - ); - } - - const members = await this.room.getEncryptionTargetMembers(); - this.prefixedLogger.debug( - `Encrypting for users (shouldEncryptForInvitedMembers: ${this.room.shouldEncryptForInvitedMembers()}):`, - members.map((u) => `${u.userId} (${u.membership})`), - ); - - const userList = members.map((u) => new UserId(u.userId)); - await this.keyClaimManager.ensureSessionsForUsers(userList); - - this.prefixedLogger.debug("Sessions for users are ready; now sharing room key"); - - const rustEncryptionSettings = new EncryptionSettings(); - /* FIXME historyVisibility, rotation, etc */ - - const shareMessages = await this.olmMachine.shareRoomKey( - new RoomId(this.room.roomId), - userList, - rustEncryptionSettings, - ); - if (shareMessages) { - for (const m of shareMessages) { - await this.outgoingRequestProcessor.makeOutgoingRequest(m); - } - } - } - - /** - * Discard any existing group session for this room - */ - public async forceDiscardSession(): Promise<void> { - const r = await this.olmMachine.invalidateGroupSession(new RoomId(this.room.roomId)); - if (r) { - this.prefixedLogger.info("Discarded existing group session"); - } - } - - /** - * Encrypt an event for this room - * - * This will ensure that we have a megolm session for this room, share it with the devices in the room, and - * then encrypt the event using the session. - * - * @param event - Event to be encrypted. - */ - public async encryptEvent(event: MatrixEvent): Promise<void> { - await this.ensureEncryptionSession(); - - const encryptedContent = await this.olmMachine.encryptRoomEvent( - new RoomId(this.room.roomId), - event.getType(), - JSON.stringify(event.getContent()), - ); - - event.makeEncrypted( - EventType.RoomMessageEncrypted, - JSON.parse(encryptedContent), - this.olmMachine.identityKeys.curve25519.toBase64(), - this.olmMachine.identityKeys.ed25519.toBase64(), - ); - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/browserify-index.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/browserify-index.ts deleted file mode 100644 index 7f91e90..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/browserify-index.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* This file replaces rust-crypto/index.ts when the js-sdk is being built for browserify. - * - * It is a stub, so that we do not import the whole of the base64'ed wasm artifact into the browserify bundle. - * It deliberately does nothing except raise an exception. - */ - -import { IHttpOpts, MatrixHttpApi } from "../http-api"; - -export async function initRustCrypto( - _http: MatrixHttpApi<IHttpOpts & { onlyData: true }>, - _userId: string, - _deviceId: string, -): Promise<Crypto> { - throw new Error("Rust crypto is not supported under browserify."); -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/constants.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/constants.ts deleted file mode 100644 index 9d72060..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/constants.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/** The prefix used on indexeddbs created by rust-crypto */ -export const RUST_SDK_STORE_PREFIX = "matrix-js-sdk"; diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/index.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/index.ts deleted file mode 100644 index e2c541f..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; - -import { RustCrypto } from "./rust-crypto"; -import { logger } from "../logger"; -import { RUST_SDK_STORE_PREFIX } from "./constants"; -import { IHttpOpts, MatrixHttpApi } from "../http-api"; - -export async function initRustCrypto( - http: MatrixHttpApi<IHttpOpts & { onlyData: true }>, - userId: string, - deviceId: string, -): Promise<RustCrypto> { - // initialise the rust matrix-sdk-crypto-js, if it hasn't already been done - await RustSdkCryptoJs.initAsync(); - - // enable tracing in the rust-sdk - new RustSdkCryptoJs.Tracing(RustSdkCryptoJs.LoggerLevel.Trace).turnOn(); - - const u = new RustSdkCryptoJs.UserId(userId); - const d = new RustSdkCryptoJs.DeviceId(deviceId); - logger.info("Init OlmMachine"); - - // TODO: use the pickle key for the passphrase - const olmMachine = await RustSdkCryptoJs.OlmMachine.initialize(u, d, RUST_SDK_STORE_PREFIX, "test pass"); - const rustCrypto = new RustCrypto(olmMachine, http, userId, deviceId); - - logger.info("Completed rust crypto-sdk setup"); - return rustCrypto; -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/rust-crypto.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/rust-crypto.ts deleted file mode 100644 index 4a0b1f8..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/rust-crypto/rust-crypto.ts +++ /dev/null @@ -1,334 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; - -import type { IEventDecryptionResult, IMegolmSessionData } from "../@types/crypto"; -import type { IToDeviceEvent } from "../sync-accumulator"; -import type { IEncryptedEventInfo } from "../crypto/api"; -import { MatrixEvent } from "../models/event"; -import { Room } from "../models/room"; -import { RoomMember } from "../models/room-member"; -import { CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend"; -import { logger } from "../logger"; -import { IHttpOpts, MatrixHttpApi } from "../http-api"; -import { DeviceTrustLevel, UserTrustLevel } from "../crypto/CrossSigning"; -import { RoomEncryptor } from "./RoomEncryptor"; -import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; -import { KeyClaimManager } from "./KeyClaimManager"; - -/** - * An implementation of {@link CryptoBackend} using the Rust matrix-sdk-crypto. - */ -export class RustCrypto implements CryptoBackend { - public globalErrorOnUnknownDevices = false; - - /** whether {@link stop} has been called */ - private stopped = false; - - /** whether {@link outgoingRequestLoop} is currently running */ - private outgoingRequestLoopRunning = false; - - /** mapping of roomId → encryptor class */ - private roomEncryptors: Record<string, RoomEncryptor> = {}; - - private keyClaimManager: KeyClaimManager; - private outgoingRequestProcessor: OutgoingRequestProcessor; - - public constructor( - private readonly olmMachine: RustSdkCryptoJs.OlmMachine, - http: MatrixHttpApi<IHttpOpts & { onlyData: true }>, - _userId: string, - _deviceId: string, - ) { - this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http); - this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor); - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // CryptoBackend implementation - // - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public stop(): void { - // stop() may be called multiple times, but attempting to close() the OlmMachine twice - // will cause an error. - if (this.stopped) { - return; - } - this.stopped = true; - - this.keyClaimManager.stop(); - - // make sure we close() the OlmMachine; doing so means that all the Rust objects will be - // cleaned up; in particular, the indexeddb connections will be closed, which means they - // can then be deleted. - this.olmMachine.close(); - } - - public async encryptEvent(event: MatrixEvent, _room: Room): Promise<void> { - const roomId = event.getRoomId()!; - const encryptor = this.roomEncryptors[roomId]; - - if (!encryptor) { - throw new Error(`Cannot encrypt event in unconfigured room ${roomId}`); - } - - await encryptor.encryptEvent(event); - } - - public async decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult> { - const roomId = event.getRoomId(); - if (!roomId) { - // presumably, a to-device message. These are normally decrypted in preprocessToDeviceMessages - // so the fact it has come back here suggests that decryption failed. - // - // once we drop support for the libolm crypto implementation, we can stop passing to-device messages - // through decryptEvent and hence get rid of this case. - throw new Error("to-device event was not decrypted in preprocessToDeviceMessages"); - } - const res = (await this.olmMachine.decryptRoomEvent( - JSON.stringify({ - event_id: event.getId(), - type: event.getWireType(), - sender: event.getSender(), - state_key: event.getStateKey(), - content: event.getWireContent(), - origin_server_ts: event.getTs(), - }), - new RustSdkCryptoJs.RoomId(event.getRoomId()!), - )) as RustSdkCryptoJs.DecryptedRoomEvent; - return { - clearEvent: JSON.parse(res.event), - claimedEd25519Key: res.senderClaimedEd25519Key, - senderCurve25519Key: res.senderCurve25519Key, - forwardingCurve25519KeyChain: res.forwardingCurve25519KeyChain, - }; - } - - public getEventEncryptionInfo(event: MatrixEvent): IEncryptedEventInfo { - // TODO: make this work properly. Or better, replace it. - - const ret: Partial<IEncryptedEventInfo> = {}; - - ret.senderKey = event.getSenderKey() ?? undefined; - ret.algorithm = event.getWireContent().algorithm; - - if (!ret.senderKey || !ret.algorithm) { - ret.encrypted = false; - return ret as IEncryptedEventInfo; - } - ret.encrypted = true; - ret.authenticated = true; - ret.mismatchedSender = true; - return ret as IEncryptedEventInfo; - } - - public checkUserTrust(userId: string): UserTrustLevel { - // TODO - return new UserTrustLevel(false, false, false); - } - - public checkDeviceTrust(userId: string, deviceId: string): DeviceTrustLevel { - // TODO - return new DeviceTrustLevel(false, false, false, false); - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // CryptoApi implementation - // - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public globalBlacklistUnverifiedDevices = false; - - public async userHasCrossSigningKeys(): Promise<boolean> { - // TODO - return false; - } - - public prepareToEncrypt(room: Room): void { - const encryptor = this.roomEncryptors[room.roomId]; - - if (encryptor) { - encryptor.ensureEncryptionSession(); - } - } - - public forceDiscardSession(roomId: string): Promise<void> { - return this.roomEncryptors[roomId]?.forceDiscardSession(); - } - - public async exportRoomKeys(): Promise<IMegolmSessionData[]> { - // TODO - return []; - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // SyncCryptoCallbacks implementation - // - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Apply sync changes to the olm machine - * @param events - the received to-device messages - * @param oneTimeKeysCounts - the received one time key counts - * @param unusedFallbackKeys - the received unused fallback keys - * @returns A list of preprocessed to-device messages. - */ - private async receiveSyncChanges({ - events, - oneTimeKeysCounts = new Map<string, number>(), - unusedFallbackKeys = new Set<string>(), - }: { - events?: IToDeviceEvent[]; - oneTimeKeysCounts?: Map<string, number>; - unusedFallbackKeys?: Set<string>; - }): Promise<IToDeviceEvent[]> { - const result = await this.olmMachine.receiveSyncChanges( - events ? JSON.stringify(events) : "[]", - new RustSdkCryptoJs.DeviceLists(), - oneTimeKeysCounts, - unusedFallbackKeys, - ); - - // receiveSyncChanges returns a JSON-encoded list of decrypted to-device messages. - return JSON.parse(result); - } - - /** called by the sync loop to preprocess incoming to-device messages - * - * @param events - the received to-device messages - * @returns A list of preprocessed to-device messages. - */ - public preprocessToDeviceMessages(events: IToDeviceEvent[]): Promise<IToDeviceEvent[]> { - // send the received to-device messages into receiveSyncChanges. We have no info on device-list changes, - // one-time-keys, or fallback keys, so just pass empty data. - return this.receiveSyncChanges({ events }); - } - - /** called by the sync loop to preprocess one time key counts - * - * @param oneTimeKeysCounts - the received one time key counts - * @returns A list of preprocessed to-device messages. - */ - public async preprocessOneTimeKeyCounts(oneTimeKeysCounts: Map<string, number>): Promise<void> { - await this.receiveSyncChanges({ oneTimeKeysCounts }); - } - - /** called by the sync loop to preprocess unused fallback keys - * - * @param unusedFallbackKeys - the received unused fallback keys - * @returns A list of preprocessed to-device messages. - */ - public async preprocessUnusedFallbackKeys(unusedFallbackKeys: Set<string>): Promise<void> { - await this.receiveSyncChanges({ unusedFallbackKeys }); - } - - /** called by the sync loop on m.room.encrypted events - * - * @param room - in which the event was received - * @param event - encryption event to be processed - */ - public async onCryptoEvent(room: Room, event: MatrixEvent): Promise<void> { - const config = event.getContent(); - - const existingEncryptor = this.roomEncryptors[room.roomId]; - if (existingEncryptor) { - existingEncryptor.onCryptoEvent(config); - } else { - this.roomEncryptors[room.roomId] = new RoomEncryptor( - this.olmMachine, - this.keyClaimManager, - this.outgoingRequestProcessor, - room, - config, - ); - } - - // start tracking devices for any users already known to be in this room. - const members = await room.getEncryptionTargetMembers(); - logger.debug( - `[${room.roomId} encryption] starting to track devices for: `, - members.map((u) => `${u.userId} (${u.membership})`), - ); - await this.olmMachine.updateTrackedUsers(members.map((u) => new RustSdkCryptoJs.UserId(u.userId))); - } - - /** called by the sync loop after processing each sync. - * - * TODO: figure out something equivalent for sliding sync. - * - * @param syncState - information on the completed sync. - */ - public onSyncCompleted(syncState: OnSyncCompletedData): void { - // Processing the /sync may have produced new outgoing requests which need sending, so kick off the outgoing - // request loop, if it's not already running. - this.outgoingRequestLoop(); - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // Other public functions - // - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - /** called by the MatrixClient on a room membership event - * - * @param event - The matrix event which caused this event to fire. - * @param member - The member whose RoomMember.membership changed. - * @param oldMembership - The previous membership state. Null if it's a new member. - */ - public onRoomMembership(event: MatrixEvent, member: RoomMember, oldMembership?: string): void { - const enc = this.roomEncryptors[event.getRoomId()!]; - if (!enc) { - // not encrypting in this room - return; - } - enc.onRoomMembership(member); - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // Outgoing requests - // - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - private async outgoingRequestLoop(): Promise<void> { - if (this.outgoingRequestLoopRunning) { - return; - } - this.outgoingRequestLoopRunning = true; - try { - while (!this.stopped) { - const outgoingRequests: Object[] = await this.olmMachine.outgoingRequests(); - if (outgoingRequests.length == 0 || this.stopped) { - // no more messages to send (or we have been told to stop): exit the loop - return; - } - for (const msg of outgoingRequests) { - await this.outgoingRequestProcessor.makeOutgoingRequest(msg as OutgoingRequest); - } - } - } catch (e) { - logger.error("Error processing outgoing-message requests from rust crypto-sdk", e); - } finally { - this.outgoingRequestLoopRunning = false; - } - } -} |