Skip to content

Commit

Permalink
test(crypto): remove old legacy comments and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
florianduros committed Feb 3, 2025
1 parent 36a58e9 commit ca364eb
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 53 deletions.
10 changes: 0 additions & 10 deletions spec/TestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ import MockHttpBackend from "matrix-mock-request";

import type { IDeviceKeys, IOneTimeKey } from "../src/@types/crypto";
import type { IE2EKeyReceiver } from "./test-utils/E2EKeyReceiver";
import { LocalStorageCryptoStore } from "../src/crypto/store/localStorage-crypto-store";
import { logger } from "../src/logger";
import { syncPromise } from "./test-utils/test-utils";
import { createClient, IStartClientOpts } from "../src/matrix";
import { ICreateClientOpts, IDownloadKeyResult, MatrixClient, PendingEventOrdering } from "../src/client";
import { MockStorageApi } from "./MockStorageApi";
import { IKeysUploadResponse, IUploadKeysRequest } from "../src/client";
import { ISyncResponder } from "./test-utils/SyncResponder";

Expand All @@ -55,10 +53,6 @@ export class TestClient implements IE2EKeyReceiver, ISyncResponder {
sessionStoreBackend?: Storage,
options?: Partial<ICreateClientOpts>,
) {
if (sessionStoreBackend === undefined) {
sessionStoreBackend = new MockStorageApi() as unknown as Storage;
}

this.httpBackend = new MockHttpBackend();

const fullOptions: ICreateClientOpts = {
Expand All @@ -69,10 +63,6 @@ export class TestClient implements IE2EKeyReceiver, ISyncResponder {
fetchFn: this.httpBackend.fetchFn as typeof globalThis.fetch,
...options,
};
if (!fullOptions.cryptoStore) {
// expose this so the tests can get to it
fullOptions.cryptoStore = new LocalStorageCryptoStore(sessionStoreBackend);
}
this.client = createClient(fullOptions);

this.deviceKeys = null;
Expand Down
6 changes: 1 addition & 5 deletions spec/integ/crypto/cross-signing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,8 @@ describe("cross-signing", () => {
function awaitCrossSigningKeysUpload() {
return new Promise<any>((resolve) => {
fetchMock.post(
// legacy crypto uses /unstable/; /v3/ is correct
{
url: new RegExp("/_matrix/client/(unstable|v3)/keys/device_signing/upload"),
url: new RegExp("/_matrix/client/v3/keys/device_signing/upload"),
name: "upload-keys",
},
(url, options) => {
Expand Down Expand Up @@ -472,9 +471,6 @@ describe("cross-signing", () => {
await aliceClient.startClient();
await syncPromise(aliceClient);

// Wait for legacy crypto to find the device
await jest.advanceTimersByTimeAsync(10);

const devices = await aliceClient.getCrypto()!.getUserDeviceInfo([aliceClient.getSafeUserId()]);
expect(devices.get(aliceClient.getSafeUserId())!.has(testData.TEST_DEVICE_ID)).toBeTruthy();
});
Expand Down
47 changes: 18 additions & 29 deletions spec/integ/crypto/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import {
IContent,
IDownloadKeyResult,
IEvent,
IndexedDBCryptoStore,
IStartClientOpts,
MatrixClient,
MatrixEvent,
Expand Down Expand Up @@ -1901,7 +1900,6 @@ describe("crypto", () => {
});

describe("bootstrapSecretStorage", () => {
// Doesn't work with legacy crypto, which will try to bootstrap even without private key, which is buggy.
it("should throw an error if we are unable to create a key because createSecretStorageKey is not set", async () => {
await expect(
aliceClient.getCrypto()!.bootstrapSecretStorage({ setupNewSecretStorage: true }),
Expand Down Expand Up @@ -1947,8 +1945,6 @@ describe("crypto", () => {
});

it("should do nothing if an AES key is already in the secret storage and setupNewSecretStorage is not set", async () => {
const awaitAccountDataClientUpdate = awaitAccountDataUpdate("m.secret_storage.default_key");

const bootstrapPromise = aliceClient.getCrypto()!.bootstrapSecretStorage({ createSecretStorageKey });

// Wait for the key to be uploaded in the account data
Expand All @@ -1960,9 +1956,6 @@ describe("crypto", () => {
// Wait for bootstrapSecretStorage to finished
await bootstrapPromise;

// On legacy crypto we need to wait for ClientEvent.AccountData before calling bootstrap again.
await awaitAccountDataClientUpdate;

// Call again bootstrapSecretStorage
await aliceClient.getCrypto()!.bootstrapSecretStorage({ createSecretStorageKey });

Expand Down Expand Up @@ -2210,7 +2203,6 @@ describe("crypto", () => {

await aliceClient.getCrypto()!.deleteKeyBackupVersion(nextVersion!);
await aliceClient.getCrypto()!.checkKeyBackupAndEnable();
// XXX Legacy crypto does not update 4S when doing that; should ensure that rust implem does it.
expect(await aliceClient.getCrypto()!.getActiveSessionBackupVersion()).toBeNull();
});
});
Expand Down Expand Up @@ -2313,7 +2305,7 @@ describe("crypto", () => {

/** Guards against downgrade attacks from servers hiding or manipulating the crypto settings. */
describe("Persistent encryption settings", () => {
let persistentStoreClient: MatrixClient;
let client1: MatrixClient;
let client2: MatrixClient;

beforeEach(async () => {
Expand All @@ -2326,26 +2318,27 @@ describe("crypto", () => {
// For legacy crypto, these tests only work properly with a proper (indexeddb-based) CryptoStore, so
// rather than using the existing `aliceClient`, create a new client. Once we drop legacy crypto, we can
// just use `aliceClient` here.
persistentStoreClient = await makeNewClient(homeserverurl, userId, "persistentStoreClient");
await persistentStoreClient.startClient({});
// XXX: Even with the rust-crypto, we need to create to a new client. The tests fail with a timeout error.
client1 = await makeNewClient(homeserverurl, userId, "client1");
await client1.startClient({});
});

afterEach(async () => {
persistentStoreClient.stopClient();
client1.stopClient();
client2?.stopClient();
});

test("Sending a message in a room where the server is hiding the state event does not send a plaintext event", async () => {
// Alice is in an encrypted room
const encryptionState = mkEncryptionEvent({ algorithm: "m.megolm.v1.aes-sha2" });
syncResponder.sendOrQueueSyncResponse(getSyncResponseWithState([encryptionState]));
await syncPromise(persistentStoreClient);
await syncPromise(client1);

// Send a message, and expect to get an `m.room.encrypted` event.
await Promise.all([persistentStoreClient.sendTextMessage(ROOM_ID, "test"), expectEncryptedSendMessage()]);
await Promise.all([client1.sendTextMessage(ROOM_ID, "test"), expectEncryptedSendMessage()]);

// We now replace the client, and allow the new one to resync, *without* the encryption event.
client2 = await replaceClient(persistentStoreClient);
client2 = await replaceClient(client1);
syncResponder.sendOrQueueSyncResponse(getSyncResponseWithState([]));
await client2.startClient({});
await syncPromise(client2);
Expand All @@ -2358,11 +2351,11 @@ describe("crypto", () => {
// Alice is in an encrypted room, where the rotation period is set to 2 messages
const encryptionState = mkEncryptionEvent({ algorithm: "m.megolm.v1.aes-sha2", rotation_period_msgs: 2 });
syncResponder.sendOrQueueSyncResponse(getSyncResponseWithState([encryptionState]));
await syncPromise(persistentStoreClient);
await syncPromise(client1);

// Send a message, and expect to get an `m.room.encrypted` event.
const [, msg1Content] = await Promise.all([
persistentStoreClient.sendTextMessage(ROOM_ID, "test1"),
client1.sendTextMessage(ROOM_ID, "test1"),
expectEncryptedSendMessage(),
]);

Expand All @@ -2376,17 +2369,17 @@ describe("crypto", () => {
next_batch: "1",
rooms: { join: { [TEST_ROOM_ID]: { timeline: { events: [encryptionState2], prev_batch: "" } } } },
});
await syncPromise(persistentStoreClient);
await syncPromise(client1);

// Send two more messages. The first should use the same megolm session as the first; the second should
// use a different one.
const [, msg2Content] = await Promise.all([
persistentStoreClient.sendTextMessage(ROOM_ID, "test2"),
client1.sendTextMessage(ROOM_ID, "test2"),
expectEncryptedSendMessage(),
]);
expect(msg2Content.session_id).toEqual(msg1Content.session_id);
const [, msg3Content] = await Promise.all([
persistentStoreClient.sendTextMessage(ROOM_ID, "test3"),
client1.sendTextMessage(ROOM_ID, "test3"),
expectEncryptedSendMessage(),
]);
expect(msg3Content.session_id).not.toEqual(msg1Content.session_id);
Expand All @@ -2396,13 +2389,13 @@ describe("crypto", () => {
// Alice is in an encrypted room, where the rotation period is set to 2 messages
const encryptionState = mkEncryptionEvent({ algorithm: "m.megolm.v1.aes-sha2", rotation_period_msgs: 2 });
syncResponder.sendOrQueueSyncResponse(getSyncResponseWithState([encryptionState]));
await syncPromise(persistentStoreClient);
await syncPromise(client1);

// Send a message, and expect to get an `m.room.encrypted` event.
await Promise.all([persistentStoreClient.sendTextMessage(ROOM_ID, "test1"), expectEncryptedSendMessage()]);
await Promise.all([client1.sendTextMessage(ROOM_ID, "test1"), expectEncryptedSendMessage()]);

// We now replace the client, and allow the new one to resync with a *different* encryption event.
client2 = await replaceClient(persistentStoreClient);
client2 = await replaceClient(client1);
const encryptionState2 = mkEncryptionEvent({
algorithm: "m.megolm.v1.aes-sha2",
rotation_period_msgs: 100,
Expand Down Expand Up @@ -2433,11 +2426,7 @@ describe("crypto", () => {
userId: userId,
accessToken: "akjgkrgjs",
deviceId: "xzcvb",
cryptoCallbacks: createCryptoCallbacks(),
logger: logger.getChild(loggerPrefix),

// For legacy crypto, these tests only work with a proper persistent cryptoStore.
cryptoStore: new IndexedDBCryptoStore(indexedDB, "test"),
});
await client.initRustCrypto();
mockInitialApiRequests(client.getHomeserverUrl());
Expand All @@ -2446,7 +2435,7 @@ describe("crypto", () => {

function mkEncryptionEvent(content: object) {
return mkEventCustom({
sender: persistentStoreClient.getSafeUserId(),
sender: client1.getSafeUserId(),
type: "m.room.encryption",
state_key: "",
content: content,
Expand All @@ -2463,7 +2452,7 @@ describe("crypto", () => {
events: [
mkMembershipCustom({
membership: KnownMembership.Join,
sender: persistentStoreClient.getSafeUserId(),
sender: client1.getSafeUserId(),
}),
...stateEvents,
],
Expand Down
7 changes: 2 additions & 5 deletions spec/integ/crypto/verification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,9 +420,8 @@ describe("verification", () => {
expect(requests[0].transactionId).toEqual(transactionId);
}

// legacy crypto picks devices individually; rust crypto uses a broadcast message
const toDeviceMessage =
requestBody.messages[TEST_USER_ID]["*"] ?? requestBody.messages[TEST_USER_ID][TEST_DEVICE_ID];
// rust crypto uses a broadcast message
const toDeviceMessage = requestBody.messages[TEST_USER_ID]["*"];
expect(toDeviceMessage.from_device).toEqual(aliceClient.deviceId);
expect(toDeviceMessage.transaction_id).toEqual(transactionId);
});
Expand Down Expand Up @@ -510,10 +509,8 @@ describe("verification", () => {
reciprocateQRCodeCallbacks.confirm();
await sendToDevicePromise;

// at this point, on legacy crypto, the master key is already marked as trusted, and the request is "Done".
// Rust crypto, on the other hand, waits for the 'done' to arrive from the other side.
if (request.phase === VerificationPhase.Done) {
// legacy crypto: we're all done
const userVerificationStatus = await aliceClient.getCrypto()!.getUserVerificationStatus(TEST_USER_ID);
// eslint-disable-next-line jest/no-conditional-expect
expect(userVerificationStatus.isCrossSigningVerified()).toBeTruthy();
Expand Down
6 changes: 2 additions & 4 deletions spec/integ/matrix-client-syncing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
UNSTABLE_MSC2716_MARKER,
MatrixClient,
ClientEvent,
IndexedDBCryptoStore,
ISyncResponse,
IRoomEvent,
IJoinedRoom,
Expand Down Expand Up @@ -2571,9 +2570,8 @@ describe("MatrixClient syncing (IndexedDB version)", () => {
};

it("should emit ClientEvent.Room when invited while using indexeddb crypto store", async () => {
const idbTestClient = new TestClient(selfUserId, "DEVICE", selfAccessToken, undefined, {
cryptoStore: new IndexedDBCryptoStore(globalThis.indexedDB, "tests"),
});
// rust crypto used by default indexeddb
const idbTestClient = new TestClient(selfUserId, "DEVICE", selfAccessToken);
const idbHttpBackend = idbTestClient.httpBackend;
const idbClient = idbTestClient.client;
idbHttpBackend.when("GET", "/versions").respond(200, {});
Expand Down

0 comments on commit ca364eb

Please sign in to comment.