From 7c34deecb6b4d806ad1c37abeee3f44e1f67e2e3 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:37:51 +0000 Subject: [PATCH] Pass CryptoBackend into SyncApi (#3010) I need to start calling back into the new rust crypto implementation from the /sync loops, so I need to pass it into SyncApi. To reduce the coupling, I've defined a new interface specifying the methods which exist for that purpose. Currently it's only onSyncCompleted. --- spec/integ/sliding-sync-sdk.spec.ts | 2 +- src/client.ts | 1 + src/common-crypto/CryptoBackend.ts | 26 +++++++++++++++++++++++++- src/crypto/index.ts | 4 ++-- src/rust-crypto/rust-crypto.ts | 10 +++++++++- src/sync.ts | 16 +++++++++++++--- 6 files changed, 51 insertions(+), 8 deletions(-) diff --git a/spec/integ/sliding-sync-sdk.spec.ts b/spec/integ/sliding-sync-sdk.spec.ts index 499bf08c6..a54cf71cb 100644 --- a/spec/integ/sliding-sync-sdk.spec.ts +++ b/spec/integ/sliding-sync-sdk.spec.ts @@ -119,7 +119,7 @@ describe("SlidingSyncSdk", () => { if (testOpts.withCrypto) { httpBackend!.when("GET", "/room_keys/version").respond(404, {}); await client!.initCrypto(); - syncOpts.crypto = client!.crypto; + syncOpts.cryptoCallbacks = syncOpts.crypto = client!.crypto; } httpBackend!.when("GET", "/_matrix/client/r0/pushrules").respond(200, {}); sdk = new SlidingSyncSdk(mockSlidingSync, client, testOpts, syncOpts); diff --git a/src/client.ts b/src/client.ts index 278237d15..3430c008e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1453,6 +1453,7 @@ export class MatrixClient extends TypedEventEmitter { if (!this.canResetTimelineCallback) { return false; diff --git a/src/common-crypto/CryptoBackend.ts b/src/common-crypto/CryptoBackend.ts index 2d09fc227..82db3f28a 100644 --- a/src/common-crypto/CryptoBackend.ts +++ b/src/common-crypto/CryptoBackend.ts @@ -20,7 +20,7 @@ import { MatrixEvent } from "../models/event"; /** * Common interface for the crypto implementations */ -export interface CryptoBackend { +export interface CryptoBackend extends SyncCryptoCallbacks { /** * Global override for whether the client should ever send encrypted * messages to unverified devices. This provides the default for rooms which @@ -71,3 +71,27 @@ export interface CryptoBackend { */ exportRoomKeys(): Promise; } + +/** The methods which crypto implementations should expose to the Sync api */ +export interface SyncCryptoCallbacks { + /** + * Called by the /sync loop after each /sync response is processed. + * + * Used to complete batch processing, or to initiate background processes + * + * @param syncState - information about the completed sync. + */ + onSyncCompleted(syncState: OnSyncCompletedData): void; +} + +export interface OnSyncCompletedData { + /** + * The 'next_batch' result from /sync, which will become the 'since' token for the next call to /sync. + */ + nextSyncToken?: string; + + /** + * True if we are working our way through a backlog of events after connecting. + */ + catchingUp?: boolean; +} diff --git a/src/crypto/index.ts b/src/crypto/index.ts index b925483e4..fe8719a4c 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -88,7 +88,7 @@ import { IContent } from "../models/event"; import { ISyncResponse } from "../sync-accumulator"; import { ISignatures } from "../@types/signed"; import { IMessage } from "./algorithms/olm"; -import { CryptoBackend } from "../common-crypto/CryptoBackend"; +import { CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend"; import { RoomState, RoomStateEvent } from "../models/room-state"; const DeviceVerification = DeviceInfo.DeviceVerification; @@ -3013,7 +3013,7 @@ export class Crypto extends TypedEventEmitter { + public async onSyncCompleted(syncData: OnSyncCompletedData): Promise { this.deviceList.setSyncToken(syncData.nextSyncToken ?? null); this.deviceList.saveIfDirty(); diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index a273bd164..b28b8b858 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -18,7 +18,7 @@ import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; import type { IEventDecryptionResult, IMegolmSessionData } from "../@types/crypto"; import { MatrixEvent } from "../models/event"; -import { CryptoBackend } from "../common-crypto/CryptoBackend"; +import { CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend"; // import { logger } from "../logger"; @@ -62,4 +62,12 @@ export class RustCrypto implements CryptoBackend { // TODO return []; } + + /** 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 {} } diff --git a/src/sync.ts b/src/sync.ts index d2576b32a..0ba52ba8c 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -25,6 +25,7 @@ limitations under the License. import { Optional } from "matrix-events-sdk"; +import type { SyncCryptoCallbacks } from "./common-crypto/CryptoBackend"; import { User, UserEvent } from "./models/user"; import { NotificationCountType, Room, RoomEvent } from "./models/room"; import * as utils from "./utils"; @@ -115,9 +116,18 @@ function debuglog(...params: any[]): void { * Options passed into the constructor of SyncApi by MatrixClient */ export interface SyncApiOptions { - // Crypto manager + /** + * Crypto manager + * + * @deprecated in favour of cryptoCallbacks + */ crypto?: Crypto; + /** + * If crypto is enabled on our client, callbacks into the crypto module + */ + cryptoCallbacks?: SyncCryptoCallbacks; + /** * A function which is called * with a room ID and returns a boolean. It should return 'true' if the SDK can @@ -925,8 +935,8 @@ export class SyncApi { // tell the crypto module to do its processing. It may block (to do a // /keys/changes request). - if (this.syncOpts.crypto) { - await this.syncOpts.crypto.onSyncCompleted(syncEventData); + if (this.syncOpts.cryptoCallbacks) { + await this.syncOpts.cryptoCallbacks.onSyncCompleted(syncEventData); } // keep emitting SYNCING -> SYNCING for clients who want to do bulk updates