From 5caf05cfa18069b5e0c27f2a57bb9d3e3ba670ee Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 11 May 2021 11:25:43 +0100 Subject: [PATCH 01/19] Apply new linting rules --- spec/TestClient.js | 25 +++-- spec/browserify/sync-browserify.spec.js | 8 +- spec/integ/devicelist-integ-spec.js | 17 ++-- spec/integ/matrix-client-crypto.spec.js | 38 ++++--- .../integ/matrix-client-event-emitter.spec.js | 2 +- .../matrix-client-event-timeline.spec.js | 19 ++-- spec/integ/matrix-client-methods.spec.js | 15 ++- spec/integ/matrix-client-opts.spec.js | 8 +- spec/integ/matrix-client-retrying.spec.js | 10 +- .../integ/matrix-client-room-timeline.spec.js | 23 +++-- spec/integ/matrix-client-syncing.spec.js | 11 +-- spec/integ/megolm-integ.spec.js | 19 ++-- spec/olm-loader.js | 2 +- spec/test-utils.js | 7 +- spec/unit/autodiscovery.spec.js | 2 +- spec/unit/content-repo.spec.js | 2 +- spec/unit/crypto.spec.js | 24 ++--- spec/unit/crypto/CrossSigningInfo.spec.js | 8 +- spec/unit/crypto/DeviceList.spec.js | 6 +- spec/unit/crypto/algorithms/megolm.spec.js | 25 +++-- spec/unit/crypto/algorithms/olm.spec.js | 10 +- spec/unit/crypto/backup.spec.js | 18 ++-- spec/unit/crypto/cross-signing.spec.js | 26 ++--- spec/unit/crypto/crypto-utils.js | 3 +- .../crypto/outgoing-room-key-requests.spec.js | 2 +- spec/unit/crypto/secrets.spec.js | 50 +++++----- .../crypto/verification/InRoomChannel.spec.js | 4 +- spec/unit/crypto/verification/qr_code.spec.js | 2 +- spec/unit/crypto/verification/request.spec.js | 12 +-- spec/unit/crypto/verification/sas.spec.js | 26 ++--- .../verification/secret_request.spec.js | 8 +- spec/unit/crypto/verification/util.js | 8 +- .../verification/verification_request.spec.js | 18 ++-- spec/unit/event-timeline.spec.js | 16 ++- spec/unit/event.spec.js | 4 +- spec/unit/filter-component.spec.js | 4 +- spec/unit/filter.spec.js | 2 +- spec/unit/interactive-auth.spec.js | 10 +- spec/unit/login.spec.js | 2 +- spec/unit/matrix-client.spec.js | 8 +- spec/unit/pushprocessor.spec.js | 2 +- spec/unit/room-member.spec.js | 2 +- spec/unit/room-state.spec.js | 52 +++++----- spec/unit/room.spec.js | 51 +++++----- spec/unit/scheduler.spec.js | 16 +-- spec/unit/sync-accumulator.spec.js | 2 +- spec/unit/timeline-window.spec.js | 26 +++-- spec/unit/user.spec.js | 2 +- spec/unit/utils.spec.js | 23 +++-- src/autodiscovery.js | 8 +- src/base-apis.js | 89 ++++++++--------- src/client.js | 98 +++++++++---------- src/crypto/CrossSigning.js | 10 +- src/crypto/DeviceList.js | 15 ++- src/crypto/EncryptionSetup.js | 20 ++-- src/crypto/OlmDevice.js | 18 +--- src/crypto/OutgoingRoomKeyRequestManager.js | 2 +- src/crypto/RoomList.js | 2 +- src/crypto/SecretStorage.js | 20 ++-- src/crypto/aes.js | 14 +-- src/crypto/algorithms/megolm.js | 27 +++-- src/crypto/algorithms/olm.js | 7 +- src/crypto/dehydration.ts | 14 +-- src/crypto/index.js | 75 ++++++-------- src/crypto/key_passphrase.js | 4 +- src/crypto/olmlib.js | 4 +- .../store/indexeddb-crypto-store-backend.js | 16 +-- src/crypto/store/indexeddb-crypto-store.js | 8 +- src/crypto/store/localStorage-crypto-store.js | 12 +-- src/crypto/store/memory-crypto-store.js | 12 +-- src/crypto/verification/Base.js | 16 +-- src/crypto/verification/Error.js | 10 +- src/crypto/verification/IllegalMethod.js | 2 +- src/crypto/verification/QRCode.js | 8 +- src/crypto/verification/SAS.js | 8 +- .../verification/request/InRoomChannel.js | 4 +- .../verification/request/ToDeviceChannel.js | 11 +-- .../request/VerificationRequest.js | 42 ++++---- src/errors.js | 1 - src/filter.js | 2 +- src/http-api.js | 7 +- src/indexeddb-worker.js | 2 +- src/interactive-auth.js | 2 +- src/matrix.ts | 19 ++-- src/models/event-context.js | 4 +- src/models/event-timeline-set.js | 13 ++- src/models/event-timeline.js | 4 +- src/models/event.js | 17 ++-- src/models/group.js | 2 +- src/models/relations.js | 6 +- src/models/room-member.js | 6 +- src/models/room-state.js | 9 +- src/models/room.js | 32 +++--- src/models/search-result.js | 2 +- src/models/user.js | 4 +- src/pushprocessor.js | 6 +- src/realtime-callbacks.js | 3 +- src/scheduler.js | 3 +- src/store/indexeddb-local-backend.js | 7 +- src/store/indexeddb-remote-backend.js | 5 +- src/store/indexeddb-store-worker.js | 4 +- src/store/indexeddb.js | 15 ++- src/store/memory.js | 2 +- src/store/session/webstorage.js | 2 +- src/sync-accumulator.js | 4 +- src/sync.js | 20 ++-- src/timeline-window.js | 7 +- src/utils.ts | 2 +- src/webrtc/call.ts | 13 ++- src/webrtc/callEventHandler.ts | 2 +- src/webrtc/callFeed.ts | 4 +- 111 files changed, 680 insertions(+), 807 deletions(-) diff --git a/spec/TestClient.js b/spec/TestClient.js index 52b4b3d70..aa6db4f2a 100644 --- a/spec/TestClient.js +++ b/spec/TestClient.js @@ -20,12 +20,12 @@ limitations under the License. import './olm-loader'; import MockHttpBackend from 'matrix-mock-request'; -import {LocalStorageCryptoStore} from '../src/crypto/store/localStorage-crypto-store'; -import {logger} from '../src/logger'; -import {WebStorageSessionStore} from "../src/store/session/webstorage"; -import {syncPromise} from "./test-utils"; -import {createClient} from "../src/matrix"; -import {MockStorageApi} from "./MockStorageApi"; +import { LocalStorageCryptoStore } from '../src/crypto/store/localStorage-crypto-store'; +import { logger } from '../src/logger'; +import { WebStorageSessionStore } from "../src/store/session/webstorage"; +import { syncPromise } from "./test-utils"; +import { createClient } from "../src/matrix"; +import { MockStorageApi } from "./MockStorageApi"; /** * Wrapper for a MockStorageApi, MockHttpBackend and MatrixClient @@ -129,11 +129,10 @@ TestClient.prototype.expectDeviceKeyUpload = function() { expect(Object.keys(self.oneTimeKeys).length).toEqual(0); self.deviceKeys = content.device_keys; - return {one_time_key_counts: {signed_curve25519: 0}}; + return { one_time_key_counts: { signed_curve25519: 0 } }; }); }; - /** * If one-time keys have already been uploaded, return them. Otherwise, * set up an expectation that the keys will be uploaded, and wait for @@ -151,9 +150,9 @@ TestClient.prototype.awaitOneTimeKeyUpload = function() { .respond(200, (path, content) => { expect(content.device_keys).toBe(undefined); expect(content.one_time_keys).toBe(undefined); - return {one_time_key_counts: { + return { one_time_key_counts: { signed_curve25519: Object.keys(this.oneTimeKeys).length, - }}; + } }; }); this.httpBackend.when("POST", "/keys/upload") @@ -164,9 +163,9 @@ TestClient.prototype.awaitOneTimeKeyUpload = function() { logger.log('%s: received %i one-time keys', this, Object.keys(content.one_time_keys).length); this.oneTimeKeys = content.one_time_keys; - return {one_time_key_counts: { + return { one_time_key_counts: { signed_curve25519: Object.keys(this.oneTimeKeys).length, - }}; + } }; }); // this can take ages @@ -197,7 +196,6 @@ TestClient.prototype.expectKeyQuery = function(response) { }); }; - /** * get the uploaded curve25519 device key * @@ -208,7 +206,6 @@ TestClient.prototype.getDeviceKey = function() { return this.deviceKeys.keys[keyId]; }; - /** * get the uploaded ed25519 device key * diff --git a/spec/browserify/sync-browserify.spec.js b/spec/browserify/sync-browserify.spec.js index da0c510ac..8f5b3bf03 100644 --- a/spec/browserify/sync-browserify.spec.js +++ b/spec/browserify/sync-browserify.spec.js @@ -17,10 +17,10 @@ limitations under the License. // load XmlHttpRequest mock import "./setupTests"; import "../../dist/browser-matrix"; // uses browser-matrix instead of the src -import {MockStorageApi} from "../MockStorageApi"; -import {WebStorageSessionStore} from "../../src/store/session/webstorage"; +import { MockStorageApi } from "../MockStorageApi"; +import { WebStorageSessionStore } from "../../src/store/session/webstorage"; import MockHttpBackend from "matrix-mock-request"; -import {LocalStorageCryptoStore} from "../../src/crypto/store/localStorage-crypto-store"; +import { LocalStorageCryptoStore } from "../../src/crypto/store/localStorage-crypto-store"; import * as utils from "../test-utils"; const USER_ID = "@user:test.server"; @@ -58,7 +58,7 @@ describe("Browserify Test", function() { } beforeEach(async () => { - ({client, httpBackend} = await createTestClient()); + ({ client, httpBackend } = await createTestClient()); await client.startClient(); }); diff --git a/spec/integ/devicelist-integ-spec.js b/spec/integ/devicelist-integ-spec.js index ea3b28531..96bebe5c6 100644 --- a/spec/integ/devicelist-integ-spec.js +++ b/spec/integ/devicelist-integ-spec.js @@ -16,9 +16,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {TestClient} from '../TestClient'; +import { TestClient } from '../TestClient'; import * as testUtils from '../test-utils'; -import {logger} from '../../src/logger'; +import { logger } from '../../src/logger'; const ROOM_ID = "!room:id"; @@ -67,7 +67,6 @@ function getSyncResponse(roomMembers) { return syncResponse; } - describe("DeviceList management:", function() { if (!global.Olm) { logger.warn('not running deviceList tests: Olm not present'); @@ -98,7 +97,7 @@ describe("DeviceList management:", function() { }); it("Alice shouldn't do a second /query for non-e2e-capable devices", function() { - aliceTestClient.expectKeyQuery({device_keys: {'@alice:localhost': {}}}); + aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } }); return aliceTestClient.start().then(function() { const syncResponse = getSyncResponse(['@bob:xyz']); aliceTestClient.httpBackend.when('GET', '/sync').respond(200, syncResponse); @@ -137,11 +136,10 @@ describe("DeviceList management:", function() { }); }); - it("We should not get confused by out-of-order device query responses", () => { // https://github.com/vector-im/element-web/issues/3126 - aliceTestClient.expectKeyQuery({device_keys: {'@alice:localhost': {}}}); + aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } }); return aliceTestClient.start().then(() => { aliceTestClient.httpBackend.when('GET', '/sync').respond( 200, getSyncResponse(['@bob:xyz', '@chris:abc'])); @@ -160,7 +158,7 @@ describe("DeviceList management:", function() { ); aliceTestClient.httpBackend.when('PUT', '/send/').respond( - 200, {event_id: '$event1'}); + 200, { event_id: '$event1' }); return Promise.all([ aliceTestClient.client.sendTextMessage(ROOM_ID, 'test'), @@ -199,7 +197,7 @@ describe("DeviceList management:", function() { }, token: '3', }).respond(200, { - device_keys: {'@chris:abc': {}}, + device_keys: { '@chris:abc': {} }, }); return aliceTestClient.httpBackend.flush('/keys/query', 1); }).then((flushed) => { @@ -228,7 +226,7 @@ describe("DeviceList management:", function() { }, token: '2', }).respond(200, { - device_keys: {'@bob:xyz': {}}, + device_keys: { '@bob:xyz': {} }, }); return aliceTestClient.httpBackend.flush('/keys/query', 1); }).then((flushed) => { @@ -323,7 +321,6 @@ describe("DeviceList management:", function() { }, ); - await aliceTestClient.flushSync(); await aliceTestClient.client._crypto._deviceList.saveIfDirty(); diff --git a/spec/integ/matrix-client-crypto.spec.js b/spec/integ/matrix-client-crypto.spec.js index 3ca72c320..be9d725a8 100644 --- a/spec/integ/matrix-client-crypto.spec.js +++ b/spec/integ/matrix-client-crypto.spec.js @@ -28,11 +28,11 @@ limitations under the License. // load olm before the sdk if possible import '../olm-loader'; -import {logger} from '../../src/logger'; +import { logger } from '../../src/logger'; import * as testUtils from "../test-utils"; import * as utils from "../../src/utils"; -import {TestClient} from "../TestClient"; -import {CRYPTO_ENABLED} from "../../src/client"; +import { TestClient } from "../TestClient"; +import { CRYPTO_ENABLED } from "../../src/client"; let aliTestClient; const roomId = "!room:localhost"; @@ -76,7 +76,7 @@ function expectAliQueryKeys() { ); const result = {}; result[bobUserId] = bobKeys; - return {device_keys: result}; + return { device_keys: result }; }); return aliTestClient.httpBackend.flush("/keys/query", 1); } @@ -104,7 +104,7 @@ function expectBobQueryKeys() { ); const result = {}; result[aliUserId] = aliKeys; - return {device_keys: result}; + return { device_keys: result }; }); return bobTestClient.httpBackend.flush("/keys/query", 1); } @@ -133,7 +133,7 @@ function expectAliClaimKeys() { result[bobUserId] = {}; result[bobUserId][bobDeviceId] = {}; result[bobUserId][bobDeviceId][keyId] = keys[keyId]; - return {one_time_keys: result}; + return { one_time_keys: result }; }); }).then(() => { // it can take a while to process the key query, so give it some extra @@ -145,7 +145,6 @@ function expectAliClaimKeys() { }); } - function aliDownloadsKeys() { // can't query keys before bob has uploaded them expect(bobTestClient.getSigningKey()).toBeTruthy(); @@ -270,7 +269,7 @@ function expectBobSendMessageRequest() { function sendMessage(client) { return client.sendMessage( - roomId, {msgtype: "m.text", body: "Hello, World"}, + roomId, { msgtype: "m.text", body: "Hello, World" }, ); } @@ -358,7 +357,6 @@ function recvMessage(httpBackend, client, sender, message) { }); } - /** * Send an initial sync response to the client (which just includes the member * list for our test room). @@ -396,7 +394,6 @@ function firstSync(testClient) { return testClient.flushSync(); } - describe("MatrixClient crypto", function() { if (!CRYPTO_ENABLED) { return; @@ -478,7 +475,7 @@ describe("MatrixClient crypto", function() { ).respond(200, function(path, content) { const result = {}; result[bobUserId] = bobKeys; - return {device_keys: result}; + return { device_keys: result }; }); return Promise.all([ @@ -520,7 +517,7 @@ describe("MatrixClient crypto", function() { ).respond(200, function(path, content) { const result = {}; result[bobUserId] = bobKeys; - return {device_keys: result}; + return { device_keys: result }; }); return Promise.all([ @@ -534,7 +531,6 @@ describe("MatrixClient crypto", function() { }); }); - it("Bob starts his client and uploads device keys and one-time keys", function() { return Promise.resolve() .then(() => bobTestClient.start()) @@ -546,7 +542,7 @@ describe("MatrixClient crypto", function() { }); it("Ali sends a message", function() { - aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); + aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -556,7 +552,7 @@ describe("MatrixClient crypto", function() { }); it("Bob receives a message", function() { - aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); + aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -567,7 +563,7 @@ describe("MatrixClient crypto", function() { }); it("Bob receives a message with a bogus sender", function() { - aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); + aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -621,7 +617,7 @@ describe("MatrixClient crypto", function() { }); it("Ali blocks Bob's device", function() { - aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); + aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -641,7 +637,7 @@ describe("MatrixClient crypto", function() { }); it("Bob receives two pre-key messages", function() { - aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); + aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -654,8 +650,8 @@ describe("MatrixClient crypto", function() { }); it("Bob replies to the message", function() { - aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); - bobTestClient.expectKeyQuery({device_keys: {[bobUserId]: {}}}); + aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); + bobTestClient.expectKeyQuery({ device_keys: { [bobUserId]: {} } }); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -673,7 +669,7 @@ describe("MatrixClient crypto", function() { it("Ali does a key query when encryption is enabled", function() { // enabling encryption in the room should make alice download devices // for both members. - aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); + aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => firstSync(aliTestClient)) diff --git a/spec/integ/matrix-client-event-emitter.spec.js b/spec/integ/matrix-client-event-emitter.spec.js index b8f3b1868..a76caf379 100644 --- a/spec/integ/matrix-client-event-emitter.spec.js +++ b/spec/integ/matrix-client-event-emitter.spec.js @@ -1,5 +1,5 @@ import * as utils from "../test-utils"; -import {TestClient} from "../TestClient"; +import { TestClient } from "../TestClient"; describe("MatrixClient events", function() { let client; diff --git a/spec/integ/matrix-client-event-timeline.spec.js b/spec/integ/matrix-client-event-timeline.spec.js index acaff0cee..c8ec42c74 100644 --- a/spec/integ/matrix-client-event-timeline.spec.js +++ b/spec/integ/matrix-client-event-timeline.spec.js @@ -1,7 +1,7 @@ import * as utils from "../test-utils"; -import {EventTimeline} from "../../src/matrix"; -import {logger} from "../../src/logger"; -import {TestClient} from "../TestClient"; +import { EventTimeline } from "../../src/matrix"; +import { logger } from "../../src/logger"; +import { TestClient } from "../TestClient"; const userId = "@alice:localhost"; const userName = "Alice"; @@ -127,7 +127,7 @@ describe("getEventTimeline support", function() { "DEVICE", accessToken, undefined, - {timelineSupport: true}, + { timelineSupport: true }, ); client = testClient.client; httpBackend = testClient.httpBackend; @@ -141,7 +141,6 @@ describe("getEventTimeline support", function() { }); }); - it("scrollback should be able to scroll back to before a gappy /sync", function() { // need a client with timelineSupport disabled to make this work @@ -218,7 +217,7 @@ describe("MatrixClient event timelines", function() { "DEVICE", accessToken, undefined, - {timelineSupport: true}, + { timelineSupport: true }, ); client = testClient.client; httpBackend = testClient.httpBackend; @@ -516,7 +515,7 @@ describe("MatrixClient event timelines", function() { client.getEventTimeline(timelineSet, EVENTS[0].event_id, ).then(function(tl0) { tl = tl0; - return client.paginateEventTimeline(tl, {backwards: true}); + return client.paginateEventTimeline(tl, { backwards: true }); }).then(function(success) { expect(success).toBeTruthy(); expect(tl.getEvents().length).toEqual(3); @@ -532,7 +531,6 @@ describe("MatrixClient event timelines", function() { ]); }); - it("should allow you to paginate forwards", function() { const room = client.getRoom(roomId); const timelineSet = room.getTimelineSets()[0]; @@ -569,7 +567,7 @@ describe("MatrixClient event timelines", function() { ).then(function(tl0) { tl = tl0; return client.paginateEventTimeline( - tl, {backwards: false, limit: 20}); + tl, { backwards: false, limit: 20 }); }).then(function(success) { expect(success).toBeTruthy(); expect(tl.getEvents().length).toEqual(3); @@ -591,7 +589,7 @@ describe("MatrixClient event timelines", function() { const event = utils.mkMessage({ room: roomId, user: userId, msg: "a body", }); - event.unsigned = {transaction_id: TXN_ID}; + event.unsigned = { transaction_id: TXN_ID }; beforeEach(function() { // set up handlers for both the message send, and the @@ -680,7 +678,6 @@ describe("MatrixClient event timelines", function() { }); }); - it("should handle gappy syncs after redactions", function() { // https://github.com/vector-im/vector-web/issues/1389 diff --git a/spec/integ/matrix-client-methods.spec.js b/spec/integ/matrix-client-methods.spec.js index b79fd26d7..742beec27 100644 --- a/spec/integ/matrix-client-methods.spec.js +++ b/spec/integ/matrix-client-methods.spec.js @@ -1,7 +1,7 @@ import * as utils from "../test-utils"; -import {CRYPTO_ENABLED} from "../../src/client"; -import {Filter, MemoryStore, Room} from "../../src/matrix"; -import {TestClient} from "../TestClient"; +import { CRYPTO_ENABLED } from "../../src/client"; +import { Filter, MemoryStore, Room } from "../../src/matrix"; +import { TestClient } from "../TestClient"; describe("MatrixClient", function() { let client = null; @@ -285,7 +285,6 @@ describe("MatrixClient", function() { }); }); - describe("downloadKeys", function() { if (!CRYPTO_ENABLED) { return; @@ -346,10 +345,10 @@ describe("MatrixClient", function() { */ httpBackend.when("POST", "/keys/query").check(function(req) { - expect(req.data).toEqual({device_keys: { + expect(req.data).toEqual({ device_keys: { 'boris': [], 'chaz': [], - }}); + } }); }).respond(200, { device_keys: { boris: borisKeys, @@ -379,12 +378,12 @@ describe("MatrixClient", function() { }); describe("deleteDevice", function() { - const auth = {a: 1}; + const auth = { a: 1 }; it("should pass through an auth dict", function() { httpBackend.when( "DELETE", "/_matrix/client/r0/devices/my_device", ).check(function(req) { - expect(req.data).toEqual({auth: auth}); + expect(req.data).toEqual({ auth: auth }); }).respond(200); const prom = client.deleteDevice("my_device", auth); diff --git a/spec/integ/matrix-client-opts.spec.js b/spec/integ/matrix-client-opts.spec.js index 7c256fd58..87f9285fb 100644 --- a/spec/integ/matrix-client-opts.spec.js +++ b/spec/integ/matrix-client-opts.spec.js @@ -1,9 +1,9 @@ import * as utils from "../test-utils"; import HttpBackend from "matrix-mock-request"; -import {MatrixClient} from "../../src/matrix"; -import {MatrixScheduler} from "../../src/scheduler"; -import {MemoryStore} from "../../src/store/memory"; -import {MatrixError} from "../../src/http-api"; +import { MatrixClient } from "../../src/matrix"; +import { MatrixScheduler } from "../../src/scheduler"; +import { MemoryStore } from "../../src/store/memory"; +import { MatrixError } from "../../src/http-api"; describe("MatrixClient opts", function() { const baseUrl = "http://localhost.or.something"; diff --git a/spec/integ/matrix-client-retrying.spec.js b/spec/integ/matrix-client-retrying.spec.js index c45d9ced1..99f99f7dd 100644 --- a/spec/integ/matrix-client-retrying.spec.js +++ b/spec/integ/matrix-client-retrying.spec.js @@ -1,7 +1,7 @@ -import {EventStatus} from "../../src/matrix"; -import {MatrixScheduler} from "../../src/scheduler"; -import {Room} from "../../src/models/room"; -import {TestClient} from "../TestClient"; +import { EventStatus } from "../../src/matrix"; +import { MatrixScheduler } from "../../src/scheduler"; +import { Room } from "../../src/models/room"; +import { TestClient } from "../TestClient"; describe("MatrixClient retrying", function() { let client = null; @@ -19,7 +19,7 @@ describe("MatrixClient retrying", function() { "DEVICE", accessToken, undefined, - {scheduler}, + { scheduler }, ); httpBackend = testClient.httpBackend; client = testClient.client; diff --git a/spec/integ/matrix-client-room-timeline.spec.js b/spec/integ/matrix-client-room-timeline.spec.js index b3de310a9..3fd017354 100644 --- a/spec/integ/matrix-client-room-timeline.spec.js +++ b/spec/integ/matrix-client-room-timeline.spec.js @@ -1,7 +1,6 @@ import * as utils from "../test-utils"; -import {EventStatus} from "../../src/models/event"; -import {TestClient} from "../TestClient"; - +import { EventStatus } from "../../src/models/event"; +import { TestClient } from "../TestClient"; describe("MatrixClient room timelines", function() { let client = null; @@ -104,7 +103,7 @@ describe("MatrixClient room timelines", function() { "DEVICE", accessToken, undefined, - {timelineSupport: true}, + { timelineSupport: true }, ); httpBackend = testClient.httpBackend; client = testClient.client; @@ -166,7 +165,7 @@ describe("MatrixClient room timelines", function() { body: "I am a fish", user: userId, room: roomId, }); ev.event_id = eventId; - ev.unsigned = {transaction_id: "txn1"}; + ev.unsigned = { transaction_id: "txn1" }; setNextSyncData([ev]); client.on("sync", function(state) { @@ -198,7 +197,7 @@ describe("MatrixClient room timelines", function() { body: "I am a fish", user: userId, room: roomId, }); ev.event_id = eventId; - ev.unsigned = {transaction_id: "txn1"}; + ev.unsigned = { transaction_id: "txn1" }; setNextSyncData([ev]); client.on("sync", function(state) { @@ -396,8 +395,8 @@ describe("MatrixClient room timelines", function() { describe("new events", function() { it("should be added to the right place in the timeline", function() { const eventData = [ - utils.mkMessage({user: userId, room: roomId}), - utils.mkMessage({user: userId, room: roomId}), + utils.mkMessage({ user: userId, room: roomId }), + utils.mkMessage({ user: userId, room: roomId }), ]; setNextSyncData(eventData); @@ -434,11 +433,11 @@ describe("MatrixClient room timelines", function() { it("should set the right event.sender values", function() { const eventData = [ - utils.mkMessage({user: userId, room: roomId}), + utils.mkMessage({ user: userId, room: roomId }), utils.mkMembership({ user: userId, room: roomId, mship: "join", name: "New Name", }), - utils.mkMessage({user: userId, room: roomId}), + utils.mkMessage({ user: userId, room: roomId }), ]; eventData[1].__prev_event = USER_MEMBERSHIP_EVENT; setNextSyncData(eventData); @@ -546,7 +545,7 @@ describe("MatrixClient room timelines", function() { describe("gappy sync", function() { it("should copy the last known state to the new timeline", function() { const eventData = [ - utils.mkMessage({user: userId, room: roomId}), + utils.mkMessage({ user: userId, room: roomId }), ]; setNextSyncData(eventData); NEXT_SYNC_DATA.rooms.join[roomId].timeline.limited = true; @@ -579,7 +578,7 @@ describe("MatrixClient room timelines", function() { it("should emit a 'Room.timelineReset' event", function() { const eventData = [ - utils.mkMessage({user: userId, room: roomId}), + utils.mkMessage({ user: userId, room: roomId }), ]; setNextSyncData(eventData); NEXT_SYNC_DATA.rooms.join[roomId].timeline.limited = true; diff --git a/spec/integ/matrix-client-syncing.spec.js b/spec/integ/matrix-client-syncing.spec.js index adb6be965..6181efebf 100644 --- a/spec/integ/matrix-client-syncing.spec.js +++ b/spec/integ/matrix-client-syncing.spec.js @@ -1,7 +1,7 @@ -import {MatrixEvent} from "../../src/models/event"; -import {EventTimeline} from "../../src/models/event-timeline"; +import { MatrixEvent } from "../../src/models/event"; +import { EventTimeline } from "../../src/models/event-timeline"; import * as utils from "../test-utils"; -import {TestClient} from "../TestClient"; +import { TestClient } from "../TestClient"; describe("MatrixClient syncing", function() { let client = null; @@ -122,7 +122,6 @@ describe("MatrixClient syncing", function() { resolveInvitesToProfiles: true, }); - return Promise.all([ httpBackend.flushAllExpected(), awaitSyncEvent(), @@ -677,8 +676,8 @@ describe("MatrixClient syncing", function() { it("should create and use an appropriate filter", function() { httpBackend.when("POST", "/filter").check(function(req) { expect(req.data).toEqual({ - room: { timeline: {limit: 1}, - include_leave: true }}); + room: { timeline: { limit: 1 }, + include_leave: true } }); }).respond(200, { filter_id: "another_id" }); const prom = new Promise((resolve) => { diff --git a/spec/integ/megolm-integ.spec.js b/spec/integ/megolm-integ.spec.js index 8c49b1c28..6edbcc49e 100644 --- a/spec/integ/megolm-integ.spec.js +++ b/spec/integ/megolm-integ.spec.js @@ -18,8 +18,8 @@ limitations under the License. import anotherjson from "another-json"; import * as utils from "../../src/utils"; import * as testUtils from "../test-utils"; -import {TestClient} from "../TestClient"; -import {logger} from "../../src/logger"; +import { TestClient } from "../TestClient"; +import { logger } from "../../src/logger"; const ROOM_ID = "!room:id"; @@ -197,7 +197,6 @@ function getSyncResponse(roomMembers) { return syncResponse; } - describe("megolm", function() { if (!global.Olm) { logger.warn('not running megolm tests: Olm not present'); @@ -269,7 +268,7 @@ describe("megolm", function() { 'ed25519:DEVICE_ID': sig, }; - const claimResponse = {one_time_keys: {}}; + const claimResponse = { one_time_keys: {} }; claimResponse.one_time_keys[userId] = { 'DEVICE_ID': {}, }; @@ -494,7 +493,7 @@ describe("megolm", function() { it('Alice sends a megolm message', function() { let p2pSession; - aliceTestClient.expectKeyQuery({device_keys: {'@alice:localhost': {}}}); + aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } }); return aliceTestClient.start().then(() => { // establish an olm session with alice return createOlmSession(testOlmAccount, aliceTestClient); @@ -577,7 +576,7 @@ describe("megolm", function() { }); it("We shouldn't attempt to send to blocked devices", function() { - aliceTestClient.expectKeyQuery({device_keys: {'@alice:localhost': {}}}); + aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } }); return aliceTestClient.start().then(() => { // establish an olm session with alice return createOlmSession(testOlmAccount, aliceTestClient); @@ -634,7 +633,7 @@ describe("megolm", function() { let p2pSession; let megolmSessionId; - aliceTestClient.expectKeyQuery({device_keys: {'@alice:localhost': {}}}); + aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } }); return aliceTestClient.start().then(() => { // establish an olm session with alice return createOlmSession(testOlmAccount, aliceTestClient); @@ -841,13 +840,12 @@ describe("megolm", function() { }); }); - it('Alice should wait for device list to complete when sending a megolm message', function() { let downloadPromise; let sendPromise; - aliceTestClient.expectKeyQuery({device_keys: {'@alice:localhost': {}}}); + aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } }); return aliceTestClient.start().then(() => { // establish an olm session with alice return createOlmSession(testOlmAccount, aliceTestClient); @@ -887,11 +885,10 @@ describe("megolm", function() { }); }); - it("Alice exports megolm keys and imports them to a new device", function() { let messageEncrypted; - aliceTestClient.expectKeyQuery({device_keys: {'@alice:localhost': {}}}); + aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } }); return aliceTestClient.start().then(() => { // establish an olm session with alice return createOlmSession(testOlmAccount, aliceTestClient); diff --git a/spec/olm-loader.js b/spec/olm-loader.js index 49d7abac0..639a97b9e 100644 --- a/spec/olm-loader.js +++ b/spec/olm-loader.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../src/logger'; +import { logger } from '../src/logger'; import * as utils from "../src/utils"; // try to load the olm library. diff --git a/spec/test-utils.js b/spec/test-utils.js index 3ca1a5b9a..6c7679432 100644 --- a/spec/test-utils.js +++ b/spec/test-utils.js @@ -1,8 +1,8 @@ // load olm before the sdk if possible import './olm-loader'; -import {logger} from '../src/logger'; -import {MatrixEvent} from "../src/models/event"; +import { logger } from '../src/logger'; +import { MatrixEvent } from "../src/models/event"; /** * Return a promise that is resolved when the client next emits a @@ -177,7 +177,6 @@ export function mkMessage(opts) { return mkEvent(opts); } - /** * A mock implementation of webstorage * @@ -204,7 +203,6 @@ MockStorageApi.prototype = { }, }; - /** * If an event is being decrypted, wait for it to finish being decrypted. * @@ -226,7 +224,6 @@ export function awaitDecryption(event) { }); } - export function HttpResponse( httpLookups, acceptKeepalives, ignoreUnhandledSync, ) { diff --git a/spec/unit/autodiscovery.spec.js b/spec/unit/autodiscovery.spec.js index 684186cd7..cdce28eee 100644 --- a/spec/unit/autodiscovery.spec.js +++ b/spec/unit/autodiscovery.spec.js @@ -17,7 +17,7 @@ limitations under the License. import MockHttpBackend from "matrix-mock-request"; import * as sdk from "../../src"; -import {AutoDiscovery} from "../../src/autodiscovery"; +import { AutoDiscovery } from "../../src/autodiscovery"; describe("AutoDiscovery", function() { let httpBackend = null; diff --git a/spec/unit/content-repo.spec.js b/spec/unit/content-repo.spec.js index 377aedd52..e773b0577 100644 --- a/spec/unit/content-repo.spec.js +++ b/spec/unit/content-repo.spec.js @@ -1,4 +1,4 @@ -import {getHttpUriForMxc} from "../../src/content-repo"; +import { getHttpUriForMxc } from "../../src/content-repo"; describe("ContentRepo", function() { const baseUrl = "https://my.home.server"; diff --git a/spec/unit/crypto.spec.js b/spec/unit/crypto.spec.js index 8f7fff107..22f0b2d0d 100644 --- a/spec/unit/crypto.spec.js +++ b/spec/unit/crypto.spec.js @@ -1,16 +1,16 @@ import '../olm-loader'; -import {Crypto} from "../../src/crypto"; -import {WebStorageSessionStore} from "../../src/store/session/webstorage"; -import {MemoryCryptoStore} from "../../src/crypto/store/memory-crypto-store"; -import {MockStorageApi} from "../MockStorageApi"; -import {TestClient} from "../TestClient"; -import {MatrixEvent} from "../../src/models/event"; -import {Room} from "../../src/models/room"; +import { Crypto } from "../../src/crypto"; +import { WebStorageSessionStore } from "../../src/store/session/webstorage"; +import { MemoryCryptoStore } from "../../src/crypto/store/memory-crypto-store"; +import { MockStorageApi } from "../MockStorageApi"; +import { TestClient } from "../TestClient"; +import { MatrixEvent } from "../../src/models/event"; +import { Room } from "../../src/models/room"; import * as olmlib from "../../src/crypto/olmlib"; -import {sleep} from "../../src/utils"; -import {EventEmitter} from "events"; -import {CRYPTO_ENABLED} from "../../src/client"; -import {DeviceInfo} from "../../src/crypto/deviceinfo"; +import { sleep } from "../../src/utils"; +import { EventEmitter } from "events"; +import { CRYPTO_ENABLED } from "../../src/client"; +import { DeviceInfo } from "../../src/crypto/deviceinfo"; const Olm = global.Olm; @@ -46,7 +46,7 @@ describe("Crypto", function() { // unknown sender (e.g. deleted device), forwarded megolm key (untrusted) event.getSenderKey = () => 'YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI'; - event.getWireContent = () => {return {algorithm: olmlib.MEGOLM_ALGORITHM};}; + event.getWireContent = () => {return { algorithm: olmlib.MEGOLM_ALGORITHM };}; event.getForwardingCurve25519KeyChain = () => ["not empty"]; event.isKeySourceUntrusted = () => false; event.getClaimedEd25519Key = diff --git a/spec/unit/crypto/CrossSigningInfo.spec.js b/spec/unit/crypto/CrossSigningInfo.spec.js index 541f6e479..5c3ebade1 100644 --- a/spec/unit/crypto/CrossSigningInfo.spec.js +++ b/spec/unit/crypto/CrossSigningInfo.spec.js @@ -22,11 +22,11 @@ import { import { IndexedDBCryptoStore, } from '../../../src/crypto/store/indexeddb-crypto-store'; -import {MemoryCryptoStore} from '../../../src/crypto/store/memory-crypto-store'; +import { MemoryCryptoStore } from '../../../src/crypto/store/memory-crypto-store'; import 'fake-indexeddb/auto'; import 'jest-localstorage-mock'; -import {OlmDevice} from "../../../src/crypto/OlmDevice"; -import {logger} from '../../../src/logger'; +import { OlmDevice } from "../../../src/crypto/OlmDevice"; +import { logger } from '../../../src/logger'; const userId = "@alice:example.com"; @@ -66,7 +66,7 @@ describe("CrossSigningInfo.getCrossSigningKey", function() { }); it.each(types)("should throw if the callback returns falsey", - async ({type, shouldCache}) => { + async ({ type, shouldCache }) => { const info = new CrossSigningInfo(userId, { getCrossSigningKey: () => false, }); diff --git a/spec/unit/crypto/DeviceList.spec.js b/spec/unit/crypto/DeviceList.spec.js index a9ff83054..251f07358 100644 --- a/spec/unit/crypto/DeviceList.spec.js +++ b/spec/unit/crypto/DeviceList.spec.js @@ -16,10 +16,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from "../../../src/logger"; +import { logger } from "../../../src/logger"; import * as utils from "../../../src/utils"; -import {MemoryCryptoStore} from "../../../src/crypto/store/memory-crypto-store"; -import {DeviceList} from "../../../src/crypto/DeviceList"; +import { MemoryCryptoStore } from "../../../src/crypto/store/memory-crypto-store"; +import { DeviceList } from "../../../src/crypto/DeviceList"; const signedDeviceList = { "failures": {}, diff --git a/spec/unit/crypto/algorithms/megolm.spec.js b/spec/unit/crypto/algorithms/megolm.spec.js index 22c668fcf..d4b9e1247 100644 --- a/spec/unit/crypto/algorithms/megolm.spec.js +++ b/spec/unit/crypto/algorithms/megolm.spec.js @@ -1,14 +1,14 @@ import '../../../olm-loader'; import * as algorithms from "../../../../src/crypto/algorithms"; -import {MemoryCryptoStore} from "../../../../src/crypto/store/memory-crypto-store"; -import {MockStorageApi} from "../../../MockStorageApi"; +import { MemoryCryptoStore } from "../../../../src/crypto/store/memory-crypto-store"; +import { MockStorageApi } from "../../../MockStorageApi"; import * as testUtils from "../../../test-utils"; -import {OlmDevice} from "../../../../src/crypto/OlmDevice"; -import {Crypto} from "../../../../src/crypto"; -import {logger} from "../../../../src/logger"; -import {MatrixEvent} from "../../../../src/models/event"; -import {TestClient} from "../../../TestClient"; -import {Room} from "../../../../src/models/room"; +import { OlmDevice } from "../../../../src/crypto/OlmDevice"; +import { Crypto } from "../../../../src/crypto"; +import { logger } from "../../../../src/logger"; +import { MatrixEvent } from "../../../../src/models/event"; +import { TestClient } from "../../../TestClient"; +import { Room } from "../../../../src/models/room"; import * as olmlib from "../../../../src/crypto/olmlib"; const MegolmDecryption = algorithms.DECRYPTION_CLASSES['m.megolm.v1.aes-sha2']; @@ -50,7 +50,6 @@ describe("MegolmDecryption", function() { roomId: ROOM_ID, }); - // we stub out the olm encryption bits mockOlmLib = {}; mockOlmLib.ensureOlmSessionsForDevices = jest.fn(); @@ -136,9 +135,9 @@ describe("MegolmDecryption", function() { mockCrypto.getStoredDevice.mockReturnValue(deviceInfo); mockOlmLib.ensureOlmSessionsForDevices.mockResolvedValue({ - '@alice:foo': {'alidevice': { + '@alice:foo': { 'alidevice': { sessionId: 'alisession', - }}, + } }, }); const awaitEncryptForDevice = new Promise((res, rej) => { @@ -313,7 +312,7 @@ describe("MegolmDecryption", function() { }); const mockRoom = { getEncryptionTargetMembers: jest.fn().mockReturnValue( - [{userId: "@alice:home.server"}], + [{ userId: "@alice:home.server" }], ), getBlacklistUnverifiedDevices: jest.fn().mockReturnValue(false), }; @@ -373,7 +372,7 @@ describe("MegolmDecryption", function() { const roomId = "!someroom"; const room = new Room(roomId, aliceClient, "@alice:example.com", {}); room.getEncryptionTargetMembers = async function() { - return [{userId: "@bob:example.com"}]; + return [{ userId: "@bob:example.com" }]; }; room.setBlacklistUnverifiedDevices(true); aliceClient.store.storeRoom(room); diff --git a/spec/unit/crypto/algorithms/olm.spec.js b/spec/unit/crypto/algorithms/olm.spec.js index c548355b5..882f67235 100644 --- a/spec/unit/crypto/algorithms/olm.spec.js +++ b/spec/unit/crypto/algorithms/olm.spec.js @@ -16,12 +16,12 @@ limitations under the License. */ import '../../../olm-loader'; -import {MemoryCryptoStore} from "../../../../src/crypto/store/memory-crypto-store"; -import {MockStorageApi} from "../../../MockStorageApi"; -import {logger} from "../../../../src/logger"; -import {OlmDevice} from "../../../../src/crypto/OlmDevice"; +import { MemoryCryptoStore } from "../../../../src/crypto/store/memory-crypto-store"; +import { MockStorageApi } from "../../../MockStorageApi"; +import { logger } from "../../../../src/logger"; +import { OlmDevice } from "../../../../src/crypto/OlmDevice"; import * as olmlib from "../../../../src/crypto/olmlib"; -import {DeviceInfo} from "../../../../src/crypto/deviceinfo"; +import { DeviceInfo } from "../../../../src/crypto/deviceinfo"; function makeOlmDevice() { const mockStorage = new MockStorageApi(); diff --git a/spec/unit/crypto/backup.spec.js b/spec/unit/crypto/backup.spec.js index 96623dda3..a9fb93d64 100644 --- a/spec/unit/crypto/backup.spec.js +++ b/spec/unit/crypto/backup.spec.js @@ -16,18 +16,18 @@ limitations under the License. */ import '../../olm-loader'; -import {logger} from "../../../src/logger"; +import { logger } from "../../../src/logger"; import * as olmlib from "../../../src/crypto/olmlib"; -import {MatrixClient} from "../../../src/client"; -import {MatrixEvent} from "../../../src/models/event"; +import { MatrixClient } from "../../../src/client"; +import { MatrixEvent } from "../../../src/models/event"; import * as algorithms from "../../../src/crypto/algorithms"; -import {WebStorageSessionStore} from "../../../src/store/session/webstorage"; -import {MemoryCryptoStore} from "../../../src/crypto/store/memory-crypto-store"; -import {MockStorageApi} from "../../MockStorageApi"; +import { WebStorageSessionStore } from "../../../src/store/session/webstorage"; +import { MemoryCryptoStore } from "../../../src/crypto/store/memory-crypto-store"; +import { MockStorageApi } from "../../MockStorageApi"; import * as testUtils from "../../test-utils"; -import {OlmDevice} from "../../../src/crypto/OlmDevice"; -import {Crypto} from "../../../src/crypto"; -import {resetCrossSigningKeys} from "./crypto-utils"; +import { OlmDevice } from "../../../src/crypto/OlmDevice"; +import { Crypto } from "../../../src/crypto"; +import { resetCrossSigningKeys } from "./crypto-utils"; const Olm = global.Olm; diff --git a/spec/unit/crypto/cross-signing.spec.js b/spec/unit/crypto/cross-signing.spec.js index 1195db2db..af2f2dabd 100644 --- a/spec/unit/crypto/cross-signing.spec.js +++ b/spec/unit/crypto/cross-signing.spec.js @@ -18,11 +18,11 @@ limitations under the License. import '../../olm-loader'; import anotherjson from 'another-json'; import * as olmlib from "../../../src/crypto/olmlib"; -import {TestClient} from '../../TestClient'; -import {HttpResponse, setHttpResponses} from '../../test-utils'; +import { TestClient } from '../../TestClient'; +import { HttpResponse, setHttpResponses } from '../../test-utils'; import { resetCrossSigningKeys } from "./crypto-utils"; import { MatrixError } from '../../../src/http-api'; -import {logger} from '../../../src/logger'; +import { logger } from '../../../src/logger'; async function makeTestClient(userInfo, options, keys) { if (!keys) keys = {}; @@ -60,7 +60,7 @@ describe("Cross Signing", function() { it("should sign the master key with the device key", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); alice.uploadDeviceSigningKeys = jest.fn(async (auth, keys) => { await olmlib.verifySignature( @@ -80,7 +80,7 @@ describe("Cross Signing", function() { it("should abort bootstrap if device signing auth fails", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); alice.uploadDeviceSigningKeys = async (auth, keys) => { const errorResponse = { @@ -131,7 +131,7 @@ describe("Cross Signing", function() { it("should upload a signature when a user is verified", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); alice.uploadDeviceSigningKeys = async () => {}; alice.uploadKeySignatures = async () => {}; @@ -175,7 +175,7 @@ describe("Cross Signing", function() { ]); const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, { cryptoCallbacks: { // will be called to sign our own device @@ -328,7 +328,7 @@ describe("Cross Signing", function() { it("should use trust chain to determine device verification", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); alice.uploadDeviceSigningKeys = async () => {}; alice.uploadKeySignatures = async () => {}; @@ -413,7 +413,7 @@ describe("Cross Signing", function() { it("should trust signatures received from other devices", async function() { const aliceKeys = {}; const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, null, aliceKeys, ); @@ -575,7 +575,7 @@ describe("Cross Signing", function() { it("should dis-trust an unsigned device", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); alice.uploadDeviceSigningKeys = async () => {}; alice.uploadKeySignatures = async () => {}; @@ -644,7 +644,7 @@ describe("Cross Signing", function() { it("should dis-trust a user when their ssk changes", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); alice.uploadDeviceSigningKeys = async () => {}; alice.uploadKeySignatures = async () => {}; @@ -782,7 +782,7 @@ describe("Cross Signing", function() { let upgradeResolveFunc; const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, { cryptoCallbacks: { shouldUpgradeDeviceVerifications: (verifs) => { @@ -794,7 +794,7 @@ describe("Cross Signing", function() { }, ); const bob = await makeTestClient( - {userId: "@bob:example.com", deviceId: "Dynabook"}, + { userId: "@bob:example.com", deviceId: "Dynabook" }, ); bob.uploadDeviceSigningKeys = async () => {}; diff --git a/spec/unit/crypto/crypto-utils.js b/spec/unit/crypto/crypto-utils.js index b54802b05..ec8a8f82a 100644 --- a/spec/unit/crypto/crypto-utils.js +++ b/spec/unit/crypto/crypto-utils.js @@ -1,5 +1,4 @@ -import {IndexedDBCryptoStore} from '../../../src/crypto/store/indexeddb-crypto-store'; - +import { IndexedDBCryptoStore } from '../../../src/crypto/store/indexeddb-crypto-store'; // needs to be phased out and replaced with bootstrapSecretStorage, // but that is doing too much extra stuff for it to be an easy transition. diff --git a/spec/unit/crypto/outgoing-room-key-requests.spec.js b/spec/unit/crypto/outgoing-room-key-requests.spec.js index a27629f60..a1fa62a70 100644 --- a/spec/unit/crypto/outgoing-room-key-requests.spec.js +++ b/spec/unit/crypto/outgoing-room-key-requests.spec.js @@ -17,7 +17,7 @@ limitations under the License. import { IndexedDBCryptoStore, } from '../../../src/crypto/store/indexeddb-crypto-store'; -import {MemoryCryptoStore} from '../../../src/crypto/store/memory-crypto-store'; +import { MemoryCryptoStore } from '../../../src/crypto/store/memory-crypto-store'; import 'fake-indexeddb/auto'; import 'jest-localstorage-mock'; diff --git a/spec/unit/crypto/secrets.spec.js b/spec/unit/crypto/secrets.spec.js index bcf1871da..2198256b3 100644 --- a/spec/unit/crypto/secrets.spec.js +++ b/spec/unit/crypto/secrets.spec.js @@ -16,13 +16,13 @@ limitations under the License. import '../../olm-loader'; import * as olmlib from "../../../src/crypto/olmlib"; -import {SECRET_STORAGE_ALGORITHM_V1_AES} from "../../../src/crypto/SecretStorage"; -import {MatrixEvent} from "../../../src/models/event"; -import {TestClient} from '../../TestClient'; -import {makeTestClients} from './verification/util'; -import {encryptAES} from "../../../src/crypto/aes"; -import {resetCrossSigningKeys, createSecretStorageKey} from "./crypto-utils"; -import {logger} from '../../../src/logger'; +import { SECRET_STORAGE_ALGORITHM_V1_AES } from "../../../src/crypto/SecretStorage"; +import { MatrixEvent } from "../../../src/models/event"; +import { TestClient } from '../../TestClient'; +import { makeTestClients } from './verification/util'; +import { encryptAES } from "../../../src/crypto/aes"; +import { resetCrossSigningKeys, createSecretStorageKey } from "./crypto-utils"; +import { logger } from '../../../src/logger'; import * as utils from "../../../src/utils"; @@ -91,7 +91,7 @@ describe("Secrets", function() { }); const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, { cryptoCallbacks: { getCrossSigningKey: t => signingKey, @@ -141,7 +141,7 @@ describe("Secrets", function() { it("should throw if given a key that doesn't exist", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); try { @@ -155,7 +155,7 @@ describe("Secrets", function() { it("should refuse to encrypt with zero keys", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); try { @@ -175,7 +175,7 @@ describe("Secrets", function() { let keys = {}; const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, { cryptoCallbacks: { getCrossSigningKey: t => keys[t], @@ -208,7 +208,7 @@ describe("Secrets", function() { it("should refuse to encrypt if no keys given and no default key", async function() { const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, ); try { @@ -221,8 +221,8 @@ describe("Secrets", function() { it("should request secrets from other clients", async function() { const [osborne2, vax] = await makeTestClients( [ - {userId: "@alice:example.com", deviceId: "Osborne2"}, - {userId: "@alice:example.com", deviceId: "VAX"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, + { userId: "@alice:example.com", deviceId: "VAX" }, ], { cryptoCallbacks: { @@ -419,12 +419,12 @@ describe("Secrets", function() { key_id: SSSSKey, }; const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, { cryptoCallbacks: { getCrossSigningKey: t => crossSigningKeys[t], saveCrossSigningKeys: k => crossSigningKeys = k, - getSecretStorageKey: ({keys}, name) => { + getSecretStorageKey: ({ keys }, name) => { for (const keyId of Object.keys(keys)) { if (secretStorageKeys[keyId]) { return [keyId, secretStorageKeys[keyId]]; @@ -458,7 +458,7 @@ describe("Secrets", function() { type: "m.cross_signing.master", content: { encrypted: { - key_id: {ciphertext: "bla", mac: "bla", iv: "bla"}, + key_id: { ciphertext: "bla", mac: "bla", iv: "bla" }, }, }, }), @@ -466,7 +466,7 @@ describe("Secrets", function() { type: "m.cross_signing.self_signing", content: { encrypted: { - key_id: {ciphertext: "bla", mac: "bla", iv: "bla"}, + key_id: { ciphertext: "bla", mac: "bla", iv: "bla" }, }, }, }), @@ -474,7 +474,7 @@ describe("Secrets", function() { type: "m.cross_signing.user_signing", content: { encrypted: { - key_id: {ciphertext: "bla", mac: "bla", iv: "bla"}, + key_id: { ciphertext: "bla", mac: "bla", iv: "bla" }, }, }, }), @@ -525,7 +525,7 @@ describe("Secrets", function() { await alice.bootstrapSecretStorage(); expect(alice.getAccountData("m.secret_storage.default_key").getContent()) - .toEqual({key: "key_id"}); + .toEqual({ key: "key_id" }); const keyInfo = alice.getAccountData("m.secret_storage.key.key_id") .getContent(); expect(keyInfo.algorithm) @@ -550,12 +550,12 @@ describe("Secrets", function() { key_id: SSSSKey, }; const alice = await makeTestClient( - {userId: "@alice:example.com", deviceId: "Osborne2"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, { cryptoCallbacks: { getCrossSigningKey: t => crossSigningKeys[t], saveCrossSigningKeys: k => crossSigningKeys = k, - getSecretStorageKey: ({keys}, name) => { + getSecretStorageKey: ({ keys }, name) => { for (const keyId of Object.keys(keys)) { if (secretStorageKeys[keyId]) { return [keyId, secretStorageKeys[keyId]]; @@ -587,7 +587,7 @@ describe("Secrets", function() { type: "m.cross_signing.master", content: { encrypted: { - key_id: {ciphertext: "bla", mac: "bla", iv: "bla"}, + key_id: { ciphertext: "bla", mac: "bla", iv: "bla" }, }, }, }), @@ -595,7 +595,7 @@ describe("Secrets", function() { type: "m.cross_signing.self_signing", content: { encrypted: { - key_id: {ciphertext: "bla", mac: "bla", iv: "bla"}, + key_id: { ciphertext: "bla", mac: "bla", iv: "bla" }, }, }, }), @@ -603,7 +603,7 @@ describe("Secrets", function() { type: "m.cross_signing.user_signing", content: { encrypted: { - key_id: {ciphertext: "bla", mac: "bla", iv: "bla"}, + key_id: { ciphertext: "bla", mac: "bla", iv: "bla" }, }, }, }), diff --git a/spec/unit/crypto/verification/InRoomChannel.spec.js b/spec/unit/crypto/verification/InRoomChannel.spec.js index da39bea53..634d75c4f 100644 --- a/spec/unit/crypto/verification/InRoomChannel.spec.js +++ b/spec/unit/crypto/verification/InRoomChannel.spec.js @@ -13,9 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import {InRoomChannel} from "../../../../src/crypto/verification/request/InRoomChannel"; +import { InRoomChannel } from "../../../../src/crypto/verification/request/InRoomChannel"; "../../../../src/crypto/verification/request/ToDeviceChannel"; -import {MatrixEvent} from "../../../../src/models/event"; +import { MatrixEvent } from "../../../../src/models/event"; describe("InRoomChannel tests", function() { const ALICE = "@alice:hs.tld"; diff --git a/spec/unit/crypto/verification/qr_code.spec.js b/spec/unit/crypto/verification/qr_code.spec.js index e72bc8776..33fa2405c 100644 --- a/spec/unit/crypto/verification/qr_code.spec.js +++ b/spec/unit/crypto/verification/qr_code.spec.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ import "../../../olm-loader"; -import {logger} from "../../../../src/logger"; +import { logger } from "../../../../src/logger"; const Olm = global.Olm; diff --git a/spec/unit/crypto/verification/request.spec.js b/spec/unit/crypto/verification/request.spec.js index 3df49c0ee..113934385 100644 --- a/spec/unit/crypto/verification/request.spec.js +++ b/spec/unit/crypto/verification/request.spec.js @@ -15,10 +15,10 @@ See the License for the specific language governing permissions and limitations under the License. */ import "../../../olm-loader"; -import {verificationMethods} from "../../../../src/crypto"; -import {logger} from "../../../../src/logger"; -import {SAS} from "../../../../src/crypto/verification/SAS"; -import {makeTestClients, setupWebcrypto, teardownWebcrypto} from './util'; +import { verificationMethods } from "../../../../src/crypto"; +import { logger } from "../../../../src/logger"; +import { SAS } from "../../../../src/crypto/verification/SAS"; +import { makeTestClients, setupWebcrypto, teardownWebcrypto } from './util'; const Olm = global.Olm; @@ -42,8 +42,8 @@ describe("verification request integration tests with crypto layer", function() it("should request and accept a verification", async function() { const [alice, bob] = await makeTestClients( [ - {userId: "@alice:example.com", deviceId: "Osborne2"}, - {userId: "@bob:example.com", deviceId: "Dynabook"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, + { userId: "@bob:example.com", deviceId: "Dynabook" }, ], { verificationMethods: [verificationMethods.SAS], diff --git a/spec/unit/crypto/verification/sas.spec.js b/spec/unit/crypto/verification/sas.spec.js index 607712318..db517ea5c 100644 --- a/spec/unit/crypto/verification/sas.spec.js +++ b/spec/unit/crypto/verification/sas.spec.js @@ -15,14 +15,14 @@ See the License for the specific language governing permissions and limitations under the License. */ import "../../../olm-loader"; -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 { 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 * as olmlib from "../../../../src/crypto/olmlib"; -import {logger} from "../../../../src/logger"; -import {resetCrossSigningKeys} from "../crypto-utils"; +import { logger } from "../../../../src/logger"; +import { resetCrossSigningKeys } from "../crypto-utils"; const Olm = global.Olm; @@ -79,8 +79,8 @@ describe("SAS verification", function() { beforeEach(async () => { [alice, bob] = await makeTestClients( [ - {userId: "@alice:example.com", deviceId: "Osborne2"}, - {userId: "@bob:example.com", deviceId: "Dynabook"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, + { userId: "@bob:example.com", deviceId: "Dynabook" }, ], { verificationMethods: [verificationMethods.SAS], @@ -336,8 +336,8 @@ describe("SAS verification", function() { it("should send a cancellation message on error", async function() { const [alice, bob] = await makeTestClients( [ - {userId: "@alice:example.com", deviceId: "Osborne2"}, - {userId: "@bob:example.com", deviceId: "Dynabook"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, + { userId: "@bob:example.com", deviceId: "Dynabook" }, ], { verificationMethods: [verificationMethods.SAS], @@ -390,8 +390,8 @@ describe("SAS verification", function() { beforeEach(async function() { [alice, bob] = await makeTestClients( [ - {userId: "@alice:example.com", deviceId: "Osborne2"}, - {userId: "@bob:example.com", deviceId: "Dynabook"}, + { userId: "@alice:example.com", deviceId: "Osborne2" }, + { userId: "@bob:example.com", deviceId: "Dynabook" }, ], { verificationMethods: [verificationMethods.SAS], diff --git a/spec/unit/crypto/verification/secret_request.spec.js b/spec/unit/crypto/verification/secret_request.spec.js index e848bb18d..2af336af7 100644 --- a/spec/unit/crypto/verification/secret_request.spec.js +++ b/spec/unit/crypto/verification/secret_request.spec.js @@ -14,10 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {VerificationBase} from '../../../../src/crypto/verification/Base'; -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 { CrossSigningInfo } from '../../../../src/crypto/CrossSigning'; +import { encodeBase64 } from "../../../../src/crypto/olmlib"; +import { setupWebcrypto, teardownWebcrypto } from './util'; jest.useFakeTimers(); diff --git a/spec/unit/crypto/verification/util.js b/spec/unit/crypto/verification/util.js index 66c5d3162..0ff4d2412 100644 --- a/spec/unit/crypto/verification/util.js +++ b/spec/unit/crypto/verification/util.js @@ -15,10 +15,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {TestClient} from '../../../TestClient'; -import {MatrixEvent} from "../../../../src/models/event"; +import { TestClient } from '../../../TestClient'; +import { MatrixEvent } from "../../../../src/models/event"; import nodeCrypto from "crypto"; -import {logger} from '../../../../src/logger'; +import { logger } from '../../../../src/logger'; export async function makeTestClients(userInfos, options) { const clients = []; @@ -76,7 +76,7 @@ export async function makeTestClients(userInfos, options) { } }); - return Promise.resolve({event_id: eventId}); + return Promise.resolve({ event_id: eventId }); }; for (const userInfo of userInfos) { diff --git a/spec/unit/crypto/verification/verification_request.spec.js b/spec/unit/crypto/verification/verification_request.spec.js index a90d04824..f8de29cee 100644 --- a/spec/unit/crypto/verification/verification_request.spec.js +++ b/spec/unit/crypto/verification/verification_request.spec.js @@ -13,13 +13,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import {VerificationRequest, READY_TYPE, START_TYPE, DONE_TYPE} from +import { VerificationRequest, READY_TYPE, START_TYPE, DONE_TYPE } from "../../../../src/crypto/verification/request/VerificationRequest"; -import {InRoomChannel} from "../../../../src/crypto/verification/request/InRoomChannel"; -import {ToDeviceChannel} from +import { InRoomChannel } from "../../../../src/crypto/verification/request/InRoomChannel"; +import { ToDeviceChannel } from "../../../../src/crypto/verification/request/ToDeviceChannel"; -import {MatrixEvent} from "../../../../src/models/event"; -import {setupWebcrypto, teardownWebcrypto} from "./util"; +import { MatrixEvent } from "../../../../src/models/event"; +import { setupWebcrypto, teardownWebcrypto } from "./util"; function makeMockClient(userId, deviceId) { let counter = 1; @@ -40,7 +40,7 @@ function makeMockClient(userId, deviceId) { content, origin_server_ts: Date.now(), })); - return Promise.resolve({event_id: eventId}); + return Promise.resolve({ event_id: eventId }); }, sendToDevice(type, msgMap) { @@ -48,7 +48,7 @@ function makeMockClient(userId, deviceId) { const deviceMap = msgMap[userId]; for (const deviceId of Object.keys(deviceMap)) { const content = deviceMap[deviceId]; - const event = new MatrixEvent({content, type}); + const event = new MatrixEvent({ content, type }); deviceEvents[userId] = deviceEvents[userId] || {}; deviceEvents[userId][deviceId] = deviceEvents[userId][deviceId] || []; deviceEvents[userId][deviceId].push(event); @@ -90,7 +90,7 @@ class MockVerifier { if (this._startEvent) { await this._channel.send(DONE_TYPE, {}); } else { - await this._channel.send(START_TYPE, {method: MOCK_METHOD}); + await this._channel.send(START_TYPE, { method: MOCK_METHOD }); } } @@ -226,7 +226,7 @@ describe("verification request unit tests", function() { new ToDeviceChannel(bob1, bob1.getUserId(), ["device1", "device2"], ToDeviceChannel.makeTransactionId(), "device2"), new Map([[MOCK_METHOD, MockVerifier]]), bob1); - const to = {userId: "@bob:matrix.tld", deviceId: "device2"}; + const to = { userId: "@bob:matrix.tld", deviceId: "device2" }; const verifier = bob1Request.beginKeyVerification(MOCK_METHOD, to); expect(verifier).toBeInstanceOf(MockVerifier); await verifier.start(); diff --git a/spec/unit/event-timeline.spec.js b/spec/unit/event-timeline.spec.js index bf5645d8d..ed3bfb4d5 100644 --- a/spec/unit/event-timeline.spec.js +++ b/spec/unit/event-timeline.spec.js @@ -1,6 +1,6 @@ import * as utils from "../test-utils"; -import {EventTimeline} from "../../src/models/event-timeline"; -import {RoomState} from "../../src/models/room-state"; +import { EventTimeline } from "../../src/models/event-timeline"; +import { RoomState } from "../../src/models/room-state"; function mockRoomStates(timeline) { timeline._startState = utils.mock(RoomState, "startState"); @@ -15,7 +15,7 @@ describe("EventTimeline", function() { beforeEach(function() { // XXX: this is a horrid hack; should use sinon or something instead to mock - const timelineSet = { room: { roomId: roomId }}; + const timelineSet = { room: { roomId: roomId } }; timelineSet.room.getUnfilteredTimelineSet = function() { return timelineSet; }; @@ -94,7 +94,6 @@ describe("EventTimeline", function() { }); }); - describe("neighbouringTimelines", function() { it("neighbouring timelines should start null", function() { expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(null); @@ -102,8 +101,8 @@ describe("EventTimeline", function() { }); it("setNeighbouringTimeline should set neighbour", function() { - const prev = {a: "a"}; - const next = {b: "b"}; + const prev = { a: "a" }; + const next = { b: "b" }; timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS); timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS); expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(prev); @@ -111,8 +110,8 @@ describe("EventTimeline", function() { }); it("setNeighbouringTimeline should throw if called twice", function() { - const prev = {a: "a"}; - const next = {b: "b"}; + const prev = { a: "a" }; + const next = { b: "b" }; expect(function() { timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS); }).not.toThrow(); @@ -278,7 +277,6 @@ describe("EventTimeline", function() { not.toHaveBeenCalled(); }); - it("should call setStateEvents on the right RoomState with the right " + "forwardLooking value for old events", function() { const events = [ diff --git a/spec/unit/event.spec.js b/spec/unit/event.spec.js index 9b88e7ce9..a28b9224f 100644 --- a/spec/unit/event.spec.js +++ b/spec/unit/event.spec.js @@ -15,8 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from "../../src/logger"; -import {MatrixEvent} from "../../src/models/event"; +import { logger } from "../../src/logger"; +import { MatrixEvent } from "../../src/models/event"; describe("MatrixEvent", () => { describe(".attemptDecryption", () => { diff --git a/spec/unit/filter-component.spec.js b/spec/unit/filter-component.spec.js index 9f43b15fe..49f1d5614 100644 --- a/spec/unit/filter-component.spec.js +++ b/spec/unit/filter-component.spec.js @@ -1,5 +1,5 @@ -import {FilterComponent} from "../../src/filter-component"; -import {mkEvent} from '../test-utils'; +import { FilterComponent } from "../../src/filter-component"; +import { mkEvent } from '../test-utils'; describe("Filter Component", function() { describe("types", function() { diff --git a/spec/unit/filter.spec.js b/spec/unit/filter.spec.js index 743296dd7..539df5c46 100644 --- a/spec/unit/filter.spec.js +++ b/spec/unit/filter.spec.js @@ -1,4 +1,4 @@ -import {Filter} from "../../src/filter"; +import { Filter } from "../../src/filter"; describe("Filter", function() { const filterId = "f1lt3ring15g00d4ursoul"; diff --git a/spec/unit/interactive-auth.spec.js b/spec/unit/interactive-auth.spec.js index 609d21eb9..da2bf1917 100644 --- a/spec/unit/interactive-auth.spec.js +++ b/spec/unit/interactive-auth.spec.js @@ -15,9 +15,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from "../../src/logger"; -import {InteractiveAuth} from "../../src/interactive-auth"; -import {MatrixError} from "../../src/http-api"; +import { logger } from "../../src/logger"; +import { InteractiveAuth } from "../../src/interactive-auth"; +import { MatrixError } from "../../src/http-api"; // Trivial client object to test interactive auth // (we do not need TestClient here) @@ -63,7 +63,7 @@ describe("InteractiveAuth", function() { }); // .. which should trigger a call here - const requestRes = {"a": "b"}; + const requestRes = { "a": "b" }; doRequest.mockImplementation(function(authData) { logger.log('cccc'); expect(authData).toEqual({ @@ -112,7 +112,7 @@ describe("InteractiveAuth", function() { }); // .. which should be followed by a call to stateUpdated - const requestRes = {"a": "b"}; + const requestRes = { "a": "b" }; stateUpdated.mockImplementation(function(stage) { expect(stage).toEqual("logintype"); expect(ia.getSessionId()).toEqual("sessionId"); diff --git a/spec/unit/login.spec.js b/spec/unit/login.spec.js index 32d68f458..36dc45aa0 100644 --- a/spec/unit/login.spec.js +++ b/spec/unit/login.spec.js @@ -1,4 +1,4 @@ -import {TestClient} from '../TestClient'; +import { TestClient } from '../TestClient'; describe('Login request', function() { let client; diff --git a/spec/unit/matrix-client.spec.js b/spec/unit/matrix-client.spec.js index 3811c5b56..a7feb8103 100644 --- a/spec/unit/matrix-client.spec.js +++ b/spec/unit/matrix-client.spec.js @@ -1,6 +1,6 @@ -import {logger} from "../../src/logger"; -import {MatrixClient} from "../../src/client"; -import {Filter} from "../../src/filter"; +import { logger } from "../../src/logger"; +import { MatrixClient } from "../../src/client"; +import { Filter } from "../../src/filter"; jest.useFakeTimers(); @@ -178,7 +178,7 @@ describe("MatrixClient", function() { const filterId = "ehfewf"; store.getFilterIdByName.mockReturnValue(filterId); const filter = new Filter(0, filterId); - filter.setDefinition({"room": {"timeline": {"limit": 8}}}); + filter.setDefinition({ "room": { "timeline": { "limit": 8 } } }); store.getFilter.mockReturnValue(filter); const syncPromise = new Promise((resolve, reject) => { client.on("sync", function syncListener(state) { diff --git a/spec/unit/pushprocessor.spec.js b/spec/unit/pushprocessor.spec.js index c1258f74d..b625ade48 100644 --- a/spec/unit/pushprocessor.spec.js +++ b/spec/unit/pushprocessor.spec.js @@ -1,5 +1,5 @@ import * as utils from "../test-utils"; -import {PushProcessor} from "../../src/pushprocessor"; +import { PushProcessor } from "../../src/pushprocessor"; describe('NotificationService', function() { const testUserId = "@ali:matrix.org"; diff --git a/spec/unit/room-member.spec.js b/spec/unit/room-member.spec.js index d902154c6..ef59d404a 100644 --- a/spec/unit/room-member.spec.js +++ b/spec/unit/room-member.spec.js @@ -1,5 +1,5 @@ import * as utils from "../test-utils"; -import {RoomMember} from "../../src/models/room-member"; +import { RoomMember } from "../../src/models/room-member"; describe("RoomMember", function() { const roomId = "!foo:bar"; diff --git a/spec/unit/room-state.spec.js b/spec/unit/room-state.spec.js index a950d63be..182f38d12 100644 --- a/spec/unit/room-state.spec.js +++ b/spec/unit/room-state.spec.js @@ -1,6 +1,6 @@ import * as utils from "../test-utils"; -import {RoomState} from "../../src/models/room-state"; -import {RoomMember} from "../../src/models/room-member"; +import { RoomState } from "../../src/models/room-state"; +import { RoomMember } from "../../src/models/room-member"; describe("RoomState", function() { const roomId = "!foo:bar"; @@ -471,13 +471,13 @@ describe("RoomState", function() { it("should update after adding joined member", function() { state.setStateEvents([ - utils.mkMembership({event: true, mship: "join", - user: userA, room: roomId}), + utils.mkMembership({ event: true, mship: "join", + user: userA, room: roomId }), ]); expect(state.getJoinedMemberCount()).toEqual(1); state.setStateEvents([ - utils.mkMembership({event: true, mship: "join", - user: userC, room: roomId}), + utils.mkMembership({ event: true, mship: "join", + user: userC, room: roomId }), ]); expect(state.getJoinedMemberCount()).toEqual(2); }); @@ -490,13 +490,13 @@ describe("RoomState", function() { it("should update after adding invited member", function() { state.setStateEvents([ - utils.mkMembership({event: true, mship: "invite", - user: userA, room: roomId}), + utils.mkMembership({ event: true, mship: "invite", + user: userA, room: roomId }), ]); expect(state.getInvitedMemberCount()).toEqual(1); state.setStateEvents([ - utils.mkMembership({event: true, mship: "invite", - user: userC, room: roomId}), + utils.mkMembership({ event: true, mship: "invite", + user: userC, room: roomId }), ]); expect(state.getInvitedMemberCount()).toEqual(2); }); @@ -509,15 +509,15 @@ describe("RoomState", function() { it("should, once used, override counting members from state", function() { state.setStateEvents([ - utils.mkMembership({event: true, mship: "join", - user: userA, room: roomId}), + utils.mkMembership({ event: true, mship: "join", + user: userA, room: roomId }), ]); expect(state.getJoinedMemberCount()).toEqual(1); state.setJoinedMemberCount(100); expect(state.getJoinedMemberCount()).toEqual(100); state.setStateEvents([ - utils.mkMembership({event: true, mship: "join", - user: userC, room: roomId}), + utils.mkMembership({ event: true, mship: "join", + user: userC, room: roomId }), ]); expect(state.getJoinedMemberCount()).toEqual(100); }); @@ -525,14 +525,14 @@ describe("RoomState", function() { it("should, once used, override counting members from state, " + "also after clone", function() { state.setStateEvents([ - utils.mkMembership({event: true, mship: "join", - user: userA, room: roomId}), + utils.mkMembership({ event: true, mship: "join", + user: userA, room: roomId }), ]); state.setJoinedMemberCount(100); const copy = state.clone(); copy.setStateEvents([ - utils.mkMembership({event: true, mship: "join", - user: userC, room: roomId}), + utils.mkMembership({ event: true, mship: "join", + user: userC, room: roomId }), ]); expect(state.getJoinedMemberCount()).toEqual(100); }); @@ -545,15 +545,15 @@ describe("RoomState", function() { it("should, once used, override counting members from state", function() { state.setStateEvents([ - utils.mkMembership({event: true, mship: "invite", - user: userB, room: roomId}), + utils.mkMembership({ event: true, mship: "invite", + user: userB, room: roomId }), ]); expect(state.getInvitedMemberCount()).toEqual(1); state.setInvitedMemberCount(100); expect(state.getInvitedMemberCount()).toEqual(100); state.setStateEvents([ - utils.mkMembership({event: true, mship: "invite", - user: userC, room: roomId}), + utils.mkMembership({ event: true, mship: "invite", + user: userC, room: roomId }), ]); expect(state.getInvitedMemberCount()).toEqual(100); }); @@ -561,14 +561,14 @@ describe("RoomState", function() { it("should, once used, override counting members from state, " + "also after clone", function() { state.setStateEvents([ - utils.mkMembership({event: true, mship: "invite", - user: userB, room: roomId}), + utils.mkMembership({ event: true, mship: "invite", + user: userB, room: roomId }), ]); state.setInvitedMemberCount(100); const copy = state.clone(); copy.setStateEvents([ - utils.mkMembership({event: true, mship: "invite", - user: userC, room: roomId}), + utils.mkMembership({ event: true, mship: "invite", + user: userC, room: roomId }), ]); expect(state.getInvitedMemberCount()).toEqual(100); }); diff --git a/spec/unit/room.spec.js b/spec/unit/room.spec.js index 85f72ab9e..e67fff56b 100644 --- a/spec/unit/room.spec.js +++ b/spec/unit/room.spec.js @@ -1,9 +1,9 @@ import * as utils from "../test-utils"; -import {EventStatus, MatrixEvent} from "../../src/models/event"; -import {EventTimeline} from "../../src/models/event-timeline"; -import {RoomState} from "../../src/models/room-state"; -import {Room} from "../../src/models/room"; -import {TestClient} from "../TestClient"; +import { EventStatus, MatrixEvent } from "../../src/models/event"; +import { EventTimeline } from "../../src/models/event-timeline"; +import { RoomState } from "../../src/models/room-state"; +import { Room } from "../../src/models/room"; +import { TestClient } from "../TestClient"; describe("Room", function() { const roomId = "!foo:bar"; @@ -191,7 +191,7 @@ describe("Room", function() { const remoteEvent = utils.mkMessage({ room: roomId, user: userA, event: true, }); - remoteEvent.event.unsigned = {transaction_id: "TXN_ID"}; + remoteEvent.event.unsigned = { transaction_id: "TXN_ID" }; const remoteEventId = remoteEvent.getId(); let callCount = 0; @@ -375,7 +375,7 @@ describe("Room", function() { let events = null; beforeEach(function() { - room = new Room(roomId, null, null, {timelineSupport: timelineSupport}); + room = new Room(roomId, null, null, { timelineSupport: timelineSupport }); // set events each time to avoid resusing Event objects (which // doesn't work because they get frozen) events = [ @@ -457,7 +457,7 @@ describe("Room", function() { describe("compareEventOrdering", function() { beforeEach(function() { - room = new Room(roomId, null, null, {timelineSupport: true}); + room = new Room(roomId, null, null, { timelineSupport: true }); }); const events = [ @@ -713,7 +713,7 @@ describe("Room", function() { it("uses hero name from state", function() { const name = "Mr B"; addMember(userA, "invite"); - addMember(userB, "join", {name}); + addMember(userB, "join", { name }); room.setSummary({ "m.heroes": [userB], }); @@ -724,7 +724,7 @@ describe("Room", function() { it("uses counts from summary", function() { const name = "Mr B"; - addMember(userB, "join", {name}); + addMember(userB, "join", { name }); room.setSummary({ "m.heroes": [userB], "m.joined_member_count": 50, @@ -737,8 +737,8 @@ describe("Room", function() { it("relies on heroes in case of absent counts", function() { const nameB = "Mr Bean"; const nameC = "Mel C"; - addMember(userB, "join", {name: nameB}); - addMember(userC, "join", {name: nameC}); + addMember(userB, "join", { name: nameB }); + addMember(userC, "join", { name: nameC }); room.setSummary({ "m.heroes": [userB, userC], }); @@ -748,7 +748,7 @@ describe("Room", function() { it("uses only heroes", function() { const nameB = "Mr Bean"; - addMember(userB, "join", {name: nameB}); + addMember(userB, "join", { name: nameB }); addMember(userC, "join"); room.setSummary({ "m.heroes": [userB], @@ -841,7 +841,7 @@ describe("Room", function() { it("should show the other user's name for private" + " (invite join_rules) rooms if you are invited to it.", function() { setJoinRule("invite"); - addMember(userA, "invite", {user: userB}); + addMember(userA, "invite", { user: userB }); addMember(userB); room.recalculate(); const name = room.name; @@ -916,8 +916,8 @@ describe("Room", function() { "available", function() { setJoinRule("invite"); - addMember(userB, 'join', {name: "Alice"}); - addMember(userA, "invite", {user: userA}); + addMember(userB, 'join', { name: "Alice" }); + addMember(userA, "invite", { user: userA }); room.recalculate(); const name = room.name; expect(name).toEqual("Alice"); @@ -927,7 +927,7 @@ describe("Room", function() { function() { setJoinRule("invite"); addMember(userB); - addMember(userA, "invite", {user: userA}); + addMember(userA, "invite", { user: userA }); room.recalculate(); const name = room.name; expect(name).toEqual(userB); @@ -1267,7 +1267,6 @@ describe("Room", function() { expect(callCount).toEqual(1); }); - it("should remove cancelled events from the timeline", function() { const room = new Room(roomId, null, userA); const eventA = utils.mkMessage({ @@ -1321,7 +1320,7 @@ describe("Room", function() { if (this.serverResponse instanceof Error) { return Promise.reject(this.serverResponse); } else { - return Promise.resolve({chunk: this.serverResponse}); + return Promise.resolve({ chunk: this.serverResponse }); } }, }, @@ -1351,7 +1350,7 @@ describe("Room", function() { it("should load members from server on first call", async function() { const client = createClientMock([memberEvent]); - const room = new Room(roomId, client, null, {lazyLoadMembers: true}); + const room = new Room(roomId, client, null, { lazyLoadMembers: true }); await room.loadMembersIfNeeded(); const memberA = room.getMember("@user_a:bar"); expect(memberA.name).toEqual("User A"); @@ -1366,7 +1365,7 @@ describe("Room", function() { room: roomId, event: true, name: "Ms A", }); const client = createClientMock([memberEvent2], [memberEvent]); - const room = new Room(roomId, client, null, {lazyLoadMembers: true}); + const room = new Room(roomId, client, null, { lazyLoadMembers: true }); await room.loadMembersIfNeeded(); @@ -1376,7 +1375,7 @@ describe("Room", function() { it("should allow retry on error", async function() { const client = createClientMock(new Error("server says no")); - const room = new Room(roomId, client, null, {lazyLoadMembers: true}); + const room = new Room(roomId, client, null, { lazyLoadMembers: true }); let hasThrown = false; try { await room.loadMembersIfNeeded(); @@ -1404,17 +1403,17 @@ describe("Room", function() { const room = new Room(roomId, null, userA); const events = []; room.on("Room.myMembership", (_room, membership, oldMembership) => { - events.push({membership, oldMembership}); + events.push({ membership, oldMembership }); }); room.updateMyMembership("invite"); expect(room.getMyMembership()).toEqual("invite"); - expect(events[0]).toEqual({membership: "invite", oldMembership: null}); + expect(events[0]).toEqual({ membership: "invite", oldMembership: null }); events.splice(0); //clear room.updateMyMembership("invite"); expect(events.length).toEqual(0); room.updateMyMembership("join"); expect(room.getMyMembership()).toEqual("join"); - expect(events[0]).toEqual({membership: "join", oldMembership: "invite"}); + expect(events[0]).toEqual({ membership: "join", oldMembership: "invite" }); }); }); @@ -1422,7 +1421,7 @@ describe("Room", function() { it("should return first hero id", function() { const room = new Room(roomId, null, userA); - room.setSummary({'m.heroes': [userB]}); + room.setSummary({ 'm.heroes': [userB] }); expect(room.guessDMUserId()).toEqual(userB); }); it("should return first member that isn't self", diff --git a/spec/unit/scheduler.spec.js b/spec/unit/scheduler.spec.js index b4e83c4ef..daa752ac8 100644 --- a/spec/unit/scheduler.spec.js +++ b/spec/unit/scheduler.spec.js @@ -1,9 +1,9 @@ // This file had a function whose name is all caps, which displeases eslint /* eslint new-cap: "off" */ -import {defer} from '../../src/utils'; -import {MatrixError} from "../../src/http-api"; -import {MatrixScheduler} from "../../src/scheduler"; +import { defer } from '../../src/utils'; +import { MatrixError } from "../../src/http-api"; +import { MatrixScheduler } from "../../src/scheduler"; import * as utils from "../test-utils"; jest.useFakeTimers(); @@ -62,8 +62,8 @@ describe("MatrixScheduler", function() { scheduler.queueEvent(eventA), scheduler.queueEvent(eventB), ]); - deferB.resolve({b: true}); - deferA.resolve({a: true}); + deferB.resolve({ b: true }); + deferA.resolve({ a: true }); const [a, b] = await abPromise; expect(a.a).toEqual(true); expect(b.b).toEqual(true); @@ -156,8 +156,8 @@ describe("MatrixScheduler", function() { // Expect to have processFn invoked for A&B. // Resolve A. // Expect to have processFn invoked for D. - const eventC = utils.mkMessage({user: "@a:bar", room: roomId, event: true}); - const eventD = utils.mkMessage({user: "@b:bar", room: roomId, event: true}); + const eventC = utils.mkMessage({ user: "@a:bar", room: roomId, event: true }); + const eventD = utils.mkMessage({ user: "@b:bar", room: roomId, event: true }); const buckets = {}; buckets[eventA.getId()] = "queue_A"; @@ -241,7 +241,7 @@ describe("MatrixScheduler", function() { expect(queue).toEqual([eventA, eventB]); // modify the queue const eventC = utils.mkMessage( - {user: "@a:bar", room: roomId, event: true}, + { user: "@a:bar", room: roomId, event: true }, ); queue.push(eventC); const queueAgain = scheduler.getQueueForEvent(eventA); diff --git a/spec/unit/sync-accumulator.spec.js b/spec/unit/sync-accumulator.spec.js index b9f4ecbc2..b089e0ceb 100644 --- a/spec/unit/sync-accumulator.spec.js +++ b/spec/unit/sync-accumulator.spec.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {SyncAccumulator} from "../../src/sync-accumulator"; +import { SyncAccumulator } from "../../src/sync-accumulator"; // The event body & unsigned object get frozen to assert that they don't get altered // by the impl diff --git a/spec/unit/timeline-window.spec.js b/spec/unit/timeline-window.spec.js index af873cc3d..2a8be36d6 100644 --- a/spec/unit/timeline-window.spec.js +++ b/spec/unit/timeline-window.spec.js @@ -1,5 +1,5 @@ -import {EventTimeline} from "../../src/models/event-timeline"; -import {TimelineIndex, TimelineWindow} from "../../src/timeline-window"; +import { EventTimeline } from "../../src/models/event-timeline"; +import { TimelineIndex, TimelineWindow } from "../../src/timeline-window"; import * as utils from "../test-utils"; const ROOM_ID = "roomId"; @@ -18,7 +18,7 @@ function createTimeline(numEvents, baseIndex) { } // XXX: this is a horrid hack - const timelineSet = { room: { roomId: ROOM_ID }}; + const timelineSet = { room: { roomId: ROOM_ID } }; timelineSet.room.getUnfilteredTimelineSet = function() { return timelineSet; }; @@ -46,7 +46,6 @@ function addEventsToTimeline(timeline, numEvents, atStart) { } } - /* * create a pair of linked timelines */ @@ -58,7 +57,6 @@ function createLinkedTimelines() { return [tl1, tl2]; } - describe("TimelineIndex", function() { describe("minIndex", function() { it("should return the min index relative to BaseIndex", function() { @@ -133,7 +131,6 @@ describe("TimelineIndex", function() { }); }); - describe("TimelineWindow", function() { /** * create a dummy eventTimelineSet and client, and a TimelineWindow @@ -142,7 +139,7 @@ describe("TimelineWindow", function() { let timelineSet; let client; function createWindow(timeline, opts) { - timelineSet = {getTimelineForEvent: () => null}; + timelineSet = { getTimelineForEvent: () => null }; client = {}; client.getEventTimeline = function(timelineSet0, eventId0) { expect(timelineSet0).toBe(timelineSet); @@ -171,7 +168,7 @@ describe("TimelineWindow", function() { const timeline = createTimeline(); const eventId = timeline.getEvents()[1].getId(); - const timelineSet = {getTimelineForEvent: () => null}; + const timelineSet = { getTimelineForEvent: () => null }; const client = {}; client.getEventTimeline = function(timelineSet0, eventId0) { expect(timelineSet0).toBe(timelineSet); @@ -193,7 +190,7 @@ describe("TimelineWindow", function() { const eventId = timeline.getEvents()[1].getId(); - const timelineSet = {getTimelineForEvent: () => null}; + const timelineSet = { getTimelineForEvent: () => null }; const client = {}; const timelineWindow = new TimelineWindow(client, timelineSet); @@ -266,7 +263,7 @@ describe("TimelineWindow", function() { it("should advance into next timeline", function() { const tls = createLinkedTimelines(); const eventId = tls[0].getEvents()[1].getId(); - const timelineWindow = createWindow(tls[0], {windowLimit: 5}); + const timelineWindow = createWindow(tls[0], { windowLimit: 5 }); return timelineWindow.load(eventId, 3).then(function() { const expectedEvents = tls[0].getEvents(); @@ -311,7 +308,7 @@ describe("TimelineWindow", function() { it("should retreat into previous timeline", function() { const tls = createLinkedTimelines(); const eventId = tls[1].getEvents()[1].getId(); - const timelineWindow = createWindow(tls[1], {windowLimit: 5}); + const timelineWindow = createWindow(tls[1], { windowLimit: 5 }); return timelineWindow.load(eventId, 3).then(function() { const expectedEvents = tls[1].getEvents(); @@ -357,7 +354,7 @@ describe("TimelineWindow", function() { const timeline = createTimeline(); timeline.setPaginationToken("toktok", EventTimeline.FORWARDS); - const timelineWindow = createWindow(timeline, {windowLimit: 5}); + const timelineWindow = createWindow(timeline, { windowLimit: 5 }); const eventId = timeline.getEvents()[1].getId(); client.paginateEventTimeline = function(timeline0, opts) { @@ -385,12 +382,11 @@ describe("TimelineWindow", function() { }); }); - it("should make backward pagination requests", function() { const timeline = createTimeline(); timeline.setPaginationToken("toktok", EventTimeline.BACKWARDS); - const timelineWindow = createWindow(timeline, {windowLimit: 5}); + const timelineWindow = createWindow(timeline, { windowLimit: 5 }); const eventId = timeline.getEvents()[1].getId(); client.paginateEventTimeline = function(timeline0, opts) { @@ -422,7 +418,7 @@ describe("TimelineWindow", function() { const timeline = createTimeline(); timeline.setPaginationToken("toktok", EventTimeline.FORWARDS); - const timelineWindow = createWindow(timeline, {windowLimit: 5}); + const timelineWindow = createWindow(timeline, { windowLimit: 5 }); const eventId = timeline.getEvents()[1].getId(); let paginateCount = 0; diff --git a/spec/unit/user.spec.js b/spec/unit/user.spec.js index adef6e3c1..caf83db87 100644 --- a/spec/unit/user.spec.js +++ b/spec/unit/user.spec.js @@ -1,4 +1,4 @@ -import {User} from "../../src/models/user"; +import { User } from "../../src/models/user"; import * as utils from "../test-utils"; describe("User", function() { diff --git a/spec/unit/utils.spec.js b/spec/unit/utils.spec.js index 686912913..62201f06d 100644 --- a/spec/unit/utils.spec.js +++ b/spec/unit/utils.spec.js @@ -188,19 +188,19 @@ describe("utils", function() { it("should handle simple objects", function() { assert.isTrue(utils.deepCompare({}, {})); - assert.isTrue(utils.deepCompare({a: 1, b: 2}, {a: 1, b: 2})); - assert.isTrue(utils.deepCompare({a: 1, b: 2}, {b: 2, a: 1})); - assert.isFalse(utils.deepCompare({a: 1, b: 2}, {a: 1, b: 3})); + assert.isTrue(utils.deepCompare({ a: 1, b: 2 }, { a: 1, b: 2 })); + assert.isTrue(utils.deepCompare({ a: 1, b: 2 }, { b: 2, a: 1 })); + assert.isFalse(utils.deepCompare({ a: 1, b: 2 }, { a: 1, b: 3 })); - assert.isTrue(utils.deepCompare({1: {name: "mhc", age: 28}, - 2: {name: "arb", age: 26}}, - {1: {name: "mhc", age: 28}, - 2: {name: "arb", age: 26}})); + assert.isTrue(utils.deepCompare({ 1: { name: "mhc", age: 28 }, + 2: { name: "arb", age: 26 } }, + { 1: { name: "mhc", age: 28 }, + 2: { name: "arb", age: 26 } })); - assert.isFalse(utils.deepCompare({1: {name: "mhc", age: 28}, - 2: {name: "arb", age: 26}}, - {1: {name: "mhc", age: 28}, - 2: {name: "arb", age: 27}})); + assert.isFalse(utils.deepCompare({ 1: { name: "mhc", age: 28 }, + 2: { name: "arb", age: 26 } }, + { 1: { name: "mhc", age: 28 }, + 2: { name: "arb", age: 27 } })); assert.isFalse(utils.deepCompare({}, null)); assert.isFalse(utils.deepCompare({}, undefined)); @@ -223,7 +223,6 @@ describe("utils", function() { }); }); - describe("extend", function() { const SOURCE = { "prop2": 1, "string2": "x", "newprop": "new" }; diff --git a/src/autodiscovery.js b/src/autodiscovery.js index 98df1962f..1ccbbaa86 100644 --- a/src/autodiscovery.js +++ b/src/autodiscovery.js @@ -17,8 +17,8 @@ limitations under the License. /** @module auto-discovery */ -import {logger} from './logger'; -import {URL as NodeURL} from "url"; +import { logger } from './logger'; +import { URL as NodeURL } from "url"; // Dev note: Auto discovery is part of the spec. // See: https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery @@ -511,12 +511,12 @@ export class AutoDiscovery { action = "IGNORE"; reason = AutoDiscovery.ERROR_MISSING_WELLKNOWN; } - resolve({raw: {}, action: action, reason: reason, error: err}); + resolve({ raw: {}, action: action, reason: reason, error: err }); return; } try { - resolve({raw: JSON.parse(body), action: "SUCCESS"}); + resolve({ raw: JSON.parse(body), action: "SUCCESS" }); } catch (e) { let reason = AutoDiscovery.ERROR_INVALID; if (e.name === "SyntaxError") { diff --git a/src/base-apis.js b/src/base-apis.js index 1bdfb1f7e..de661eb16 100644 --- a/src/base-apis.js +++ b/src/base-apis.js @@ -24,11 +24,11 @@ limitations under the License. * @module base-apis */ -import {SERVICE_TYPES} from './service-types'; -import {logger} from './logger'; -import {PushProcessor} from "./pushprocessor"; +import { SERVICE_TYPES } from './service-types'; +import { logger } from './logger'; +import { PushProcessor } from "./pushprocessor"; import * as utils from "./utils"; -import {MatrixHttpApi, PREFIX_IDENTITY_V2, PREFIX_R0, PREFIX_UNSTABLE} from "./http-api"; +import { MatrixHttpApi, PREFIX_IDENTITY_V2, PREFIX_R0, PREFIX_UNSTABLE } from "./http-api"; function termsUrlForService(serviceType, baseUrl) { switch (serviceType) { @@ -158,7 +158,6 @@ MatrixBaseApis.prototype.makeTxnId = function() { return "m" + new Date().getTime() + "." + (this._txnCtr++); }; - // Registration/Login operations // ============================= @@ -197,7 +196,7 @@ MatrixBaseApis.prototype.register = function( ) { // backwards compat if (bindThreepids === true) { - bindThreepids = {email: true}; + bindThreepids = { email: true }; } else if (bindThreepids === null || bindThreepids === undefined) { bindThreepids = {}; } @@ -401,7 +400,6 @@ MatrixBaseApis.prototype.loginWithToken = function(token, callback) { }, callback); }; - /** * Logs out the current session. * Obviously, further calls that require authorisation should fail after this @@ -547,7 +545,7 @@ MatrixBaseApis.prototype.fetchRelations = * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.roomState = function(roomId, callback) { - const path = utils.encodeUri("/rooms/$roomId/state", {$roomId: roomId}); + const path = utils.encodeUri("/rooms/$roomId/state", { $roomId: roomId }); return this._http.authedRequest(callback, "GET", path); }; @@ -595,7 +593,7 @@ function(roomId, includeMembership, excludeMembership, atEventId, callback) { const queryString = utils.encodeParams(queryParams); const path = utils.encodeUri("/rooms/$roomId/members?" + queryString, - {$roomId: roomId}); + { $roomId: roomId }); return this._http.authedRequest(callback, "GET", path); }; @@ -607,20 +605,19 @@ function(roomId, includeMembership, excludeMembership, atEventId, callback) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.upgradeRoom = function(roomId, newVersion) { - const path = utils.encodeUri("/rooms/$roomId/upgrade", {$roomId: roomId}); + const path = utils.encodeUri("/rooms/$roomId/upgrade", { $roomId: roomId }); return this._http.authedRequest( - undefined, "POST", path, undefined, {new_version: newVersion}, + undefined, "POST", path, undefined, { new_version: newVersion }, ); }; - /** * @param {string} groupId * @return {Promise} Resolves: Group summary object * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.getGroupSummary = function(groupId) { - const path = utils.encodeUri("/groups/$groupId/summary", {$groupId: groupId}); + const path = utils.encodeUri("/groups/$groupId/summary", { $groupId: groupId }); return this._http.authedRequest(undefined, "GET", path); }; @@ -630,7 +627,7 @@ MatrixBaseApis.prototype.getGroupSummary = function(groupId) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.getGroupProfile = function(groupId) { - const path = utils.encodeUri("/groups/$groupId/profile", {$groupId: groupId}); + const path = utils.encodeUri("/groups/$groupId/profile", { $groupId: groupId }); return this._http.authedRequest(undefined, "GET", path); }; @@ -645,7 +642,7 @@ MatrixBaseApis.prototype.getGroupProfile = function(groupId) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.setGroupProfile = function(groupId, profile) { - const path = utils.encodeUri("/groups/$groupId/profile", {$groupId: groupId}); + const path = utils.encodeUri("/groups/$groupId/profile", { $groupId: groupId }); return this._http.authedRequest( undefined, "POST", path, undefined, profile, ); @@ -663,7 +660,7 @@ MatrixBaseApis.prototype.setGroupProfile = function(groupId, profile) { MatrixBaseApis.prototype.setGroupJoinPolicy = function(groupId, policy) { const path = utils.encodeUri( "/groups/$groupId/settings/m.join_policy", - {$groupId: groupId}, + { $groupId: groupId }, ); return this._http.authedRequest( undefined, "PUT", path, undefined, { @@ -678,7 +675,7 @@ MatrixBaseApis.prototype.setGroupJoinPolicy = function(groupId, policy) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.getGroupUsers = function(groupId) { - const path = utils.encodeUri("/groups/$groupId/users", {$groupId: groupId}); + const path = utils.encodeUri("/groups/$groupId/users", { $groupId: groupId }); return this._http.authedRequest(undefined, "GET", path); }; @@ -688,7 +685,7 @@ MatrixBaseApis.prototype.getGroupUsers = function(groupId) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.getGroupInvitedUsers = function(groupId) { - const path = utils.encodeUri("/groups/$groupId/invited_users", {$groupId: groupId}); + const path = utils.encodeUri("/groups/$groupId/invited_users", { $groupId: groupId }); return this._http.authedRequest(undefined, "GET", path); }; @@ -698,7 +695,7 @@ MatrixBaseApis.prototype.getGroupInvitedUsers = function(groupId) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.getGroupRooms = function(groupId) { - const path = utils.encodeUri("/groups/$groupId/rooms", {$groupId: groupId}); + const path = utils.encodeUri("/groups/$groupId/rooms", { $groupId: groupId }); return this._http.authedRequest(undefined, "GET", path); }; @@ -711,7 +708,7 @@ MatrixBaseApis.prototype.getGroupRooms = function(groupId) { MatrixBaseApis.prototype.inviteUserToGroup = function(groupId, userId) { const path = utils.encodeUri( "/groups/$groupId/admin/users/invite/$userId", - {$groupId: groupId, $userId: userId}, + { $groupId: groupId, $userId: userId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, {}); }; @@ -725,7 +722,7 @@ MatrixBaseApis.prototype.inviteUserToGroup = function(groupId, userId) { MatrixBaseApis.prototype.removeUserFromGroup = function(groupId, userId) { const path = utils.encodeUri( "/groups/$groupId/admin/users/remove/$userId", - {$groupId: groupId, $userId: userId}, + { $groupId: groupId, $userId: userId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, {}); }; @@ -742,7 +739,7 @@ MatrixBaseApis.prototype.addUserToGroupSummary = function(groupId, userId, roleI roleId ? "/groups/$groupId/summary/$roleId/users/$userId" : "/groups/$groupId/summary/users/$userId", - {$groupId: groupId, $roleId: roleId, $userId: userId}, + { $groupId: groupId, $roleId: roleId, $userId: userId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, {}); }; @@ -756,7 +753,7 @@ MatrixBaseApis.prototype.addUserToGroupSummary = function(groupId, userId, roleI MatrixBaseApis.prototype.removeUserFromGroupSummary = function(groupId, userId) { const path = utils.encodeUri( "/groups/$groupId/summary/users/$userId", - {$groupId: groupId, $userId: userId}, + { $groupId: groupId, $userId: userId }, ); return this._http.authedRequest(undefined, "DELETE", path, undefined, {}); }; @@ -773,7 +770,7 @@ MatrixBaseApis.prototype.addRoomToGroupSummary = function(groupId, roomId, categ categoryId ? "/groups/$groupId/summary/$categoryId/rooms/$roomId" : "/groups/$groupId/summary/rooms/$roomId", - {$groupId: groupId, $categoryId: categoryId, $roomId: roomId}, + { $groupId: groupId, $categoryId: categoryId, $roomId: roomId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, {}); }; @@ -787,7 +784,7 @@ MatrixBaseApis.prototype.addRoomToGroupSummary = function(groupId, roomId, categ MatrixBaseApis.prototype.removeRoomFromGroupSummary = function(groupId, roomId) { const path = utils.encodeUri( "/groups/$groupId/summary/rooms/$roomId", - {$groupId: groupId, $roomId: roomId}, + { $groupId: groupId, $roomId: roomId }, ); return this._http.authedRequest(undefined, "DELETE", path, undefined, {}); }; @@ -805,7 +802,7 @@ MatrixBaseApis.prototype.addRoomToGroup = function(groupId, roomId, isPublic) { } const path = utils.encodeUri( "/groups/$groupId/admin/rooms/$roomId", - {$groupId: groupId, $roomId: roomId}, + { $groupId: groupId, $roomId: roomId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, { "m.visibility": { type: isPublic ? "public" : "private" } }, @@ -827,7 +824,7 @@ MatrixBaseApis.prototype.updateGroupRoomVisibility = function(groupId, roomId, i const path = utils.encodeUri( "/groups/$groupId/admin/rooms/$roomId/config/m.visibility", - {$groupId: groupId, $roomId: roomId}, + { $groupId: groupId, $roomId: roomId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, { type: isPublic ? "public" : "private" }, @@ -843,7 +840,7 @@ MatrixBaseApis.prototype.updateGroupRoomVisibility = function(groupId, roomId, i MatrixBaseApis.prototype.removeRoomFromGroup = function(groupId, roomId) { const path = utils.encodeUri( "/groups/$groupId/admin/rooms/$roomId", - {$groupId: groupId, $roomId: roomId}, + { $groupId: groupId, $roomId: roomId }, ); return this._http.authedRequest(undefined, "DELETE", path, undefined, {}); }; @@ -857,7 +854,7 @@ MatrixBaseApis.prototype.removeRoomFromGroup = function(groupId, roomId) { MatrixBaseApis.prototype.acceptGroupInvite = function(groupId, opts = null) { const path = utils.encodeUri( "/groups/$groupId/self/accept_invite", - {$groupId: groupId}, + { $groupId: groupId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, opts || {}); }; @@ -870,7 +867,7 @@ MatrixBaseApis.prototype.acceptGroupInvite = function(groupId, opts = null) { MatrixBaseApis.prototype.joinGroup = function(groupId) { const path = utils.encodeUri( "/groups/$groupId/self/join", - {$groupId: groupId}, + { $groupId: groupId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, {}); }; @@ -883,7 +880,7 @@ MatrixBaseApis.prototype.joinGroup = function(groupId) { MatrixBaseApis.prototype.leaveGroup = function(groupId) { const path = utils.encodeUri( "/groups/$groupId/self/leave", - {$groupId: groupId}, + { $groupId: groupId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, {}); }; @@ -940,7 +937,7 @@ MatrixBaseApis.prototype.getPublicisedGroups = function(userIds) { MatrixBaseApis.prototype.setGroupPublicity = function(groupId, isPublic) { const path = utils.encodeUri( "/groups/$groupId/self/update_publicity", - {$groupId: groupId}, + { $groupId: groupId }, ); return this._http.authedRequest(undefined, "PUT", path, undefined, { publicise: isPublic, @@ -1008,7 +1005,7 @@ MatrixBaseApis.prototype.roomInitialSync = function(roomId, limit, callback) { callback = limit; limit = undefined; } const path = utils.encodeUri("/rooms/$roomId/initialSync", - {$roomId: roomId}, + { $roomId: roomId }, ); if (!limit) { limit = 30; @@ -1159,7 +1156,7 @@ MatrixBaseApis.prototype.deleteAlias = function(alias, callback) { MatrixBaseApis.prototype.unstableGetLocalAliases = function(roomId, callback) { const path = utils.encodeUri("/rooms/$roomId/aliases", - {$roomId: roomId}); + { $roomId: roomId }); const prefix = PREFIX_UNSTABLE + "/org.matrix.msc2432"; return this._http.authedRequest(callback, "GET", path, null, null, { prefix }); @@ -1190,7 +1187,7 @@ MatrixBaseApis.prototype.getRoomIdForAlias = function(alias, callback) { */ MatrixBaseApis.prototype.resolveRoomAlias = function(roomAlias, callback) { // TODO: deprecate this or getRoomIdForAlias - const path = utils.encodeUri("/directory/room/$alias", {$alias: roomAlias}); + const path = utils.encodeUri("/directory/room/$alias", { $alias: roomAlias }); return this._http.request(callback, "GET", path); }; @@ -1278,7 +1275,6 @@ MatrixBaseApis.prototype.searchUserDirectory = function(opts) { ); }; - // Media operations // ================ @@ -1347,7 +1343,6 @@ MatrixBaseApis.prototype.getCurrentUploads = function() { return this._http.getCurrentUploads(); }; - // Profile operations // ================== @@ -1372,7 +1367,6 @@ MatrixBaseApis.prototype.getProfileInfo = function(userId, info, callback) { return this._http.authedRequest(callback, "GET", path); }; - // Account operations // ================== @@ -1518,7 +1512,6 @@ MatrixBaseApis.prototype.setPassword = function(authDict, newPassword, callback) ); }; - // Device operations // ================= @@ -1595,7 +1588,7 @@ MatrixBaseApis.prototype.deleteDevice = function(device_id, auth) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixBaseApis.prototype.deleteMultipleDevices = function(devices, auth) { - const body = {devices}; + const body = { devices }; if (auth) { body.auth = auth; @@ -1605,7 +1598,6 @@ MatrixBaseApis.prototype.deleteMultipleDevices = function(devices, auth) { return this._http.authedRequest(undefined, "POST", path, undefined, body); }; - // Push operations // =============== @@ -1703,7 +1695,7 @@ MatrixBaseApis.prototype.setPushRuleEnabled = function(scope, kind, $ruleId: ruleId, }); return this._http.authedRequest( - callback, "PUT", path, undefined, {"enabled": enabled}, + callback, "PUT", path, undefined, { "enabled": enabled }, ); }; @@ -1724,11 +1716,10 @@ MatrixBaseApis.prototype.setPushRuleActions = function(scope, kind, $ruleId: ruleId, }); return this._http.authedRequest( - callback, "PUT", path, undefined, {"actions": actions}, + callback, "PUT", path, undefined, { "actions": actions }, ); }; - // Search // ====== @@ -1842,7 +1833,7 @@ MatrixBaseApis.prototype.claimOneTimeKeys = function(devices, key_algorithm, tim queries[userId] = query; query[deviceId] = key_algorithm; } - const content = {one_time_keys: queries}; + const content = { one_time_keys: queries }; if (timeout) { content.timeout = timeout; } @@ -1872,7 +1863,7 @@ MatrixBaseApis.prototype.getKeyChanges = function(oldToken, newToken) { MatrixBaseApis.prototype.uploadDeviceSigningKeys = function(auth, keys) { const data = Object.assign({}, keys); - if (auth) Object.assign(data, {auth}); + if (auth) Object.assign(data, { auth }); return this._http.authedRequest( undefined, "POST", "/keys/device_signing/upload", undefined, data, { prefix: PREFIX_UNSTABLE, @@ -2166,7 +2157,7 @@ MatrixBaseApis.prototype.identityHashedLookup = async function( throw new Error("Identity server returned more results than expected"); } - foundAddresses.push({address: plainAddress, mxid}); + foundAddresses.push({ address: plainAddress, mxid }); } return foundAddresses; }; @@ -2257,7 +2248,7 @@ MatrixBaseApis.prototype.bulkLookupThreePids = async function( ]); } - return {threepids: v1results}; + return { threepids: v1results }; }; /** @@ -2401,7 +2392,7 @@ MatrixBaseApis.prototype.reportEvent = function(roomId, eventId, score, reason) $eventId: eventId, }); - return this._http.authedRequest(undefined, "POST", path, null, {score, reason}); + return this._http.authedRequest(undefined, "POST", path, null, { score, reason }); }; /** diff --git a/src/client.js b/src/client.js index 63514c2e5..c3ec7710d 100644 --- a/src/client.js +++ b/src/client.js @@ -17,46 +17,45 @@ See the License for the specific language governing permissions and limitations under the License. */ - /** * This is an internal module. See {@link MatrixClient} for the public class. * @module client */ import url from "url"; -import {EventEmitter} from "events"; -import {MatrixBaseApis} from "./base-apis"; -import {Filter} from "./filter"; -import {SyncApi} from "./sync"; -import {EventStatus, MatrixEvent} from "./models/event"; -import {EventTimeline} from "./models/event-timeline"; -import {SearchResult} from "./models/search-result"; -import {StubStore} from "./store/stub"; -import {createNewMatrixCall} from "./webrtc/call"; -import {CallEventHandler} from './webrtc/callEventHandler'; +import { EventEmitter } from "events"; +import { MatrixBaseApis } from "./base-apis"; +import { Filter } from "./filter"; +import { SyncApi } from "./sync"; +import { EventStatus, MatrixEvent } from "./models/event"; +import { EventTimeline } from "./models/event-timeline"; +import { SearchResult } from "./models/search-result"; +import { StubStore } from "./store/stub"; +import { createNewMatrixCall } from "./webrtc/call"; +import { CallEventHandler } from './webrtc/callEventHandler'; import * as utils from './utils'; -import {sleep} from './utils'; +import { sleep } from './utils'; import { MatrixError, PREFIX_MEDIA_R0, PREFIX_UNSTABLE, retryNetworkOperation, } from "./http-api"; -import {getHttpUriForMxc} from "./content-repo"; +import { getHttpUriForMxc } from "./content-repo"; import * as ContentHelpers from "./content-helpers"; import * as olmlib from "./crypto/olmlib"; -import {ReEmitter} from './ReEmitter'; -import {RoomList} from './crypto/RoomList'; -import {logger} from './logger'; -import {Crypto, isCryptoAvailable, fixBackupKey} from './crypto'; -import {decodeRecoveryKey} from './crypto/recoverykey'; -import {keyFromAuthData} from './crypto/key_passphrase'; -import {randomString} from './randomstring'; -import {PushProcessor} from "./pushprocessor"; -import {encodeBase64, decodeBase64} from "./crypto/olmlib"; +import { ReEmitter } from './ReEmitter'; +import { RoomList } from './crypto/RoomList'; +import { logger } from './logger'; +import { Crypto, isCryptoAvailable, fixBackupKey } from './crypto'; +import { decodeRecoveryKey } from './crypto/recoverykey'; +import { keyFromAuthData } from './crypto/key_passphrase'; +import { randomString } from './randomstring'; +import { PushProcessor } from "./pushprocessor"; +import { encodeBase64, decodeBase64 } from "./crypto/olmlib"; import { User } from "./models/user"; -import {AutoDiscovery} from "./autodiscovery"; -import {DEHYDRATION_ALGORITHM} from "./crypto/dehydration"; +import { AutoDiscovery } from "./autodiscovery"; +import { DEHYDRATION_ALGORITHM } from "./crypto/dehydration"; const SCROLLBACK_DELAY_MS = 3000; export const CRYPTO_ENABLED = isCryptoAvailable(); @@ -702,7 +701,6 @@ MatrixClient.prototype.getDeviceId = function() { return this.deviceId; }; - /** * Check if the runtime environment supports VoIP calling. * @return {boolean} True if VoIP is supported. @@ -965,14 +963,12 @@ MatrixClient.prototype.initCrypto = async function() { this.olmVersion = Crypto.getOlmVersion(); - // if crypto initialisation was successful, tell it to attach its event // handlers. crypto.registerEventHandlers(this); this._crypto = crypto; }; - /** * Is end-to-end crypto enabled for this client. * @return {boolean} True if end-to-end is enabled. @@ -1786,7 +1782,7 @@ MatrixClient.prototype.checkKeyBackup = function() { MatrixClient.prototype.getKeyBackupVersion = function() { return this._http.authedRequest( undefined, "GET", "/room_keys/version", undefined, undefined, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ).then((res) => { if (res.algorithm !== olmlib.MEGOLM_BACKUP_ALGORITHM) { const err = "Unknown backup algorithm: " + res.algorithm; @@ -1964,7 +1960,7 @@ MatrixClient.prototype.createKeyBackupVersion = async function(info) { const res = await this._http.authedRequest( undefined, "POST", "/room_keys/version", undefined, data, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ); // We could assume everything's okay and enable directly, but this ensures @@ -1996,7 +1992,7 @@ MatrixClient.prototype.deleteKeyBackupVersion = function(version) { return this._http.authedRequest( undefined, "DELETE", path, undefined, undefined, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ); }; @@ -2038,7 +2034,7 @@ MatrixClient.prototype.sendKeyBackup = function(roomId, sessionId, version, data const path = this._makeKeyBackupPath(roomId, sessionId, version); return this._http.authedRequest( undefined, "PUT", path.path, path.queryData, data, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ); }; @@ -2238,7 +2234,7 @@ MatrixClient.prototype._restoreKeyBackup = function( // doesn't match the one in the auth_data, the user has enetered // a different recovery key / the wrong passphrase. if (backupPubKey !== backupInfo.auth_data.public_key) { - return Promise.reject({errcode: MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY}); + return Promise.reject({ errcode: MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY }); } // Cache the key, if possible. @@ -2256,7 +2252,7 @@ MatrixClient.prototype._restoreKeyBackup = function( return this._http.authedRequest( undefined, "GET", path.path, path.queryData, undefined, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ).then((res) => { if (res.rooms) { for (const [roomId, roomData] of Object.entries(res.rooms)) { @@ -2296,7 +2292,7 @@ MatrixClient.prototype._restoreKeyBackup = function( }).then(() => { return this._crypto.setTrustedBackupPubKey(backupPubKey); }).then(() => { - return {total: totalKeyCount, imported: keys.length}; + return { total: totalKeyCount, imported: keys.length }; }).finally(() => { decryption.free(); }); @@ -2310,7 +2306,7 @@ MatrixClient.prototype.deleteKeysFromBackup = function(roomId, sessionId, versio const path = this._makeKeyBackupPath(roomId, sessionId, version); return this._http.authedRequest( undefined, "DELETE", path.path, path.queryData, undefined, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ); }; @@ -2545,7 +2541,7 @@ MatrixClient.prototype.getIgnoredUsers = function() { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixClient.prototype.setIgnoredUsers = function(userIds, callback) { - const content = {ignored_users: {}}; + const content = { ignored_users: {} }; userIds.map((u) => content.ignored_users[u] = {}); return this.setAccountData("m.ignored_user_list", content, callback); }; @@ -2606,7 +2602,7 @@ MatrixClient.prototype.joinRoom = function(roomIdOrAlias, opts, callback) { queryString["server_name"] = opts.viaServers; } - const reqOpts = {qsStringifyOptions: {arrayFormat: 'repeat'}}; + const reqOpts = { qsStringifyOptions: { arrayFormat: 'repeat' } }; const self = this; const prom = new Promise((resolve, reject) => { @@ -2616,7 +2612,7 @@ MatrixClient.prototype.joinRoom = function(roomIdOrAlias, opts, callback) { data.third_party_signed = signed_invite_object; } - const path = utils.encodeUri("/join/$roomid", { $roomid: roomIdOrAlias}); + const path = utils.encodeUri("/join/$roomid", { $roomid: roomIdOrAlias }); return self._http.authedRequest( undefined, "POST", path, queryString, data, reqOpts); }).then(function(res) { @@ -2680,7 +2676,7 @@ MatrixClient.prototype.cancelPendingEvent = function(event) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixClient.prototype.setRoomName = function(roomId, name, callback) { - return this.sendStateEvent(roomId, "m.room.name", {name: name}, + return this.sendStateEvent(roomId, "m.room.name", { name: name }, undefined, callback); }; @@ -2692,7 +2688,7 @@ MatrixClient.prototype.setRoomName = function(roomId, name, callback) { * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixClient.prototype.setRoomTopic = function(roomId, topic, callback) { - return this.sendStateEvent(roomId, "m.room.topic", {topic: topic}, + return this.sendStateEvent(roomId, "m.room.topic", { topic: topic }, undefined, callback); }; @@ -2878,7 +2874,6 @@ MatrixClient.prototype._sendCompleteEvent = function(roomId, eventObject, txnId, return _sendEvent(this, room, localEvent, callback); }; - // encrypts the event if necessary // adds the event to the queue, or sends it // marks the event as sent/unsent @@ -3726,7 +3721,7 @@ function _setMembershipState(client, roomId, userId, membershipValue, reason, const path = utils.encodeUri( "/rooms/$roomId/state/m.room.member/$userId", - { $roomId: roomId, $userId: userId}, + { $roomId: roomId, $userId: userId }, ); return client._http.authedRequest(callback, "PUT", path, undefined, { @@ -4041,7 +4036,7 @@ MatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) { let params = undefined; if (this._clientOpts.lazyLoadMembers) { - params = {filter: JSON.stringify(Filter.LAZY_LOADING_MESSAGES_FILTER)}; + params = { filter: JSON.stringify(Filter.LAZY_LOADING_MESSAGES_FILTER) }; } // TODO: we should implement a backoff (as per scrollback()) to deal more @@ -4107,7 +4102,7 @@ MatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) { MatrixClient.prototype._createMessagesRequest = function(roomId, fromToken, limit, dir, timelineFilter = undefined) { const path = utils.encodeUri( - "/rooms/$roomId/messages", {$roomId: roomId}, + "/rooms/$roomId/messages", { $roomId: roomId }, ); if (limit === undefined) { limit = 30; @@ -4562,7 +4557,6 @@ MatrixClient.prototype._requestTokenFromEndpoint = async function(endpoint, para ); }; - // Push operations // =============== @@ -4741,7 +4735,7 @@ MatrixClient.prototype.searchRoomEvents = function(opts) { highlights: [], }; - return this.search({body: body}).then( + return this.search({ body: body }).then( this._processRoomEventsSearch.bind(this, searchResults), ); }; @@ -4818,7 +4812,6 @@ MatrixClient.prototype._processRoomEventsSearch = function(searchResults, respon return searchResults; }; - /** * Populate the store with rooms the user has left. * @return {Promise} Resolves: TODO - Resolved when the rooms have @@ -4964,7 +4957,6 @@ MatrixClient.prototype.getOrCreateFilter = async function(filterName, filter) { return createdFilter.filterId; }; - /** * Gets a bearer token from the Home Server that the user can * present to a third party in order to prove their ownership @@ -4982,7 +4974,6 @@ MatrixClient.prototype.getOpenIdToken = function() { ); }; - // VoIP operations // =============== @@ -5092,7 +5083,7 @@ MatrixClient.prototype.isSynapseAdministrator = function() { { $userId: this.getUserId() }, ); return this._http.authedRequest( - undefined, 'GET', path, undefined, undefined, {prefix: ''}, + undefined, 'GET', path, undefined, undefined, { prefix: '' }, ).then(r => r['admin']); // pull out the specific boolean we want }; @@ -5109,7 +5100,7 @@ MatrixClient.prototype.whoisSynapseUser = function(userId) { { $userId: userId }, ); return this._http.authedRequest( - undefined, 'GET', path, undefined, undefined, {prefix: ''}, + undefined, 'GET', path, undefined, undefined, { prefix: '' }, ); }; @@ -5125,7 +5116,7 @@ MatrixClient.prototype.deactivateSynapseUser = function(userId) { { $userId: userId }, ); return this._http.authedRequest( - undefined, 'POST', path, undefined, undefined, {prefix: ''}, + undefined, 'POST', path, undefined, undefined, { prefix: '' }, ); }; @@ -5143,7 +5134,6 @@ MatrixClient.prototype.deactivateSynapseUser = function(userId) { // due to ambiguity (or should this be on a chat-specific layer)? // reconnect after connectivity outages - /** * High level helper method to begin syncing and poll for new events. To listen for these * events, add a listener for {@link module:client~MatrixClient#event:"event"} @@ -5294,7 +5284,7 @@ MatrixClient.prototype._unstable_getSharedRooms = async function(userId) { }); const res = await this._http.authedRequest( undefined, "GET", path, undefined, undefined, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ); return res.joined; }; diff --git a/src/crypto/CrossSigning.js b/src/crypto/CrossSigning.js index 6dc5e3ed9..2143f0c75 100644 --- a/src/crypto/CrossSigning.js +++ b/src/crypto/CrossSigning.js @@ -20,11 +20,11 @@ limitations under the License. * @module crypto/CrossSigning */ -import {decodeBase64, encodeBase64, pkSign, pkVerify} from './olmlib'; -import {EventEmitter} from 'events'; -import {logger} from '../logger'; -import {IndexedDBCryptoStore} from '../crypto/store/indexeddb-crypto-store'; -import {decryptAES, encryptAES} from './aes'; +import { decodeBase64, encodeBase64, pkSign, pkVerify } from './olmlib'; +import { EventEmitter } from 'events'; +import { logger } from '../logger'; +import { IndexedDBCryptoStore } from '../crypto/store/indexeddb-crypto-store'; +import { decryptAES, encryptAES } from './aes'; const KEY_REQUEST_TIMEOUT_MS = 1000 * 60; diff --git a/src/crypto/DeviceList.js b/src/crypto/DeviceList.js index 97836b5a4..9b74a54db 100644 --- a/src/crypto/DeviceList.js +++ b/src/crypto/DeviceList.js @@ -22,14 +22,13 @@ limitations under the License. * Manages the list of other users' devices */ -import {EventEmitter} from 'events'; -import {logger} from '../logger'; -import {DeviceInfo} from './deviceinfo'; -import {CrossSigningInfo} from './CrossSigning'; +import { EventEmitter } from 'events'; +import { logger } from '../logger'; +import { DeviceInfo } from './deviceinfo'; +import { CrossSigningInfo } from './CrossSigning'; import * as olmlib from './olmlib'; -import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; -import {chunkPromises, defer, sleep} from '../utils'; - +import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; +import { chunkPromises, defer, sleep } from '../utils'; /* State transition diagram for DeviceList._deviceTrackingStatus * @@ -51,7 +50,6 @@ import {chunkPromises, defer, sleep} from '../utils'; * +----------------------- UP_TO_DATE ------------------------+ */ - // constants for DeviceList._deviceTrackingStatus const TRACKING_STATUS_NOT_TRACKED = 0; const TRACKING_STATUS_PENDING_DOWNLOAD = 1; @@ -892,7 +890,6 @@ class DeviceListUpdateSerialiser { } } - async function _updateStoredDeviceKeysForUser( _olmDevice, userId, userStore, userResult, localUserId, localDeviceId, ) { diff --git a/src/crypto/EncryptionSetup.js b/src/crypto/EncryptionSetup.js index f001cb259..d5421ea50 100644 --- a/src/crypto/EncryptionSetup.js +++ b/src/crypto/EncryptionSetup.js @@ -1,8 +1,8 @@ import { logger } from "../logger"; -import {MatrixEvent} from "../models/event"; -import {EventEmitter} from "events"; -import {createCryptoStoreCacheCallbacks} from "./CrossSigning"; -import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; +import { MatrixEvent } from "../models/event"; +import { EventEmitter } from "events"; +import { createCryptoStoreCacheCallbacks } from "./CrossSigning"; +import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { PREFIX_UNSTABLE, } from "../http-api"; @@ -43,7 +43,7 @@ export class EncryptionSetupBuilder { * @param {Object} keys the new keys */ addCrossSigningKeys(authUpload, keys) { - this._crossSigningKeys = {authUpload, keys}; + this._crossSigningKeys = { authUpload, keys }; } /** @@ -86,7 +86,6 @@ export class EncryptionSetupBuilder { userSignatures[deviceId] = signature; } - /** * @param {String} type * @param {Object} content @@ -211,21 +210,20 @@ export class EncryptionSetupOperation { algorithm: this._keyBackupInfo.algorithm, auth_data: this._keyBackupInfo.auth_data, }, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ); } else { // add new key backup await baseApis._http.authedRequest( undefined, "POST", "/room_keys/version", undefined, this._keyBackupInfo, - {prefix: PREFIX_UNSTABLE}, + { prefix: PREFIX_UNSTABLE }, ); } } } } - /** * Catches account data set by SecretStorage during bootstrapping by * implementing the methods related to account data in MatrixClient @@ -276,7 +274,7 @@ class AccountDataClientAdapter extends EventEmitter { // as SecretStorage listens for it while calling this method // and it seems to rely on this. return Promise.resolve().then(() => { - const event = new MatrixEvent({type, content}); + const event = new MatrixEvent({ type, content }); this.emit("accountData", event, lastEvent); }); } @@ -335,7 +333,7 @@ class SSSSCryptoCallbacks { // for it to the general crypto callbacks and cache it if (this._delegateCryptoCallbacks) { const result = await this._delegateCryptoCallbacks. - getSecretStorageKey({keys}, name); + getSecretStorageKey({ keys }, name); if (result) { const [keyId, privateKey] = result; this._privateKeys.set(keyId, privateKey); diff --git a/src/crypto/OlmDevice.js b/src/crypto/OlmDevice.js index df0733e65..b0410df72 100644 --- a/src/crypto/OlmDevice.js +++ b/src/crypto/OlmDevice.js @@ -16,8 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../logger'; -import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; +import { logger } from '../logger'; +import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import * as algorithms from './algorithms'; // The maximum size of an event is 65K, and we base64 the content, so this is a @@ -48,7 +48,6 @@ function checkPayloadLength(payloadString) { } } - /** * The type of object we use for importing and exporting megolm session data. * @@ -62,7 +61,6 @@ function checkPayloadLength(payloadString) { * @property {String} session_key Base64'ed key data */ - /** * Manages the olm cryptography functions. Each OlmDevice has a single * OlmAccount and a number of OlmSessions. @@ -350,7 +348,7 @@ OlmDevice.prototype._unpickleSession = function(sessionInfo, func) { const session = new global.Olm.Session(); try { session.unpickle(this._pickleKey, sessionInfo.session); - const unpickledSessInfo = Object.assign({}, sessionInfo, {session}); + const unpickledSessInfo = Object.assign({}, sessionInfo, { session }); func(unpickledSessInfo); } finally { @@ -376,7 +374,6 @@ OlmDevice.prototype._saveSession = function(deviceKey, sessionInfo, txn) { ); }; - /** * get an OlmUtility and call the given function * @@ -393,7 +390,6 @@ OlmDevice.prototype._getUtility = function(func) { } }; - /** * Signs a message with the ed25519 key for this account. * @@ -434,7 +430,6 @@ OlmDevice.prototype.getOneTimeKeys = async function() { return result; }; - /** * Get the maximum number of one-time keys we can store. * @@ -550,7 +545,6 @@ OlmDevice.prototype.createOutboundSession = async function( return newSessionId; }; - /** * Generate a new inbound session, given an incoming message * @@ -612,7 +606,6 @@ OlmDevice.prototype.createInboundSession = async function( return result; }; - /** * Get a list of known session IDs for the given device * @@ -856,7 +849,6 @@ OlmDevice.prototype.filterOutNotifiedErrorDevices = async function(devices) { return await this._cryptoStore.filterOutNotifiedErrorDevices(devices); }; - // Outbound group session // ====================== @@ -871,7 +863,6 @@ OlmDevice.prototype._saveOutboundGroupSession = function(session) { this._outboundGroupSessionStore[session.session_id()] = pickledSession; }; - /** * extract an OutboundGroupSession from _outboundGroupSessionStore and call the * given function @@ -896,7 +887,6 @@ OlmDevice.prototype._getOutboundGroupSession = function(sessionId, func) { } }; - /** * Generate a new outbound group session * @@ -913,7 +903,6 @@ OlmDevice.prototype.createOutboundGroupSession = function() { } }; - /** * Encrypt an outgoing message with an outbound group session * @@ -953,7 +942,6 @@ OlmDevice.prototype.getOutboundGroupSessionKey = function(sessionId) { }); }; - // Inbound group session // ===================== diff --git a/src/crypto/OutgoingRoomKeyRequestManager.js b/src/crypto/OutgoingRoomKeyRequestManager.js index c3f314f7a..94bd45d23 100644 --- a/src/crypto/OutgoingRoomKeyRequestManager.js +++ b/src/crypto/OutgoingRoomKeyRequestManager.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../logger'; +import { logger } from '../logger'; import * as utils from '../utils'; /** diff --git a/src/crypto/RoomList.js b/src/crypto/RoomList.js index 6a3c6c22f..b00445247 100644 --- a/src/crypto/RoomList.js +++ b/src/crypto/RoomList.js @@ -20,7 +20,7 @@ limitations under the License. * Manages the list of encrypted rooms */ -import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; +import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; /** * @alias module:crypto/RoomList diff --git a/src/crypto/SecretStorage.js b/src/crypto/SecretStorage.js index 120e2bdfa..5b20bc934 100644 --- a/src/crypto/SecretStorage.js +++ b/src/crypto/SecretStorage.js @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {EventEmitter} from 'events'; -import {logger} from '../logger'; +import { EventEmitter } from 'events'; +import { logger } from '../logger'; import * as olmlib from './olmlib'; -import {randomString} from '../randomstring'; -import {encryptAES, decryptAES} from './aes'; -import {encodeBase64} from "./olmlib"; +import { randomString } from '../randomstring'; +import { encryptAES, decryptAES } from './aes'; +import { encodeBase64 } from "./olmlib"; export const SECRET_STORAGE_ALGORITHM_V1_AES = "m.secret_storage.v1.aes-hmac-sha2"; @@ -86,7 +86,7 @@ export class SecretStorage extends EventEmitter { * keyInfo: {object} details about the key (iv, mac, passphrase) */ async addKey(algorithm, opts, keyId) { - const keyInfo = {algorithm}; + const keyInfo = { algorithm }; if (!opts) opts = {}; @@ -99,7 +99,7 @@ export class SecretStorage extends EventEmitter { keyInfo.passphrase = opts.passphrase; } if (opts.key) { - const {iv, mac} = await SecretStorage._calculateKeyCheck(opts.key); + const { iv, mac } = await SecretStorage._calculateKeyCheck(opts.key); keyInfo.iv = iv; keyInfo.mac = mac; } @@ -171,7 +171,7 @@ export class SecretStorage extends EventEmitter { async checkKey(key, info) { if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { if (info.mac) { - const {mac} = await SecretStorage._calculateKeyCheck(key, info.iv); + const { mac } = await SecretStorage._calculateKeyCheck(key, info.iv); return info.mac.replace(/=+$/g, '') === mac.replace(/=+$/g, ''); } else { // if we have no information, we have to assume the key is right @@ -220,7 +220,7 @@ export class SecretStorage extends EventEmitter { // encrypt secret, based on the algorithm if (keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { - const keys = {[keyId]: keyInfo}; + const keys = { [keyId]: keyInfo }; const [, encryption] = await this._getSecretStorageKey(keys, name); encrypted[keyId] = await encryption.encrypt(secret); } else { @@ -231,7 +231,7 @@ export class SecretStorage extends EventEmitter { } // save encrypted secret - await this._baseApis.setAccountData(name, {encrypted}); + await this._baseApis.setAccountData(name, { encrypted }); } /** diff --git a/src/crypto/aes.js b/src/crypto/aes.js index 1556413f7..c121b6e2b 100644 --- a/src/crypto/aes.js +++ b/src/crypto/aes.js @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {getCrypto} from '../utils'; -import {decodeBase64, encodeBase64} from './olmlib'; +import { getCrypto } from '../utils'; +import { decodeBase64, encodeBase64 } from './olmlib'; const subtleCrypto = (typeof window !== "undefined" && window.crypto) ? (window.crypto.subtle || window.crypto.webkitSubtle) : null; @@ -148,7 +148,7 @@ async function encryptBrowser(data, key, name, ivStr) { ); const hmac = await subtleCrypto.sign( - {name: 'HMAC'}, + { name: 'HMAC' }, hmacKey, ciphertext, ); @@ -176,7 +176,7 @@ async function decryptBrowser(data, key, name) { const ciphertext = decodeBase64(data.ciphertext); if (!await subtleCrypto.verify( - {name: "HMAC"}, + { name: "HMAC" }, hmacKey, decodeBase64(data.mac), ciphertext, @@ -201,7 +201,7 @@ async function deriveKeysBrowser(key, name) { const hkdfkey = await subtleCrypto.importKey( 'raw', key, - {name: "HKDF"}, + { name: "HKDF" }, false, ["deriveBits"], ); @@ -222,7 +222,7 @@ async function deriveKeysBrowser(key, name) { const aesProm = subtleCrypto.importKey( 'raw', aesKey, - {name: 'AES-CTR'}, + { name: 'AES-CTR' }, false, ['encrypt', 'decrypt'], ); @@ -232,7 +232,7 @@ async function deriveKeysBrowser(key, name) { hmacKey, { name: 'HMAC', - hash: {name: 'SHA-256'}, + hash: { name: 'SHA-256' }, }, false, ['sign', 'verify'], diff --git a/src/crypto/algorithms/megolm.js b/src/crypto/algorithms/megolm.js index 0bf77cd29..c4e987f0a 100644 --- a/src/crypto/algorithms/megolm.js +++ b/src/crypto/algorithms/megolm.js @@ -22,9 +22,9 @@ limitations under the License. * @module crypto/algorithms/megolm */ -import {logger} from '../../logger'; +import { logger } from '../../logger'; import * as utils from "../../utils"; -import {polyfillSuper} from "../../utils"; +import { polyfillSuper } from "../../utils"; import * as olmlib from "../olmlib"; import { DecryptionAlgorithm, @@ -34,7 +34,7 @@ import { UnknownDeviceError, } from "./base"; -import {WITHHELD_MESSAGES} from '../OlmDevice'; +import { WITHHELD_MESSAGES } from '../OlmDevice'; // determine whether the key can be shared with invitees function isRoomSharedHistory(room) { @@ -75,7 +75,6 @@ function OutboundSessionInfo(sessionId, sharedHistory = false) { this.sharedHistory = sharedHistory; } - /** * Check if it's time to rotate the session * @@ -158,7 +157,6 @@ OutboundSessionInfo.prototype.sharedWithTooManyDevices = function( } }; - /** * Megolm encryption implementation * @@ -328,7 +326,7 @@ MegolmEncryption.prototype._ensureOutboundSession = async function( failedServerMap.add(server); } const failedDevices = []; - for (const {userId, deviceInfo} of errorDevices) { + for (const { userId, deviceInfo } of errorDevices) { const userHS = userId.slice(userId.indexOf(":") + 1); if (failedServerMap.has(userHS)) { retryDevices[userId] = retryDevices[userId] || []; @@ -336,7 +334,7 @@ MegolmEncryption.prototype._ensureOutboundSession = async function( } else { // if we aren't going to retry, then handle it // as a failed device - failedDevices.push({userId, deviceInfo}); + failedDevices.push({ userId, deviceInfo }); } } @@ -410,8 +408,8 @@ MegolmEncryption.prototype._prepareNewSession = async function(sharedHistory) { await this._olmDevice.addInboundGroupSession( this._roomId, this._olmDevice.deviceCurve25519Key, [], sessionId, - key.key, {ed25519: this._olmDevice.deviceEd25519Key}, false, - {sharedHistory: sharedHistory}, + key.key, { ed25519: this._olmDevice.deviceEd25519Key }, false, + { sharedHistory: sharedHistory }, ); // don't wait for it to complete @@ -454,7 +452,7 @@ MegolmEncryption.prototype._getDevicesWithoutSessions = function( // no session with this device, probably because there // were no one-time keys. - noOlmDevices.push({userId, deviceInfo}); + noOlmDevices.push({ userId, deviceInfo }); delete sessionResults[deviceId]; // ensureOlmSessionsForUsers has already done the logging, @@ -819,7 +817,7 @@ MegolmEncryption.prototype._notifyFailedOlmDevices = async function( // mark the devices that failed as "handled" because we don't want to try // to claim a one-time-key for dead devices on every message. - for (const {userId, deviceInfo} of failedDevices) { + for (const { userId, deviceInfo } of failedDevices) { const deviceId = deviceInfo.deviceId; session.markSharedWithDevice( @@ -836,7 +834,7 @@ MegolmEncryption.prototype._notifyFailedOlmDevices = async function( `in ${this._roomId}`, ); const blockedMap = {}; - for (const {userId, deviceInfo} of filteredFailedDevices) { + for (const { userId, deviceInfo } of filteredFailedDevices) { blockedMap[userId] = blockedMap[userId] || {}; // we use a similar format to what // olmlib.ensureOlmSessionsForDevices returns, so that @@ -1341,7 +1339,6 @@ MegolmDecryption.prototype._removeEventFromPendingList = function(event) { } }; - /** * @inheritdoc * @@ -1489,7 +1486,7 @@ MegolmDecryption.prototype.onRoomKeyWithheldEvent = async function(event) { } } await olmlib.ensureOlmSessionsForDevices( - this._olmDevice, this._baseApis, {[sender]: [device]}, false, + this._olmDevice, this._baseApis, { [sender]: [device] }, false, ); const encryptedContent = { algorithm: olmlib.OLM_ALGORITHM, @@ -1503,7 +1500,7 @@ MegolmDecryption.prototype.onRoomKeyWithheldEvent = async function(event) { this._olmDevice, sender, device, - {type: "m.dummy"}, + { type: "m.dummy" }, ); await this._olmDevice.recordSessionProblem(senderKey, "no_olm", true); diff --git a/src/crypto/algorithms/olm.js b/src/crypto/algorithms/olm.js index 6add378e9..56c316e88 100644 --- a/src/crypto/algorithms/olm.js +++ b/src/crypto/algorithms/olm.js @@ -20,11 +20,11 @@ limitations under the License. * @module crypto/algorithms/olm */ -import {logger} from '../../logger'; +import { logger } from '../../logger'; import * as utils from "../../utils"; -import {polyfillSuper} from "../../utils"; +import { polyfillSuper } from "../../utils"; import * as olmlib from "../olmlib"; -import {DeviceInfo} from "../deviceinfo"; +import { DeviceInfo } from "../deviceinfo"; import { DecryptionAlgorithm, DecryptionError, @@ -358,5 +358,4 @@ OlmDecryption.prototype._reallyDecryptMessage = async function( return res.payload; }; - registerAlgorithm(olmlib.OLM_ALGORITHM, OlmEncryption, OlmDecryption); diff --git a/src/crypto/dehydration.ts b/src/crypto/dehydration.ts index 07bf04131..2fcae9cea 100644 --- a/src/crypto/dehydration.ts +++ b/src/crypto/dehydration.ts @@ -14,11 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {decodeBase64, encodeBase64} from './olmlib'; -import {IndexedDBCryptoStore} from '../crypto/store/indexeddb-crypto-store'; -import {decryptAES, encryptAES} from './aes'; +import { decodeBase64, encodeBase64 } from './olmlib'; +import { IndexedDBCryptoStore } from '../crypto/store/indexeddb-crypto-store'; +import { decryptAES, encryptAES } from './aes'; import anotherjson from "another-json"; -import {logger} from '../logger'; +import { logger } from '../logger'; // FIXME: these types should eventually go in a different file type Signatures = Record>; @@ -59,7 +59,7 @@ export class DehydrationManager { txn, async (result) => { if (result) { - const {key, keyInfo, deviceDisplayName, time} = result; + const { key, keyInfo, deviceDisplayName, time } = result; const pickleKey = Buffer.from(this.crypto._olmDevice._pickleKey); const decrypted = await decryptAES(key, pickleKey, DEHYDRATION_ALGORITHM); this.key = decodeBase64(decrypted); @@ -231,7 +231,7 @@ export class DehydrationManager { logger.log("Preparing one-time keys"); const oneTimeKeys = {}; for (const [keyId, key] of Object.entries(otks.curve25519)) { - const k: OneTimeKey = {key}; + const k: OneTimeKey = { key }; const signature = account.sign(anotherjson.stringify(k)); k.signatures = { [this.crypto._userId]: { @@ -244,7 +244,7 @@ export class DehydrationManager { logger.log("Preparing fallback keys"); const fallbackKeys = {}; for (const [keyId, key] of Object.entries(fallbacks.curve25519)) { - const k: OneTimeKey = {key, fallback: true}; + const k: OneTimeKey = { key, fallback: true }; const signature = account.sign(anotherjson.stringify(k)); k.signatures = { [this.crypto._userId]: { diff --git a/src/crypto/index.js b/src/crypto/index.js index 802d4660a..be7896321 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -22,15 +22,15 @@ limitations under the License. */ import anotherjson from "another-json"; -import {EventEmitter} from 'events'; -import {ReEmitter} from '../ReEmitter'; -import {logger} from '../logger'; +import { EventEmitter } from 'events'; +import { ReEmitter } from '../ReEmitter'; +import { logger } from '../logger'; import * as utils from "../utils"; -import {sleep} from "../utils"; -import {OlmDevice} from "./OlmDevice"; +import { sleep } from "../utils"; +import { OlmDevice } from "./OlmDevice"; import * as olmlib from "./olmlib"; -import {DeviceList} from "./DeviceList"; -import {DeviceInfo} from "./deviceinfo"; +import { DeviceList } from "./DeviceList"; +import { DeviceInfo } from "./deviceinfo"; import * as algorithms from "./algorithms"; import { CrossSigningInfo, @@ -38,25 +38,25 @@ import { UserTrustLevel, createCryptoStoreCacheCallbacks, } from './CrossSigning'; -import {EncryptionSetupBuilder} from "./EncryptionSetup"; -import {SECRET_STORAGE_ALGORITHM_V1_AES, SecretStorage} from './SecretStorage'; -import {OutgoingRoomKeyRequestManager} from './OutgoingRoomKeyRequestManager'; -import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; +import { EncryptionSetupBuilder } from "./EncryptionSetup"; +import { SECRET_STORAGE_ALGORITHM_V1_AES, SecretStorage } from './SecretStorage'; +import { OutgoingRoomKeyRequestManager } from './OutgoingRoomKeyRequestManager'; +import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { ReciprocateQRCode, SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD, } from './verification/QRCode'; -import {SAS} from './verification/SAS'; -import {keyFromPassphrase} from './key_passphrase'; -import {encodeRecoveryKey, decodeRecoveryKey} from './recoverykey'; -import {VerificationRequest} from "./verification/request/VerificationRequest"; -import {InRoomChannel, InRoomRequests} from "./verification/request/InRoomChannel"; -import {ToDeviceChannel, ToDeviceRequests} from "./verification/request/ToDeviceChannel"; -import {IllegalMethod} from "./verification/IllegalMethod"; -import {KeySignatureUploadError} from "../errors"; -import {decryptAES, encryptAES} from './aes'; -import {DehydrationManager} from './dehydration'; +import { SAS } from './verification/SAS'; +import { keyFromPassphrase } from './key_passphrase'; +import { encodeRecoveryKey, decodeRecoveryKey } from './recoverykey'; +import { VerificationRequest } from "./verification/request/VerificationRequest"; +import { InRoomChannel, InRoomRequests } from "./verification/request/InRoomChannel"; +import { ToDeviceChannel, ToDeviceRequests } from "./verification/request/ToDeviceChannel"; +import { IllegalMethod } from "./verification/IllegalMethod"; +import { KeySignatureUploadError } from "../errors"; +import { decryptAES, encryptAES } from './aes'; +import { DehydrationManager } from './dehydration'; import { MatrixEvent } from "../models/event"; const DeviceVerification = DeviceInfo.DeviceVerification; @@ -682,12 +682,12 @@ Crypto.prototype.bootstrapSecretStorage = async function({ const ensureCanCheckPassphrase = async (keyId, keyInfo) => { if (!keyInfo.mac) { const key = await this._baseApis._cryptoCallbacks.getSecretStorageKey( - {keys: {[keyId]: keyInfo}}, "", + { keys: { [keyId]: keyInfo } }, "", ); if (key) { const privateKey = key[1]; builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, privateKey); - const {iv, mac} = await SecretStorage._calculateKeyCheck(privateKey); + const { iv, mac } = await SecretStorage._calculateKeyCheck(privateKey); keyInfo.iv = iv; keyInfo.mac = mac; @@ -1599,7 +1599,7 @@ Crypto.prototype._checkAndStartKeyBackup = async function() { } } - return {backupInfo, trustInfo}; + return { backupInfo, trustInfo }; }; Crypto.prototype.setTrustedBackupPubKey = async function(trustedPubKey) { @@ -1774,7 +1774,6 @@ Crypto.prototype.registerEventHandlers = function(eventEmitter) { eventEmitter.on("Event.decrypted", timelineHandler); }; - /** Start background processes related to crypto */ Crypto.prototype.start = function() { this._outgoingRoomKeyRequestManager.start(); @@ -2231,7 +2230,7 @@ Crypto.prototype.setDeviceVerification = async function( } if (device) { - const upload = async ({shouldEmit}) => { + const upload = async ({ shouldEmit }) => { logger.info("Uploading signature for " + deviceId); const response = await this._baseApis.uploadKeySignatures({ [userId]: { @@ -2251,7 +2250,7 @@ Crypto.prototype.setDeviceVerification = async function( throw new KeySignatureUploadError("Key upload failed", { failures }); } }; - await upload({shouldEmit: true}); + await upload({ shouldEmit: true }); // XXX: we'll need to wait for the device list to be updated } } @@ -2344,7 +2343,7 @@ Crypto.prototype.beginKeyVerification = function( this._toDeviceVerificationRequests.setRequestBySenderAndTxnId( userId, transactionId, request); } - return request.beginKeyVerification(method, {userId, deviceId}); + return request.beginKeyVerification(method, { userId, deviceId }); }; Crypto.prototype.legacyDeviceVerification = async function( @@ -2357,7 +2356,7 @@ Crypto.prototype.legacyDeviceVerification = async function( channel, this._verificationMethods, this._baseApis); this._toDeviceVerificationRequests.setRequestBySenderAndTxnId( userId, transactionId, request); - const verifier = request.beginKeyVerification(method, {userId, deviceId}); + const verifier = request.beginKeyVerification(method, { userId, deviceId }); // either reject by an error from verify() while sending .start // or resolve when the request receives the // local (fake remote) echo for sending the .start event @@ -2368,7 +2367,6 @@ Crypto.prototype.legacyDeviceVerification = async function( return request; }; - /** * Get information on the active olm sessions with a user *

@@ -2399,7 +2397,6 @@ Crypto.prototype.getOlmSessionsForUser = async function(userId) { return result; }; - /** * Get the device which sent an event * @@ -2644,7 +2641,6 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic } }; - /** * Make sure we are tracking the device lists for all users in this room. * @@ -2867,7 +2863,7 @@ Crypto.prototype._backupPendingKeys = async function(limit) { for (const session of sessions) { const roomId = session.sessionData.room_id; if (data[roomId] === undefined) { - data[roomId] = {sessions: {}}; + data[roomId] = { sessions: {} }; } const sessionData = await this._olmDevice.exportInboundGroupSession( @@ -2901,7 +2897,7 @@ Crypto.prototype._backupPendingKeys = async function(limit) { await this._baseApis.sendKeyBackup( undefined, undefined, this.backupInfo.version, - {rooms: data}, + { rooms: data }, ); await this._cryptoStore.unmarkSessionsNeedingBackup(sessions); @@ -3301,7 +3297,6 @@ Crypto.prototype._getTrackedE2eRooms = function() { }); }; - Crypto.prototype._onToDeviceEvent = function(event) { try { logger.log(`received to_device ${event.getType()} from: ` + @@ -3439,7 +3434,7 @@ Crypto.prototype._onKeyVerificationMessage = function(event) { * @param {bool} data.liveEvent whether this is a live event */ Crypto.prototype._onTimelineEvent = function( - event, room, atStart, removed, {liveEvent} = {}, + event, room, atStart, removed, { liveEvent } = {}, ) { if (!InRoomChannel.validateEvent(event, this._baseApis)) { return; @@ -3577,7 +3572,7 @@ Crypto.prototype._onToDeviceBadEncrypted = async function(event) { this._olmDevice, sender, device, - {type: "m.dummy"}, + { type: "m.dummy" }, ); await this._olmDevice.recordSessionProblem(deviceKey, "wedged", true); @@ -3589,7 +3584,6 @@ Crypto.prototype._onToDeviceBadEncrypted = async function(event) { }, }); - // Most of the time this probably won't be necessary since we'll have queued up a key request when // we failed to decrypt the message and will be waiting a bit for the key to arrive before sending // it. This won't always be the case though so we need to re-send any that have already been sent @@ -3646,7 +3640,6 @@ Crypto.prototype._onRoomMembership = function(event, member, oldMembership) { alg.onRoomMembership(event, member, oldMembership); }; - /** * Called when we get an m.room_key_request event. * @@ -3799,7 +3792,6 @@ Crypto.prototype._processReceivedRoomKeyRequest = async function(req) { this.emit("crypto.roomKeyRequest", req); }; - /** * Helper for processReceivedRoomKeyRequests * @@ -3875,7 +3867,6 @@ Crypto.prototype._getRoomDecryptor = function(roomId, algorithm) { return alg; }; - /** * Get all the room decryptors for a given encryption algorithm. * @@ -3893,7 +3884,6 @@ Crypto.prototype._getRoomDecryptors = function(algorithm) { return decryptors; }; - /** * sign the given object with our ed25519 key * @@ -3913,7 +3903,6 @@ Crypto.prototype._signObject = async function(obj) { if (unsigned !== undefined) obj.unsigned = unsigned; }; - /** * The parameters of a room key request. The details of the request may * vary with the crypto algorithm, but the management and storage layers for diff --git a/src/crypto/key_passphrase.js b/src/crypto/key_passphrase.js index 47c964726..84384cc4e 100644 --- a/src/crypto/key_passphrase.js +++ b/src/crypto/key_passphrase.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {randomString} from '../randomstring'; +import { randomString } from '../randomstring'; const DEFAULT_ITERATIONS = 500000; @@ -63,7 +63,7 @@ export async function deriveKey(password, salt, iterations, numBits = DEFAULT_BI const key = await subtleCrypto.importKey( 'raw', new TextEncoder().encode(password), - {name: 'PBKDF2'}, + { name: 'PBKDF2' }, false, ['deriveBits'], ); diff --git a/src/crypto/olmlib.js b/src/crypto/olmlib.js index f1e487e97..5be11040b 100644 --- a/src/crypto/olmlib.js +++ b/src/crypto/olmlib.js @@ -22,7 +22,7 @@ limitations under the License. * Utilities common to olm encryption algorithms */ -import {logger} from '../logger'; +import { logger } from '../logger'; import * as utils from "../utils"; import anotherjson from "another-json"; @@ -41,7 +41,6 @@ export const MEGOLM_ALGORITHM = "m.megolm.v1.aes-sha2"; */ export const MEGOLM_BACKUP_ALGORITHM = "m.megolm_backup.v1.curve25519-aes-sha2"; - /** * Encrypt an event payload for an Olm device * @@ -408,7 +407,6 @@ async function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceIn return sid; } - /** * Verify the signature on an object * diff --git a/src/crypto/store/indexeddb-crypto-store-backend.js b/src/crypto/store/indexeddb-crypto-store-backend.js index 58bfee576..9a54a3537 100644 --- a/src/crypto/store/indexeddb-crypto-store-backend.js +++ b/src/crypto/store/indexeddb-crypto-store-backend.js @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../../logger'; +import { logger } from '../../logger'; import * as utils from "../../utils"; export const VERSION = 10; @@ -230,7 +230,7 @@ export class Backend { const cursor = ev.target.result; if (cursor) { const keyReq = cursor.value; - if (keyReq.recipients.includes({userId, deviceId})) { + if (keyReq.recipients.includes({ userId, deviceId })) { results.push(keyReq); } cursor.continue(); @@ -496,7 +496,7 @@ export class Backend { const lastProblem = problems[problems.length - 1]; for (const problem of problems) { if (problem.time > timestamp) { - result = Object.assign({}, problem, {fixed: lastProblem.fixed}); + result = Object.assign({}, problem, { fixed: lastProblem.fixed }); return; } } @@ -519,11 +519,11 @@ export class Backend { await Promise.all(devices.map((device) => { return new Promise((resolve) => { - const {userId, deviceInfo} = device; + const { userId, deviceInfo } = device; const getReq = objectStore.get([userId, deviceInfo.deviceId]); getReq.onsuccess = function() { if (!getReq.result) { - objectStore.put({userId, deviceId: deviceInfo.deviceId}); + objectStore.put({ userId, deviceId: deviceInfo.deviceId }); ret.push(device); } resolve(); @@ -768,9 +768,9 @@ export class Backend { const objectStore = txn.objectStore("shared_history_inbound_group_sessions"); const req = objectStore.get([roomId]); req.onsuccess = () => { - const {sessions} = req.result || {sessions: []}; + const { sessions } = req.result || { sessions: [] }; sessions.push([senderKey, sessionId]); - objectStore.put({roomId, sessions}); + objectStore.put({ roomId, sessions }); }; } @@ -784,7 +784,7 @@ export class Backend { const req = objectStore.get([roomId]); return new Promise((resolve, reject) => { req.onsuccess = () => { - const {sessions} = req.result || {sessions: []}; + const { sessions } = req.result || { sessions: [] }; resolve(sessions); }; req.onerror = reject; diff --git a/src/crypto/store/indexeddb-crypto-store.js b/src/crypto/store/indexeddb-crypto-store.js index 4cfe36128..02a99e4e2 100644 --- a/src/crypto/store/indexeddb-crypto-store.js +++ b/src/crypto/store/indexeddb-crypto-store.js @@ -16,11 +16,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../../logger'; -import {LocalStorageCryptoStore} from './localStorage-crypto-store'; -import {MemoryCryptoStore} from './memory-crypto-store'; +import { logger } from '../../logger'; +import { LocalStorageCryptoStore } from './localStorage-crypto-store'; +import { MemoryCryptoStore } from './memory-crypto-store'; import * as IndexedDBCryptoStoreBackend from './indexeddb-crypto-store-backend'; -import {InvalidCryptoStoreError} from '../../errors'; +import { InvalidCryptoStoreError } from '../../errors'; import * as IndexedDBHelpers from "../../indexeddb-helpers"; /** diff --git a/src/crypto/store/localStorage-crypto-store.js b/src/crypto/store/localStorage-crypto-store.js index 3e673168a..0a982311e 100644 --- a/src/crypto/store/localStorage-crypto-store.js +++ b/src/crypto/store/localStorage-crypto-store.js @@ -15,8 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../../logger'; -import {MemoryCryptoStore} from './memory-crypto-store'; +import { logger } from '../../logger'; +import { MemoryCryptoStore } from './memory-crypto-store'; /** * Internal module. Partial localStorage backed storage for e2e. @@ -136,7 +136,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore { async storeEndToEndSessionProblem(deviceKey, type, fixed) { const key = keyEndToEndSessionProblems(deviceKey); const problems = getJsonItem(this.store, key) || []; - problems.push({type, fixed, time: Date.now()}); + problems.push({ type, fixed, time: Date.now() }); problems.sort((a, b) => { return a.time - b.time; }); @@ -152,7 +152,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore { const lastProblem = problems[problems.length - 1]; for (const problem of problems) { if (problem.time > timestamp) { - return Object.assign({}, problem, {fixed: lastProblem.fixed}); + return Object.assign({}, problem, { fixed: lastProblem.fixed }); } } if (lastProblem.fixed) { @@ -168,7 +168,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore { const ret = []; for (const device of devices) { - const {userId, deviceInfo} = device; + const { userId, deviceInfo } = device; if (userId in notifiedErrorDevices) { if (!(deviceInfo.deviceId in notifiedErrorDevices[userId])) { ret.push(device); @@ -176,7 +176,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore { } } else { ret.push(device); - notifiedErrorDevices[userId] = {[deviceInfo.deviceId]: true }; + notifiedErrorDevices[userId] = { [deviceInfo.deviceId]: true }; } } diff --git a/src/crypto/store/memory-crypto-store.js b/src/crypto/store/memory-crypto-store.js index ac4e7be0b..9577fcad3 100644 --- a/src/crypto/store/memory-crypto-store.js +++ b/src/crypto/store/memory-crypto-store.js @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../../logger'; +import { logger } from '../../logger'; import * as utils from "../../utils"; /** @@ -186,7 +186,7 @@ export class MemoryCryptoStore { for (const req of this._outgoingRoomKeyRequests) { for (const state of wantedStates) { - if (req.state === state && req.recipients.includes({userId, deviceId})) { + if (req.state === state && req.recipients.includes({ userId, deviceId })) { results.push(req); } } @@ -324,7 +324,7 @@ export class MemoryCryptoStore { async storeEndToEndSessionProblem(deviceKey, type, fixed) { const problems = this._sessionProblems[deviceKey] = this._sessionProblems[deviceKey] || []; - problems.push({type, fixed, time: Date.now()}); + problems.push({ type, fixed, time: Date.now() }); problems.sort((a, b) => { return a.time - b.time; }); @@ -338,7 +338,7 @@ export class MemoryCryptoStore { const lastProblem = problems[problems.length - 1]; for (const problem of problems) { if (problem.time > timestamp) { - return Object.assign({}, problem, {fixed: lastProblem.fixed}); + return Object.assign({}, problem, { fixed: lastProblem.fixed }); } } if (lastProblem.fixed) { @@ -353,7 +353,7 @@ export class MemoryCryptoStore { const ret = []; for (const device of devices) { - const {userId, deviceInfo} = device; + const { userId, deviceInfo } = device; if (userId in notifiedErrorDevices) { if (!(deviceInfo.deviceId in notifiedErrorDevices[userId])) { ret.push(device); @@ -361,7 +361,7 @@ export class MemoryCryptoStore { } } else { ret.push(device); - notifiedErrorDevices[userId] = {[deviceInfo.deviceId]: true }; + notifiedErrorDevices[userId] = { [deviceInfo.deviceId]: true }; } } diff --git a/src/crypto/verification/Base.js b/src/crypto/verification/Base.js index 144d42e90..fd23668ac 100644 --- a/src/crypto/verification/Base.js +++ b/src/crypto/verification/Base.js @@ -20,12 +20,12 @@ limitations under the License. * @module crypto/verification/Base */ -import {MatrixEvent} from '../../models/event'; -import {EventEmitter} from 'events'; -import {logger} from '../../logger'; -import {DeviceInfo} from '../deviceinfo'; -import {newTimeoutError} from "./Error"; -import {requestKeysDuringVerification} from "../CrossSigning"; +import { MatrixEvent } from '../../models/event'; +import { EventEmitter } from 'events'; +import { logger } from '../../logger'; +import { DeviceInfo } from '../deviceinfo'; +import { newTimeoutError } from "./Error"; +import { requestKeysDuringVerification } from "../CrossSigning"; const timeoutException = new Error("Verification timed out"); @@ -138,7 +138,7 @@ export class VerificationBase extends EventEmitter { switchStartEvent(event) { if (this.canSwitchStartEvent(event)) { logger.log("Verification Base: switching verification start event", - {restartingFlow: !!this._rejectEvent}); + { restartingFlow: !!this._rejectEvent }); if (this._rejectEvent) { const reject = this._rejectEvent; this._rejectEvent = undefined; @@ -167,7 +167,7 @@ export class VerificationBase extends EventEmitter { // there is only promise to reject if verify has been called if (reject) { const content = e.getContent(); - const {reason, code} = content; + const { reason, code } = content; reject(new Error(`Other side cancelled verification ` + `because ${reason} (${code})`)); } diff --git a/src/crypto/verification/Error.js b/src/crypto/verification/Error.js index 5fe9fde4c..794976f56 100644 --- a/src/crypto/verification/Error.js +++ b/src/crypto/verification/Error.js @@ -20,10 +20,10 @@ limitations under the License. * @module crypto/verification/Error */ -import {MatrixEvent} from "../../models/event"; +import { MatrixEvent } from "../../models/event"; export function newVerificationError(code, reason, extradata) { - const content = Object.assign({}, {code, reason}, extradata); + const content = Object.assign({}, { code, reason }, extradata); return new MatrixEvent({ type: "m.key.verification.cancel", content, @@ -87,9 +87,9 @@ export const newInvalidMessageError = errorFactory( export function errorFromEvent(event) { const content = event.getContent(); if (content) { - const {code, reason} = content; - return {code, reason}; + const { code, reason } = content; + return { code, reason }; } else { - return {code: "Unknown error", reason: "m.unknown"}; + return { code: "Unknown error", reason: "m.unknown" }; } } diff --git a/src/crypto/verification/IllegalMethod.js b/src/crypto/verification/IllegalMethod.js index 2f05a28c7..3eb8d79dd 100644 --- a/src/crypto/verification/IllegalMethod.js +++ b/src/crypto/verification/IllegalMethod.js @@ -20,7 +20,7 @@ limitations under the License. * @module crypto/verification/IllegalMethod */ -import {VerificationBase as Base} from "./Base"; +import { VerificationBase as Base } from "./Base"; /** * @class crypto/verification/IllegalMethod/IllegalMethod diff --git a/src/crypto/verification/QRCode.js b/src/crypto/verification/QRCode.js index adfe5e28d..1a271c0a6 100644 --- a/src/crypto/verification/QRCode.js +++ b/src/crypto/verification/QRCode.js @@ -20,13 +20,13 @@ limitations under the License. * @module crypto/verification/QRCode */ -import {VerificationBase as Base} from "./Base"; +import { VerificationBase as Base } from "./Base"; import { newKeyMismatchError, newUserCancelledError, } from './Error'; -import {encodeUnpaddedBase64, decodeBase64} from "../olmlib"; -import {logger} from '../../logger'; +import { encodeUnpaddedBase64, decodeBase64 } from "../olmlib"; +import { logger } from '../../logger'; export const SHOW_QR_CODE_METHOD = "m.qr_code.show.v1"; export const SCAN_QR_CODE_METHOD = "m.qr_code.scan.v1"; @@ -51,7 +51,7 @@ export class ReciprocateQRCode extends Base { "with this method yet."); } - const {qrCodeData} = this.request; + const { qrCodeData } = this.request; // 1. check the secret if (this.startEvent.getContent()['secret'] !== qrCodeData.encodedSharedSecret) { throw newKeyMismatchError(); diff --git a/src/crypto/verification/SAS.js b/src/crypto/verification/SAS.js index c69f9f7e8..8c3de1768 100644 --- a/src/crypto/verification/SAS.js +++ b/src/crypto/verification/SAS.js @@ -19,7 +19,7 @@ limitations under the License. * @module crypto/verification/SAS */ -import {VerificationBase as Base, SwitchStartEventError} from "./Base"; +import { VerificationBase as Base, SwitchStartEventError } from "./Base"; import anotherjson from 'another-json'; import { errorFactory, @@ -28,7 +28,7 @@ import { newUnknownMethodError, newUserCancelledError, } from './Error'; -import {logger} from '../../logger'; +import { logger } from '../../logger'; const START_TYPE = "m.key.verification.start"; @@ -323,7 +323,6 @@ export class SAS extends Base { key: this.ourSASPubKey, }); - e = await this._waitForEvent("m.key.verification.key"); // FIXME: make sure event is properly formed content = e.getContent(); @@ -353,7 +352,6 @@ export class SAS extends Base { this.emit("show_sas", this.sasEvent); }); - [e] = await Promise.all([ this._waitForEvent("m.key.verification.mac") .then((e) => { @@ -411,7 +409,6 @@ export class SAS extends Base { commitment: olmutil.sha256(commitmentStr), }); - let e = await this._waitForEvent("m.key.verification.key"); // FIXME: make sure event is properly formed content = e.getContent(); @@ -440,7 +437,6 @@ export class SAS extends Base { this.emit("show_sas", this.sasEvent); }); - [e] = await Promise.all([ this._waitForEvent("m.key.verification.mac") .then((e) => { diff --git a/src/crypto/verification/request/InRoomChannel.js b/src/crypto/verification/request/InRoomChannel.js index dfcbfee0e..72b6af4b2 100644 --- a/src/crypto/verification/request/InRoomChannel.js +++ b/src/crypto/verification/request/InRoomChannel.js @@ -21,7 +21,7 @@ import { READY_TYPE, START_TYPE, } from "./VerificationRequest"; -import {logger} from '../../../logger'; +import { logger } from '../../../logger'; const MESSAGE_TYPE = "m.room.message"; const M_REFERENCE = "m.reference"; @@ -157,7 +157,7 @@ export class InRoomChannel { if (type === MESSAGE_TYPE) { const content = event.getContent(); if (content) { - const {msgtype} = content; + const { msgtype } = content; if (msgtype === REQUEST_TYPE) { return REQUEST_TYPE; } diff --git a/src/crypto/verification/request/ToDeviceChannel.js b/src/crypto/verification/request/ToDeviceChannel.js index 9f3659389..f45a69d3d 100644 --- a/src/crypto/verification/request/ToDeviceChannel.js +++ b/src/crypto/verification/request/ToDeviceChannel.js @@ -15,8 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {randomString} from '../../../randomstring'; -import {logger} from '../../../logger'; +import { randomString } from '../../../randomstring'; +import { logger } from '../../../logger'; import { CANCEL_TYPE, PHASE_STARTED, @@ -26,8 +26,8 @@ import { START_TYPE, VerificationRequest, } from "./VerificationRequest"; -import {errorFromEvent, newUnexpectedMessageError} from "../Error"; -import {MatrixEvent} from "../../../models/event"; +import { errorFromEvent, newUnexpectedMessageError } from "../Error"; +import { MatrixEvent } from "../../../models/event"; /** * A key verification channel that sends verification events over to_device messages. @@ -277,7 +277,7 @@ export class ToDeviceChannel { msgMap[deviceId] = content; } - return this._client.sendToDevice(type, {[this.userId]: msgMap}); + return this._client.sendToDevice(type, { [this.userId]: msgMap }); } else { return Promise.resolve(); } @@ -292,7 +292,6 @@ export class ToDeviceChannel { } } - export class ToDeviceRequests { constructor() { this._requestsByUserId = new Map(); diff --git a/src/crypto/verification/request/VerificationRequest.js b/src/crypto/verification/request/VerificationRequest.js index a77b8c96d..6a4f290b4 100644 --- a/src/crypto/verification/request/VerificationRequest.js +++ b/src/crypto/verification/request/VerificationRequest.js @@ -15,15 +15,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../../../logger'; -import {EventEmitter} from 'events'; +import { logger } from '../../../logger'; +import { EventEmitter } from 'events'; import { errorFactory, errorFromEvent, newUnexpectedMessageError, newUnknownMethodError, } from "../Error"; -import {QRCodeData, SCAN_QR_CODE_METHOD} from "../QRCode"; +import { QRCodeData, SCAN_QR_CODE_METHOD } from "../QRCode"; // How long after the event's timestamp that the request times out const TIMEOUT_FROM_EVENT_TS = 10 * 60 * 1000; // 10 minutes @@ -37,7 +37,6 @@ const TIMEOUT_FROM_EVENT_RECEIPT = 2 * 60 * 1000; // 2 minutes // are this amount of time away from expiring. const VERIFICATION_REQUEST_MARGIN = 3 * 1000; // 3 seconds - export const EVENT_PREFIX = "m.key.verification."; export const REQUEST_TYPE = EVENT_PREFIX + "request"; export const START_TYPE = EVENT_PREFIX + "start"; @@ -52,7 +51,6 @@ export const PHASE_STARTED = 4; export const PHASE_CANCELLED = 5; export const PHASE_DONE = 6; - /** * State machine for verification requests. * Things that differ based on what channel is used to @@ -98,7 +96,6 @@ export class VerificationRequest extends EventEmitter { static validateEvent(type, event, client) { const content = event.getContent(); - if (!type || !type.startsWith(EVENT_PREFIX)) { return false; } @@ -265,7 +262,7 @@ export class VerificationRequest extends EventEmitter { if (!content) { return false; } - const {methods} = content; + const { methods } = content; if (!Array.isArray(methods)) { return false; } @@ -355,7 +352,6 @@ export class VerificationRequest extends EventEmitter { return this._observeOnly; } - /** * Gets which device the verification should be started with * given the events sent so far in the verification. This is the @@ -414,7 +410,7 @@ export class VerificationRequest extends EventEmitter { async sendRequest() { if (!this.observeOnly && this._phase === PHASE_UNSENT) { const methods = [...this._verificationMethods.keys()]; - await this.channel.send(REQUEST_TYPE, {methods}); + await this.channel.send(REQUEST_TYPE, { methods }); } } @@ -424,7 +420,7 @@ export class VerificationRequest extends EventEmitter { * @param {string?} error.code the error code to send the cancellation with * @returns {Promise} resolves when the event has been sent. */ - async cancel({reason = "User declined", code = "m.user"} = {}) { + async cancel({ reason = "User declined", code = "m.user" } = {}) { if (!this.observeOnly && this._phase !== PHASE_CANCELLED) { this._declining = true; this.emit("change"); @@ -432,7 +428,7 @@ export class VerificationRequest extends EventEmitter { return this._verifier.cancel(errorFactory(code, reason)()); } else { this._cancellingUserId = this._client.getUserId(); - await this.channel.send(CANCEL_TYPE, {code, reason}); + await this.channel.send(CANCEL_TYPE, { code, reason }); } } } @@ -446,7 +442,7 @@ export class VerificationRequest extends EventEmitter { const methods = [...this._verificationMethods.keys()]; this._accepting = true; this.emit("change"); - await this.channel.send(READY_TYPE, {methods}); + await this.channel.send(READY_TYPE, { methods }); } } @@ -499,20 +495,20 @@ export class VerificationRequest extends EventEmitter { } _calculatePhaseTransitions() { - const transitions = [{phase: PHASE_UNSENT}]; + const transitions = [{ phase: PHASE_UNSENT }]; const phase = () => transitions[transitions.length - 1].phase; // always pass by .request first to be sure channel.userId has been set const hasRequestByThem = this._eventsByThem.has(REQUEST_TYPE); const requestEvent = this._getEventBy(REQUEST_TYPE, hasRequestByThem); if (requestEvent) { - transitions.push({phase: PHASE_REQUESTED, event: requestEvent}); + transitions.push({ phase: PHASE_REQUESTED, event: requestEvent }); } const readyEvent = requestEvent && this._getEventBy(READY_TYPE, !hasRequestByThem); if (readyEvent && phase() === PHASE_REQUESTED) { - transitions.push({phase: PHASE_READY, event: readyEvent}); + transitions.push({ phase: PHASE_READY, event: readyEvent }); } let startEvent; @@ -535,18 +531,18 @@ export class VerificationRequest extends EventEmitter { const fromUnsentPhase = phase() === PHASE_UNSENT && this.channel.constructor.canCreateRequest(START_TYPE); if (fromRequestPhase || phase() === PHASE_READY || fromUnsentPhase) { - transitions.push({phase: PHASE_STARTED, event: startEvent}); + transitions.push({ phase: PHASE_STARTED, event: startEvent }); } } const ourDoneEvent = this._eventsByUs.get(DONE_TYPE); if (this._verifierHasFinished || (ourDoneEvent && phase() === PHASE_STARTED)) { - transitions.push({phase: PHASE_DONE}); + transitions.push({ phase: PHASE_DONE }); } const cancelEvent = this._getEventByEither(CANCEL_TYPE); if ((this._cancelled || cancelEvent) && phase() !== PHASE_DONE) { - transitions.push({phase: PHASE_CANCELLED, event: cancelEvent}); + transitions.push({ phase: PHASE_CANCELLED, event: cancelEvent }); return transitions; } @@ -554,7 +550,7 @@ export class VerificationRequest extends EventEmitter { } _transitionToPhase(transition) { - const {phase, event} = transition; + const { phase, event } = transition; // get common methods if (phase === PHASE_REQUESTED || phase === PHASE_READY) { if (!this._wasSentByOwnDevice(event)) { @@ -581,7 +577,7 @@ export class VerificationRequest extends EventEmitter { } // create verifier if (phase === PHASE_STARTED) { - const {method} = event.getContent(); + const { method } = event.getContent(); if (!this._verifier && !this.observeOnly) { this._verifier = this._createVerifier(method, event); if (!this._verifier) { @@ -731,7 +727,7 @@ export class VerificationRequest extends EventEmitter { } const lastTransition = newTransitions[newTransitions.length - 1]; - const {phase} = lastTransition; + const { phase } = lastTransition; this._setupTimeout(phase); // set phase as last thing as this emits the "change" event @@ -809,7 +805,7 @@ export class VerificationRequest extends EventEmitter { logger.warn(`Cancelling, unexpected ${type} verification ` + `event from ${event.getSender()}`); const reason = `Unexpected ${type} event in phase ${this.phase}`; - await this.cancel(errorFromEvent(newUnexpectedMessageError({reason}))); + await this.cancel(errorFromEvent(newUnexpectedMessageError({ reason }))); return true; } return false; @@ -849,7 +845,7 @@ export class VerificationRequest extends EventEmitter { if (!targetDevice) { targetDevice = this.targetDevice; } - const {userId, deviceId} = targetDevice; + const { userId, deviceId } = targetDevice; const VerifierCtor = this._verificationMethods.get(method); if (!VerifierCtor) { diff --git a/src/errors.js b/src/errors.js index 32d72d9a8..186fc6911 100644 --- a/src/errors.js +++ b/src/errors.js @@ -22,7 +22,6 @@ InvalidStoreError.prototype = Object.create(Error.prototype, { }); Reflect.setPrototypeOf(InvalidStoreError, Error); - export function InvalidCryptoStoreError(reason) { const message = `Crypto store is invalid because ${reason}, ` + `please stop the client, delete all data and start the client again`; diff --git a/src/filter.js b/src/filter.js index 6ab581c6a..08e747092 100644 --- a/src/filter.js +++ b/src/filter.js @@ -19,7 +19,7 @@ limitations under the License. * @module filter */ -import {FilterComponent} from "./filter-component"; +import { FilterComponent } from "./filter-component"; /** * @param {Object} obj diff --git a/src/http-api.js b/src/http-api.js index 26b3d5f5b..d723e5b98 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -20,9 +20,9 @@ limitations under the License. * @module http-api */ -import {parse as parseContentType} from "content-type"; +import { parse as parseContentType } from "content-type"; import * as utils from "./utils"; -import {logger} from './logger'; +import { logger } from './logger'; // we use our own implementation of setTimeout, so that if we get suspended in // the middle of a /sync, we cancel the sync as soon as we awake, rather than @@ -344,7 +344,7 @@ MatrixHttpApi.prototype = { promise = this.authedRequest( opts.callback, "POST", "/upload", queryParams, body, { prefix: "/_matrix/media/r0", - headers: {"Content-Type": contentType}, + headers: { "Content-Type": contentType }, json: false, bodyParser: bodyParser, }, @@ -862,7 +862,6 @@ function parseErrorResponse(response, body) { return err; } - /** * extract the Content-Type header from the response object, and * parse it to a `{type, parameters}` object. diff --git a/src/indexeddb-worker.js b/src/indexeddb-worker.js index b51d90afd..45facc485 100644 --- a/src/indexeddb-worker.js +++ b/src/indexeddb-worker.js @@ -21,5 +21,5 @@ limitations under the License. */ /** The {@link module:indexeddb-store-worker~IndexedDBStoreWorker} class. */ -export {IndexedDBStoreWorker} from "./store/indexeddb-store-worker"; +export { IndexedDBStoreWorker } from "./store/indexeddb-store-worker"; diff --git a/src/interactive-auth.js b/src/interactive-auth.js index edf5a4290..c1537fe85 100644 --- a/src/interactive-auth.js +++ b/src/interactive-auth.js @@ -20,7 +20,7 @@ limitations under the License. import url from "url"; import * as utils from "./utils"; -import {logger} from './logger'; +import { logger } from './logger'; const EMAIL_STAGE_TYPE = "m.login.email.identity"; const MSISDN_STAGE_TYPE = "m.login.msisdn"; diff --git a/src/matrix.ts b/src/matrix.ts index 144cd07c0..92f374a16 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -18,15 +18,15 @@ limitations under the License. import type Request from "request"; -import {MemoryCryptoStore} from "./crypto/store/memory-crypto-store"; -import {LocalStorageCryptoStore} from "./crypto/store/localStorage-crypto-store"; -import {IndexedDBCryptoStore} from "./crypto/store/indexeddb-crypto-store"; -import {MemoryStore} from "./store/memory"; -import {StubStore} from "./store/stub"; -import {LocalIndexedDBStoreBackend} from "./store/indexeddb-local-backend"; -import {RemoteIndexedDBStoreBackend} from "./store/indexeddb-remote-backend"; -import {MatrixScheduler} from "./scheduler"; -import {MatrixClient} from "./client"; +import { MemoryCryptoStore } from "./crypto/store/memory-crypto-store"; +import { LocalStorageCryptoStore } from "./crypto/store/localStorage-crypto-store"; +import { IndexedDBCryptoStore } from "./crypto/store/indexeddb-crypto-store"; +import { MemoryStore } from "./store/memory"; +import { StubStore } from "./store/stub"; +import { LocalIndexedDBStoreBackend } from "./store/indexeddb-local-backend"; +import { RemoteIndexedDBStoreBackend } from "./store/indexeddb-remote-backend"; +import { MatrixScheduler } from "./scheduler"; +import { MatrixClient } from "./client"; export * from "./client"; export * from "./http-api"; @@ -59,7 +59,6 @@ export { setVideoInput as setMatrixCallVideoInput, } from "./webrtc/call"; - // expose the underlying request object so different environments can use // different request libs (e.g. request or browser-request) let requestInstance; diff --git a/src/models/event-context.js b/src/models/event-context.js index 5ffb103fe..b04018aba 100644 --- a/src/models/event-context.js +++ b/src/models/event-context.js @@ -36,10 +36,10 @@ limitations under the License. export function EventContext(ourEvent) { this._timeline = [ourEvent]; this._ourEventIndex = 0; - this._paginateTokens = {b: null, f: null}; + this._paginateTokens = { b: null, f: null }; // this is used by MatrixClient to keep track of active requests - this._paginateRequests = {b: null, f: null}; + this._paginateRequests = { b: null, f: null }; } /** diff --git a/src/models/event-timeline-set.js b/src/models/event-timeline-set.js index fd04eabe5..13316ea7d 100644 --- a/src/models/event-timeline-set.js +++ b/src/models/event-timeline-set.js @@ -19,12 +19,12 @@ limitations under the License. * @module models/event-timeline-set */ -import {EventEmitter} from "events"; -import {EventTimeline} from "./event-timeline"; -import {EventStatus} from "./event"; +import { EventEmitter } from "events"; +import { EventTimeline } from "./event-timeline"; +import { EventStatus } from "./event"; import * as utils from "../utils"; -import {logger} from '../logger'; -import {Relations} from './relations'; +import { logger } from '../logger'; +import { Relations } from './relations'; // var DEBUG = false; const DEBUG = true; @@ -271,7 +271,6 @@ EventTimelineSet.prototype.addTimeline = function() { return timeline; }; - /** * Add events to a timeline * @@ -474,7 +473,7 @@ EventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimel // timeline we ended up on. if (lastEventWasNew || !didUpdate) { if (direction === EventTimeline.FORWARDS && timeline === this._liveTimeline) { - logger.warn({lastEventWasNew, didUpdate}); // for debugging + logger.warn({ lastEventWasNew, didUpdate }); // for debugging logger.warn( `Refusing to set forwards pagination token of live timeline ` + `${timeline} to ${paginationToken}`, diff --git a/src/models/event-timeline.js b/src/models/event-timeline.js index 20fee86a2..288659611 100644 --- a/src/models/event-timeline.js +++ b/src/models/event-timeline.js @@ -19,7 +19,7 @@ limitations under the License. * @module models/event-timeline */ -import {RoomState} from "./room-state"; +import { RoomState } from "./room-state"; /** * Construct a new EventTimeline @@ -55,7 +55,7 @@ export function EventTimeline(eventTimelineSet) { this._nextTimeline = null; // this is used by client.js - this._paginationRequests = {'b': null, 'f': null}; + this._paginationRequests = { 'b': null, 'f': null }; this._name = this._roomId + ":" + new Date().toISOString(); } diff --git a/src/models/event.js b/src/models/event.js index 767539895..b7e22a606 100644 --- a/src/models/event.js +++ b/src/models/event.js @@ -21,9 +21,9 @@ limitations under the License. * @module models/event */ -import {EventEmitter} from 'events'; +import { EventEmitter } from 'events'; import * as utils from '../utils'; -import {logger} from '../logger'; +import { logger } from '../logger'; /** * Enum for event statuses. @@ -180,7 +180,6 @@ export const MatrixEvent = function( }; utils.inherits(MatrixEvent, EventEmitter); - utils.extend(MatrixEvent.prototype, { /** * Get the event_id for this event. @@ -1128,7 +1127,6 @@ utils.extend(MatrixEvent.prototype, { }, }); - /* _REDACT_KEEP_KEY_MAP gives the keys we keep when an event is redacted * * This is specified here: @@ -1147,17 +1145,16 @@ const _REDACT_KEEP_KEY_MAP = [ // a map from event type to the .content keys we keep when an event is redacted const _REDACT_KEEP_CONTENT_MAP = { - 'm.room.member': {'membership': 1}, - 'm.room.create': {'creator': 1}, - 'm.room.join_rules': {'join_rule': 1}, - 'm.room.power_levels': {'ban': 1, 'events': 1, 'events_default': 1, + 'm.room.member': { 'membership': 1 }, + 'm.room.create': { 'creator': 1 }, + 'm.room.join_rules': { 'join_rule': 1 }, + 'm.room.power_levels': { 'ban': 1, 'events': 1, 'events_default': 1, 'kick': 1, 'redact': 1, 'state_default': 1, 'users': 1, 'users_default': 1, }, - 'm.room.aliases': {'aliases': 1}, + 'm.room.aliases': { 'aliases': 1 }, }; - /** * Fires when an event is decrypted * diff --git a/src/models/group.js b/src/models/group.js index 74b86f53e..e228aa1be 100644 --- a/src/models/group.js +++ b/src/models/group.js @@ -20,7 +20,7 @@ limitations under the License. */ import * as utils from "../utils"; -import {EventEmitter} from "events"; +import { EventEmitter } from "events"; /** * Construct a new Group. diff --git a/src/models/relations.js b/src/models/relations.js index 273a823be..80d894ce8 100644 --- a/src/models/relations.js +++ b/src/models/relations.js @@ -14,9 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {EventEmitter} from 'events'; -import {EventStatus} from '../models/event'; -import {logger} from '../logger'; +import { EventEmitter } from 'events'; +import { EventStatus } from '../models/event'; +import { logger } from '../logger'; /** * A container for relation events that supports easy access to common ways of diff --git a/src/models/room-member.js b/src/models/room-member.js index 444c45609..586f12e31 100644 --- a/src/models/room-member.js +++ b/src/models/room-member.js @@ -19,8 +19,8 @@ limitations under the License. * @module models/room-member */ -import {EventEmitter} from "events"; -import {getHttpUriForMxc} from "../content-repo"; +import { EventEmitter } from "events"; +import { getHttpUriForMxc } from "../content-repo"; import * as utils from "../utils"; /** @@ -202,7 +202,6 @@ RoomMember.prototype.getLastModifiedTime = function() { return this._modified; }; - RoomMember.prototype.isKicked = function() { return this.membership === "leave" && this.events.member.getSender() !== this.events.member.getStateKey(); @@ -239,7 +238,6 @@ RoomMember.prototype.getDMInviter = function() { } }; - /** * Get the avatar URL for a room member. * @param {string} baseUrl The base homeserver URL See diff --git a/src/models/room-state.js b/src/models/room-state.js index 9be252f2c..5bf674f9c 100644 --- a/src/models/room-state.js +++ b/src/models/room-state.js @@ -19,11 +19,11 @@ limitations under the License. * @module models/room-state */ -import {EventEmitter} from "events"; -import {RoomMember} from "./room-member"; -import {logger} from '../logger'; +import { EventEmitter } from "events"; +import { RoomMember } from "./room-member"; +import { logger } from '../logger'; import * as utils from "../utils"; -import {EventType} from "../@types/event"; +import { EventType } from "../@types/event"; // possible statuses for out-of-band member loading const OOB_STATUS_NOTSTARTED = 1; @@ -735,7 +735,6 @@ RoomState.prototype.getJoinRule = function() { return joinRuleContent["join_rule"] || "invite"; }; - function _updateThirdPartyTokenCache(roomState, memberEvent) { if (!memberEvent.getContent().third_party_invite) { return; diff --git a/src/models/room.js b/src/models/room.js index b573c0622..22b04891b 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -20,17 +20,17 @@ limitations under the License. * @module models/room */ -import {EventEmitter} from "events"; -import {EventTimelineSet} from "./event-timeline-set"; -import {EventTimeline} from "./event-timeline"; -import {getHttpUriForMxc} from "../content-repo"; +import { EventEmitter } from "events"; +import { EventTimelineSet } from "./event-timeline-set"; +import { EventTimeline } from "./event-timeline"; +import { getHttpUriForMxc } from "../content-repo"; import * as utils from "../utils"; -import {EventStatus, MatrixEvent} from "./event"; -import {RoomMember} from "./room-member"; -import {RoomSummary} from "./room-summary"; -import {logger} from '../logger'; -import {ReEmitter} from '../ReEmitter'; -import {EventType, RoomCreateTypeField, RoomType} from "../@types/event"; +import { EventStatus, MatrixEvent } from "./event"; +import { RoomMember } from "./room-member"; +import { RoomSummary } from "./room-summary"; +import { logger } from '../logger'; +import { ReEmitter } from '../ReEmitter'; +import { EventType, RoomCreateTypeField, RoomType } from "../@types/event"; // These constants are used as sane defaults when the homeserver doesn't support // the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be @@ -58,7 +58,6 @@ function synthesizeReceipt(userId, event, receiptType) { return new MatrixEvent(fakeReceipt); } - /** * Construct a new Room. * @@ -441,7 +440,6 @@ Room.prototype.getLiveTimeline = function() { return this.getUnfilteredTimelineSet().getLiveTimeline(); }; - /** * Get the timestamp of the last message in the room * @@ -580,13 +578,12 @@ Room.prototype._loadMembersFromServer = async function() { at: lastSyncToken, }); const path = utils.encodeUri("/rooms/$roomId/members?" + queryString, - {$roomId: this.roomId}); + { $roomId: this.roomId }); const http = this._client._http; const response = await http.authedRequest(undefined, "GET", path); return response.chunk; }; - Room.prototype._loadMembers = async function() { // were the members loaded from the server? let fromServer = false; @@ -599,7 +596,7 @@ Room.prototype._loadMembers = async function() { `members from server for room ${this.roomId}`); } const memberEvents = rawMembersEvents.map(this._client.getEventMapper()); - return {memberEvents, fromServer}; + return { memberEvents, fromServer }; }; /** @@ -1071,7 +1068,6 @@ Room.prototype.getInvitedAndJoinedMemberCount = function() { return calculateRoomName(this, userId, true); }; - /** * Check if the given user_id has the given membership state. * @param {string} userId The user ID to check. @@ -1228,7 +1224,6 @@ Room.prototype._addLiveEvent = function(event, duplicateStrategy, fromCache) { } }; - /** * Add a pending outgoing event to this room. * @@ -1639,7 +1634,6 @@ Room.prototype.removeEvent = function(eventId) { return removedAny; }; - /** * Recalculate various aspects of the room, including the room name and * room summary. Call this any time the room's current state is modified. @@ -1863,7 +1857,6 @@ Room.prototype._buildReceiptCache = function(receipts) { return receiptCacheByEventId; }; - /** * Add a temporary local-echo receipt to the room to reflect in the * client the fact that we've sent one. @@ -1921,7 +1914,6 @@ Room.prototype.getAccountData = function(type) { return this.accountData[type]; }; - /** * Returns whether the syncing user has permission to send a message in the room * @return {boolean} true if the user should be permitted to send diff --git a/src/models/search-result.js b/src/models/search-result.js index a8b50ea4b..667b6c88e 100644 --- a/src/models/search-result.js +++ b/src/models/search-result.js @@ -20,7 +20,7 @@ limitations under the License. */ import * as utils from "../utils"; -import {EventContext} from "./event-context"; +import { EventContext } from "./event-context"; /** * Construct a new SearchResult diff --git a/src/models/user.js b/src/models/user.js index 0a98ea9ed..ec1127e84 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -20,7 +20,7 @@ limitations under the License. */ import * as utils from "../utils"; -import {EventEmitter} from "events"; +import { EventEmitter } from "events"; /** * Construct a new User. A User must have an ID and can optionally have extra @@ -139,7 +139,6 @@ User.prototype.setDisplayName = function(name) { } }; - /** * Manually set this user's non-disambiguated display name. No event is emitted * in response to this as there is no underlying MatrixEvent to emit with. @@ -153,7 +152,6 @@ User.prototype.setRawDisplayName = function(name) { } }; - /** * Manually set this user's avatar URL. No event is emitted in response to this * as there is no underlying MatrixEvent to emit with. diff --git a/src/pushprocessor.js b/src/pushprocessor.js index 0e8958b09..4ab881623 100644 --- a/src/pushprocessor.js +++ b/src/pushprocessor.js @@ -15,8 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {escapeRegExp, globToRegexp, isNullOrUndefined} from "./utils"; -import {logger} from './logger'; +import { escapeRegExp, globToRegexp, isNullOrUndefined } from "./utils"; +import { logger } from './logger'; /** * @module pushprocessor @@ -360,7 +360,6 @@ export function PushProcessor(client) { return ret; }; - /** * Get the user's push actions for the given event * @@ -468,4 +467,3 @@ PushProcessor.rewriteDefaultRules = function(incomingRules) { * noise. */ - diff --git a/src/realtime-callbacks.js b/src/realtime-callbacks.js index c4d13f9e3..5fa2008ca 100644 --- a/src/realtime-callbacks.js +++ b/src/realtime-callbacks.js @@ -24,7 +24,7 @@ limitations under the License. * it will instead fire as soon as possible after resume. */ -import {logger} from './logger'; +import { logger } from './logger'; // we schedule a callback at least this often, to check if we've missed out on // some wall-clock time due to being suspended. @@ -177,7 +177,6 @@ function _runCallbacks() { } } - /* search in a sorted array. * * returns the index of the last element for which func returns diff --git a/src/scheduler.js b/src/scheduler.js index 9addbc8e5..9ae68135e 100644 --- a/src/scheduler.js +++ b/src/scheduler.js @@ -21,7 +21,7 @@ limitations under the License. * @module scheduler */ import * as utils from "./utils"; -import {logger} from './logger'; +import { logger } from './logger'; const DEBUG = false; // set true to enable console logging. @@ -93,7 +93,6 @@ MatrixScheduler.prototype.removeEventFromQueue = function(event) { return removed; }; - /** * Set the process function. Required for events in the queue to be processed. * If set after events have been added to the queue, this will immediately start diff --git a/src/store/indexeddb-local-backend.js b/src/store/indexeddb-local-backend.js index 3a0af28b1..21364991c 100644 --- a/src/store/indexeddb-local-backend.js +++ b/src/store/indexeddb-local-backend.js @@ -16,10 +16,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {SyncAccumulator} from "../sync-accumulator"; +import { SyncAccumulator } from "../sync-accumulator"; import * as utils from "../utils"; import * as IndexedDBHelpers from "../indexeddb-helpers"; -import {logger} from '../logger'; +import { logger } from '../logger'; const VERSION = 3; @@ -45,10 +45,9 @@ function upgradeSchemaV2(db) { function upgradeSchemaV3(db) { db.createObjectStore("client_options", - { keyPath: ["clobber"]}); + { keyPath: ["clobber"] }); } - /** * Helper method to collect results from a Cursor and promiseify it. * @param {ObjectStore|Index} store The store to perform openCursor on. diff --git a/src/store/indexeddb-remote-backend.js b/src/store/indexeddb-remote-backend.js index a00b16977..efe57db55 100644 --- a/src/store/indexeddb-remote-backend.js +++ b/src/store/indexeddb-remote-backend.js @@ -16,8 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {logger} from '../logger'; -import {defer} from '../utils'; +import { logger } from '../logger'; +import { defer } from '../utils'; /** * An IndexedDB store backend where the actual backend sits in a web @@ -48,7 +48,6 @@ export function RemoteIndexedDBStoreBackend( this._startPromise = null; } - RemoteIndexedDBStoreBackend.prototype = { /** * Attempt to connect to the database. This can fail if the user does not diff --git a/src/store/indexeddb-store-worker.js b/src/store/indexeddb-store-worker.js index 5c1971bb0..35af82ab4 100644 --- a/src/store/indexeddb-store-worker.js +++ b/src/store/indexeddb-store-worker.js @@ -16,8 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {LocalIndexedDBStoreBackend} from "./indexeddb-local-backend.js"; -import {logger} from '../logger'; +import { LocalIndexedDBStoreBackend } from "./indexeddb-local-backend.js"; +import { logger } from '../logger'; /** * This class lives in the webworker and drives a LocalIndexedDBStoreBackend diff --git a/src/store/indexeddb.js b/src/store/indexeddb.js index 5aebcfe6f..e661c83a8 100644 --- a/src/store/indexeddb.js +++ b/src/store/indexeddb.js @@ -18,14 +18,14 @@ limitations under the License. /* eslint-disable @babel/no-invalid-this */ -import {MemoryStore} from "./memory"; +import { MemoryStore } from "./memory"; import * as utils from "../utils"; -import {EventEmitter} from 'events'; -import {LocalIndexedDBStoreBackend} from "./indexeddb-local-backend.js"; -import {RemoteIndexedDBStoreBackend} from "./indexeddb-remote-backend.js"; -import {User} from "../models/user"; -import {MatrixEvent} from "../models/event"; -import {logger} from '../logger'; +import { EventEmitter } from 'events'; +import { LocalIndexedDBStoreBackend } from "./indexeddb-local-backend.js"; +import { RemoteIndexedDBStoreBackend } from "./indexeddb-remote-backend.js"; +import { User } from "../models/user"; +import { MatrixEvent } from "../models/event"; +import { logger } from '../logger'; /** * This is an internal module. See {@link IndexedDBStore} for the public class. @@ -39,7 +39,6 @@ import {logger} from '../logger'; // response is persisted each time. const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes - /** * Construct a new Indexed Database store, which extends MemoryStore. * diff --git a/src/store/memory.js b/src/store/memory.js index bf2e9cfd2..673fc15d6 100644 --- a/src/store/memory.js +++ b/src/store/memory.js @@ -22,7 +22,7 @@ limitations under the License. * @module store/memory */ -import {User} from "../models/user"; +import { User } from "../models/user"; import * as utils from "../utils"; function isValidFilterId(filterId) { diff --git a/src/store/session/webstorage.js b/src/store/session/webstorage.js index 0bdceb0e0..7dcd1339d 100644 --- a/src/store/session/webstorage.js +++ b/src/store/session/webstorage.js @@ -22,7 +22,7 @@ limitations under the License. */ import * as utils from "../../utils"; -import {logger} from '../../logger'; +import { logger } from '../../logger'; const DEBUG = false; // set true to enable console logging. const E2E_PREFIX = "session.e2e."; diff --git a/src/sync-accumulator.js b/src/sync-accumulator.js index a22de7e11..1f190538c 100644 --- a/src/sync-accumulator.js +++ b/src/sync-accumulator.js @@ -21,8 +21,8 @@ limitations under the License. * @module sync-accumulator */ -import {logger} from './logger'; -import {deepCopy} from "./utils"; +import { logger } from './logger'; +import { deepCopy } from "./utils"; /** * The purpose of this class is to accumulate /sync responses such that a diff --git a/src/sync.js b/src/sync.js index d48091091..bf4dcd323 100644 --- a/src/sync.js +++ b/src/sync.js @@ -26,15 +26,15 @@ limitations under the License. * for HTTP and WS at some point. */ -import {User} from "./models/user"; -import {Room} from "./models/room"; -import {Group} from "./models/group"; +import { User } from "./models/user"; +import { Room } from "./models/room"; +import { Group } from "./models/group"; import * as utils from "./utils"; -import {Filter} from "./filter"; -import {EventTimeline} from "./models/event-timeline"; -import {PushProcessor} from "./pushprocessor"; -import {logger} from './logger'; -import {InvalidStoreError} from './errors'; +import { Filter } from "./filter"; +import { EventTimeline } from "./models/event-timeline"; +import { PushProcessor } from "./pushprocessor"; +import { logger } from './logger'; +import { InvalidStoreError } from './errors'; const DEBUG = true; @@ -62,7 +62,6 @@ function debuglog(...params) { logger.log(...params); } - /** * Internal class - unstable. * Construct an entity which is able to sync with a homeserver. @@ -188,7 +187,6 @@ SyncApi.prototype._deregisterStateListeners = function(room) { room.currentState.removeAllListeners("RoomState.newMember"); }; - /** * Sync rooms the user has left. * @return {Promise} Resolved when they've been added to the store. @@ -1479,7 +1477,7 @@ SyncApi.prototype._processGroupSyncEntry = function(groupsSection, sectionName) ); } if (groupInfo.inviter) { - group.setInviter({userId: groupInfo.inviter}); + group.setInviter({ userId: groupInfo.inviter }); } group.setMyMembership(sectionName); if (isBrandNew) { diff --git a/src/timeline-window.js b/src/timeline-window.js index 50ca10729..0fc9f3ae4 100644 --- a/src/timeline-window.js +++ b/src/timeline-window.js @@ -17,8 +17,8 @@ limitations under the License. /** @module timeline-window */ -import {EventTimeline} from './models/event-timeline'; -import {logger} from './logger'; +import { EventTimeline } from './models/event-timeline'; +import { logger } from './logger'; /** * @private @@ -335,7 +335,6 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest, return prom; }; - /** * Remove `delta` events from the start or end of the timeline. * @@ -368,7 +367,6 @@ TimelineWindow.prototype.unpaginate = function(delta, startOfTimeline) { } }; - /** * Get a list of the events currently in the window * @@ -420,7 +418,6 @@ TimelineWindow.prototype.getEvents = function() { return result; }; - /** * a thing which contains a timeline reference, and an index into it. * diff --git a/src/utils.ts b/src/utils.ts index 17b3924cd..7c5700c5e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -729,7 +729,7 @@ export function defer() { reject = _reject; }); - return {resolve, reject, promise}; + return { resolve, reject, promise }; } export async function promiseMapSeries( diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index d84be56b7..090d5f74c 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -21,11 +21,11 @@ limitations under the License. * @module webrtc/call */ -import {logger} from '../logger'; -import {EventEmitter} from 'events'; +import { logger } from '../logger'; +import { EventEmitter } from 'events'; import * as utils from '../utils'; import MatrixEvent from '../models/event'; -import {EventType} from '../@types/event'; +import { EventType } from '../@types/event'; import { RoomMember } from '../models/room-member'; import { randomString } from '../randomstring'; import { @@ -37,7 +37,6 @@ import { } from './callEventTypes'; import { CallFeed } from './callFeed'; - // events: hangup, error(err), replaced(call), state(state, oldState) /** @@ -1705,7 +1704,7 @@ function getUserMediaContraints(type: ConstraintsType) { case ConstraintsType.Audio: { return { audio: { - deviceId: audioInput ? {ideal: audioInput} : undefined, + deviceId: audioInput ? { ideal: audioInput } : undefined, }, video: false, }; @@ -1713,9 +1712,9 @@ function getUserMediaContraints(type: ConstraintsType) { case ConstraintsType.Video: { return { audio: { - deviceId: audioInput ? {ideal: audioInput} : undefined, + deviceId: audioInput ? { ideal: audioInput } : undefined, }, video: { - deviceId: videoInput ? {ideal: videoInput} : undefined, + deviceId: videoInput ? { ideal: videoInput } : undefined, /* We want 640x360. Chrome will give it only if we ask exactly, FF refuses entirely if we ask exactly, so have to ask for ideal instead diff --git a/src/webrtc/callEventHandler.ts b/src/webrtc/callEventHandler.ts index 9c4c38b26..0d8b9f028 100644 --- a/src/webrtc/callEventHandler.ts +++ b/src/webrtc/callEventHandler.ts @@ -15,7 +15,7 @@ limitations under the License. */ import MatrixEvent from '../models/event'; -import {logger} from '../logger'; +import { logger } from '../logger'; import { createNewMatrixCall, MatrixCall, CallErrorCode, CallState, CallDirection } from './call'; import { EventType } from '../@types/event'; import { MatrixClient } from '../client'; diff --git a/src/webrtc/callFeed.ts b/src/webrtc/callFeed.ts index b0004639f..762fe63f8 100644 --- a/src/webrtc/callFeed.ts +++ b/src/webrtc/callFeed.ts @@ -15,9 +15,9 @@ limitations under the License. */ import EventEmitter from "events"; -import {SDPStreamMetadataPurpose} from "./callEventTypes"; +import { SDPStreamMetadataPurpose } from "./callEventTypes"; import MatrixClient from "../client" -import {RoomMember} from "../models/room-member"; +import { RoomMember } from "../models/room-member"; export enum CallFeedEvent { NewStream = "new_stream", From 52764045ce113712ba8d22f2e2a2fe8e894aca59 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 19 May 2021 14:29:50 +0100 Subject: [PATCH 02/19] Prepare changelog for v11.1.0-rc.1 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 466c840a9..d4e81f907 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +Changes in [11.1.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v11.1.0-rc.1) (2021-05-19) +============================================================================================================ +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v11.0.0...v11.1.0-rc.1) + + * Fix regressed glare + [\#1690](https://github.com/matrix-org/matrix-js-sdk/pull/1690) + * Add m.reaction to EventType enum + [\#1692](https://github.com/matrix-org/matrix-js-sdk/pull/1692) + * Prioritise and reduce the amount of events decrypted on application startup + [\#1684](https://github.com/matrix-org/matrix-js-sdk/pull/1684) + * Decrypt relations before applying them to target event + [\#1696](https://github.com/matrix-org/matrix-js-sdk/pull/1696) + * Guard against duplicates in `Relations` model + Changes in [11.0.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v11.0.0) (2021-05-17) ================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v11.0.0-rc.1...v11.0.0) From 65de184d882087717c067ee794ad6ea9cd18dc50 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 19 May 2021 14:29:51 +0100 Subject: [PATCH 03/19] v11.1.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e98615ba1..7869f7cf9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "11.0.0", + "version": "11.1.0-rc.1", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", @@ -28,7 +28,7 @@ "keywords": [ "matrix-org" ], - "main": "./src/index.ts", + "main": "./lib/index.js", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", @@ -108,5 +108,6 @@ "coverageReporters": [ "text" ] - } + }, + "typings": "./lib/index.d.ts" } From b6763ce89f4a031bd70fe2748b4e1adae9edf7f9 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 19 May 2021 15:45:21 +0100 Subject: [PATCH 04/19] Change call event handlers to adapt to undecrypted events --- src/client.js | 4 ++++ src/webrtc/callEventHandler.ts | 30 +++++------------------------- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/src/client.js b/src/client.js index d71aa6cb5..35493acfe 100644 --- a/src/client.js +++ b/src/client.js @@ -353,6 +353,10 @@ export function MatrixClient(opts) { if (call) { this._callEventHandler = new CallEventHandler(this); this._supportsVoip = true; + // Start listening for calls after the initial sync is done + // We do not need to backfill the call event buffer + // with encrypted events that might never get decrypted + this.once("sync", () => this._callEventHandler.start()); } else { this._callEventHandler = null; } diff --git a/src/webrtc/callEventHandler.ts b/src/webrtc/callEventHandler.ts index 44815ee63..822d223ab 100644 --- a/src/webrtc/callEventHandler.ts +++ b/src/webrtc/callEventHandler.ts @@ -43,6 +43,9 @@ export class CallEventHandler { // after loading and after we've been offline for a bit. this.callEventBuffer = []; this.candidateEventsByCall = new Map>(); + } + + public start() { this.client.on("sync", this.evaluateEventBuffer); this.client.on("event", this.onEvent); } @@ -87,39 +90,16 @@ export class CallEventHandler { } } - private onEvent = (event: MatrixEvent) => { - // any call events or ones that might be once they're decrypted - const isBeingDecrypted = event.isBeingDecrypted(); - const shouldAttemptDecryption = event.shouldAttemptDecryption(); + private onEvent = async (event: MatrixEvent) => { + await this.client.decryptEventIfNeeded(event); if ( event.getType().indexOf("m.call.") === 0 || event.getType().indexOf("org.matrix.call.") === 0 - || isBeingDecrypted || shouldAttemptDecryption ) { // queue up for processing once all events from this sync have been // processed (see above). this.callEventBuffer.push(event); } - - if (event.isDecryptionFailure() || isBeingDecrypted || shouldAttemptDecryption) { - // add an event listener for once the event is decrypted. - event.once("Event.decrypted", () => { - if (event.getType().indexOf("m.call.") === -1) return; - - if (this.callEventBuffer.includes(event)) { - // we were waiting for that event to decrypt, so recheck the buffer - this.evaluateEventBuffer(); - } else { - // This one wasn't buffered so just run the event handler for it - // straight away - try { - this.handleCallEvent(event); - } catch (e) { - logger.error("Caught exception handling call event", e); - } - } - }); - } } private handleCallEvent(event: MatrixEvent) { From 2a863025c6e0d859b6475c8e6340170c0bb27274 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 19 May 2021 17:05:20 +0100 Subject: [PATCH 05/19] listen to call event handlers when sync is prepared --- src/client.js | 8 +++++++- src/webrtc/callEventHandler.ts | 35 +++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/client.js b/src/client.js index 35493acfe..74ac0d2c1 100644 --- a/src/client.js +++ b/src/client.js @@ -356,7 +356,13 @@ export function MatrixClient(opts) { // Start listening for calls after the initial sync is done // We do not need to backfill the call event buffer // with encrypted events that might never get decrypted - this.once("sync", () => this._callEventHandler.start()); + function startCallEventHandler() { + if (this.isInitialSyncComplete()) { + this._callEventHandler.start(); + this.off("sync", startCallEventHandler); + } + } + this.on("sync", startCallEventHandler); } else { this._callEventHandler = null; } diff --git a/src/webrtc/callEventHandler.ts b/src/webrtc/callEventHandler.ts index 822d223ab..c6396bed7 100644 --- a/src/webrtc/callEventHandler.ts +++ b/src/webrtc/callEventHandler.ts @@ -55,12 +55,11 @@ export class CallEventHandler { this.client.removeListener("event", this.onEvent); } - private evaluateEventBuffer = () => { + private evaluateEventBuffer = async () => { if (this.client.getSyncState() === "SYNCING") { - // don't process any events until they are all decrypted - if (this.callEventBuffer.some((e) => { - return e.isBeingDecrypted() || e.shouldAttemptDecryption() - })) return; + await Promise.all(this.callEventBuffer.map(event => { + this.client.decryptEventIfNeeded(event); + })); const ignoreCallIds = new Set(); // inspect the buffer and mark all calls which have been answered @@ -90,16 +89,38 @@ export class CallEventHandler { } } - private onEvent = async (event: MatrixEvent) => { - await this.client.decryptEventIfNeeded(event); + private onEvent = (event: MatrixEvent) => { + this.client.decryptEventIfNeeded(event); + // any call events or ones that might be once they're decrypted if ( event.getType().indexOf("m.call.") === 0 || event.getType().indexOf("org.matrix.call.") === 0 + || event.isBeingDecrypted() ) { // queue up for processing once all events from this sync have been // processed (see above). this.callEventBuffer.push(event); } + + if (event.isBeingDecrypted() || event.isDecryptionFailure()) { + // add an event listener for once the event is decrypted. + event.once("Event.decrypted", () => { + if (event.getType().indexOf("m.call.") === -1) return; + + if (this.callEventBuffer.includes(event)) { + // we were waiting for that event to decrypt, so recheck the buffer + this.evaluateEventBuffer(); + } else { + // This one wasn't buffered so just run the event handler for it + // straight away + try { + this.handleCallEvent(event); + } catch (e) { + logger.error("Caught exception handling call event", e); + } + } + }); + } } private handleCallEvent(event: MatrixEvent) { From 155113b75db76703d2ce38589fd79522ae3e76b2 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 19 May 2021 17:15:44 +0100 Subject: [PATCH 06/19] move startEventCallHandler to MatrixClient prototype --- src/client.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/client.js b/src/client.js index 74ac0d2c1..f1074f5b9 100644 --- a/src/client.js +++ b/src/client.js @@ -356,13 +356,7 @@ export function MatrixClient(opts) { // Start listening for calls after the initial sync is done // We do not need to backfill the call event buffer // with encrypted events that might never get decrypted - function startCallEventHandler() { - if (this.isInitialSyncComplete()) { - this._callEventHandler.start(); - this.off("sync", startCallEventHandler); - } - } - this.on("sync", startCallEventHandler); + this.on("sync", this._startCallEventHandler); } else { this._callEventHandler = null; } @@ -4996,6 +4990,13 @@ MatrixClient.prototype.getOpenIdToken = function() { // VoIP operations // =============== +MatrixClient.prototype._startCallEventHandler = function() { + if (this.isInitialSyncComplete()) { + this._callEventHandler.start(); + this.off("sync", this._startCallEventHandler); + } +}; + /** * @param {module:client.callback} callback Optional. * @return {Promise} Resolves: TODO From f17cd142d571c56e0b0c16042bc6d7c161426273 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 20 May 2021 15:43:22 +0100 Subject: [PATCH 07/19] Fix uploadContent not rejecting promise when http status code >= 400 --- src/http-api.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/http-api.js b/src/http-api.js index 26b3d5f5b..1a90b0045 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -790,6 +790,8 @@ const requestCallback = function( userDefinedCallback = userDefinedCallback || function() {}; return function(err, response, body) { + const httpStatus = response.status || response.statusCode; // XMLHttpRequest vs http.IncomingMessage + if (err) { // the unit tests use matrix-mock-request, which throw the string "aborted" when aborting a request. // See https://github.com/matrix-org/matrix-mock-request/blob/3276d0263a561b5b8326b47bae720578a2c7473a/src/index.js#L48 @@ -803,7 +805,7 @@ const requestCallback = function( } if (!err) { try { - if (response.statusCode >= 400) { + if (httpStatus >= 400) { err = parseErrorResponse(response, body); } else if (bodyParser) { body = bodyParser(body); @@ -818,7 +820,7 @@ const requestCallback = function( userDefinedCallback(err); } else { const res = { - code: response.statusCode, + code: httpStatus, // XXX: why do we bother with this? it doesn't work for // XMLHttpRequest, so clearly we don't use it. @@ -842,7 +844,7 @@ const requestCallback = function( * @returns {Error} */ function parseErrorResponse(response, body) { - const httpStatus = response.statusCode; + const httpStatus = response.status || response.statusCode; // XMLHttpRequest vs http.IncomingMessage const contentType = getResponseContentType(response); let err; From e8367ad24168eb237f85f61dc7884e7883aa4ab9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 20 May 2021 18:33:17 +0100 Subject: [PATCH 08/19] fix httpStatus being resolved when response is undefined --- src/http-api.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/http-api.js b/src/http-api.js index 1a90b0045..dfa0c8c57 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -790,8 +790,6 @@ const requestCallback = function( userDefinedCallback = userDefinedCallback || function() {}; return function(err, response, body) { - const httpStatus = response.status || response.statusCode; // XMLHttpRequest vs http.IncomingMessage - if (err) { // the unit tests use matrix-mock-request, which throw the string "aborted" when aborting a request. // See https://github.com/matrix-org/matrix-mock-request/blob/3276d0263a561b5b8326b47bae720578a2c7473a/src/index.js#L48 @@ -805,6 +803,7 @@ const requestCallback = function( } if (!err) { try { + const httpStatus = response.status || response.statusCode; // XMLHttpRequest vs http.IncomingMessage if (httpStatus >= 400) { err = parseErrorResponse(response, body); } else if (bodyParser) { @@ -820,7 +819,7 @@ const requestCallback = function( userDefinedCallback(err); } else { const res = { - code: httpStatus, + code: response.status || response.statusCode, // XMLHttpRequest vs http.IncomingMessage // XXX: why do we bother with this? it doesn't work for // XMLHttpRequest, so clearly we don't use it. From 56a2eeac7721664270d585225a279c757e7fb217 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 21 May 2021 16:04:54 -0400 Subject: [PATCH 09/19] Bump libolm version and update package name. --- package.json | 2 +- src/@types/global.d.ts | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e98615ba1..4b89b738f 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "jest-localstorage-mock": "^2.4.6", "jsdoc": "^3.6.6", "matrix-mock-request": "^1.2.3", - "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz", + "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz", "rimraf": "^3.0.2", "terser": "^5.5.1", "tsify": "^5.0.2", diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index dd437247a..337768428 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -15,7 +15,7 @@ limitations under the License. */ // this is needed to tell TS about global.Olm -import * as Olm from "olm"; // eslint-disable-line @typescript-eslint/no-unused-vars +import * as Olm from "@matrix-org/olm"; // eslint-disable-line @typescript-eslint/no-unused-vars export {}; diff --git a/yarn.lock b/yarn.lock index 9e97396d6..1d2ddf004 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1130,6 +1130,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz": + version "3.2.2" + resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz#5e3d784461ca3bbeb791ac8f3c175375aeb81318" + "@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": version "2.1.8-no-fsevents" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz#da7c3996b8e6e19ebd14d82eaced2313e7769f9b" @@ -5142,10 +5146,6 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -"olm@https://packages.matrix.org/npm/olm/olm-3.2.1.tgz": - version "3.2.1" - resolved "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz#d623d76f99c3518dde68be8c86618d68bc7b004a" - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" From 9e30c4f7dd89a050fe128fe1ef09831778bc7827 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 21 May 2021 16:28:37 -0400 Subject: [PATCH 10/19] update test too --- spec/olm-loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/olm-loader.js b/spec/olm-loader.js index 49d7abac0..2b806ec2c 100644 --- a/spec/olm-loader.js +++ b/spec/olm-loader.js @@ -20,7 +20,7 @@ import * as utils from "../src/utils"; // try to load the olm library. try { - global.Olm = require('olm'); + global.Olm = require('@matrix-org/olm'); logger.log('loaded libolm'); } catch (e) { logger.warn("unable to run crypto tests: libolm not available"); From 095f6569986b4ae3a5126d676d976f9cfad60c06 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 24 May 2021 11:10:52 -0400 Subject: [PATCH 11/19] bump olm to 3.2.3 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 4b89b738f..ba08563fb 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "jest-localstorage-mock": "^2.4.6", "jsdoc": "^3.6.6", "matrix-mock-request": "^1.2.3", - "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz", + "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz", "rimraf": "^3.0.2", "terser": "^5.5.1", "tsify": "^5.0.2", diff --git a/yarn.lock b/yarn.lock index 1d2ddf004..f48a13d6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1130,9 +1130,9 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz": - version "3.2.2" - resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz#5e3d784461ca3bbeb791ac8f3c175375aeb81318" +"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz": + version "3.2.3" + resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz#cc332fdd25c08ef0e40f4d33fc3f822a0f98b6f4" "@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": version "2.1.8-no-fsevents" From 6711ab5f9a8d86636ca2a262b598a9c5213150af Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 21 May 2021 16:04:54 -0400 Subject: [PATCH 12/19] Bump libolm version and update package name. --- package.json | 2 +- src/@types/global.d.ts | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 7869f7cf9..caba5c34e 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "jest-localstorage-mock": "^2.4.6", "jsdoc": "^3.6.6", "matrix-mock-request": "^1.2.3", - "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz", + "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz", "rimraf": "^3.0.2", "terser": "^5.5.1", "tsify": "^5.0.2", diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index dd437247a..337768428 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -15,7 +15,7 @@ limitations under the License. */ // this is needed to tell TS about global.Olm -import * as Olm from "olm"; // eslint-disable-line @typescript-eslint/no-unused-vars +import * as Olm from "@matrix-org/olm"; // eslint-disable-line @typescript-eslint/no-unused-vars export {}; diff --git a/yarn.lock b/yarn.lock index 9e97396d6..1d2ddf004 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1130,6 +1130,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz": + version "3.2.2" + resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz#5e3d784461ca3bbeb791ac8f3c175375aeb81318" + "@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": version "2.1.8-no-fsevents" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz#da7c3996b8e6e19ebd14d82eaced2313e7769f9b" @@ -5142,10 +5146,6 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -"olm@https://packages.matrix.org/npm/olm/olm-3.2.1.tgz": - version "3.2.1" - resolved "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz#d623d76f99c3518dde68be8c86618d68bc7b004a" - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" From 498109bd53351bc9aaf84f6601558f2a577c4cc5 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 21 May 2021 16:28:37 -0400 Subject: [PATCH 13/19] update test too --- spec/olm-loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/olm-loader.js b/spec/olm-loader.js index 49d7abac0..2b806ec2c 100644 --- a/spec/olm-loader.js +++ b/spec/olm-loader.js @@ -20,7 +20,7 @@ import * as utils from "../src/utils"; // try to load the olm library. try { - global.Olm = require('olm'); + global.Olm = require('@matrix-org/olm'); logger.log('loaded libolm'); } catch (e) { logger.warn("unable to run crypto tests: libolm not available"); From 66fb21bd0b355c12758d52fdd3292fdd0013f933 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 24 May 2021 11:10:52 -0400 Subject: [PATCH 14/19] bump olm to 3.2.3 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index caba5c34e..31357c555 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "jest-localstorage-mock": "^2.4.6", "jsdoc": "^3.6.6", "matrix-mock-request": "^1.2.3", - "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz", + "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz", "rimraf": "^3.0.2", "terser": "^5.5.1", "tsify": "^5.0.2", diff --git a/yarn.lock b/yarn.lock index 1d2ddf004..f48a13d6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1130,9 +1130,9 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz": - version "3.2.2" - resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.2.tgz#5e3d784461ca3bbeb791ac8f3c175375aeb81318" +"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz": + version "3.2.3" + resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz#cc332fdd25c08ef0e40f4d33fc3f822a0f98b6f4" "@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": version "2.1.8-no-fsevents" From c26b571b1c29d41372c6844f5e101cfddac8b09c Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 24 May 2021 17:09:08 +0100 Subject: [PATCH 15/19] Prepare changelog for v11.1.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4e81f907..1af3ede1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +Changes in [11.1.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v11.1.0) (2021-05-24) +================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v11.1.0-rc.1...v11.1.0) + + * [Release] Bump libolm version and update package name + [\#1707](https://github.com/matrix-org/matrix-js-sdk/pull/1707) + * [Release] Change call event handlers to adapt to undecrypted events + [\#1699](https://github.com/matrix-org/matrix-js-sdk/pull/1699) + Changes in [11.1.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v11.1.0-rc.1) (2021-05-19) ============================================================================================================ [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v11.0.0...v11.1.0-rc.1) From c706618229a47e51f9415596703d55f320fc3b4c Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 24 May 2021 17:09:09 +0100 Subject: [PATCH 16/19] v11.1.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 31357c555..3a02807b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "11.1.0-rc.1", + "version": "11.1.0", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", @@ -72,6 +72,7 @@ "@babel/preset-env": "^7.12.11", "@babel/preset-typescript": "^7.12.7", "@babel/register": "^7.12.10", + "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz", "@types/jest": "^26.0.20", "@types/node": "12", "@types/request": "^2.48.5", @@ -91,7 +92,6 @@ "jest-localstorage-mock": "^2.4.6", "jsdoc": "^3.6.6", "matrix-mock-request": "^1.2.3", - "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz", "rimraf": "^3.0.2", "terser": "^5.5.1", "tsify": "^5.0.2", From acb9bc8cc5234326a7583514a8e120a4ac42eedc Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 24 May 2021 17:14:02 +0100 Subject: [PATCH 17/19] Resetting package fields for development --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3a02807b2..3a2320efd 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "keywords": [ "matrix-org" ], - "main": "./lib/index.js", + "main": "./src/index.ts", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", @@ -108,6 +108,5 @@ "coverageReporters": [ "text" ] - }, - "typings": "./lib/index.d.ts" + } } From 270be2df7a7a4ee63ab9e486f61ca41f8431341a Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 26 May 2021 16:35:49 +0100 Subject: [PATCH 18/19] Emit relations created when target event added later This changes the "relations created" event to ensure it is properly emitted even if the target event is added to the timeline after the relation event. There was perhaps always a risk of this happening in the past, but is seems more likely to bite now with delayed decryption. Part of https://github.com/vector-im/element-web/issues/17461 --- spec/unit/relations.spec.ts | 60 ++++++++++++++++++++++++++++++++ src/models/event-timeline-set.js | 20 +++-------- src/models/relations.js | 23 ++++++++++++ 3 files changed, 87 insertions(+), 16 deletions(-) diff --git a/spec/unit/relations.spec.ts b/spec/unit/relations.spec.ts index 0e561c856..3be34f332 100644 --- a/spec/unit/relations.spec.ts +++ b/spec/unit/relations.spec.ts @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { EventTimelineSet } from "../../src/models/event-timeline-set"; import { MatrixEvent } from "../../src/models/event"; import { Relations } from "../../src/models/relations"; @@ -70,4 +71,63 @@ describe("Relations", function() { expect(events.size).toEqual(1); } }); + + it("should emit created regardless of ordering", async function () { + const targetEvent = new MatrixEvent({ + "sender": "@bob:example.com", + "type": "m.room.message", + "event_id": "$2s4yYpEkVQrPglSCSqB_m6E8vDhWsg0yFNyOJdVIb_o", + "room_id": "!pzVjCQSoQPpXQeHpmK:example.com", + "content": {}, + }); + const relationEvent = new MatrixEvent({ + "sender": "@bob:example.com", + "type": "m.reaction", + "event_id": "$cZ1biX33ENJqIm00ks0W_hgiO_6CHrsAc3ZQrnLeNTw", + "room_id": "!pzVjCQSoQPpXQeHpmK:example.com", + "content": { + "m.relates_to": { + "event_id": "$2s4yYpEkVQrPglSCSqB_m6E8vDhWsg0yFNyOJdVIb_o", + "key": "👍️", + "rel_type": "m.annotation", + }, + }, + }); + + // Stub the room + const room = { + getPendingEvent() { return null; }, + getUnfilteredTimelineSet() { return null; }, + }; + + // Add the target event first, then the relation event + { + const relationsCreated = new Promise(resolve => { + targetEvent.once("Event.relationsCreated", resolve); + }) + + const timelineSet = new EventTimelineSet(room, { + unstableClientRelationAggregation: true, + }); + timelineSet.addLiveEvent(targetEvent); + timelineSet.addLiveEvent(relationEvent); + + await relationsCreated; + } + + // Add the relation event first, then the target event + { + const relationsCreated = new Promise(resolve => { + targetEvent.once("Event.relationsCreated", resolve); + }) + + const timelineSet = new EventTimelineSet(room, { + unstableClientRelationAggregation: true, + }); + timelineSet.addLiveEvent(relationEvent); + timelineSet.addLiveEvent(targetEvent); + + await relationsCreated; + } + }); }); diff --git a/src/models/event-timeline-set.js b/src/models/event-timeline-set.js index 784dea359..c24e3a79d 100644 --- a/src/models/event-timeline-set.js +++ b/src/models/event-timeline-set.js @@ -740,16 +740,11 @@ EventTimelineSet.prototype.setRelationsTarget = function(event) { if (!relationsForEvent) { return; } - // don't need it for non m.replace relations for now - const relationsWithRelType = relationsForEvent["m.replace"]; - if (!relationsWithRelType) { - return; - } - // only doing replacements for messages for now (e.g. edits) - const relationsWithEventType = relationsWithRelType["m.room.message"]; - if (relationsWithEventType) { - relationsWithEventType.setTargetEvent(event); + for (const relationsWithRelType of Object.values(relationsForEvent)) { + for (const relationsWithEventType of Object.values(relationsWithRelType)) { + relationsWithEventType.setTargetEvent(event); + } } }; @@ -797,7 +792,6 @@ EventTimelineSet.prototype.aggregateRelations = function(event) { } let relationsWithEventType = relationsWithRelType[eventType]; - let isNewRelations = false; let relatesToEvent; if (!relationsWithEventType) { relationsWithEventType = relationsWithRelType[eventType] = new Relations( @@ -805,7 +799,6 @@ EventTimelineSet.prototype.aggregateRelations = function(event) { eventType, this.room, ); - isNewRelations = true; relatesToEvent = this.findEventById(relatesToEventId) || this.room.getPendingEvent(relatesToEventId); if (relatesToEvent) { relationsWithEventType.setTargetEvent(relatesToEvent); @@ -813,11 +806,6 @@ EventTimelineSet.prototype.aggregateRelations = function(event) { } relationsWithEventType.addEvent(event); - - // only emit once event has been added to relations - if (isNewRelations && relatesToEvent) { - relatesToEvent.emit("Event.relationsCreated", relationType, eventType); - } }; /** diff --git a/src/models/relations.js b/src/models/relations.js index 6be559af8..3ea0f3bb2 100644 --- a/src/models/relations.js +++ b/src/models/relations.js @@ -48,6 +48,7 @@ export class Relations extends EventEmitter { this._sortedAnnotationsByKey = []; this._targetEvent = null; this._room = room; + this._creationEmitted = false; } /** @@ -94,6 +95,8 @@ export class Relations extends EventEmitter { event.on("Event.beforeRedaction", this._onBeforeRedaction); this.emit("Relations.add", event); + + this._maybeEmitCreated(); } /** @@ -345,6 +348,7 @@ export class Relations extends EventEmitter { return; } this._targetEvent = event; + if (this.relationType === "m.replace") { const replacement = await this.getLastReplacement(); // this is the initial update, so only call it if we already have something @@ -353,5 +357,24 @@ export class Relations extends EventEmitter { this._targetEvent.makeReplaced(replacement); } } + + this._maybeEmitCreated(); + } + + _maybeEmitCreated() { + if (this._creationEmitted) { + return; + } + // Only emit we're "created" once we have a target event instance _and_ + // at least one related event. + if (!this._targetEvent || !this._relations.size) { + return; + } + this._creationEmitted = true; + this._targetEvent.emit( + "Event.relationsCreated", + this.relationType, + this.eventType, + ); } } From cb91c4292c4d6d906cae01c66f7acde579794f32 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 27 May 2021 16:00:12 +0100 Subject: [PATCH 19/19] Merge branch 'develop' into gsouquet/pr-review-linting-rules --- CHANGELOG.md | 54 ++++ package.json | 4 +- spec/integ/matrix-client-crypto.spec.js | 43 +-- spec/integ/megolm-integ.spec.js | 11 +- spec/olm-loader.js | 2 +- spec/test-utils.js | 23 +- spec/unit/utils.spec.js | 48 --- src/@types/event.ts | 10 +- src/@types/global.d.ts | 2 +- src/client.js | 55 +++- src/content-repo.js | 4 +- src/crypto/OutgoingRoomKeyRequestManager.js | 5 +- src/crypto/algorithms/megolm.js | 6 +- src/crypto/algorithms/olm.js | 2 +- src/crypto/index.js | 7 +- src/http-api.js | 7 +- src/index.ts | 1 - src/models/event-timeline-set.js | 24 +- src/models/event.js | 32 +- src/models/relations.js | 59 +++- src/models/room-member.js | 9 +- src/models/room-state.js | 14 +- src/models/room.js | 110 +++++-- src/models/search-result.js | 7 +- src/scheduler.js | 28 +- src/store/memory.js | 11 +- src/sync.js | 43 +-- src/utils.ts | 331 +------------------- src/webrtc/call.ts | 8 +- src/webrtc/callEventHandler.ts | 11 +- yarn.lock | 8 +- 31 files changed, 421 insertions(+), 558 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5dc8a32f..1af3ede1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,57 @@ +Changes in [11.1.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v11.1.0) (2021-05-24) +================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v11.1.0-rc.1...v11.1.0) + + * [Release] Bump libolm version and update package name + [\#1707](https://github.com/matrix-org/matrix-js-sdk/pull/1707) + * [Release] Change call event handlers to adapt to undecrypted events + [\#1699](https://github.com/matrix-org/matrix-js-sdk/pull/1699) + +Changes in [11.1.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v11.1.0-rc.1) (2021-05-19) +============================================================================================================ +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v11.0.0...v11.1.0-rc.1) + + * Fix regressed glare + [\#1690](https://github.com/matrix-org/matrix-js-sdk/pull/1690) + * Add m.reaction to EventType enum + [\#1692](https://github.com/matrix-org/matrix-js-sdk/pull/1692) + * Prioritise and reduce the amount of events decrypted on application startup + [\#1684](https://github.com/matrix-org/matrix-js-sdk/pull/1684) + * Decrypt relations before applying them to target event + [\#1696](https://github.com/matrix-org/matrix-js-sdk/pull/1696) + * Guard against duplicates in `Relations` model + +Changes in [11.0.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v11.0.0) (2021-05-17) +================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v11.0.0-rc.1...v11.0.0) + + * [Release] Fix regressed glare + [\#1695](https://github.com/matrix-org/matrix-js-sdk/pull/1695) + +Changes in [11.0.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v11.0.0-rc.1) (2021-05-11) +============================================================================================================ +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v10.1.0...v11.0.0-rc.1) + +BREAKING CHANGES +--- + + * `MatrixCall` and related APIs have been redesigned to support multiple streams + (see [\#1660](https://github.com/matrix-org/matrix-js-sdk/pull/1660) for more details) + +All changes +--- + + * Switch from MSC1772 unstable prefixes to stable + [\#1679](https://github.com/matrix-org/matrix-js-sdk/pull/1679) + * Update the VoIP example to work with the new changes + [\#1680](https://github.com/matrix-org/matrix-js-sdk/pull/1680) + * Bump hosted-git-info from 2.8.8 to 2.8.9 + [\#1687](https://github.com/matrix-org/matrix-js-sdk/pull/1687) + * Support for multiple streams (not MSC3077) + [\#1660](https://github.com/matrix-org/matrix-js-sdk/pull/1660) + * Tweak missing m.room.create errors to describe their source + [\#1683](https://github.com/matrix-org/matrix-js-sdk/pull/1683) + Changes in [10.1.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v10.1.0) (2021-05-10) ================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v10.1.0-rc.1...v10.1.0) diff --git a/package.json b/package.json index d9ed10c73..3a2320efd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "10.1.0", + "version": "11.1.0", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", @@ -72,6 +72,7 @@ "@babel/preset-env": "^7.12.11", "@babel/preset-typescript": "^7.12.7", "@babel/register": "^7.12.10", + "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz", "@types/jest": "^26.0.20", "@types/node": "12", "@types/request": "^2.48.5", @@ -91,7 +92,6 @@ "jest-localstorage-mock": "^2.4.6", "jsdoc": "^3.6.6", "matrix-mock-request": "^1.2.3", - "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz", "rimraf": "^3.0.2", "terser": "^5.5.1", "tsify": "^5.0.2", diff --git a/spec/integ/matrix-client-crypto.spec.js b/spec/integ/matrix-client-crypto.spec.js index be9d725a8..c86e0e60e 100644 --- a/spec/integ/matrix-client-crypto.spec.js +++ b/spec/integ/matrix-client-crypto.spec.js @@ -28,11 +28,10 @@ limitations under the License. // load olm before the sdk if possible import '../olm-loader'; -import { logger } from '../../src/logger'; +import {logger} from '../../src/logger'; import * as testUtils from "../test-utils"; -import * as utils from "../../src/utils"; -import { TestClient } from "../TestClient"; -import { CRYPTO_ENABLED } from "../../src/client"; +import {TestClient} from "../TestClient"; +import {CRYPTO_ENABLED} from "../../src/client"; let aliTestClient; const roomId = "!room:localhost"; @@ -76,7 +75,7 @@ function expectAliQueryKeys() { ); const result = {}; result[bobUserId] = bobKeys; - return { device_keys: result }; + return {device_keys: result}; }); return aliTestClient.httpBackend.flush("/keys/query", 1); } @@ -104,7 +103,7 @@ function expectBobQueryKeys() { ); const result = {}; result[aliUserId] = aliKeys; - return { device_keys: result }; + return {device_keys: result}; }); return bobTestClient.httpBackend.flush("/keys/query", 1); } @@ -133,7 +132,7 @@ function expectAliClaimKeys() { result[bobUserId] = {}; result[bobUserId][bobDeviceId] = {}; result[bobUserId][bobDeviceId][keyId] = keys[keyId]; - return { one_time_keys: result }; + return {one_time_keys: result}; }); }).then(() => { // it can take a while to process the key query, so give it some extra @@ -145,6 +144,7 @@ function expectAliClaimKeys() { }); } + function aliDownloadsKeys() { // can't query keys before bob has uploaded them expect(bobTestClient.getSigningKey()).toBeTruthy(); @@ -243,7 +243,7 @@ function bobSendsReplyMessage() { function expectAliSendMessageRequest() { return expectSendMessageRequest(aliTestClient.httpBackend).then(function(content) { aliMessages.push(content); - expect(utils.keys(content.ciphertext)).toEqual([bobTestClient.getDeviceKey()]); + expect(Object.keys(content.ciphertext)).toEqual([bobTestClient.getDeviceKey()]); const ciphertext = content.ciphertext[bobTestClient.getDeviceKey()]; expect(ciphertext).toBeTruthy(); return ciphertext; @@ -260,7 +260,7 @@ function expectBobSendMessageRequest() { bobMessages.push(content); const aliKeyId = "curve25519:" + aliDeviceId; const aliDeviceCurve25519Key = aliTestClient.deviceKeys.keys[aliKeyId]; - expect(utils.keys(content.ciphertext)).toEqual([aliDeviceCurve25519Key]); + expect(Object.keys(content.ciphertext)).toEqual([aliDeviceCurve25519Key]); const ciphertext = content.ciphertext[aliDeviceCurve25519Key]; expect(ciphertext).toBeTruthy(); return ciphertext; @@ -269,7 +269,7 @@ function expectBobSendMessageRequest() { function sendMessage(client) { return client.sendMessage( - roomId, { msgtype: "m.text", body: "Hello, World" }, + roomId, {msgtype: "m.text", body: "Hello, World"}, ); } @@ -357,6 +357,7 @@ function recvMessage(httpBackend, client, sender, message) { }); } + /** * Send an initial sync response to the client (which just includes the member * list for our test room). @@ -394,6 +395,7 @@ function firstSync(testClient) { return testClient.flushSync(); } + describe("MatrixClient crypto", function() { if (!CRYPTO_ENABLED) { return; @@ -475,7 +477,7 @@ describe("MatrixClient crypto", function() { ).respond(200, function(path, content) { const result = {}; result[bobUserId] = bobKeys; - return { device_keys: result }; + return {device_keys: result}; }); return Promise.all([ @@ -517,7 +519,7 @@ describe("MatrixClient crypto", function() { ).respond(200, function(path, content) { const result = {}; result[bobUserId] = bobKeys; - return { device_keys: result }; + return {device_keys: result}; }); return Promise.all([ @@ -531,6 +533,7 @@ describe("MatrixClient crypto", function() { }); }); + it("Bob starts his client and uploads device keys and one-time keys", function() { return Promise.resolve() .then(() => bobTestClient.start()) @@ -542,7 +545,7 @@ describe("MatrixClient crypto", function() { }); it("Ali sends a message", function() { - aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); + aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -552,7 +555,7 @@ describe("MatrixClient crypto", function() { }); it("Bob receives a message", function() { - aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); + aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -563,7 +566,7 @@ describe("MatrixClient crypto", function() { }); it("Bob receives a message with a bogus sender", function() { - aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); + aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -617,7 +620,7 @@ describe("MatrixClient crypto", function() { }); it("Ali blocks Bob's device", function() { - aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); + aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -637,7 +640,7 @@ describe("MatrixClient crypto", function() { }); it("Bob receives two pre-key messages", function() { - aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); + aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -650,8 +653,8 @@ describe("MatrixClient crypto", function() { }); it("Bob replies to the message", function() { - aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); - bobTestClient.expectKeyQuery({ device_keys: { [bobUserId]: {} } }); + aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); + bobTestClient.expectKeyQuery({device_keys: {[bobUserId]: {}}}); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => bobTestClient.start()) @@ -669,7 +672,7 @@ describe("MatrixClient crypto", function() { it("Ali does a key query when encryption is enabled", function() { // enabling encryption in the room should make alice download devices // for both members. - aliTestClient.expectKeyQuery({ device_keys: { [aliUserId]: {} } }); + aliTestClient.expectKeyQuery({device_keys: {[aliUserId]: {}}}); return Promise.resolve() .then(() => aliTestClient.start()) .then(() => firstSync(aliTestClient)) diff --git a/spec/integ/megolm-integ.spec.js b/spec/integ/megolm-integ.spec.js index 6edbcc49e..8461bc385 100644 --- a/spec/integ/megolm-integ.spec.js +++ b/spec/integ/megolm-integ.spec.js @@ -16,7 +16,6 @@ limitations under the License. */ import anotherjson from "another-json"; -import * as utils from "../../src/utils"; import * as testUtils from "../test-utils"; import { TestClient } from "../TestClient"; import { logger } from "../../src/logger"; @@ -32,7 +31,7 @@ const ROOM_ID = "!room:id"; */ function createOlmSession(olmAccount, recipientTestClient) { return recipientTestClient.awaitOneTimeKeyUpload().then((keys) => { - const otkId = utils.keys(keys)[0]; + const otkId = Object.keys(keys)[0]; const otk = keys[otkId]; const session = new global.Olm.Session(); @@ -256,7 +255,7 @@ describe("megolm", function() { const testOneTimeKeys = JSON.parse(testOlmAccount.one_time_keys()); testOlmAccount.mark_keys_as_published(); - const keyId = utils.keys(testOneTimeKeys.curve25519)[0]; + const keyId = Object.keys(testOneTimeKeys.curve25519)[0]; const oneTimeKey = testOneTimeKeys.curve25519[keyId]; const keyResult = { 'key': oneTimeKey, @@ -483,8 +482,9 @@ describe("megolm", function() { return aliceTestClient.flushSync().then(() => { return aliceTestClient.flushSync(); }); - }).then(function() { + }).then(async function() { const room = aliceTestClient.client.getRoom(ROOM_ID); + await room.decryptCriticalEvents(); const event = room.getLiveTimeline().getEvents()[0]; expect(event.getContent().body).toEqual('42'); }); @@ -930,8 +930,9 @@ describe("megolm", function() { aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse); return aliceTestClient.flushSync(); - }).then(function() { + }).then(async function() { const room = aliceTestClient.client.getRoom(ROOM_ID); + await room.decryptCriticalEvents(); const event = room.getLiveTimeline().getEvents()[0]; expect(event.getContent().body).toEqual('42'); diff --git a/spec/olm-loader.js b/spec/olm-loader.js index 639a97b9e..505c08615 100644 --- a/spec/olm-loader.js +++ b/spec/olm-loader.js @@ -20,7 +20,7 @@ import * as utils from "../src/utils"; // try to load the olm library. try { - global.Olm = require('olm'); + global.Olm = require('@matrix-org/olm'); logger.log('loaded libolm'); } catch (e) { logger.warn("unable to run crypto tests: libolm not available"); diff --git a/spec/test-utils.js b/spec/test-utils.js index 6c7679432..d308b6d35 100644 --- a/spec/test-utils.js +++ b/spec/test-utils.js @@ -210,18 +210,21 @@ MockStorageApi.prototype = { * @returns {Promise} promise which resolves (to `event`) when the event has been decrypted */ export function awaitDecryption(event) { - if (!event.isBeingDecrypted()) { - return Promise.resolve(event); - } + // An event is not always decrypted ahead of time + // getClearContent is a good signal to know whether an event has been decrypted + // already + if (event.getClearContent() !== null) { + return event; + } else { + logger.log(`${Date.now()} event ${event.getId()} is being decrypted; waiting`); - logger.log(`${Date.now()} event ${event.getId()} is being decrypted; waiting`); - - return new Promise((resolve, reject) => { - event.once('Event.decrypted', (ev) => { - logger.log(`${Date.now()} event ${event.getId()} now decrypted`); - resolve(ev); + return new Promise((resolve, reject) => { + event.once('Event.decrypted', (ev) => { + logger.log(`${Date.now()} event ${event.getId()} now decrypted`); + resolve(ev); + }); }); - }); + } } export function HttpResponse( diff --git a/spec/unit/utils.spec.js b/spec/unit/utils.spec.js index 62201f06d..703326f46 100644 --- a/spec/unit/utils.spec.js +++ b/spec/unit/utils.spec.js @@ -26,40 +26,6 @@ describe("utils", function() { }); }); - describe("forEach", function() { - it("should be invoked for each element", function() { - const arr = []; - utils.forEach([55, 66, 77], function(element) { - arr.push(element); - }); - expect(arr).toEqual([55, 66, 77]); - }); - }); - - describe("findElement", function() { - it("should find only 1 element if there is a match", function() { - const matchFn = function() { - return true; - }; - const arr = [55, 66, 77]; - expect(utils.findElement(arr, matchFn)).toEqual(55); - }); - it("should be able to find in reverse order", function() { - const matchFn = function() { - return true; - }; - const arr = [55, 66, 77]; - expect(utils.findElement(arr, matchFn, true)).toEqual(77); - }); - it("should find nothing if the function never returns true", function() { - const matchFn = function() { - return false; - }; - const arr = [55, 66, 77]; - expect(utils.findElement(arr, matchFn)).toBeFalsy(); - }); - }); - describe("removeElement", function() { it("should remove only 1 element if there is a match", function() { const matchFn = function() { @@ -103,20 +69,6 @@ describe("utils", function() { }); }); - describe("isArray", function() { - it("should return true for arrays", function() { - expect(utils.isArray([])).toBe(true); - expect(utils.isArray([5, 3, 7])).toBe(true); - - expect(utils.isArray()).toBe(false); - expect(utils.isArray(null)).toBe(false); - expect(utils.isArray({})).toBe(false); - expect(utils.isArray("foo")).toBe(false); - expect(utils.isArray(555)).toBe(false); - expect(utils.isArray(function() {})).toBe(false); - }); - }); - describe("checkObjectHasKeys", function() { it("should throw for missing keys", function() { expect(function() { diff --git a/src/@types/event.ts b/src/@types/event.ts index a908088d7..3c905442b 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -36,9 +36,8 @@ export enum EventType { */ RoomAliases = "m.room.aliases", // deprecated https://matrix.org/docs/spec/client_server/r0.6.1#historical-events - // Spaces MSC1772 - SpaceChild = "org.matrix.msc1772.space.child", - SpaceParent = "org.matrix.msc1772.space.parent", + SpaceChild = "m.space.child", + SpaceParent = "m.space.parent", // Room timeline events RoomRedaction = "m.room.redaction", @@ -62,6 +61,7 @@ export enum EventType { KeyVerificationDone = "m.key.verification.done", // use of this is discouraged https://matrix.org/docs/spec/client_server/r0.6.1#m-room-message-feedback RoomMessageFeedback = "m.room.message.feedback", + Reaction = "m.reaction", // Room ephemeral events Typing = "m.typing", @@ -95,8 +95,8 @@ export enum MsgType { Video = "m.video", } -export const RoomCreateTypeField = "org.matrix.msc1772.type"; // Spaces MSC1772 +export const RoomCreateTypeField = "type"; export enum RoomType { - Space = "org.matrix.msc1772.space", // Spaces MSC1772 + Space = "m.space", } diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index dd437247a..337768428 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -15,7 +15,7 @@ limitations under the License. */ // this is needed to tell TS about global.Olm -import * as Olm from "olm"; // eslint-disable-line @typescript-eslint/no-unused-vars +import * as Olm from "@matrix-org/olm"; // eslint-disable-line @typescript-eslint/no-unused-vars export {}; diff --git a/src/client.js b/src/client.js index c3ec7710d..cb60705ef 100644 --- a/src/client.js +++ b/src/client.js @@ -352,6 +352,10 @@ export function MatrixClient(opts) { if (call) { this._callEventHandler = new CallEventHandler(this); this._supportsVoip = true; + // Start listening for calls after the initial sync is done + // We do not need to backfill the call event buffer + // with encrypted events that might never get decrypted + this.on("sync", this._startCallEventHandler); } else { this._callEventHandler = null; } @@ -3971,9 +3975,9 @@ MatrixClient.prototype.scrollback = function(room, limit, callback) { limit, 'b'); }).then(function(res) { - const matrixEvents = utils.map(res.chunk, _PojoToMatrixEventMapper(self)); + const matrixEvents = res.chunk.map(_PojoToMatrixEventMapper(self)); if (res.state) { - const stateEvents = utils.map(res.state, _PojoToMatrixEventMapper(self)); + const stateEvents = res.state.map(_PojoToMatrixEventMapper(self)); room.currentState.setUnknownStateEvents(stateEvents); } room.addEventsToTimeline(matrixEvents, true, room.getLiveTimeline()); @@ -4062,16 +4066,16 @@ MatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) { const events = res.events_after .concat([res.event]) .concat(res.events_before); - const matrixEvents = utils.map(events, self.getEventMapper()); + const matrixEvents = events.map(self.getEventMapper()); let timeline = timelineSet.getTimelineForEvent(matrixEvents[0].getId()); if (!timeline) { timeline = timelineSet.addTimeline(); - timeline.initialiseState(utils.map(res.state, + timeline.initialiseState(res.state.map( self.getEventMapper())); timeline.getState(EventTimeline.FORWARDS).paginationToken = res.end; } else { - const stateEvents = utils.map(res.state, self.getEventMapper()); + const stateEvents = res.state.map(self.getEventMapper()); timeline.getState(EventTimeline.BACKWARDS).setUnknownStateEvents(stateEvents); } timelineSet.addEventsToTimeline(matrixEvents, true, timeline, res.start); @@ -4234,11 +4238,11 @@ MatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) { promise.then(function(res) { if (res.state) { const roomState = eventTimeline.getState(dir); - const stateEvents = utils.map(res.state, self.getEventMapper()); + const stateEvents = res.state.map(self.getEventMapper()); roomState.setUnknownStateEvents(stateEvents); } const token = res.end; - const matrixEvents = utils.map(res.chunk, self.getEventMapper()); + const matrixEvents = res.chunk.map(self.getEventMapper()); eventTimeline.getTimelineSet() .addEventsToTimeline(matrixEvents, backwards, eventTimeline, token); @@ -4977,6 +4981,13 @@ MatrixClient.prototype.getOpenIdToken = function() { // VoIP operations // =============== +MatrixClient.prototype._startCallEventHandler = function() { + if (this.isInitialSyncComplete()) { + this._callEventHandler.start(); + this.off("sync", this._startCallEventHandler); + } +}; + /** * @param {module:client.callback} callback Optional. * @return {Promise} Resolves: TODO @@ -5544,8 +5555,9 @@ function _resolve(callback, resolve, res) { resolve(res); } -function _PojoToMatrixEventMapper(client, options) { - const preventReEmit = Boolean(options && options.preventReEmit); +function _PojoToMatrixEventMapper(client, options = {}) { + const preventReEmit = Boolean(options.preventReEmit); + const decrypt = options.decrypt !== false; function mapper(plainOldJsObject) { const event = new MatrixEvent(plainOldJsObject); if (event.isEncrypted()) { @@ -5554,7 +5566,9 @@ function _PojoToMatrixEventMapper(client, options) { "Event.decrypted", ]); } - event.attemptDecryption(client._crypto); + if (decrypt) { + client.decryptEventIfNeeded(event); + } } if (!preventReEmit) { client.reEmitter.reEmit(event, ["Event.replaced"]); @@ -5567,6 +5581,7 @@ function _PojoToMatrixEventMapper(client, options) { /** * @param {object} [options] * @param {bool} options.preventReEmit don't reemit events emitted on an event mapped by this mapper on the client + * @param {bool} options.decrypt decrypt event proactively * @return {Function} */ MatrixClient.prototype.getEventMapper = function(options = undefined) { @@ -5594,6 +5609,26 @@ MatrixClient.prototype.generateClientSecret = function() { return randomString(32); }; +/** + * Attempts to decrypt an event + * @param {MatrixEvent} event The event to decrypt + * @returns {Promise} A decryption promise + * @param {object} options + * @param {bool} options.isRetry True if this is a retry (enables more logging) + * @param {bool} options.emit Emits "event.decrypted" if set to true + */ +MatrixClient.prototype.decryptEventIfNeeded = function(event, options) { + if (event.shouldAttemptDecryption()) { + event.attemptDecryption(this._crypto, options); + } + + if (event.isBeingDecrypted()) { + return event._decryptionPromise; + } else { + return Promise.resolve(); + } +}; + // MatrixClient Event JSDocs /** diff --git a/src/content-repo.js b/src/content-repo.js index 0d1ae1ea0..1b92d59ae 100644 --- a/src/content-repo.js +++ b/src/content-repo.js @@ -59,7 +59,7 @@ export function getHttpUriForMxc(baseUrl, mxc, width, height, if (resizeMethod) { params.method = resizeMethod; } - if (utils.keys(params).length > 0) { + if (Object.keys(params).length > 0) { // these are thumbnailing params so they probably want the // thumbnailing API... prefix = "/_matrix/media/r0/thumbnail/"; @@ -72,6 +72,6 @@ export function getHttpUriForMxc(baseUrl, mxc, width, height, serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); } return baseUrl + prefix + serverAndMediaId + - (utils.keys(params).length === 0 ? "" : + (Object.keys(params).length === 0 ? "" : ("?" + utils.encodeParams(params))) + fragment; } diff --git a/src/crypto/OutgoingRoomKeyRequestManager.js b/src/crypto/OutgoingRoomKeyRequestManager.js index 94bd45d23..899c3ca96 100644 --- a/src/crypto/OutgoingRoomKeyRequestManager.js +++ b/src/crypto/OutgoingRoomKeyRequestManager.js @@ -14,8 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { logger } from '../logger'; -import * as utils from '../utils'; +import {logger} from '../logger'; /** * Internal module. Management of outgoing room key requests. @@ -496,7 +495,7 @@ function stringifyRequestBody(requestBody) { function stringifyRecipientList(recipients) { return '[' - + utils.map(recipients, (r) => `${r.userId}:${r.deviceId}`).join(",") + + recipients.map((r) => `${r.userId}:${r.deviceId}`).join(",") + ']'; } diff --git a/src/crypto/algorithms/megolm.js b/src/crypto/algorithms/megolm.js index c4e987f0a..0d97b2450 100644 --- a/src/crypto/algorithms/megolm.js +++ b/src/crypto/algorithms/megolm.js @@ -1074,7 +1074,7 @@ MegolmEncryption.prototype._removeUnknownDevices = function(devicesInRoom) { */ MegolmEncryption.prototype._getDevicesInRoom = async function(room) { const members = await room.getEncryptionTargetMembers(); - const roomMembers = utils.map(members, function(u) { + const roomMembers = members.map(function(u) { return u.userId; }); @@ -1368,7 +1368,7 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) { if (event.getType() == "m.forwarded_room_key") { exportFormat = true; forwardingKeyChain = content.forwarding_curve25519_key_chain; - if (!utils.isArray(forwardingKeyChain)) { + if (!Array.isArray(forwardingKeyChain)) { forwardingKeyChain = []; } @@ -1689,7 +1689,7 @@ MegolmDecryption.prototype._retryDecryption = async function(senderKey, sessionI await Promise.all([...pending].map(async (ev) => { try { - await ev.attemptDecryption(this._crypto, true); + await ev.attemptDecryption(this._crypto, { isRetry: true }); } catch (e) { // don't die if something goes wrong } diff --git a/src/crypto/algorithms/olm.js b/src/crypto/algorithms/olm.js index 56c316e88..74444b75a 100644 --- a/src/crypto/algorithms/olm.js +++ b/src/crypto/algorithms/olm.js @@ -95,7 +95,7 @@ OlmEncryption.prototype.encryptMessage = async function(room, eventType, content const members = await room.getEncryptionTargetMembers(); - const users = utils.map(members, function(u) { + const users = members.map(function(u) { return u.userId; }); diff --git a/src/crypto/index.js b/src/crypto/index.js index be7896321..ae8de2af1 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -186,7 +186,7 @@ export function Crypto(baseApis, sessionStore, userId, deviceId, // map from algorithm to DecryptionAlgorithm instance, for each room this._roomDecryptors = {}; - this._supportedAlgorithms = utils.keys( + this._supportedAlgorithms = Object.keys( algorithms.DECRYPTION_CLASSES, ); @@ -3317,7 +3317,10 @@ Crypto.prototype._onToDeviceEvent = function(event) { this._onKeyVerificationMessage(event); } else if (event.getContent().msgtype === "m.bad.encrypted") { this._onToDeviceBadEncrypted(event); - } else if (event.isBeingDecrypted()) { + } else if (event.isBeingDecrypted() || event.shouldAttemptDecryption()) { + if (!event.isBeingDecrypted()) { + event.attemptDecryption(this); + } // once the event has been decrypted, try again event.once('Event.decrypted', (ev) => { this._onToDeviceEvent(ev); diff --git a/src/http-api.js b/src/http-api.js index d723e5b98..a48c165d0 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -803,7 +803,8 @@ const requestCallback = function( } if (!err) { try { - if (response.statusCode >= 400) { + const httpStatus = response.status || response.statusCode; // XMLHttpRequest vs http.IncomingMessage + if (httpStatus >= 400) { err = parseErrorResponse(response, body); } else if (bodyParser) { body = bodyParser(body); @@ -818,7 +819,7 @@ const requestCallback = function( userDefinedCallback(err); } else { const res = { - code: response.statusCode, + code: response.status || response.statusCode, // XMLHttpRequest vs http.IncomingMessage // XXX: why do we bother with this? it doesn't work for // XMLHttpRequest, so clearly we don't use it. @@ -842,7 +843,7 @@ const requestCallback = function( * @returns {Error} */ function parseErrorResponse(response, body) { - const httpStatus = response.statusCode; + const httpStatus = response.status || response.statusCode; // XMLHttpRequest vs http.IncomingMessage const contentType = getResponseContentType(response); let err; diff --git a/src/index.ts b/src/index.ts index 29edc8bb0..e599e0065 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,7 +19,6 @@ import * as utils from "./utils"; import request from "request"; matrixcs.request(request); -utils.runPolyfills(); try { // eslint-disable-next-line @typescript-eslint/no-var-requires diff --git a/src/models/event-timeline-set.js b/src/models/event-timeline-set.js index 13316ea7d..5835e5343 100644 --- a/src/models/event-timeline-set.js +++ b/src/models/event-timeline-set.js @@ -249,7 +249,7 @@ EventTimelineSet.prototype.findEventById = function(eventId) { if (!tl) { return undefined; } - return utils.findElement(tl.getEvents(), function(ev) { + return tl.getEvents().find(function(ev) { return ev.getId() == eventId; }); }; @@ -739,16 +739,11 @@ EventTimelineSet.prototype.setRelationsTarget = function(event) { if (!relationsForEvent) { return; } - // don't need it for non m.replace relations for now - const relationsWithRelType = relationsForEvent["m.replace"]; - if (!relationsWithRelType) { - return; - } - // only doing replacements for messages for now (e.g. edits) - const relationsWithEventType = relationsWithRelType["m.room.message"]; - if (relationsWithEventType) { - relationsWithEventType.setTargetEvent(event); + for (const relationsWithRelType of Object.values(relationsForEvent)) { + for (const relationsWithEventType of Object.values(relationsWithRelType)) { + relationsWithEventType.setTargetEvent(event); + } } }; @@ -768,7 +763,7 @@ EventTimelineSet.prototype.aggregateRelations = function(event) { } // If the event is currently encrypted, wait until it has been decrypted. - if (event.isBeingDecrypted()) { + if (event.isBeingDecrypted() || event.shouldAttemptDecryption()) { event.once("Event.decrypted", () => { this.aggregateRelations(event); }); @@ -796,7 +791,6 @@ EventTimelineSet.prototype.aggregateRelations = function(event) { } let relationsWithEventType = relationsWithRelType[eventType]; - let isNewRelations = false; let relatesToEvent; if (!relationsWithEventType) { relationsWithEventType = relationsWithRelType[eventType] = new Relations( @@ -804,7 +798,6 @@ EventTimelineSet.prototype.aggregateRelations = function(event) { eventType, this.room, ); - isNewRelations = true; relatesToEvent = this.findEventById(relatesToEventId) || this.room.getPendingEvent(relatesToEventId); if (relatesToEvent) { relationsWithEventType.setTargetEvent(relatesToEvent); @@ -812,11 +805,6 @@ EventTimelineSet.prototype.aggregateRelations = function(event) { } relationsWithEventType.addEvent(event); - - // only emit once event has been added to relations - if (isNewRelations && relatesToEvent) { - relatesToEvent.emit("Event.relationsCreated", relationType, eventType); - } }; /** diff --git a/src/models/event.js b/src/models/event.js index b7e22a606..1b3bec755 100644 --- a/src/models/event.js +++ b/src/models/event.js @@ -398,6 +398,12 @@ utils.extend(MatrixEvent.prototype, { this._clearEvent.content.msgtype === "m.bad.encrypted"; }, + shouldAttemptDecryption: function() { + return this.isEncrypted() + && !this.isBeingDecrypted() + && this.getClearContent() === null; + }, + /** * Start the process of trying to decrypt this event. * @@ -406,12 +412,22 @@ utils.extend(MatrixEvent.prototype, { * @internal * * @param {module:crypto} crypto crypto module - * @param {bool} isRetry True if this is a retry (enables more logging) + * @param {object} options + * @param {bool} options.isRetry True if this is a retry (enables more logging) + * @param {bool} options.emit Emits "event.decrypted" if set to true * * @returns {Promise} promise which resolves (to undefined) when the decryption * attempt is completed. */ - attemptDecryption: async function(crypto, isRetry) { + attemptDecryption: async function(crypto, options = {}) { + // For backwards compatibility purposes + // The function signature used to be attemptDecryption(crypto, isRetry) + if (typeof options === "boolean") { + options = { + isRetry: options, + }; + } + // start with a couple of sanity checks. if (!this.isEncrypted()) { throw new Error("Attempt to decrypt event which isn't encrypted"); @@ -441,7 +457,7 @@ utils.extend(MatrixEvent.prototype, { return this._decryptionPromise; } - this._decryptionPromise = this._decryptionLoop(crypto, isRetry); + this._decryptionPromise = this._decryptionLoop(crypto, options); return this._decryptionPromise; }, @@ -486,7 +502,7 @@ utils.extend(MatrixEvent.prototype, { return recipients; }, - _decryptionLoop: async function(crypto, isRetry) { + _decryptionLoop: async function(crypto, options = {}) { // make sure that this method never runs completely synchronously. // (doing so would mean that we would clear _decryptionPromise *before* // it is set in attemptDecryption - and hence end up with a stuck @@ -503,7 +519,7 @@ utils.extend(MatrixEvent.prototype, { res = this._badEncryptedMessage("Encryption not enabled"); } else { res = await crypto.decryptEvent(this); - if (isRetry) { + if (options.isRetry === true) { logger.info(`Decrypted event on retry (id=${this.getId()})`); } } @@ -511,7 +527,7 @@ utils.extend(MatrixEvent.prototype, { if (e.name !== "DecryptionError") { // not a decryption error: log the whole exception as an error // (and don't bother with a retry) - const re = isRetry ? 're' : ''; + const re = options.isRetry ? 're' : ''; logger.error( `Error ${re}decrypting event ` + `(id=${this.getId()}): ${e.stack || e}`, @@ -577,7 +593,9 @@ utils.extend(MatrixEvent.prototype, { // pick up the wrong contents. this.setPushActions(null); - this.emit("Event.decrypted", this, err); + if (options.emit !== false) { + this.emit("Event.decrypted", this, err); + } return; } diff --git a/src/models/relations.js b/src/models/relations.js index 80d894ce8..1e24d534e 100644 --- a/src/models/relations.js +++ b/src/models/relations.js @@ -41,11 +41,14 @@ export class Relations extends EventEmitter { super(); this.relationType = relationType; this.eventType = eventType; + this._relationEventIds = new Set(); this._relations = new Set(); this._annotationsByKey = {}; this._annotationsBySender = {}; this._sortedAnnotationsByKey = []; this._targetEvent = null; + this._room = room; + this._creationEmitted = false; } /** @@ -54,8 +57,8 @@ export class Relations extends EventEmitter { * @param {MatrixEvent} event * The new relation event to be added. */ - addEvent(event) { - if (this._relations.has(event)) { + async addEvent(event) { + if (this._relationEventIds.has(event.getId())) { return; } @@ -80,16 +83,20 @@ export class Relations extends EventEmitter { } this._relations.add(event); + this._relationEventIds.add(event.getId()); if (this.relationType === "m.annotation") { this._addAnnotationToAggregation(event); } else if (this.relationType === "m.replace" && this._targetEvent) { - this._targetEvent.makeReplaced(this.getLastReplacement()); + const lastReplacement = await this.getLastReplacement(); + this._targetEvent.makeReplaced(lastReplacement); } event.on("Event.beforeRedaction", this._onBeforeRedaction); this.emit("Relations.add", event); + + this._maybeEmitCreated(); } /** @@ -98,7 +105,7 @@ export class Relations extends EventEmitter { * @param {MatrixEvent} event * The relation event to remove. */ - _removeEvent(event) { + async _removeEvent(event) { if (!this._relations.has(event)) { return; } @@ -122,7 +129,8 @@ export class Relations extends EventEmitter { if (this.relationType === "m.annotation") { this._removeAnnotationFromAggregation(event); } else if (this.relationType === "m.replace" && this._targetEvent) { - this._targetEvent.makeReplaced(this.getLastReplacement()); + const lastReplacement = await this.getLastReplacement(); + this._targetEvent.makeReplaced(lastReplacement); } this.emit("Relations.remove", event); @@ -227,7 +235,7 @@ export class Relations extends EventEmitter { * @param {MatrixEvent} redactedEvent * The original relation event that is about to be redacted. */ - _onBeforeRedaction = (redactedEvent) => { + _onBeforeRedaction = async (redactedEvent) => { if (!this._relations.has(redactedEvent)) { return; } @@ -238,7 +246,8 @@ export class Relations extends EventEmitter { // Remove the redacted annotation from aggregation by key this._removeAnnotationFromAggregation(redactedEvent); } else if (this.relationType === "m.replace" && this._targetEvent) { - this._targetEvent.makeReplaced(this.getLastReplacement()); + const lastReplacement = await this.getLastReplacement(); + this._targetEvent.makeReplaced(lastReplacement); } redactedEvent.removeListener("Event.beforeRedaction", this._onBeforeRedaction); @@ -291,7 +300,7 @@ export class Relations extends EventEmitter { * * @return {MatrixEvent?} */ - getLastReplacement() { + async getLastReplacement() { if (this.relationType !== "m.replace") { // Aggregating on last only makes sense for this relation type return null; @@ -309,7 +318,7 @@ export class Relations extends EventEmitter { this._targetEvent.getServerAggregatedRelation("m.replace"); const minTs = replaceRelation && replaceRelation.origin_server_ts; - return this.getRelations().reduce((last, event) => { + const lastReplacement = this.getRelations().reduce((last, event) => { if (event.getSender() !== this._targetEvent.getSender()) { return last; } @@ -321,23 +330,51 @@ export class Relations extends EventEmitter { } return event; }, null); + + if (lastReplacement?.shouldAttemptDecryption()) { + await lastReplacement.attemptDecryption(this._room._client._crypto); + } else if (lastReplacement?.isBeingDecrypted()) { + await lastReplacement._decryptionPromise; + } + + return lastReplacement; } /* * @param {MatrixEvent} targetEvent the event the relations are related to. */ - setTargetEvent(event) { + async setTargetEvent(event) { if (this._targetEvent) { return; } this._targetEvent = event; + if (this.relationType === "m.replace") { - const replacement = this.getLastReplacement(); + const replacement = await this.getLastReplacement(); // this is the initial update, so only call it if we already have something // to not emit Event.replaced needlessly if (replacement) { this._targetEvent.makeReplaced(replacement); } } + + this._maybeEmitCreated(); + } + + _maybeEmitCreated() { + if (this._creationEmitted) { + return; + } + // Only emit we're "created" once we have a target event instance _and_ + // at least one related event. + if (!this._targetEvent || !this._relations.size) { + return; + } + this._creationEmitted = true; + this._targetEvent.emit( + "Event.relationsCreated", + this.relationType, + this.eventType, + ); } } diff --git a/src/models/room-member.js b/src/models/room-member.js index 586f12e31..32ed9dc5d 100644 --- a/src/models/room-member.js +++ b/src/models/room-member.js @@ -133,14 +133,15 @@ RoomMember.prototype.setPowerLevelEvent = function(powerLevelEvent) { const evContent = powerLevelEvent.getDirectionalContent(); let maxLevel = evContent.users_default || 0; - utils.forEach(utils.values(evContent.users), function(lvl) { + const users = evContent.users || {}; + Object.values(users).forEach(function(lvl) { maxLevel = Math.max(maxLevel, lvl); }); const oldPowerLevel = this.powerLevel; const oldPowerLevelNorm = this.powerLevelNorm; - if (evContent.users && evContent.users[this.userId] !== undefined) { - this.powerLevel = evContent.users[this.userId]; + if (users[this.userId] !== undefined) { + this.powerLevel = users[this.userId]; } else if (evContent.users_default !== undefined) { this.powerLevel = evContent.users_default; } else { @@ -172,7 +173,7 @@ RoomMember.prototype.setTypingEvent = function(event) { const oldTyping = this.typing; this.typing = false; const typingList = event.getContent().user_ids; - if (!utils.isArray(typingList)) { + if (!Array.isArray(typingList)) { // malformed event :/ bail early. TODO: whine? return; } diff --git a/src/models/room-state.js b/src/models/room-state.js index 5bf674f9c..e991df57c 100644 --- a/src/models/room-state.js +++ b/src/models/room-state.js @@ -154,7 +154,7 @@ RoomState.prototype.setInvitedMemberCount = function(count) { * @return {Array} A list of RoomMembers. */ RoomState.prototype.getMembers = function() { - return utils.values(this.members); + return Object.values(this.members); }; /** @@ -163,7 +163,7 @@ RoomState.prototype.getMembers = function() { * @return {Array} A list of RoomMembers. */ RoomState.prototype.getMembersExcept = function(excludedIds) { - return utils.values(this.members) + return Object.values(this.members) .filter((m) => !excludedIds.includes(m.userId)); }; @@ -296,7 +296,7 @@ RoomState.prototype.setStateEvents = function(stateEvents) { this._updateModifiedTime(); // update the core event dict - utils.forEach(stateEvents, function(event) { + stateEvents.forEach(function(event) { if (event.getRoomId() !== self.roomId) { return; } @@ -319,7 +319,7 @@ RoomState.prototype.setStateEvents = function(stateEvents) { // core event dict as these structures may depend on other state events in // the given array (e.g. disambiguating display names in one go to do both // clashing names rather than progressively which only catches 1 of them). - utils.forEach(stateEvents, function(event) { + stateEvents.forEach(function(event) { if (event.getRoomId() !== self.roomId) { return; } @@ -349,8 +349,8 @@ RoomState.prototype.setStateEvents = function(stateEvents) { self._updateMember(member); self.emit("RoomState.members", event, self, member); } else if (event.getType() === "m.room.power_levels") { - const members = utils.values(self.members); - utils.forEach(members, function(member) { + const members = Object.values(self.members); + members.forEach(function(member) { // We only propagate `RoomState.members` event if the // power levels has been changed // large room suffer from large re-rendering especially when not needed @@ -511,7 +511,7 @@ RoomState.prototype._setOutOfBandMember = function(stateEvent) { * @param {MatrixEvent} event The typing event */ RoomState.prototype.setTypingEvent = function(event) { - utils.forEach(utils.values(this.members), function(member) { + Object.values(this.members).forEach(function(member) { member.setTypingEvent(event); }); }; diff --git a/src/models/room.js b/src/models/room.js index 22b04891b..8273d0e8e 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -20,17 +20,18 @@ limitations under the License. * @module models/room */ -import { EventEmitter } from "events"; -import { EventTimelineSet } from "./event-timeline-set"; -import { EventTimeline } from "./event-timeline"; -import { getHttpUriForMxc } from "../content-repo"; +import {EventEmitter} from "events"; +import {EventTimelineSet} from "./event-timeline-set"; +import {EventTimeline} from "./event-timeline"; +import {getHttpUriForMxc} from "../content-repo"; import * as utils from "../utils"; -import { EventStatus, MatrixEvent } from "./event"; -import { RoomMember } from "./room-member"; -import { RoomSummary } from "./room-summary"; -import { logger } from '../logger'; -import { ReEmitter } from '../ReEmitter'; -import { EventType, RoomCreateTypeField, RoomType } from "../@types/event"; +import {EventStatus, MatrixEvent} from "./event"; +import {RoomMember} from "./room-member"; +import {RoomSummary} from "./room-summary"; +import {logger} from '../logger'; +import {ReEmitter} from '../ReEmitter'; +import {EventType, RoomCreateTypeField, RoomType} from "../@types/event"; +import { normalize } from "../utils"; // These constants are used as sane defaults when the homeserver doesn't support // the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be @@ -58,6 +59,7 @@ function synthesizeReceipt(userId, event, receiptType) { return new MatrixEvent(fakeReceipt); } + /** * Construct a new Room. * @@ -101,6 +103,7 @@ function synthesizeReceipt(userId, event, receiptType) { * * @prop {string} roomId The ID of this room. * @prop {string} name The human-readable display name for this room. + * @prop {string} normalizedName The unhomoglyphed name for this room. * @prop {Array} timeline The live event timeline for this room, * with the oldest event at index 0. Present for backwards compatibility - * prefer getLiveTimeline().getEvents(). @@ -215,6 +218,10 @@ export function Room(roomId, client, myUserId, opts) { } else { this._membersPromise = null; } + + // flags to stop logspam about missing m.room.create events + this.getTypeWarning = false; + this.getVersionWarning = false; } /** @@ -227,6 +234,51 @@ function pendingEventsKey(roomId) { utils.inherits(Room, EventEmitter); + +/** + * Bulk decrypt critical events in a room + * + * Critical events represents the minimal set of events to decrypt + * for a typical UI to function properly + * + * - Last event of every room (to generate likely message preview) + * - All events up to the read receipt (to calculate an accurate notification count) + * + * @returns {Promise} Signals when all events have been decrypted + */ +Room.prototype.decryptCriticalEvents = function() { + const readReceiptEventId = this.getEventReadUpTo(this._client.getUserId(), true); + const events = this.getLiveTimeline().getEvents(); + const readReceiptTimelineIndex = events.findIndex(matrixEvent => { + return matrixEvent.event.event_id === readReceiptEventId; + }); + + const decryptionPromises = events + .slice(readReceiptTimelineIndex) + .filter(event => event.shouldAttemptDecryption()) + .reverse() + .map(event => event.attemptDecryption(this._client._crypto, { isRetry: true })); + + return Promise.allSettled(decryptionPromises); +}; + +/** + * Bulk decrypt events in a room + * + * @returns {Promise} Signals when all events have been decrypted + */ +Room.prototype.decryptAllEvents = function() { + const decryptionPromises = this + .getUnfilteredTimelineSet() + .getLiveTimeline() + .getEvents() + .filter(event => event.shouldAttemptDecryption()) + .reverse() + .map(event => event.attemptDecryption(this._client._crypto, { isRetry: true })); + + return Promise.allSettled(decryptionPromises); +}; + /** * Gets the version of the room * @returns {string} The version of the room, or null if it could not be determined @@ -234,7 +286,10 @@ utils.inherits(Room, EventEmitter); Room.prototype.getVersion = function() { const createEvent = this.currentState.getStateEvents("m.room.create", ""); if (!createEvent) { - logger.warn("[getVersion] Room " + this.roomId + " does not have an m.room.create event"); + if (!this.getVersionWarning) { + logger.warn("[getVersion] Room " + this.roomId + " does not have an m.room.create event"); + this.getVersionWarning = true; + } return '1'; } const ver = createEvent.getContent()['room_version']; @@ -440,6 +495,7 @@ Room.prototype.getLiveTimeline = function() { return this.getUnfilteredTimelineSet().getLiveTimeline(); }; + /** * Get the timestamp of the last message in the room * @@ -578,12 +634,13 @@ Room.prototype._loadMembersFromServer = async function() { at: lastSyncToken, }); const path = utils.encodeUri("/rooms/$roomId/members?" + queryString, - { $roomId: this.roomId }); + {$roomId: this.roomId}); const http = this._client._http; const response = await http.authedRequest(undefined, "GET", path); return response.chunk; }; + Room.prototype._loadMembers = async function() { // were the members loaded from the server? let fromServer = false; @@ -596,7 +653,7 @@ Room.prototype._loadMembers = async function() { `members from server for room ${this.roomId}`); } const memberEvents = rawMembersEvents.map(this._client.getEventMapper()); - return { memberEvents, fromServer }; + return {memberEvents, fromServer}; }; /** @@ -901,7 +958,7 @@ Room.prototype.getAliases = function() { if (aliasEvents) { for (let i = 0; i < aliasEvents.length; ++i) { const aliasEvent = aliasEvents[i]; - if (utils.isArray(aliasEvent.getContent().aliases)) { + if (Array.isArray(aliasEvent.getContent().aliases)) { const filteredAliases = aliasEvent.getContent().aliases.filter(a => { if (typeof(a) !== "string") return false; if (a[0] !== '#') return false; @@ -1029,7 +1086,7 @@ Room.prototype.getInvitedAndJoinedMemberCount = function() { * @return {RoomMember[]} A list of members with the given membership state. */ Room.prototype.getMembersWithMembership = function(membership) { - return utils.filter(this.currentState.getMembers(), function(m) { + return this.currentState.getMembers().filter(function(m) { return m.membership === membership; }); }; @@ -1068,6 +1125,7 @@ Room.prototype.getInvitedAndJoinedMemberCount = function() { return calculateRoomName(this, userId, true); }; + /** * Check if the given user_id has the given membership state. * @param {string} userId The user ID to check. @@ -1224,6 +1282,7 @@ Room.prototype._addLiveEvent = function(event, duplicateStrategy, fromCache) { } }; + /** * Add a pending outgoing event to this room. * @@ -1634,6 +1693,7 @@ Room.prototype.removeEvent = function(eventId) { return removedAny; }; + /** * Recalculate various aspects of the room, including the room name and * room summary. Call this any time the room's current state is modified. @@ -1649,7 +1709,7 @@ Room.prototype.recalculate = function() { ); if (membershipEvent && membershipEvent.getContent().membership === "invite") { const strippedStateEvents = membershipEvent.event.invite_room_state || []; - utils.forEach(strippedStateEvents, function(strippedEvent) { + strippedStateEvents.forEach(function(strippedEvent) { const existingEvent = self.currentState.getStateEvents( strippedEvent.type, strippedEvent.state_key, ); @@ -1669,6 +1729,7 @@ Room.prototype.recalculate = function() { const oldName = this.name; this.name = calculateRoomName(this, this.myUserId); + this.normalizedName = normalize(this.name); this.summary = new RoomSummary(this.roomId, { title: this.name, }); @@ -1799,9 +1860,9 @@ Room.prototype.addReceipt = function(event, fake) { */ Room.prototype._addReceiptsToStructure = function(event, receipts) { const self = this; - utils.keys(event.getContent()).forEach(function(eventId) { - utils.keys(event.getContent()[eventId]).forEach(function(receiptType) { - utils.keys(event.getContent()[eventId][receiptType]).forEach( + Object.keys(event.getContent()).forEach(function(eventId) { + Object.keys(event.getContent()[eventId]).forEach(function(receiptType) { + Object.keys(event.getContent()[eventId][receiptType]).forEach( function(userId) { const receipt = event.getContent()[eventId][receiptType][userId]; @@ -1841,8 +1902,8 @@ Room.prototype._addReceiptsToStructure = function(event, receipts) { */ Room.prototype._buildReceiptCache = function(receipts) { const receiptCacheByEventId = {}; - utils.keys(receipts).forEach(function(receiptType) { - utils.keys(receipts[receiptType]).forEach(function(userId) { + Object.keys(receipts).forEach(function(receiptType) { + Object.keys(receipts[receiptType]).forEach(function(userId) { const receipt = receipts[receiptType][userId]; if (!receiptCacheByEventId[receipt.eventId]) { receiptCacheByEventId[receipt.eventId] = []; @@ -1857,6 +1918,7 @@ Room.prototype._buildReceiptCache = function(receipts) { return receiptCacheByEventId; }; + /** * Add a temporary local-echo receipt to the room to reflect in the * client the fact that we've sent one. @@ -1914,6 +1976,7 @@ Room.prototype.getAccountData = function(type) { return this.accountData[type]; }; + /** * Returns whether the syncing user has permission to send a message in the room * @return {boolean} true if the user should be permitted to send @@ -1955,7 +2018,10 @@ Room.prototype.getJoinRule = function() { Room.prototype.getType = function() { const createEvent = this.currentState.getStateEvents("m.room.create", ""); if (!createEvent) { - logger.warn("[getType] Room " + this.roomId + " does not have an m.room.create event"); + if (!this.getTypeWarning) { + logger.warn("[getType] Room " + this.roomId + " does not have an m.room.create event"); + this.getTypeWarning = true; + } return undefined; } return createEvent.getContent()[RoomCreateTypeField]; diff --git a/src/models/search-result.js b/src/models/search-result.js index 667b6c88e..2250e786f 100644 --- a/src/models/search-result.js +++ b/src/models/search-result.js @@ -19,8 +19,7 @@ limitations under the License. * @module models/search-result */ -import * as utils from "../utils"; -import { EventContext } from "./event-context"; +import {EventContext} from "./event-context"; /** * Construct a new SearchResult @@ -52,8 +51,8 @@ SearchResult.fromJson = function(jsonObj, eventMapper) { const context = new EventContext(eventMapper(jsonObj.result)); context.setPaginateToken(jsonContext.start, true); - context.addEvents(utils.map(events_before, eventMapper), true); - context.addEvents(utils.map(events_after, eventMapper), false); + context.addEvents(events_before.map(eventMapper), true); + context.addEvents(events_after.map(eventMapper), false); context.setPaginateToken(jsonContext.end, false); return new SearchResult(jsonObj.rank, context); diff --git a/src/scheduler.js b/src/scheduler.js index 9ae68135e..37e231ce0 100644 --- a/src/scheduler.js +++ b/src/scheduler.js @@ -65,7 +65,7 @@ MatrixScheduler.prototype.getQueueForEvent = function(event) { if (!name || !this._queues[name]) { return null; } - return utils.map(this._queues[name], function(obj) { + return this._queues[name].map(function(obj) { return obj.event; }); }; @@ -195,16 +195,18 @@ function _startProcessingQueues(scheduler) { return; } // for each inactive queue with events in them - utils.forEach(utils.filter(utils.keys(scheduler._queues), function(queueName) { - return scheduler._activeQueues.indexOf(queueName) === -1 && - scheduler._queues[queueName].length > 0; - }), function(queueName) { - // mark the queue as active - scheduler._activeQueues.push(queueName); - // begin processing the head of the queue - debuglog("Spinning up queue: '%s'", queueName); - _processQueue(scheduler, queueName); - }); + Object.keys(scheduler._queues) + .filter(function(queueName) { + return scheduler._activeQueues.indexOf(queueName) === -1 && + scheduler._queues[queueName].length > 0; + }) + .forEach(function(queueName) { + // mark the queue as active + scheduler._activeQueues.push(queueName); + // begin processing the head of the queue + debuglog("Spinning up queue: '%s'", queueName); + _processQueue(scheduler, queueName); + }); } function _processQueue(scheduler, queueName) { @@ -266,7 +268,7 @@ function _processQueue(scheduler, queueName) { function _peekNextEvent(scheduler, queueName) { const queue = scheduler._queues[queueName]; - if (!utils.isArray(queue)) { + if (!Array.isArray(queue)) { return null; } return queue[0]; @@ -274,7 +276,7 @@ function _peekNextEvent(scheduler, queueName) { function _removeNextEvent(scheduler, queueName) { const queue = scheduler._queues[queueName]; - if (!utils.isArray(queue)) { + if (!Array.isArray(queue)) { return null; } return queue.shift(); diff --git a/src/store/memory.js b/src/store/memory.js index 673fc15d6..1b582ee43 100644 --- a/src/store/memory.js +++ b/src/store/memory.js @@ -22,8 +22,7 @@ limitations under the License. * @module store/memory */ -import { User } from "../models/user"; -import * as utils from "../utils"; +import {User} from "../models/user"; function isValidFilterId(filterId) { const isValidStr = typeof filterId === "string" && @@ -113,7 +112,7 @@ MemoryStore.prototype = { * @return {Group[]} A list of groups, which may be empty. */ getGroups: function() { - return utils.values(this.groups); + return Object.values(this.groups); }, /** @@ -175,7 +174,7 @@ MemoryStore.prototype = { * @return {Room[]} A list of rooms, which may be empty. */ getRooms: function() { - return utils.values(this.rooms); + return Object.values(this.rooms); }, /** @@ -194,7 +193,7 @@ MemoryStore.prototype = { * @return {RoomSummary[]} A summary of each room. */ getRoomSummaries: function() { - return utils.map(utils.values(this.rooms), function(room) { + return Object.values(this.rooms).map(function(room) { return room.summary; }); }, @@ -221,7 +220,7 @@ MemoryStore.prototype = { * @return {User[]} A list of users, which may be empty. */ getUsers: function() { - return utils.values(this.users); + return Object.values(this.users); }, /** diff --git a/src/sync.js b/src/sync.js index bf4dcd323..8ad4af30b 100644 --- a/src/sync.js +++ b/src/sync.js @@ -276,20 +276,15 @@ SyncApi.prototype.peek = function(roomId) { // FIXME: Mostly duplicated from _processRoomEvents but not entirely // because "state" in this API is at the BEGINNING of the chunk - const oldStateEvents = utils.map( - utils.deepCopy(response.state), client.getEventMapper(), - ); - const stateEvents = utils.map( - response.state, client.getEventMapper(), - ); - const messages = utils.map( - response.messages.chunk, client.getEventMapper(), - ); + const oldStateEvents = utils.deepCopy(response.state) + .map(client.getEventMapper()); + const stateEvents = response.state.map(client.getEventMapper()); + const messages = response.messages.chunk.map(client.getEventMapper()); // XXX: copypasted from /sync until we kill off this // minging v1 API stuff) // handle presence events (User objects) - if (response.presence && utils.isArray(response.presence)) { + if (response.presence && Array.isArray(response.presence)) { response.presence.map(client.getEventMapper()).forEach( function(presenceEvent) { let user = client.store.getUser(presenceEvent.getContent().user_id); @@ -1004,7 +999,7 @@ SyncApi.prototype._processSyncResponse = async function( // - The isBrandNewRoom boilerplate is boilerplatey. // handle presence events (User objects) - if (data.presence && utils.isArray(data.presence.events)) { + if (data.presence && Array.isArray(data.presence.events)) { data.presence.events.map(client.getEventMapper()).forEach( function(presenceEvent) { let user = client.store.getUser(presenceEvent.getSender()); @@ -1020,7 +1015,7 @@ SyncApi.prototype._processSyncResponse = async function( } // handle non-room account_data - if (data.account_data && utils.isArray(data.account_data.events)) { + if (data.account_data && Array.isArray(data.account_data.events)) { const events = data.account_data.events.map(client.getEventMapper()); const prevEventsMap = events.reduce((m, c) => { m[c.getId()] = client.store.getAccountData(c.getType()); @@ -1045,7 +1040,7 @@ SyncApi.prototype._processSyncResponse = async function( } // handle to-device events - if (data.to_device && utils.isArray(data.to_device.events) && + if (data.to_device && Array.isArray(data.to_device.events) && data.to_device.events.length > 0 ) { const cancelledKeyVerificationTxns = []; @@ -1156,10 +1151,15 @@ SyncApi.prototype._processSyncResponse = async function( await utils.promiseMapSeries(joinRooms, async function(joinObj) { const room = joinObj.room; const stateEvents = self._mapSyncEventsFormat(joinObj.state, room); - const timelineEvents = self._mapSyncEventsFormat(joinObj.timeline, room); + // Prevent events from being decrypted ahead of time + // this helps large account to speed up faster + // room::decryptCriticalEvent is in charge of decrypting all the events + // required for a client to function properly + const timelineEvents = self._mapSyncEventsFormat(joinObj.timeline, room, false); const ephemeralEvents = self._mapSyncEventsFormat(joinObj.ephemeral); const accountDataEvents = self._mapSyncEventsFormat(joinObj.account_data); + const encrypted = client.isRoomEncrypted(room.roomId); // we do this first so it's correct when any of the events fire if (joinObj.unread_notifications) { room.setUnreadNotificationCount( @@ -1170,7 +1170,6 @@ SyncApi.prototype._processSyncResponse = async function( // bother setting it here. We trust our calculations better than the // server's for this case, and therefore will assume that our non-zero // count is accurate. - const encrypted = client.isRoomEncrypted(room.roomId); if (!encrypted || (encrypted && room.getUnreadNotificationCount('highlight') <= 0)) { room.setUnreadNotificationCount( @@ -1292,6 +1291,11 @@ SyncApi.prototype._processSyncResponse = async function( }); room.updateMyMembership("join"); + + // Decrypt only the last message in all rooms to make sure we can generate a preview + // And decrypt all events after the recorded read receipt to ensure an accurate + // notification count + room.decryptCriticalEvents(); }); // Handle leaves (e.g. kicked rooms) @@ -1497,7 +1501,7 @@ SyncApi.prototype._mapSyncResponseToRoomArray = function(obj) { // [{stuff+Room+isBrandNewRoom}, {stuff+Room+isBrandNewRoom}] const client = this.client; const self = this; - return utils.keys(obj).map(function(roomId) { + return Object.keys(obj).map(function(roomId) { const arrObj = obj[roomId]; let room = client.store.getRoom(roomId); let isBrandNewRoom = false; @@ -1514,13 +1518,14 @@ SyncApi.prototype._mapSyncResponseToRoomArray = function(obj) { /** * @param {Object} obj * @param {Room} room + * @param {bool} decrypt * @return {MatrixEvent[]} */ -SyncApi.prototype._mapSyncEventsFormat = function(obj, room) { - if (!obj || !utils.isArray(obj.events)) { +SyncApi.prototype._mapSyncEventsFormat = function(obj, room, decrypt = true) { + if (!obj || !Array.isArray(obj.events)) { return []; } - const mapper = this.client.getEventMapper(); + const mapper = this.client.getEventMapper({ decrypt }); return obj.events.map(function(e) { if (room) { e.room_id = room.roomId; diff --git a/src/utils.ts b/src/utils.ts index 7c5700c5e..73e973a72 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -61,116 +61,6 @@ export function encodeUri(pathTemplate: string, return pathTemplate; } -/** - * Applies a map function to the given array. - * @param {Array} array The array to apply the function to. - * @param {Function} fn The function that will be invoked for each element in - * the array with the signature fn(element){...} - * @return {Array} A new array with the results of the function. - */ -export function map(array: T[], fn: (t: T) => S): S[] { - const results = new Array(array.length); - for (let i = 0; i < array.length; i++) { - results[i] = fn(array[i]); - } - return results; -} - -/** - * Applies a filter function to the given array. - * @param {Array} array The array to apply the function to. - * @param {Function} fn The function that will be invoked for each element in - * the array. It should return true to keep the element. The function signature - * looks like fn(element, index, array){...}. - * @return {Array} A new array with the results of the function. - */ -export function filter(array: T[], - fn: (t: T, i?: number, a?: T[]) => boolean): T[] { - const results: T[] = []; - for (let i = 0; i < array.length; i++) { - if (fn(array[i], i, array)) { - results.push(array[i]); - } - } - return results; -} - -/** - * Get the keys for an object. Same as Object.keys(). - * @param {Object} obj The object to get the keys for. - * @return {string[]} The keys of the object. - */ -export function keys(obj: object): string[] { - const result = []; - for (const key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - result.push(key); - } - return result; -} - -/** - * Get the values for an object. - * @param {Object} obj The object to get the values for. - * @return {Array<*>} The values of the object. - */ -export function values(obj: Record): T[] { - const result = []; - for (const key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - result.push(obj[key]); - } - return result; -} - -/** - * Invoke a function for each item in the array. - * @param {Array} array The array. - * @param {Function} fn The function to invoke for each element. Has the - * function signature fn(element, index). - */ -export function forEach(array: T[], fn: (t: T, i: number) => void) { - for (let i = 0; i < array.length; i++) { - fn(array[i], i); - } -} - -/** - * The findElement() method returns a value in the array, if an element in the array - * satisfies (returns true) the provided testing function. Otherwise undefined - * is returned. - * @param {Array} array The array. - * @param {Function} fn Function to execute on each value in the array, with the - * function signature fn(element, index, array) - * @param {boolean} reverse True to search in reverse order. - * @return {*} The first value in the array which returns true for - * the given function. - */ -export function findElement( - array: T[], - fn: (t: T, i?: number, a?: T[]) => boolean, - reverse?: boolean, -) { - let i; - if (reverse) { - for (i = array.length - 1; i >= 0; i--) { - if (fn(array[i], i, array)) { - return array[i]; - } - } - } else { - for (i = 0; i < array.length; i++) { - if (fn(array[i], i, array)) { - return array[i]; - } - } - } -} - /** * The removeElement() method removes the first element in the array that * satisfies (returns true) the provided testing function. @@ -217,16 +107,6 @@ export function isFunction(value: any) { return Object.prototype.toString.call(value) === "[object Function]"; } -/** - * Checks if the given thing is an array. - * @param {*} value The thing to check. - * @return {boolean} True if it is an array. - */ -export function isArray(value: any) { - return Array.isArray ? Array.isArray(value) : - Boolean(value && value.constructor === Array); -} - /** * Checks that the given object has the specified keys. * @param {Object} obj The object to check. @@ -380,207 +260,6 @@ export function extend(...restParams) { return target; } -/** - * Run polyfills to add Array.map and Array.filter if they are missing. - */ -export function runPolyfills() { - // Array.prototype.filter - // ======================================================== - // SOURCE: - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter - if (!Array.prototype.filter) { - // eslint-disable-next-line no-extend-native - Array.prototype.filter = function(fun: Function/*, thisArg*/, ...restProps) { - if (this === void 0 || this === null) { - throw new TypeError(); - } - - const t = Object(this); - const len = t.length >>> 0; - if (typeof fun !== 'function') { - throw new TypeError(); - } - - const res = []; - const thisArg = restProps ? restProps[0] : void 0; - for (let i = 0; i < len; i++) { - if (i in t) { - const val = t[i]; - - // NOTE: Technically this should Object.defineProperty at - // the next index, as push can be affected by - // properties on Object.prototype and Array.prototype. - // But that method's new, and collisions should be - // rare, so use the more-compatible alternative. - if (fun.call(thisArg, val, i, t)) { - res.push(val); - } - } - } - return res; - }; - } - - // Array.prototype.map - // ======================================================== - // SOURCE: - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map - // Production steps of ECMA-262, Edition 5, 15.4.4.19 - // Reference: http://es5.github.io/#x15.4.4.19 - if (!Array.prototype.map) { - // eslint-disable-next-line no-extend-native - Array.prototype.map = function(callback, thisArg) { - let T; - let k; - - if (this === null || this === undefined) { - throw new TypeError(' this is null or not defined'); - } - - // 1. Let O be the result of calling ToObject passing the |this| - // value as the argument. - const O = Object(this); - - // 2. Let lenValue be the result of calling the Get internal - // method of O with the argument "length". - // 3. Let len be ToUint32(lenValue). - const len = O.length >>> 0; - - // 4. If IsCallable(callback) is false, throw a TypeError exception. - // See: http://es5.github.com/#x9.11 - if (typeof callback !== 'function') { - throw new TypeError(callback + ' is not a function'); - } - - // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. - if (arguments.length > 1) { - T = thisArg; - } - - // 6. Let A be a new array created as if by the expression new Array(len) - // where Array is the standard built-in constructor with that name and - // len is the value of len. - const A = new Array(len); - - // 7. Let k be 0 - k = 0; - - // 8. Repeat, while k < len - while (k < len) { - let kValue; - let mappedValue; - - // a. Let Pk be ToString(k). - // This is implicit for LHS operands of the in operator - // b. Let kPresent be the result of calling the HasProperty internal - // method of O with argument Pk. - // This step can be combined with c - // c. If kPresent is true, then - if (k in O) { - // i. Let kValue be the result of calling the Get internal - // method of O with argument Pk. - kValue = O[k]; - - // ii. Let mappedValue be the result of calling the Call internal - // method of callback with T as the this value and argument - // list containing kValue, k, and O. - mappedValue = callback.call(T, kValue, k, O); - - // iii. Call the DefineOwnProperty internal method of A with arguments - // Pk, Property Descriptor - // { Value: mappedValue, - // Writable: true, - // Enumerable: true, - // Configurable: true }, - // and false. - - // In browsers that support Object.defineProperty, use the following: - // Object.defineProperty(A, k, { - // value: mappedValue, - // writable: true, - // enumerable: true, - // configurable: true - // }); - - // For best browser support, use the following: - A[k] = mappedValue; - } - // d. Increase k by 1. - k++; - } - - // 9. return A - return A; - }; - } - - // Array.prototype.forEach - // ======================================================== - // SOURCE: - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach - // Production steps of ECMA-262, Edition 5, 15.4.4.18 - // Reference: http://es5.github.io/#x15.4.4.18 - if (!Array.prototype.forEach) { - // eslint-disable-next-line no-extend-native - Array.prototype.forEach = function(callback, thisArg) { - let T; - let k; - - if (this === null || this === undefined) { - throw new TypeError(' this is null or not defined'); - } - - // 1. Let O be the result of calling ToObject passing the |this| value as the - // argument. - const O = Object(this); - - // 2. Let lenValue be the result of calling the Get internal method of O with the - // argument "length". - // 3. Let len be ToUint32(lenValue). - const len = O.length >>> 0; - - // 4. If IsCallable(callback) is false, throw a TypeError exception. - // See: http://es5.github.com/#x9.11 - if (typeof callback !== "function") { - throw new TypeError(callback + ' is not a function'); - } - - // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. - if (arguments.length > 1) { - T = thisArg; - } - - // 6. Let k be 0 - k = 0; - - // 7. Repeat, while k < len - while (k < len) { - let kValue; - - // a. Let Pk be ToString(k). - // This is implicit for LHS operands of the in operator - // b. Let kPresent be the result of calling the HasProperty internal - // method of O with - // argument Pk. - // This step can be combined with c - // c. If kPresent is true, then - if (k in O) { - // i. Let kValue be the result of calling the Get internal method of O with - // argument Pk - kValue = O[k]; - - // ii. Call the Call internal method of callback with T as the this value and - // argument list containing kValue, k, and O. - callback.call(T, kValue, k, O); - } - // d. Increase k by 1. - k++; - } - // 8. return undefined - }; - } -} - /** * Inherit the prototype methods from one constructor into another. This is a * port of the Node.js implementation with an Object.create polyfill. @@ -667,6 +346,16 @@ export function removeHiddenChars(str: string): string { return ""; } +export function normalize(str: string): string { + // Note: we have to match the filter with the removeHiddenChars() because the + // function strips spaces and other characters (M becomes RN for example, in lowercase). + return removeHiddenChars(str.toLowerCase()) + // Strip all punctuation + .replace(/[\\'!"#$%&()*+,\-./:;<=>?@[\]^_`{|}~\u2000-\u206f\u2e00-\u2e7f]/g, "") + // We also doubly convert to lowercase to work around oddities of the library. + .toLowerCase(); +} + // Regex matching bunch of unicode control characters and otherwise misleading/invisible characters. // Includes: // various width spaces U+2000 - U+200D diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index 090d5f74c..b6e650258 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -1505,7 +1505,8 @@ export class MatrixCall extends EventEmitter { } // Order is important here: first we stopAllMedia() and only then we can deleteAllFeeds() - this.stopAllMedia(); + // We don't stop media if the call was replaced as we want to re-use streams in the successor + if (hangupReason !== CallErrorCode.Replaced) this.stopAllMedia(); this.deleteAllFeeds(); this.hangupParty = hangupParty; @@ -1802,7 +1803,10 @@ export function createNewMatrixCall(client: any, roomId: string, options?: CallO window.RTCIceCandidate || navigator.mediaDevices, ); if (!supported) { - logger.error("WebRTC is not supported in this browser / environment"); + // Adds a lot of noise to test runs, so disable logging there. + if (process.env.NODE_ENV !== "test") { + logger.error("WebRTC is not supported in this browser / environment"); + } return null; } } catch (e) { diff --git a/src/webrtc/callEventHandler.ts b/src/webrtc/callEventHandler.ts index 0d8b9f028..5bc5cb4cc 100644 --- a/src/webrtc/callEventHandler.ts +++ b/src/webrtc/callEventHandler.ts @@ -43,6 +43,9 @@ export class CallEventHandler { // after loading and after we've been offline for a bit. this.callEventBuffer = []; this.candidateEventsByCall = new Map>(); + } + + public start() { this.client.on("sync", this.evaluateEventBuffer); this.client.on("event", this.onEvent); } @@ -52,10 +55,11 @@ export class CallEventHandler { this.client.removeListener("event", this.onEvent); } - private evaluateEventBuffer = () => { + private evaluateEventBuffer = async () => { if (this.client.getSyncState() === "SYNCING") { - // don't process any events until they are all decrypted - if (this.callEventBuffer.some((e) => e.isBeingDecrypted())) return; + await Promise.all(this.callEventBuffer.map(event => { + this.client.decryptEventIfNeeded(event); + })); const ignoreCallIds = new Set(); // inspect the buffer and mark all calls which have been answered @@ -86,6 +90,7 @@ export class CallEventHandler { } private onEvent = (event: MatrixEvent) => { + this.client.decryptEventIfNeeded(event); // any call events or ones that might be once they're decrypted if ( event.getType().indexOf("m.call.") === 0 || diff --git a/yarn.lock b/yarn.lock index 9e97396d6..f48a13d6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1130,6 +1130,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz": + version "3.2.3" + resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz#cc332fdd25c08ef0e40f4d33fc3f822a0f98b6f4" + "@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": version "2.1.8-no-fsevents" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz#da7c3996b8e6e19ebd14d82eaced2313e7769f9b" @@ -5142,10 +5146,6 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -"olm@https://packages.matrix.org/npm/olm/olm-3.2.1.tgz": - version "3.2.1" - resolved "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz#d623d76f99c3518dde68be8c86618d68bc7b004a" - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"