diff --git a/spec/browserify/sync-browserify.spec.js b/spec/browserify/sync-browserify.spec.ts similarity index 100% rename from spec/browserify/sync-browserify.spec.js rename to spec/browserify/sync-browserify.spec.ts diff --git a/spec/unit/crypto/verification/sas.spec.js b/spec/unit/crypto/verification/sas.spec.ts similarity index 94% rename from spec/unit/crypto/verification/sas.spec.js rename to spec/unit/crypto/verification/sas.spec.ts index 7344c037968..f82b313fbc7 100644 --- a/spec/unit/crypto/verification/sas.spec.js +++ b/spec/unit/crypto/verification/sas.spec.ts @@ -19,10 +19,14 @@ import { makeTestClients, setupWebcrypto, teardownWebcrypto } from './util'; import { MatrixEvent } from "../../../../src/models/event"; import { SAS } from "../../../../src/crypto/verification/SAS"; import { DeviceInfo } from "../../../../src/crypto/deviceinfo"; -import { verificationMethods } from "../../../../src/crypto"; +import { CryptoEvent, verificationMethods } from "../../../../src/crypto"; import * as olmlib from "../../../../src/crypto/olmlib"; import { logger } from "../../../../src/logger"; import { resetCrossSigningKeys } from "../crypto-utils"; +import { VerificationBase } from "../../../../src/crypto/verification/Base"; +import { IVerificationChannel } from "../../../../src/crypto/verification/request/Channel"; +import { MatrixClient } from "../../../../src"; +import { VerificationRequest } from "../../../../src/crypto/verification/request/VerificationRequest"; const Olm = global.Olm; @@ -48,13 +52,15 @@ describe("SAS verification", function() { //channel, baseApis, userId, deviceId, startEvent, request const request = { onVerifierCancelled: function() {}, - }; + } as VerificationRequest; const channel = { send: function() { return Promise.resolve(); }, - }; - const sas = new SAS(channel, {}, "@alice:example.com", "ABCDEFG", null, request); + } as unknown as IVerificationChannel; + const mockClient = {} as unknown as MatrixClient; + const event = new MatrixEvent({ type: 'test' }); + const sas = new SAS(channel, mockClient, "@alice:example.com", "ABCDEFG", event, request); sas.handleEvent(new MatrixEvent({ sender: "@alice:example.com", type: "es.inquisition", @@ -65,7 +71,7 @@ describe("SAS verification", function() { expect(spy).toHaveBeenCalled(); // Cancel the SAS for cleanup (we started a verification, so abort) - sas.cancel(); + sas.cancel(new Error('error')); }); describe("verification", () => { @@ -403,16 +409,12 @@ describe("SAS verification", function() { }, ); alice.client.setDeviceVerified = jest.fn(); - alice.client.downloadKeys = () => { - return Promise.resolve(); - }; + alice.client.downloadKeys = jest.fn().mockResolvedValue({}); bob.client.setDeviceVerified = jest.fn(); - bob.client.downloadKeys = () => { - return Promise.resolve(); - }; + bob.client.downloadKeys = jest.fn().mockResolvedValue({}); - const bobPromise = new Promise((resolve, reject) => { - bob.client.on("crypto.verification.request", request => { + const bobPromise = new Promise>((resolve, reject) => { + bob.client.on(CryptoEvent.VerificationRequest, request => { request.verifier.on("show_sas", (e) => { e.mismatch(); }); @@ -421,7 +423,7 @@ describe("SAS verification", function() { }); const aliceVerifier = alice.client.beginKeyVerification( - verificationMethods.SAS, bob.client.getUserId(), bob.client.deviceId, + verificationMethods.SAS, bob.client.getUserId()!, bob.client.deviceId!, ); const aliceSpy = jest.fn(); @@ -501,7 +503,7 @@ describe("SAS verification", function() { aliceSasEvent = null; bobSasEvent = null; - bobPromise = new Promise((resolve, reject) => { + bobPromise = new Promise((resolve, reject) => { bob.client.on("crypto.verification.request", async (request) => { const verifier = request.beginKeyVerification(SAS.NAME); verifier.on("show_sas", (e) => { diff --git a/spec/unit/crypto/verification/secret_request.spec.js b/spec/unit/crypto/verification/secret_request.spec.ts similarity index 77% rename from spec/unit/crypto/verification/secret_request.spec.js rename to spec/unit/crypto/verification/secret_request.spec.ts index 398edc10a60..1c0a7410a4d 100644 --- a/spec/unit/crypto/verification/secret_request.spec.js +++ b/spec/unit/crypto/verification/secret_request.spec.ts @@ -18,6 +18,9 @@ import { CrossSigningInfo } from '../../../../src/crypto/CrossSigning'; import { encodeBase64 } from "../../../../src/crypto/olmlib"; import { setupWebcrypto, teardownWebcrypto } from './util'; import { VerificationBase } from '../../../../src/crypto/verification/Base'; +import { MatrixClient, MatrixEvent } from '../../../../src'; +import { VerificationRequest } from '../../../../src/crypto/verification/request/VerificationRequest'; +import { IVerificationChannel } from '../../../../src/crypto/verification/request/Channel'; jest.useFakeTimers(); @@ -54,9 +57,21 @@ describe("self-verifications", () => { cacheCallbacks, ); crossSigningInfo.keys = { - master: { keys: { X: testKeyPub } }, - self_signing: { keys: { X: testKeyPub } }, - user_signing: { keys: { X: testKeyPub } }, + master: { + keys: { X: testKeyPub }, + usage: [], + user_id: 'user-id', + }, + self_signing: { + keys: { X: testKeyPub }, + usage: [], + user_id: 'user-id', + }, + user_signing: { + keys: { X: testKeyPub }, + usage: [], + user_id: 'user-id', + }, }; const secretStorage = { @@ -79,20 +94,22 @@ describe("self-verifications", () => { getUserId: () => userId, getKeyBackupVersion: () => Promise.resolve({}), restoreKeyBackupWithCache, - }; + } as unknown as MatrixClient; const request = { onVerifierFinished: () => undefined, - }; + } as unknown as VerificationRequest; const verification = new VerificationBase( - undefined, // channel + undefined as unknown as IVerificationChannel, // channel client, // baseApis userId, "ABC", // deviceId - undefined, // startEvent + undefined as unknown as MatrixEvent, // startEvent request, ); + + // @ts-ignore set private property verification.resolve = () => undefined; const result = await verification.done(); @@ -102,12 +119,12 @@ describe("self-verifications", () => { expect(secretStorage.request.mock.calls.length).toBe(4); expect(cacheCallbacks.storeCrossSigningKeyCache.mock.calls[0][1]) - .toEqual(testKey); + .toEqual(testKey); expect(cacheCallbacks.storeCrossSigningKeyCache.mock.calls[1][1]) - .toEqual(testKey); + .toEqual(testKey); expect(storeSessionBackupPrivateKey.mock.calls[0][0]) - .toEqual(testKey); + .toEqual(testKey); expect(restoreKeyBackupWithCache).toHaveBeenCalled(); diff --git a/spec/unit/crypto/verification/verification_request.spec.js b/spec/unit/crypto/verification/verification_request.spec.ts similarity index 74% rename from spec/unit/crypto/verification/verification_request.spec.js rename to spec/unit/crypto/verification/verification_request.spec.ts index f8de29cee66..0b759efb993 100644 --- a/spec/unit/crypto/verification/verification_request.spec.js +++ b/spec/unit/crypto/verification/verification_request.spec.ts @@ -19,11 +19,18 @@ import { InRoomChannel } from "../../../../src/crypto/verification/request/InRoo import { ToDeviceChannel } from "../../../../src/crypto/verification/request/ToDeviceChannel"; import { MatrixEvent } from "../../../../src/models/event"; +import { MatrixClient } from "../../../../src/client"; import { setupWebcrypto, teardownWebcrypto } from "./util"; - -function makeMockClient(userId, deviceId) { +import { IVerificationChannel } from "../../../../src/crypto/verification/request/Channel"; +import { VerificationBase } from "../../../../src/crypto/verification/Base"; + +type MockClient = MatrixClient & { + popEvents: () => MatrixEvent[]; + popDeviceEvents: (userId: string, deviceId: string) => MatrixEvent[]; +}; +function makeMockClient(userId: string, deviceId: string): MockClient { let counter = 1; - let events = []; + let events: MatrixEvent[] = []; const deviceEvents = {}; return { getUserId() { return userId; }, @@ -54,16 +61,18 @@ function makeMockClient(userId, deviceId) { deviceEvents[userId][deviceId].push(event); } } - return Promise.resolve(); + return Promise.resolve({}); }, - popEvents() { + // @ts-ignore special testing fn + popEvents(): MatrixEvent[] { const e = events; events = []; return e; }, - popDeviceEvents(userId, deviceId) { + // @ts-ignore special testing fn + popDeviceEvents(userId: string, deviceId: string): MatrixEvent[] { const forDevice = deviceEvents[userId]; const events = forDevice && forDevice[deviceId]; const result = events || []; @@ -72,12 +81,21 @@ function makeMockClient(userId, deviceId) { } return result; }, - }; + } as unknown as MockClient; } const MOCK_METHOD = "mock-verify"; -class MockVerifier { - constructor(channel, client, userId, deviceId, startEvent) { +class MockVerifier extends VerificationBase<'', any> { + public _channel; + public _startEvent; + constructor( + channel: IVerificationChannel, + client: MatrixClient, + userId: string, + deviceId: string, + startEvent: MatrixEvent, + ) { + super(channel, client, userId, deviceId, startEvent, {} as unknown as VerificationRequest); this._channel = channel; this._startEvent = startEvent; } @@ -115,7 +133,10 @@ function makeRemoteEcho(event) { async function distributeEvent(ownRequest, theirRequest, event) { await ownRequest.channel.handleEvent( - makeRemoteEcho(event), ownRequest, true); + makeRemoteEcho(event), + ownRequest, + true, + ); await theirRequest.channel.handleEvent(event, theirRequest, true); } @@ -133,12 +154,19 @@ describe("verification request unit tests", function() { it("transition from UNSENT to DONE through happy path", async function() { const alice = makeMockClient("@alice:matrix.tld", "device1"); const bob = makeMockClient("@bob:matrix.tld", "device1"); + const verificationMethods = new Map( + [[MOCK_METHOD, MockVerifier]], + ) as unknown as Map; const aliceRequest = new VerificationRequest( - new InRoomChannel(alice, "!room", bob.getUserId()), - new Map([[MOCK_METHOD, MockVerifier]]), alice); + new InRoomChannel(alice, "!room", bob.getUserId()!), + verificationMethods, + alice, + ); const bobRequest = new VerificationRequest( new InRoomChannel(bob, "!room"), - new Map([[MOCK_METHOD, MockVerifier]]), bob); + verificationMethods, + bob, + ); expect(aliceRequest.invalid).toBe(true); expect(bobRequest.invalid).toBe(true); @@ -157,7 +185,7 @@ describe("verification request unit tests", function() { expect(aliceRequest.ready).toBe(true); const verifier = aliceRequest.beginKeyVerification(MOCK_METHOD); - await verifier.start(); + await (verifier as MockVerifier).start(); const [startEvent] = alice.popEvents(); expect(startEvent.getType()).toBe(START_TYPE); await distributeEvent(aliceRequest, bobRequest, startEvent); @@ -165,8 +193,7 @@ describe("verification request unit tests", function() { expect(aliceRequest.verifier).toBeInstanceOf(MockVerifier); expect(bobRequest.started).toBe(true); expect(bobRequest.verifier).toBeInstanceOf(MockVerifier); - - await bobRequest.verifier.start(); + await (bobRequest.verifier as MockVerifier).start(); const [bobDoneEvent] = bob.popEvents(); expect(bobDoneEvent.getType()).toBe(DONE_TYPE); await distributeEvent(bobRequest, aliceRequest, bobDoneEvent); @@ -180,12 +207,20 @@ describe("verification request unit tests", function() { it("methods only contains common methods", async function() { const alice = makeMockClient("@alice:matrix.tld", "device1"); const bob = makeMockClient("@bob:matrix.tld", "device1"); + const aliceVerificationMethods = new Map( + [["c", function() {}], ["a", function() {}]], + ) as unknown as Map; + const bobVerificationMethods = new Map( + [["c", function() {}], ["b", function() {}]], + ) as unknown as Map; const aliceRequest = new VerificationRequest( - new InRoomChannel(alice, "!room", bob.getUserId()), - new Map([["c", function() {}], ["a", function() {}]]), alice); + new InRoomChannel(alice, "!room", bob.getUserId()!), + aliceVerificationMethods, alice); const bobRequest = new VerificationRequest( new InRoomChannel(bob, "!room"), - new Map([["c", function() {}], ["b", function() {}]]), bob); + bobVerificationMethods, + bob, + ); await aliceRequest.sendRequest(); const [requestEvent] = alice.popEvents(); await distributeEvent(aliceRequest, bobRequest, requestEvent); @@ -201,13 +236,22 @@ describe("verification request unit tests", function() { const bob1 = makeMockClient("@bob:matrix.tld", "device1"); const bob2 = makeMockClient("@bob:matrix.tld", "device2"); const aliceRequest = new VerificationRequest( - new InRoomChannel(alice, "!room", bob1.getUserId()), new Map(), alice); + new InRoomChannel(alice, "!room", bob1.getUserId()!), + new Map(), + alice, + ); await aliceRequest.sendRequest(); const [requestEvent] = alice.popEvents(); const bob1Request = new VerificationRequest( - new InRoomChannel(bob1, "!room"), new Map(), bob1); + new InRoomChannel(bob1, "!room"), + new Map(), + bob1, + ); const bob2Request = new VerificationRequest( - new InRoomChannel(bob2, "!room"), new Map(), bob2); + new InRoomChannel(bob2, "!room"), + new Map(), + bob2, + ); await bob1Request.channel.handleEvent(requestEvent, bob1Request, true); await bob2Request.channel.handleEvent(requestEvent, bob2Request, true); @@ -222,22 +266,34 @@ describe("verification request unit tests", function() { it("verify own device with to_device messages", async function() { const bob1 = makeMockClient("@bob:matrix.tld", "device1"); const bob2 = makeMockClient("@bob:matrix.tld", "device2"); + const verificationMethods = new Map( + [[MOCK_METHOD, MockVerifier]], + ) as unknown as Map; const bob1Request = new VerificationRequest( - new ToDeviceChannel(bob1, bob1.getUserId(), ["device1", "device2"], - ToDeviceChannel.makeTransactionId(), "device2"), - new Map([[MOCK_METHOD, MockVerifier]]), bob1); + new ToDeviceChannel( + bob1, + bob1.getUserId()!, + ["device1", "device2"], + ToDeviceChannel.makeTransactionId(), + "device2", + ), + verificationMethods, + bob1, + ); const to = { userId: "@bob:matrix.tld", deviceId: "device2" }; const verifier = bob1Request.beginKeyVerification(MOCK_METHOD, to); expect(verifier).toBeInstanceOf(MockVerifier); - await verifier.start(); + await (verifier as MockVerifier).start(); const [startEvent] = bob1.popDeviceEvents(to.userId, to.deviceId); expect(startEvent.getType()).toBe(START_TYPE); const bob2Request = new VerificationRequest( - new ToDeviceChannel(bob2, bob2.getUserId(), ["device1"]), - new Map([[MOCK_METHOD, MockVerifier]]), bob2); + new ToDeviceChannel(bob2, bob2.getUserId()!, ["device1"]), + verificationMethods, + bob2, + ); await bob2Request.channel.handleEvent(startEvent, bob2Request, true); - await bob2Request.verifier.start(); + await (bob2Request.verifier as MockVerifier).start(); const [doneEvent1] = bob2.popDeviceEvents("@bob:matrix.tld", "device1"); expect(doneEvent1.getType()).toBe(DONE_TYPE); await bob1Request.channel.handleEvent(doneEvent1, bob1Request, true); @@ -253,11 +309,13 @@ describe("verification request unit tests", function() { const alice = makeMockClient("@alice:matrix.tld", "device1"); const bob = makeMockClient("@bob:matrix.tld", "device1"); const aliceRequest = new VerificationRequest( - new InRoomChannel(alice, "!room", bob.getUserId()), new Map(), alice); + new InRoomChannel(alice, "!room", bob.getUserId()!), + new Map(), + alice, + ); await aliceRequest.sendRequest(); const [requestEvent] = alice.popEvents(); - await aliceRequest.channel.handleEvent(requestEvent, aliceRequest, true, - true, true); + await aliceRequest.channel.handleEvent(requestEvent, aliceRequest, true); expect(aliceRequest.cancelled).toBe(false); expect(aliceRequest._cancellingUserId).toBe(undefined); @@ -269,11 +327,17 @@ describe("verification request unit tests", function() { const alice = makeMockClient("@alice:matrix.tld", "device1"); const bob = makeMockClient("@bob:matrix.tld", "device1"); const aliceRequest = new VerificationRequest( - new InRoomChannel(alice, "!room", bob.getUserId()), new Map(), alice); + new InRoomChannel(alice, "!room", bob.getUserId()!), + new Map(), + alice, + ); await aliceRequest.sendRequest(); const [requestEvent] = alice.popEvents(); const bobRequest = new VerificationRequest( - new InRoomChannel(bob, "!room"), new Map(), bob); + new InRoomChannel(bob, "!room"), + new Map(), + bob, + ); await bobRequest.channel.handleEvent(requestEvent, bobRequest, true);