diff --git a/README.md b/README.md index 756b8c71ca9..297d37a657e 100644 --- a/README.md +++ b/README.md @@ -307,7 +307,7 @@ Then visit `http://localhost:8005` to see the API docs. ## Initialization -**Do not use `matrixClient.initCrypto()`. This method is deprecated and no longer maintained.** +**Do not use `matrixClient.initLegacyCrypto()`. This method is deprecated and no longer maintained.** To initialize the end-to-end encryption support in the matrix client: @@ -396,10 +396,10 @@ Once the cross-signing is set up on one of your devices, you can verify another ## Migrating from the legacy crypto stack to Rust crypto -If your application previously used the legacy crypto stack, (i.e, it called `MatrixClient.initCrypto()`), you will +If your application previously used the legacy crypto stack, (i.e, it called `MatrixClient.initLegacyCrypto()`), you will need to migrate existing devices to the Rust crypto stack. -This migration happens automatically when you call `initRustCrypto()` instead of `initCrypto()`, +This migration happens automatically when you call `initRustCrypto()` instead of `initLegacyCrypto()`, but you need to provide the legacy [`cryptoStore`](https://matrix-org.github.io/matrix-js-sdk/interfaces/matrix.ICreateClientOpts.html#cryptoStore) and [`pickleKey`](https://matrix-org.github.io/matrix-js-sdk/interfaces/matrix.ICreateClientOpts.html#pickleKey) to [`createClient`](https://matrix-org.github.io/matrix-js-sdk/functions/matrix.createClient.html): ```javascript diff --git a/spec/integ/crypto/crypto.spec.ts b/spec/integ/crypto/crypto.spec.ts index 5b219d1d51c..96d809aea99 100644 --- a/spec/integ/crypto/crypto.spec.ts +++ b/spec/integ/crypto/crypto.spec.ts @@ -1741,7 +1741,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, groupSession: groupSession, room_id: ROOM_ID, }); - await testClient.client.initCrypto(); + await testClient.client.initLegacyCrypto(); const keys = [ { room_id: ROOM_ID, @@ -1853,7 +1853,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, oldBackendOnly("Alice receives shared history before being invited to a room by the sharer", async () => { const beccaTestClient = new TestClient("@becca:localhost", "foobar", "bazquux"); - await beccaTestClient.client.initCrypto(); + await beccaTestClient.client.initLegacyCrypto(); expectAliceKeyQuery({ device_keys: { "@alice:localhost": {} }, failures: {} }); await startClientAndAwaitFirstSync(); @@ -2007,7 +2007,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, oldBackendOnly("Alice receives shared history before being invited to a room by someone else", async () => { const beccaTestClient = new TestClient("@becca:localhost", "foobar", "bazquux"); - await beccaTestClient.client.initCrypto(); + await beccaTestClient.client.initLegacyCrypto(); expectAliceKeyQuery({ device_keys: { "@alice:localhost": {} }, failures: {} }); await startClientAndAwaitFirstSync(); diff --git a/spec/integ/crypto/olm-encryption-spec.ts b/spec/integ/crypto/olm-encryption-spec.ts index 5977bda74ef..5b98c63936a 100644 --- a/spec/integ/crypto/olm-encryption-spec.ts +++ b/spec/integ/crypto/olm-encryption-spec.ts @@ -345,10 +345,10 @@ describe("MatrixClient crypto", () => { beforeEach(async () => { aliTestClient = new TestClient(aliUserId, aliDeviceId, aliAccessToken); - await aliTestClient.client.initCrypto(); + await aliTestClient.client.initLegacyCrypto(); bobTestClient = new TestClient(bobUserId, bobDeviceId, bobAccessToken); - await bobTestClient.client.initCrypto(); + await bobTestClient.client.initLegacyCrypto(); aliMessages = []; bobMessages = []; diff --git a/spec/integ/devicelist-integ.spec.ts b/spec/integ/devicelist-integ.spec.ts index 88388fdf9f7..ce741d8dc39 100644 --- a/spec/integ/devicelist-integ.spec.ts +++ b/spec/integ/devicelist-integ.spec.ts @@ -77,7 +77,7 @@ describe("DeviceList management:", function () { async function createTestClient() { const testClient = new TestClient("@alice:localhost", "xzcvb", "akjgkrgjs", sessionStoreBackend); - await testClient.client.initCrypto(); + await testClient.client.initLegacyCrypto(); return testClient; } diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index d5ec9677b19..e058426cbd7 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -650,9 +650,9 @@ describe("MatrixClient", function () { } beforeEach(function () { - // running initCrypto should trigger a key upload + // running initLegacyCrypto should trigger a key upload httpBackend.when("POST", "/keys/upload").respond(200, {}); - return Promise.all([client.initCrypto(), httpBackend.flush("/keys/upload", 1)]); + return Promise.all([client.initLegacyCrypto(), httpBackend.flush("/keys/upload", 1)]); }); afterEach(() => { diff --git a/spec/integ/matrix-client-syncing.spec.ts b/spec/integ/matrix-client-syncing.spec.ts index d3156f0fb12..2c0ab315bed 100644 --- a/spec/integ/matrix-client-syncing.spec.ts +++ b/spec/integ/matrix-client-syncing.spec.ts @@ -112,7 +112,7 @@ describe("MatrixClient syncing", () => { }); it("should emit RoomEvent.MyMembership for invite->leave->invite cycles", async () => { - await client!.initCrypto(); + await client!.initLegacyCrypto(); const roomId = "!cycles:example.org"; @@ -227,7 +227,7 @@ describe("MatrixClient syncing", () => { }); it("should emit RoomEvent.MyMembership for knock->leave->knock cycles", async () => { - await client!.initCrypto(); + await client!.initLegacyCrypto(); const roomId = "!cycles:example.org"; @@ -2573,7 +2573,7 @@ describe("MatrixClient syncing (IndexedDB version)", () => { idbHttpBackend.when("GET", "/pushrules/").respond(200, {}); idbHttpBackend.when("POST", "/filter").respond(200, { filter_id: "a filter id" }); - await idbClient.initCrypto(); + await idbClient.initLegacyCrypto(); const roomId = "!invite:example.org"; diff --git a/spec/integ/sliding-sync-sdk.spec.ts b/spec/integ/sliding-sync-sdk.spec.ts index f6264530088..7b080351a6f 100644 --- a/spec/integ/sliding-sync-sdk.spec.ts +++ b/spec/integ/sliding-sync-sdk.spec.ts @@ -119,7 +119,7 @@ describe("SlidingSyncSdk", () => { mockSlidingSync = mockifySlidingSync(new SlidingSync("", new Map(), {}, client, 0)); if (testOpts.withCrypto) { httpBackend!.when("GET", "/room_keys/version").respond(404, {}); - await client!.initCrypto(); + await client!.initLegacyCrypto(); syncOpts.cryptoCallbacks = syncOpts.crypto = client!.crypto; } httpBackend!.when("GET", "/_matrix/client/v3/pushrules").respond(200, {}); diff --git a/spec/test-utils/test-utils.ts b/spec/test-utils/test-utils.ts index 22e7006e47c..d0c9abb2a5d 100644 --- a/spec/test-utils/test-utils.ts +++ b/spec/test-utils/test-utils.ts @@ -561,7 +561,7 @@ export type InitCrypto = (_: MatrixClient) => Promise; CRYPTO_BACKENDS["rust-sdk"] = (client: MatrixClient) => client.initRustCrypto(); if (globalThis.Olm) { - CRYPTO_BACKENDS["libolm"] = (client: MatrixClient) => client.initCrypto(); + CRYPTO_BACKENDS["libolm"] = (client: MatrixClient) => client.initLegacyCrypto(); } export const emitPromise = (e: EventEmitter, k: string): Promise => new Promise((r) => e.once(k, r)); diff --git a/spec/unit/crypto.spec.ts b/spec/unit/crypto.spec.ts index ce2d2389212..419bb530a66 100644 --- a/spec/unit/crypto.spec.ts +++ b/spec/unit/crypto.spec.ts @@ -119,7 +119,7 @@ describe("Crypto", function () { it("getVersion() should return the current version of the olm library", async () => { const client = new TestClient("@alice:example.com", "deviceid").client; - await client.initCrypto(); + await client.initLegacyCrypto(); const olmVersionTuple = Crypto.getOlmVersion(); expect(client.getCrypto()?.getVersion()).toBe( @@ -130,7 +130,7 @@ describe("Crypto", function () { describe("encrypted events", function () { it("provides encryption information for events from unverified senders", async function () { const client = new TestClient("@alice:example.com", "deviceid").client; - await client.initCrypto(); + await client.initLegacyCrypto(); // unencrypted event const event = { @@ -210,7 +210,7 @@ describe("Crypto", function () { let client: MatrixClient; beforeEach(async () => { client = new TestClient("@alice:example.com", "deviceid").client; - await client.initCrypto(); + await client.initLegacyCrypto(); // mock out the verification check client.crypto!.checkUserTrust = (userId) => new UserTrustLevel(true, false, false); @@ -306,7 +306,7 @@ describe("Crypto", function () { it("doesn't throw an error when attempting to decrypt a redacted event", async () => { const client = new TestClient("@alice:example.com", "deviceid").client; - await client.initCrypto(); + await client.initLegacyCrypto(); const event = new MatrixEvent({ content: {}, @@ -439,10 +439,10 @@ describe("Crypto", function () { secondAliceClient = new TestClient("@alice:example.com", "secondAliceDevice").client; bobClient = new TestClient("@bob:example.com", "bobdevice").client; claraClient = new TestClient("@clara:example.com", "claradevice").client; - await aliceClient.initCrypto(); - await secondAliceClient.initCrypto(); - await bobClient.initCrypto(); - await claraClient.initCrypto(); + await aliceClient.initLegacyCrypto(); + await secondAliceClient.initLegacyCrypto(); + await bobClient.initLegacyCrypto(); + await claraClient.initLegacyCrypto(); }); afterEach(async function () { @@ -1111,7 +1111,7 @@ describe("Crypto", function () { jest.spyOn(logger, "debug").mockImplementation(() => {}); jest.setTimeout(10000); const client = new TestClient("@a:example.com", "dev").client; - await client.initCrypto(); + await client.initLegacyCrypto(); client.crypto!.isCrossSigningReady = async () => false; client.crypto!.baseApis.uploadDeviceSigningKeys = jest.fn().mockResolvedValue(null); client.crypto!.baseApis.setAccountData = jest.fn().mockResolvedValue(null); @@ -1147,9 +1147,9 @@ describe("Crypto", function () { client = new TestClient("@alice:example.org", "aliceweb"); - // running initCrypto should trigger a key upload + // running initLegacyCrypto should trigger a key upload client.httpBackend.when("POST", "/keys/upload").respond(200, {}); - await Promise.all([client.client.initCrypto(), client.httpBackend.flush("/keys/upload", 1)]); + await Promise.all([client.client.initLegacyCrypto(), client.httpBackend.flush("/keys/upload", 1)]); encryptedPayload = { algorithm: "m.olm.v1.curve25519-aes-sha2", @@ -1264,9 +1264,9 @@ describe("Crypto", function () { client = new TestClient("@alice:example.org", "aliceweb"); - // running initCrypto should trigger a key upload + // running initLegacyCrypto should trigger a key upload client.httpBackend.when("POST", "/keys/upload").respond(200, {}); - await Promise.all([client.client.initCrypto(), client.httpBackend.flush("/keys/upload", 1)]); + await Promise.all([client.client.initLegacyCrypto(), client.httpBackend.flush("/keys/upload", 1)]); encryptedPayload = { algorithm: "m.olm.v1.curve25519-aes-sha2", @@ -1362,7 +1362,7 @@ describe("Crypto", function () { beforeEach(async () => { client = new TestClient("@alice:example.org", "aliceweb"); - await client.client.initCrypto(); + await client.client.initLegacyCrypto(); }); afterEach(async () => { @@ -1388,7 +1388,7 @@ describe("Crypto", function () { beforeEach(async () => { client = new TestClient("@alice:example.org", "aliceweb"); - await client.client.initCrypto(); + await client.client.initLegacyCrypto(); }); afterEach(async () => { @@ -1414,7 +1414,7 @@ describe("Crypto", function () { beforeEach(async () => { client = new TestClient("@alice:example.org", "aliceweb"); - await client.client.initCrypto(); + await client.client.initLegacyCrypto(); }); afterEach(async function () { diff --git a/spec/unit/crypto/algorithms/megolm.spec.ts b/spec/unit/crypto/algorithms/megolm.spec.ts index d2a1fbf3372..20d72702110 100644 --- a/spec/unit/crypto/algorithms/megolm.spec.ts +++ b/spec/unit/crypto/algorithms/megolm.spec.ts @@ -610,7 +610,11 @@ describe("MegolmDecryption", function () { const aliceClient = new TestClient("@alice:example.com", "alicedevice").client; const bobClient1 = new TestClient("@bob:example.com", "bobdevice1").client; const bobClient2 = new TestClient("@bob:example.com", "bobdevice2").client; - await Promise.all([aliceClient.initCrypto(), bobClient1.initCrypto(), bobClient2.initCrypto()]); + await Promise.all([ + aliceClient.initLegacyCrypto(), + bobClient1.initLegacyCrypto(), + bobClient2.initLegacyCrypto(), + ]); const aliceDevice = aliceClient.crypto!.olmDevice; const bobDevice1 = bobClient1.crypto!.olmDevice; const bobDevice2 = bobClient2.crypto!.olmDevice; @@ -704,7 +708,7 @@ describe("MegolmDecryption", function () { it("does not block unverified devices when sending verification events", async function () { const aliceClient = new TestClient("@alice:example.com", "alicedevice").client; const bobClient = new TestClient("@bob:example.com", "bobdevice").client; - await Promise.all([aliceClient.initCrypto(), bobClient.initCrypto()]); + await Promise.all([aliceClient.initLegacyCrypto(), bobClient.initLegacyCrypto()]); const bobDevice = bobClient.crypto!.olmDevice; const encryptionCfg = { @@ -789,7 +793,7 @@ describe("MegolmDecryption", function () { it("notifies devices when unable to create olm session", async function () { const aliceClient = new TestClient("@alice:example.com", "alicedevice").client; const bobClient = new TestClient("@bob:example.com", "bobdevice").client; - await Promise.all([aliceClient.initCrypto(), bobClient.initCrypto()]); + await Promise.all([aliceClient.initLegacyCrypto(), bobClient.initLegacyCrypto()]); const aliceDevice = aliceClient.crypto!.olmDevice; const bobDevice = bobClient.crypto!.olmDevice; @@ -873,7 +877,7 @@ describe("MegolmDecryption", function () { it("throws an error describing why it doesn't have a key", async function () { const aliceClient = new TestClient("@alice:example.com", "alicedevice").client; const bobClient = new TestClient("@bob:example.com", "bobdevice").client; - await Promise.all([aliceClient.initCrypto(), bobClient.initCrypto()]); + await Promise.all([aliceClient.initLegacyCrypto(), bobClient.initLegacyCrypto()]); const bobDevice = bobClient.crypto!.olmDevice; const aliceEventEmitter = new TypedEventEmitter(); @@ -955,7 +959,7 @@ describe("MegolmDecryption", function () { it("throws an error describing the lack of an olm session", async function () { const aliceClient = new TestClient("@alice:example.com", "alicedevice").client; const bobClient = new TestClient("@bob:example.com", "bobdevice").client; - await Promise.all([aliceClient.initCrypto(), bobClient.initCrypto()]); + await Promise.all([aliceClient.initLegacyCrypto(), bobClient.initLegacyCrypto()]); const aliceEventEmitter = new TypedEventEmitter(); aliceClient.crypto!.registerEventHandlers(aliceEventEmitter); @@ -1051,7 +1055,7 @@ describe("MegolmDecryption", function () { it("throws an error to indicate a wedged olm session", async function () { const aliceClient = new TestClient("@alice:example.com", "alicedevice").client; const bobClient = new TestClient("@bob:example.com", "bobdevice").client; - await Promise.all([aliceClient.initCrypto(), bobClient.initCrypto()]); + await Promise.all([aliceClient.initLegacyCrypto(), bobClient.initLegacyCrypto()]); const aliceEventEmitter = new TypedEventEmitter(); aliceClient.crypto!.registerEventHandlers(aliceEventEmitter); diff --git a/spec/unit/crypto/backup.spec.ts b/spec/unit/crypto/backup.spec.ts index 28bb0d4c443..c210d14c80b 100644 --- a/spec/unit/crypto/backup.spec.ts +++ b/spec/unit/crypto/backup.spec.ts @@ -231,7 +231,7 @@ describe("MegolmBackup", function () { test("fail if given backup has no version", async () => { const client = makeTestClient(cryptoStore); - await client.initCrypto(); + await client.initLegacyCrypto(); const data = { algorithm: olmlib.MEGOLM_BACKUP_ALGORITHM, auth_data: { @@ -314,7 +314,7 @@ describe("MegolmBackup", function () { megolmDecryption.olmlib = mockOlmLib; return client - .initCrypto() + .initLegacyCrypto() .then(() => { return cryptoStore.doTxn("readwrite", [IndexedDBCryptoStore.STORE_SESSIONS], (txn) => { cryptoStore.addEndToEndInboundGroupSession( @@ -391,7 +391,7 @@ describe("MegolmBackup", function () { megolmDecryption.olmlib = mockOlmLib; return client - .initCrypto() + .initLegacyCrypto() .then(() => { return client.crypto!.storeSessionBackupPrivateKey(new Uint8Array(32)); }) @@ -471,7 +471,7 @@ describe("MegolmBackup", function () { // @ts-ignore private field access megolmDecryption.olmlib = mockOlmLib; - await client.initCrypto(); + await client.initLegacyCrypto(); client.uploadDeviceSigningKeys = async function (e) { return {}; }; @@ -560,7 +560,7 @@ describe("MegolmBackup", function () { // @ts-ignore private field access megolmDecryption.olmlib = mockOlmLib; - await client.initCrypto(); + await client.initLegacyCrypto(); await cryptoStore.doTxn("readwrite", [IndexedDBCryptoStore.STORE_SESSIONS], (txn) => { cryptoStore.addEndToEndInboundGroupSession( "F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI", @@ -636,7 +636,7 @@ describe("MegolmBackup", function () { // @ts-ignore private field access megolmDecryption.olmlib = mockOlmLib; - return client.initCrypto(); + return client.initLegacyCrypto(); }); afterEach(function () { @@ -773,7 +773,7 @@ describe("MegolmBackup", function () { // initialising the crypto library will trigger a key upload request, which we can stub out client.uploadKeysRequest = jest.fn(); - await client.initCrypto(); + await client.initLegacyCrypto(); cryptoStore.countSessionsNeedingBackup = jest.fn().mockReturnValue(6); await expect(client.flagAllGroupSessionsForBackup()).resolves.toBe(6); @@ -784,7 +784,7 @@ describe("MegolmBackup", function () { describe("getKeyBackupInfo", () => { it("should return throw an `Not implemented`", async () => { const client = makeTestClient(cryptoStore); - await client.initCrypto(); + await client.initLegacyCrypto(); await expect(client.getCrypto()?.getKeyBackupInfo()).rejects.toThrow("Not implemented"); }); }); diff --git a/spec/unit/crypto/cross-signing.spec.ts b/spec/unit/crypto/cross-signing.spec.ts index 967c86ca69a..a8b7fa2624b 100644 --- a/spec/unit/crypto/cross-signing.spec.ts +++ b/spec/unit/crypto/cross-signing.spec.ts @@ -78,7 +78,7 @@ async function makeTestClient( const testClient = new TestClient(userInfo.userId, userInfo.deviceId, undefined, undefined, options); const client = testClient.client; - await client.initCrypto(); + await client.initLegacyCrypto(); return { client, httpBackend: testClient.httpBackend }; } diff --git a/spec/unit/crypto/dehydration.spec.ts b/spec/unit/crypto/dehydration.spec.ts index 37893230a46..d9a0dac895e 100644 --- a/spec/unit/crypto/dehydration.spec.ts +++ b/spec/unit/crypto/dehydration.spec.ts @@ -68,7 +68,7 @@ describe("Dehydration", () => { }, }); - await alice.client.initCrypto(); + await alice.client.initLegacyCrypto(); alice.httpBackend.when("GET", "/room_keys/version").respond(404, { errcode: "M_NOT_FOUND", diff --git a/spec/unit/crypto/secrets.spec.ts b/spec/unit/crypto/secrets.spec.ts index d7c7516a98b..88b011870f0 100644 --- a/spec/unit/crypto/secrets.spec.ts +++ b/spec/unit/crypto/secrets.spec.ts @@ -43,7 +43,7 @@ async function makeTestClient( return true; }; - await client.initCrypto(); + await client.initLegacyCrypto(); // No need to download keys for these tests jest.spyOn(client.crypto!, "downloadKeys").mockResolvedValue(new Map()); diff --git a/spec/unit/crypto/verification/util.ts b/spec/unit/crypto/verification/util.ts index 6454fd6004a..16a18559870 100644 --- a/spec/unit/crypto/verification/util.ts +++ b/spec/unit/crypto/verification/util.ts @@ -119,7 +119,7 @@ export async function makeTestClients( clients.push(testClient); } - await Promise.all(clients.map((testClient) => testClient.client.initCrypto())); + await Promise.all(clients.map((testClient) => testClient.client.initLegacyCrypto())); const destroy = () => { timeouts.forEach((t) => clearTimeout(t)); diff --git a/src/client.ts b/src/client.ts index 478e2784e51..332671dc795 100644 --- a/src/client.ts +++ b/src/client.ts @@ -294,7 +294,7 @@ export interface ICreateClientOpts { * specified, uses a default implementation (indexeddb in the browser, * in-memory otherwise). * - * This is only used for the legacy crypto implementation (as used by {@link MatrixClient#initCrypto}), + * This is only used for the legacy crypto implementation (as used by {@link MatrixClient#initLegacyCrypto}), * but if you use the rust crypto implementation ({@link MatrixClient#initRustCrypto}) and the device * previously used legacy crypto (so must be migrated), then this must still be provided, so that the * data can be migrated from the legacy store. @@ -389,7 +389,7 @@ export interface ICreateClientOpts { * * This must be set to the same value every time the client is initialised for the same device. * - * This is only used for the legacy crypto implementation (as used by {@link MatrixClient#initCrypto}), + * This is only used for the legacy crypto implementation (as used by {@link MatrixClient#initLegacyCrypto}), * but if you use the rust crypto implementation ({@link MatrixClient#initRustCrypto}) and the device * previously used legacy crypto (so must be migrated), then this must still be provided, so that the * data can be migrated from the legacy store. @@ -1222,7 +1222,7 @@ export class MatrixClient extends TypedEventEmitter(this); - public olmVersion: [number, number, number] | null = null; // populated after initCrypto + public olmVersion: [number, number, number] | null = null; // populated after initLegacyCrypto public usingExternalCrypto = false; private _store!: Store; public deviceId: string | null; @@ -1605,7 +1605,7 @@ export class MatrixClient extends TypedEventEmitter { + public async initLegacyCrypto(): Promise { if (!isCryptoAvailable()) { throw new Error( `End-to-end encryption not supported in this js-sdk build: did ` + @@ -2220,7 +2220,7 @@ export class MatrixClient extends TypedEventEmitter