Skip to content

Commit

Permalink
Remove deprecated methods and attributes of MatrixClient (#4659)
Browse files Browse the repository at this point in the history
* feat(legacy crypto)!: remove deprecated methods of `MatrixClient`

* test(legacy crypto): update existing tests to not use legacy crypto

- `Embedded.spec.ts`: casting since `encryptAndSendToDevices` is removed from `MatrixClient`.
- `room.spec.ts`: remove deprecated usage of `MatrixClient.crypto`
- `matrix-client.spec.ts` & `matrix-client-methods.spec.ts`: remove calls of deprecated methods of `MatrixClient`

* test(legacy crypto): remove test files using `MatrixClient` deprecated methods

* test(legacy crypto): update existing integ tests to run successfully

* feat(legacy crypto!): remove `ICreateClientOpts.deviceToImport`.

`ICreateClientOpts.deviceToImport` was used in the legacy cryto. The rust crypto doesn't support to import devices in this way.

* feat(legacy crypto!): remove `{get,set}GlobalErrorOnUnknownDevices`

`globalErrorOnUnknownDevices` is not used in the rust-crypto. The API is marked as unstable, we can remove it.
  • Loading branch information
florianduros authored Jan 28, 2025
1 parent ce6f971 commit 89cec0a
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 3,298 deletions.
3 changes: 2 additions & 1 deletion spec/integ/crypto/cross-signing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import "fake-indexeddb/auto";
import { IDBFactory } from "fake-indexeddb";

import { CRYPTO_BACKENDS, InitCrypto, syncPromise } from "../../test-utils/test-utils";
import { AuthDict, createClient, CryptoEvent, MatrixClient } from "../../../src";
import { AuthDict, createClient, MatrixClient } from "../../../src";
import { mockInitialApiRequests, mockSetupCrossSigningRequests } from "../../test-utils/mockEndpoints";
import encryptAESSecretStorageItem from "../../../src/utils/encryptAESSecretStorageItem.ts";
import { CryptoCallbacks, CrossSigningKey } from "../../../src/crypto-api";
Expand All @@ -37,6 +37,7 @@ import {
import * as testData from "../../test-utils/test-data";
import { E2EKeyResponder } from "../../test-utils/E2EKeyResponder";
import { AccountDataAccumulator } from "../../test-utils/AccountDataAccumulator";
import { CryptoEvent } from "../../../src/crypto-api";

afterEach(() => {
// reset fake-indexeddb after each test, to make sure we don't leak connections
Expand Down
530 changes: 11 additions & 519 deletions spec/integ/crypto/crypto.spec.ts

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions spec/integ/crypto/device-dehydration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ async function initializeSecretStorage(
privateKey: new Uint8Array(32),
};
}
await matrixClient.bootstrapCrossSigning({ setupNewCrossSigning: true });
await matrixClient.bootstrapSecretStorage({
await matrixClient.getCrypto()!.bootstrapCrossSigning({ setupNewCrossSigning: true });
await matrixClient.getCrypto()!.bootstrapSecretStorage({
createSecretStorageKey,
setupNewSecretStorage: true,
setupNewKeyBackup: false,
Expand Down
114 changes: 6 additions & 108 deletions spec/integ/crypto/megolm-backup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ function mockUploadEmitter(
describe.each(Object.entries(CRYPTO_BACKENDS))("megolm-keys backup (%s)", (backend: string, initCrypto: InitCrypto) => {
// oldBackendOnly is an alternative to `it` or `test` which will skip the test if we are running against the
// Rust backend. Once we have full support in the rust sdk, it will go away.
const oldBackendOnly = backend === "rust-sdk" ? test.skip : test;
const newBackendOnly = backend === "libolm" ? test.skip : test;

const isNewBackend = backend === "rust-sdk";
Expand Down Expand Up @@ -344,43 +343,14 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm-keys backup (%s)", (backe
fetchMock.get("express:/_matrix/client/v3/room_keys/keys", fullBackup);

const check = await aliceCrypto.checkKeyBackupAndEnable();

let onKeyCached: () => void;
const awaitKeyCached = new Promise<void>((resolve) => {
onKeyCached = resolve;
});

await aliceCrypto.storeSessionBackupPrivateKey(
decodeRecoveryKey(testData.BACKUP_DECRYPTION_KEY_BASE58),
check!.backupInfo!.version!,
);

const result = await advanceTimersUntil(
isNewBackend
? aliceCrypto.restoreKeyBackup()
: aliceClient.restoreKeyBackupWithRecoveryKey(
testData.BACKUP_DECRYPTION_KEY_BASE58,
undefined,
undefined,
check!.backupInfo!,
{
cacheCompleteCallback: () => onKeyCached(),
},
),
);
const result = await advanceTimersUntil(aliceCrypto.restoreKeyBackup());

expect(result.imported).toStrictEqual(1);

if (isNewBackend) return;

await awaitKeyCached;

// The key should be now cached
const afterCache = await advanceTimersUntil(
aliceClient.restoreKeyBackupWithCache(undefined, undefined, check!.backupInfo!),
);

expect(afterCache.imported).toStrictEqual(1);
});

/**
Expand Down Expand Up @@ -434,19 +404,9 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm-keys backup (%s)", (backe
);

const progressCallback = jest.fn();
const result = await (isNewBackend
? aliceCrypto.restoreKeyBackup({
progressCallback,
})
: aliceClient.restoreKeyBackupWithRecoveryKey(
testData.BACKUP_DECRYPTION_KEY_BASE58,
undefined,
undefined,
check!.backupInfo!,
{
progressCallback,
},
));
const result = await aliceCrypto.restoreKeyBackup({
progressCallback,
});

expect(result.imported).toStrictEqual(expectedTotal);
// Should be called 5 times: 200*4 plus one chunk with the remaining 32
Expand Down Expand Up @@ -508,17 +468,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm-keys backup (%s)", (backe
);

const progressCallback = jest.fn();
const result = await (isNewBackend
? aliceCrypto.restoreKeyBackup({ progressCallback })
: aliceClient.restoreKeyBackupWithRecoveryKey(
testData.BACKUP_DECRYPTION_KEY_BASE58,
undefined,
undefined,
check!.backupInfo!,
{
progressCallback,
},
));
const result = await aliceCrypto.restoreKeyBackup({ progressCallback });

expect(result.total).toStrictEqual(expectedTotal);
// A chunk failed to import
Expand Down Expand Up @@ -574,40 +524,13 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm-keys backup (%s)", (backe
check!.backupInfo!.version!,
);

const result = await (isNewBackend
? aliceCrypto.restoreKeyBackup()
: aliceClient.restoreKeyBackupWithRecoveryKey(
testData.BACKUP_DECRYPTION_KEY_BASE58,
undefined,
undefined,
check!.backupInfo!,
));
const result = await aliceCrypto.restoreKeyBackup();

expect(result.total).toStrictEqual(expectedTotal);
// A chunk failed to import
expect(result.imported).toStrictEqual(expectedTotal - decryptionFailureCount);
});

oldBackendOnly("recover specific session from backup", async function () {
fetchMock.get(
"express:/_matrix/client/v3/room_keys/keys/:room_id/:session_id",
testData.CURVE25519_KEY_BACKUP_DATA,
);

const check = await aliceCrypto.checkKeyBackupAndEnable();

const result = await advanceTimersUntil(
aliceClient.restoreKeyBackupWithRecoveryKey(
testData.BACKUP_DECRYPTION_KEY_BASE58,
ROOM_ID,
testData.MEGOLM_SESSION_DATA.session_id,
check!.backupInfo!,
),
);

expect(result.imported).toStrictEqual(1);
});

newBackendOnly(
"Should get the decryption key from the secret storage and restore the key backup",
async function () {
Expand All @@ -634,31 +557,6 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm-keys backup (%s)", (backe
},
);

oldBackendOnly("Fails on bad recovery key", async function () {
const fullBackup = {
rooms: {
[ROOM_ID]: {
sessions: {
[testData.MEGOLM_SESSION_DATA.session_id]: testData.CURVE25519_KEY_BACKUP_DATA,
},
},
},
};

fetchMock.get("express:/_matrix/client/v3/room_keys/keys", fullBackup);

const check = await aliceCrypto.checkKeyBackupAndEnable();

await expect(
aliceClient.restoreKeyBackupWithRecoveryKey(
"EsTx A7Xn aNFF k3jH zpV3 MQoN LJEg mscC HecF 982L wC77 mYQD",
undefined,
undefined,
check!.backupInfo!,
),
).rejects.toThrow();
});

newBackendOnly("Should throw an error if the decryption key is not found in cache", async () => {
await expect(aliceCrypto.restoreKeyBackup()).rejects.toThrow("No decryption key found in crypto store");
});
Expand Down
3 changes: 2 additions & 1 deletion spec/integ/crypto/rust-crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import "fake-indexeddb/auto";
import { IDBFactory } from "fake-indexeddb";
import fetchMock from "fetch-mock-jest";

import { createClient, CryptoEvent, IndexedDBCryptoStore } from "../../../src";
import { createClient, IndexedDBCryptoStore } from "../../../src";
import { populateStore } from "../../test-utils/test_indexeddb_cryptostore_dump";
import { MSK_NOT_CACHED_DATASET } from "../../test-utils/test_indexeddb_cryptostore_dump/no_cached_msk_dump";
import { IDENTITY_NOT_TRUSTED_DATASET } from "../../test-utils/test_indexeddb_cryptostore_dump/unverified";
import { FULL_ACCOUNT_DATASET } from "../../test-utils/test_indexeddb_cryptostore_dump/full_account";
import { EMPTY_ACCOUNT_DATASET } from "../../test-utils/test_indexeddb_cryptostore_dump/empty_account";
import { CryptoEvent } from "../../../src/crypto-api";

jest.setTimeout(15000);

Expand Down
5 changes: 1 addition & 4 deletions spec/integ/crypto/verification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import Olm from "@matrix-org/olm";

import {
createClient,
CryptoEvent,
DeviceVerification,
IContent,
ICreateClientOpts,
Expand Down Expand Up @@ -81,7 +80,7 @@ import {
getTestOlmAccountKeys,
ToDeviceEvent,
} from "./olm-utils";
import { KeyBackupInfo } from "../../../src/crypto-api";
import { KeyBackupInfo, CryptoEvent } from "../../../src/crypto-api";
import { encodeBase64 } from "../../../src/base64";

// The verification flows use javascript timers to set timeouts. We tell jest to use mock timer implementations
Expand Down Expand Up @@ -907,7 +906,6 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
describe("Send verification request in DM", () => {
beforeEach(async () => {
aliceClient = await startTestClient();
aliceClient.setGlobalErrorOnUnknownDevices(false);

e2eKeyResponder.addCrossSigningData(BOB_SIGNED_CROSS_SIGNING_KEYS_DATA);
e2eKeyResponder.addDeviceKeys(BOB_SIGNED_TEST_DEVICE_DATA);
Expand Down Expand Up @@ -990,7 +988,6 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
testOlmAccount.create();

aliceClient = await startTestClient();
aliceClient.setGlobalErrorOnUnknownDevices(false);
syncResponder.sendOrQueueSyncResponse(getSyncResponse([BOB_TEST_USER_ID]));
await syncPromise(aliceClient);

Expand Down
45 changes: 0 additions & 45 deletions spec/integ/matrix-client-methods.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import HttpBackend from "matrix-mock-request";
import { Mocked } from "jest-mock";

import * as utils from "../test-utils/test-utils";
import { IStoredClientOpts, MatrixClient } from "../../src/client";
Expand All @@ -34,7 +33,6 @@ import { THREAD_RELATION_TYPE } from "../../src/models/thread";
import { IFilterDefinition } from "../../src/filter";
import { ISearchResults } from "../../src/@types/search";
import { IStore } from "../../src/store";
import { CryptoBackend } from "../../src/common-crypto/CryptoBackend";
import { SetPresence } from "../../src/sync";
import { KnownMembership } from "../../src/@types/membership";

Expand Down Expand Up @@ -1508,49 +1506,6 @@ describe("MatrixClient", function () {
});
});

describe("uploadKeys", () => {
// uploadKeys() is a no-op nowadays, so there's not much to test here.
it("should complete successfully", async () => {
await client.uploadKeys();
});
});

describe("getCryptoTrustCrossSignedDevices", () => {
it("should throw if e2e is disabled", () => {
expect(() => client.getCryptoTrustCrossSignedDevices()).toThrow("End-to-end encryption disabled");
});

it("should proxy to the crypto backend", async () => {
const mockBackend = {
getTrustCrossSignedDevices: jest.fn().mockReturnValue(true),
} as unknown as Mocked<CryptoBackend>;
client["cryptoBackend"] = mockBackend;

expect(client.getCryptoTrustCrossSignedDevices()).toBe(true);
mockBackend.getTrustCrossSignedDevices.mockReturnValue(false);
expect(client.getCryptoTrustCrossSignedDevices()).toBe(false);
});
});

describe("setCryptoTrustCrossSignedDevices", () => {
it("should throw if e2e is disabled", () => {
expect(() => client.setCryptoTrustCrossSignedDevices(false)).toThrow("End-to-end encryption disabled");
});

it("should proxy to the crypto backend", async () => {
const mockBackend = {
setTrustCrossSignedDevices: jest.fn(),
} as unknown as Mocked<CryptoBackend>;
client["cryptoBackend"] = mockBackend;

client.setCryptoTrustCrossSignedDevices(true);
expect(mockBackend.setTrustCrossSignedDevices).toHaveBeenLastCalledWith(true);

client.setCryptoTrustCrossSignedDevices(false);
expect(mockBackend.setTrustCrossSignedDevices).toHaveBeenLastCalledWith(false);
});
});

describe("setSyncPresence", () => {
it("should pass calls through to the underlying sync api", () => {
const setPresence = jest.fn();
Expand Down
Loading

0 comments on commit 89cec0a

Please sign in to comment.