diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index 2fa73b133..c50f6e5b0 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -38,7 +38,13 @@ import { mkEvent } from "../../test-utils/test-utils"; import { CryptoBackend } from "../../../src/common-crypto/CryptoBackend"; import { IEventDecryptionResult } from "../../../src/@types/crypto"; import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; -import { ServerSideSecretStorage } from "../../../src/secret-storage"; +import { + AccountDataClient, + AddSecretStorageKeyOpts, + SecretStorageCallbacks, + ServerSideSecretStorage, + ServerSideSecretStorageImpl, +} from "../../../src/secret-storage"; import { CryptoCallbacks, EventShieldColour, @@ -51,6 +57,7 @@ import * as testData from "../../test-utils/test-data"; import { defer } from "../../../src/utils"; import { logger } from "../../../src/logger"; import { OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager"; +import { ClientEvent, ClientEventHandlerMap } from "../../../src/client"; import { Curve25519AuthData } from "../../../src/crypto-api/keybackup"; const TEST_USER = "@alice:example.com"; @@ -294,6 +301,62 @@ describe("RustCrypto", () => { expect(mockCrossSigningIdentity.bootstrapCrossSigning).toHaveBeenCalledWith({}); }); + it("bootstrapSecretStorage creates new backup when requested", async () => { + const secretStorageCallbacks = { + getSecretStorageKey: async (keys: any, name: string) => { + return [[...Object.keys(keys.keys)][0], new Uint8Array(32)]; + }, + } as SecretStorageCallbacks; + const secretStorage = new ServerSideSecretStorageImpl(new DummyAccountDataClient(), secretStorageCallbacks); + + const outgoingRequestProcessor = { + makeOutgoingRequest: jest.fn(), + } as unknown as Mocked; + + const rustCrypto = await makeTestRustCrypto( + new MatrixHttpApi(new TypedEventEmitter(), { + baseUrl: "http://server/", + prefix: "", + onlyData: true, + }), + testData.TEST_USER_ID, + undefined, + secretStorage, + ); + + rustCrypto["checkKeyBackupAndEnable"] = async () => { + return null; + }; + (rustCrypto["crossSigningIdentity"] as any)["outgoingRequestProcessor"] = outgoingRequestProcessor; + const resetKeyBackup = (rustCrypto["resetKeyBackup"] = jest.fn()); + + async function createSecretStorageKey() { + return { + keyInfo: {} as AddSecretStorageKeyOpts, + privateKey: new Uint8Array(32), + }; + } + + // create initial secret storage + await rustCrypto.bootstrapCrossSigning({ setupNewCrossSigning: true }); + await rustCrypto.bootstrapSecretStorage({ + createSecretStorageKey, + setupNewSecretStorage: true, + setupNewKeyBackup: true, + }); + // check that rustCrypto.resetKeyBackup was called + expect(resetKeyBackup.mock.calls).toHaveLength(1); + + // reset secret storage + await rustCrypto.bootstrapSecretStorage({ + createSecretStorageKey, + setupNewSecretStorage: true, + setupNewKeyBackup: true, + }); + // check that rustCrypto.resetKeyBackup was called again + expect(resetKeyBackup.mock.calls).toHaveLength(2); + }); + it("isSecretStorageReady", async () => { const mockSecretStorage = { getDefaultKeyId: jest.fn().mockResolvedValue(null), @@ -990,3 +1053,38 @@ async function makeTestRustCrypto( ): Promise { return await initRustCrypto(logger, http, userId, deviceId, secretStorage, cryptoCallbacks, null, undefined); } + +/** emulate account data, storing in memory + */ +class DummyAccountDataClient + extends TypedEventEmitter + implements AccountDataClient +{ + private storage: Map = new Map(); + + public constructor() { + super(); + } + + public async getAccountDataFromServer>(eventType: string): Promise { + const ret = this.storage.get(eventType); + + if (eventType) { + return ret as T; + } else { + return null; + } + } + + public async setAccountData(eventType: string, content: any): Promise<{}> { + this.storage.set(eventType, content); + this.emit( + ClientEvent.AccountData, + new MatrixEvent({ + content, + type: eventType, + }), + ); + return {}; + } +} diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 30072b3b1..67e44018f 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -732,10 +732,10 @@ export class RustCrypto extends TypedEventEmitter