diff --git a/package.json b/package.json index 4248cddbf..62e2b4efb 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ ], "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-js": "^0.1.3", + "@matrix-org/matrix-sdk-crypto-js": "^0.1.4", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index 7776e9ef8..61b04e388 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -34,7 +34,7 @@ import { import { mkEvent } from "../../test-utils/test-utils"; import { CryptoBackend } from "../../../src/common-crypto/CryptoBackend"; import { IEventDecryptionResult } from "../../../src/@types/crypto"; -import { OutgoingRequest, OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; +import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; import { ServerSideSecretStorage } from "../../../src/secret-storage"; import { CryptoCallbacks, ImportRoomKeysOpts, VerificationRequest } from "../../../src/crypto-api"; import * as testData from "../../test-utils/test-data"; @@ -42,6 +42,10 @@ import * as testData from "../../test-utils/test-data"; const TEST_USER = "@alice:example.com"; const TEST_DEVICE_ID = "TEST_DEVICE"; +afterEach(() => { + fetchMock.reset(); +}); + describe("RustCrypto", () => { describe(".importRoomKeys and .exportRoomKeys", () => { let rustCrypto: RustCrypto; @@ -390,60 +394,39 @@ describe("RustCrypto", () => { let rustCrypto: RustCrypto; beforeEach(async () => { - rustCrypto = await makeTestRustCrypto(undefined, testData.TEST_USER_ID); - }); - - afterEach(() => { - jest.useRealTimers(); - }); - - it("returns false initially", async () => { - jest.useFakeTimers(); - const prom = rustCrypto.userHasCrossSigningKeys(); - // the getIdentity() request should wait for a /keys/query request to complete, but times out after 1500ms - await jest.advanceTimersByTimeAsync(2000); - await expect(prom).resolves.toBe(false); - }); - - it("returns false if there is no cross-signing identity", async () => { - // @ts-ignore private field - const olmMachine = rustCrypto.olmMachine; - - const outgoingRequests: OutgoingRequest[] = await olmMachine.outgoingRequests(); - // pick out the KeysQueryRequest, and respond to it with the device keys but *no* cross-signing keys. - const req = outgoingRequests.find((r) => r instanceof KeysQueryRequest)!; - await olmMachine.markRequestAsSent( - req.id!, - req.type, - JSON.stringify({ - device_keys: { - [testData.TEST_USER_ID]: { [testData.TEST_DEVICE_ID]: testData.SIGNED_TEST_DEVICE_DATA }, - }, + rustCrypto = await makeTestRustCrypto( + new MatrixHttpApi(new TypedEventEmitter(), { + baseUrl: "http://server/", + prefix: "", + onlyData: true, }), + testData.TEST_USER_ID, ); + }); + + it("throws an error if the fetch fails", async () => { + fetchMock.post("path:/_matrix/client/v3/keys/query", 400); + await expect(rustCrypto.userHasCrossSigningKeys()).rejects.toThrow("400 error"); + }); + + it("returns false if the user has no cross-signing keys", async () => { + fetchMock.post("path:/_matrix/client/v3/keys/query", { + device_keys: { + [testData.TEST_USER_ID]: { [testData.TEST_DEVICE_ID]: testData.SIGNED_TEST_DEVICE_DATA }, + }, + }); await expect(rustCrypto.userHasCrossSigningKeys()).resolves.toBe(false); }); - it("returns true if OlmMachine has a cross-signing identity", async () => { - // @ts-ignore private field - const olmMachine = rustCrypto.olmMachine; + it("returns true if the user has cross-signing keys", async () => { + fetchMock.post("path:/_matrix/client/v3/keys/query", { + device_keys: { + [testData.TEST_USER_ID]: { [testData.TEST_DEVICE_ID]: testData.SIGNED_TEST_DEVICE_DATA }, + }, + ...testData.SIGNED_CROSS_SIGNING_KEYS_DATA, + }); - const outgoingRequests: OutgoingRequest[] = await olmMachine.outgoingRequests(); - // pick out the KeysQueryRequest, and respond to it with the cross-signing keys - const req = outgoingRequests.find((r) => r instanceof KeysQueryRequest)!; - await olmMachine.markRequestAsSent( - req.id!, - req.type, - JSON.stringify({ - device_keys: { - [testData.TEST_USER_ID]: { [testData.TEST_DEVICE_ID]: testData.SIGNED_TEST_DEVICE_DATA }, - }, - ...testData.SIGNED_CROSS_SIGNING_KEYS_DATA, - }), - ); - - // ... and we should now have cross-signing keys. await expect(rustCrypto.userHasCrossSigningKeys()).resolves.toBe(true); }); }); diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 5ca8b7f65..d7248137c 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -206,7 +206,13 @@ export class RustCrypto extends TypedEventEmitter { - const userIdentity = await this.olmMachine.getIdentity(new RustSdkCryptoJs.UserId(this.userId)); + const userId = new RustSdkCryptoJs.UserId(this.userId); + /* make sure we have an *up-to-date* idea of the user's cross-signing keys. This is important, because if we + * return "false" here, we will end up generating new cross-signing keys and replacing the existing ones. + */ + const request = this.olmMachine.queryKeysForUsers([userId]); + await this.outgoingRequestProcessor.makeOutgoingRequest(request); + const userIdentity = await this.olmMachine.getIdentity(userId); return userIdentity !== undefined; } diff --git a/yarn.lock b/yarn.lock index 06bd1a9e0..49caa8cef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1530,10 +1530,10 @@ dependencies: lodash "^4.17.21" -"@matrix-org/matrix-sdk-crypto-js@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.3.tgz#19981e7613d3673d07c885a98d39276b5fe74ef0" - integrity sha512-RcRlE3wcMnE5ijACHIHmhXFogEEJdIcb/CbJ4rK1PCMduQ4yvxycVpMxwh7aKxFNitZbHZLCK7TfRzUpzjU2tw== +"@matrix-org/matrix-sdk-crypto-js@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.4.tgz#c13c7c8c3a1d8da08e6ad195d25e5e61cc402df7" + integrity sha512-OxG84iSeR89zYLFeb+DCaFtZT+DDiIu+kTkqY8OYfhE5vpGLFX2sDVBRrAdos1IUqEoboDloDBR9+yU7hNRyog== "@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz": version "3.2.14"