diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 6e6720bbf11..00000000000 --- a/.babelrc +++ /dev/null @@ -1,22 +0,0 @@ -{ - "sourceMaps": true, - "presets": [ - [ - "@babel/preset-env", - { - "targets": { - "node": 10 - }, - "modules": "commonjs" - } - ], - "@babel/preset-typescript" - ], - "plugins": [ - "@babel/plugin-proposal-numeric-separator", - "@babel/plugin-proposal-class-properties", - "@babel/plugin-proposal-object-rest-spread", - "@babel/plugin-syntax-dynamic-import", - "@babel/plugin-transform-runtime" - ] -} diff --git a/.github/workflows/notify-downstream.yaml b/.github/workflows/notify-downstream.yaml index a1c4a28a5ce..8de5da70dcd 100644 --- a/.github/workflows/notify-downstream.yaml +++ b/.github/workflows/notify-downstream.yaml @@ -12,7 +12,7 @@ jobs: fail-fast: false matrix: include: - - repo: vector-im/element-web + - repo: element-hq/element-web event: element-web-notify - repo: matrix-org/matrix-react-sdk event: upstream-sdk-notify diff --git a/.github/workflows/triage-labelled.yml b/.github/workflows/triage-labelled.yml index cb013753c56..e464e5b7268 100644 --- a/.github/workflows/triage-labelled.yml +++ b/.github/workflows/triage-labelled.yml @@ -6,6 +6,6 @@ on: jobs: call-triage-labelled: - uses: vector-im/element-web/.github/workflows/triage-labelled.yml@develop + uses: element-hq/element-web/.github/workflows/triage-labelled.yml@develop secrets: ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index a75f7cff4fa..9c190ae9c67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,33 @@ +Changes in [33.0.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v33.0.0) (2024-06-04) +================================================================================================== +## 🚨 BREAKING CHANGES + +* Remove more deprecated methods, fields, and exports ([#4217](https://github.com/matrix-org/matrix-js-sdk/pull/4217)). Contributed by @t3chguy. +* Remove deprecated methods and fields ([#4201](https://github.com/matrix-org/matrix-js-sdk/pull/4201)). Contributed by @t3chguy. + +## 🦖 Deprecations + +* Remove more deprecated methods, fields, and exports ([#4217](https://github.com/matrix-org/matrix-js-sdk/pull/4217)). Contributed by @t3chguy. +* Remove deprecated methods and fields ([#4201](https://github.com/matrix-org/matrix-js-sdk/pull/4201)). Contributed by @t3chguy. + +## ✨ Features + +* `initRustCrypto`: allow app to pass in the store key directly ([#4210](https://github.com/matrix-org/matrix-js-sdk/pull/4210)). Contributed by @richvdh. +* Preserve ESM for async imports to work correctly ([#4187](https://github.com/matrix-org/matrix-js-sdk/pull/4187)). Contributed by @ms-dosx86. + +## 🐛 Bug Fixes + +* Don't run migration for Rust crypto if the legacy store is empty ([#4218](https://github.com/matrix-org/matrix-js-sdk/pull/4218)). Contributed by @andybalaam. +* Bump matrix-sdk-crypto-wasm to 5.0.0 ([#4216](https://github.com/matrix-org/matrix-js-sdk/pull/4216)). Contributed by @richvdh. +* Wire up verification cancel \& mismatch for rust crypto ([#4202](https://github.com/matrix-org/matrix-js-sdk/pull/4202)). Contributed by @t3chguy. +* Only pass id\_server if we had one to begin with ([#4200](https://github.com/matrix-org/matrix-js-sdk/pull/4200)). Contributed by @t3chguy. + + +Changes in [32.4.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v32.4.0) (2024-05-22) +================================================================================================== +* No changes + + Changes in [32.3.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v32.3.0) (2024-05-21) ================================================================================================== ## ✨ Features diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000000..6b39ec8271b --- /dev/null +++ b/babel.config.js @@ -0,0 +1,26 @@ +module.exports = { + sourceMaps: true, + presets: [ + [ + "@babel/preset-env", + { + targets: { + esmodules: true, + }, + // We want to output ES modules for the final build (mostly to ensure that + // async imports work correctly). However, jest doesn't support ES modules very + // well yet (see https://github.com/jestjs/jest/issues/9430), so we use commonjs + // when testing. + modules: process.env.NODE_ENV === "test" ? "commonjs" : false, + }, + ], + "@babel/preset-typescript", + ], + plugins: [ + "@babel/plugin-proposal-numeric-separator", + "@babel/plugin-proposal-class-properties", + "@babel/plugin-proposal-object-rest-spread", + "@babel/plugin-syntax-dynamic-import", + "@babel/plugin-transform-runtime", + ], +}; diff --git a/package.json b/package.json index 24d180a625b..9011449fb29 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "32.3.0", + "version": "33.0.0", "description": "Matrix Client-Server SDK for Javascript", "engines": { "node": ">=18.0.0" @@ -31,8 +31,8 @@ "keywords": [ "matrix-org" ], - "main": "./src/index.ts", - "browser": "./src/browser-index.ts", + "main": "./lib/index.js", + "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.ts", "matrix_lib_main": "./lib/index.js", @@ -53,7 +53,7 @@ ], "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-wasm": "^4.9.0", + "@matrix-org/matrix-sdk-crypto-wasm": "^5.0.0", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", @@ -132,5 +132,6 @@ "outputDirectory": "coverage", "outputName": "jest-sonar-report.xml", "relativePaths": true - } + }, + "typings": "./lib/index.d.ts" } diff --git a/spec/integ/crypto/megolm-backup.spec.ts b/spec/integ/crypto/megolm-backup.spec.ts index 66f7892daa5..eee0eafebc2 100644 --- a/spec/integ/crypto/megolm-backup.spec.ts +++ b/spec/integ/crypto/megolm-backup.spec.ts @@ -21,7 +21,7 @@ import { Mocked } from "jest-mock"; import { createClient, - CryptoApi, + Crypto, CryptoEvent, ICreateClientOpts, IEvent, @@ -310,7 +310,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm-keys backup (%s)", (backe }); describe("recover from backup", () => { - let aliceCrypto: CryptoApi; + let aliceCrypto: Crypto.CryptoApi; beforeEach(async () => { fetchMock.get("path:/_matrix/client/v3/room_keys/version", testData.SIGNED_BACKUP_DATA); diff --git a/spec/integ/crypto/rust-crypto.spec.ts b/spec/integ/crypto/rust-crypto.spec.ts index 311410febbe..a1b7a7545ed 100644 --- a/spec/integ/crypto/rust-crypto.spec.ts +++ b/spec/integ/crypto/rust-crypto.spec.ts @@ -23,6 +23,7 @@ import { populateStore } from "../../test-utils/test_indexeddb_cryptostore_dump" import { MSK_NOT_CACHED_DATASET } from "../../test-utils/test_indexeddb_cryptostore_dump/no_cached_msk_dump"; import { IDENTITY_NOT_TRUSTED_DATASET } from "../../test-utils/test_indexeddb_cryptostore_dump/unverified"; import { FULL_ACCOUNT_DATASET } from "../../test-utils/test_indexeddb_cryptostore_dump/full_account"; +import { EMPTY_ACCOUNT_DATASET } from "../../test-utils/test_indexeddb_cryptostore_dump/empty_account"; jest.setTimeout(15000); @@ -85,6 +86,44 @@ describe("MatrixClient.initRustCrypto", () => { ); }); + it("should create the meta db if given a storageKey", async () => { + const matrixClient = createClient({ + baseUrl: "http://test.server", + userId: "@alice:localhost", + deviceId: "aliceDevice", + }); + + // No databases. + expect(await indexedDB.databases()).toHaveLength(0); + + await matrixClient.initRustCrypto({ storageKey: new Uint8Array(32) }); + + // should have two indexed dbs now + const databaseNames = (await indexedDB.databases()).map((db) => db.name); + expect(databaseNames).toEqual( + expect.arrayContaining(["matrix-js-sdk::matrix-sdk-crypto", "matrix-js-sdk::matrix-sdk-crypto-meta"]), + ); + }); + + it("should create the meta db if given a storagePassword", async () => { + const matrixClient = createClient({ + baseUrl: "http://test.server", + userId: "@alice:localhost", + deviceId: "aliceDevice", + }); + + // No databases. + expect(await indexedDB.databases()).toHaveLength(0); + + await matrixClient.initRustCrypto({ storagePassword: "the cow is on the moon" }); + + // should have two indexed dbs now + const databaseNames = (await indexedDB.databases()).map((db) => db.name); + expect(databaseNames).toEqual( + expect.arrayContaining(["matrix-js-sdk::matrix-sdk-crypto", "matrix-js-sdk::matrix-sdk-crypto-meta"]), + ); + }); + it("should ignore a second call", async () => { const matrixClient = createClient({ baseUrl: "http://test.server", @@ -266,6 +305,38 @@ describe("MatrixClient.initRustCrypto", () => { }); }); + it("should not migrate if account data is missing", async () => { + // See https://github.com/element-hq/element-web/issues/27447 + + // Given we have an almost-empty legacy account in the database + fetchMock.get("path:/_matrix/client/v3/room_keys/version", { + status: 404, + body: { errcode: "M_NOT_FOUND", error: "No backup found" }, + }); + fetchMock.post("path:/_matrix/client/v3/keys/query", EMPTY_ACCOUNT_DATASET.keyQueryResponse); + + const testStoreName = "test-store"; + await populateStore(testStoreName, EMPTY_ACCOUNT_DATASET.dumpPath); + const cryptoStore = new IndexedDBCryptoStore(indexedDB, testStoreName); + + const matrixClient = createClient({ + baseUrl: "http://test.server", + userId: EMPTY_ACCOUNT_DATASET.userId, + deviceId: EMPTY_ACCOUNT_DATASET.deviceId, + cryptoStore, + pickleKey: EMPTY_ACCOUNT_DATASET.pickleKey, + }); + + // When we start Rust crypto, potentially triggering an upgrade + const progressListener = jest.fn(); + matrixClient.addListener(CryptoEvent.LegacyCryptoStoreMigrationProgress, progressListener); + + await matrixClient.initRustCrypto(); + + // Then no error occurs, and no upgrade happens + expect(progressListener.mock.calls.length).toBe(0); + }, 60000); + describe("Legacy trust migration", () => { async function populateAndStartLegacyCryptoStore(dumpPath: string): Promise { const testStoreName = "test-store"; diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index a66d41b3dbd..06986652d48 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -1825,7 +1825,6 @@ function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent { const buildEventMessageInThread = (root: MatrixEvent) => new MatrixEvent({ - age: 80098509, content: { "algorithm": "m.megolm.v1.aes-sha2", "ciphertext": "ENCRYPTEDSTUFF", @@ -1846,12 +1845,10 @@ const buildEventMessageInThread = (root: MatrixEvent) => sender: "@andybalaam-test1:matrix.org", type: "m.room.encrypted", unsigned: { age: 80098509 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventPollResponseReference = () => new MatrixEvent({ - age: 80098509, content: { "algorithm": "m.megolm.v1.aes-sha2", "ciphertext": "ENCRYPTEDSTUFF", @@ -1869,7 +1866,6 @@ const buildEventPollResponseReference = () => sender: "@andybalaam-test1:matrix.org", type: "m.room.encrypted", unsigned: { age: 80106237 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventReaction = (event: MatrixEvent) => @@ -1909,7 +1905,6 @@ const buildEventRedaction = (event: MatrixEvent) => const buildEventPollStartThreadRoot = () => new MatrixEvent({ - age: 80108647, content: { algorithm: "m.megolm.v1.aes-sha2", ciphertext: "ENCRYPTEDSTUFF", @@ -1923,12 +1918,10 @@ const buildEventPollStartThreadRoot = () => sender: "@andybalaam-test1:matrix.org", type: "m.room.encrypted", unsigned: { age: 80108647 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventReply = (target: MatrixEvent) => new MatrixEvent({ - age: 80098509, content: { "algorithm": "m.megolm.v1.aes-sha2", "ciphertext": "ENCRYPTEDSTUFF", @@ -1947,12 +1940,10 @@ const buildEventReply = (target: MatrixEvent) => sender: "@andybalaam-test1:matrix.org", type: "m.room.encrypted", unsigned: { age: 80098509 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventRoomName = () => new MatrixEvent({ - age: 80123249, content: { name: "1 poll, 1 vote, 1 thread", }, @@ -1963,12 +1954,10 @@ const buildEventRoomName = () => state_key: "", type: "m.room.name", unsigned: { age: 80123249 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventEncryption = () => new MatrixEvent({ - age: 80123383, content: { algorithm: "m.megolm.v1.aes-sha2", }, @@ -1979,12 +1968,10 @@ const buildEventEncryption = () => state_key: "", type: "m.room.encryption", unsigned: { age: 80123383 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventGuestAccess = () => new MatrixEvent({ - age: 80123473, content: { guest_access: "can_join", }, @@ -1995,12 +1982,10 @@ const buildEventGuestAccess = () => state_key: "", type: "m.room.guest_access", unsigned: { age: 80123473 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventHistoryVisibility = () => new MatrixEvent({ - age: 80123556, content: { history_visibility: "shared", }, @@ -2011,12 +1996,10 @@ const buildEventHistoryVisibility = () => state_key: "", type: "m.room.history_visibility", unsigned: { age: 80123556 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventJoinRules = () => new MatrixEvent({ - age: 80123696, content: { join_rule: KnownMembership.Invite, }, @@ -2027,12 +2010,10 @@ const buildEventJoinRules = () => state_key: "", type: "m.room.join_rules", unsigned: { age: 80123696 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventPowerLevels = () => new MatrixEvent({ - age: 80124105, content: { ban: 50, events: { @@ -2063,12 +2044,10 @@ const buildEventPowerLevels = () => state_key: "", type: "m.room.power_levels", unsigned: { age: 80124105 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventMember = () => new MatrixEvent({ - age: 80125279, content: { avatar_url: "mxc://matrix.org/aNtbVcFfwotudypZcHsIcPOc", displayname: "andybalaam-test1", @@ -2081,12 +2060,10 @@ const buildEventMember = () => state_key: "@andybalaam-test1:matrix.org", type: "m.room.member", unsigned: { age: 80125279 }, - user_id: "@andybalaam-test1:matrix.org", }); const buildEventCreate = () => new MatrixEvent({ - age: 80126105, content: { room_version: "6", }, @@ -2097,7 +2074,6 @@ const buildEventCreate = () => state_key: "", type: "m.room.create", unsigned: { age: 80126105 }, - user_id: "@andybalaam-test1:matrix.org", }); function assertObjectContains(obj: Record, expected: any): void { diff --git a/spec/integ/matrix-client-room-timeline.spec.ts b/spec/integ/matrix-client-room-timeline.spec.ts index a5d4c220a95..1d0ed86e0d3 100644 --- a/spec/integ/matrix-client-room-timeline.spec.ts +++ b/spec/integ/matrix-client-room-timeline.spec.ts @@ -333,7 +333,7 @@ describe("MatrixClient room timelines", function () { name: userName, url: "mxc://some/url", }); - oldMshipEvent.prev_content = { + oldMshipEvent.unsigned!.prev_content = { displayname: "Old Alice", avatar_url: undefined, membership: KnownMembership.Join, diff --git a/spec/test-utils/test-utils.ts b/spec/test-utils/test-utils.ts index 965a6a08806..a6cc6445565 100644 --- a/spec/test-utils/test-utils.ts +++ b/spec/test-utils/test-utils.ts @@ -173,8 +173,10 @@ export function mkEvent(opts: IEventOpts & { event?: boolean }, client?: MatrixC room_id: opts.room, sender: opts.sender || opts.user, // opts.user for backwards-compat content: opts.content, - prev_content: opts.prev_content, - unsigned: opts.unsigned || {}, + unsigned: { + ...opts.unsigned, + prev_content: opts.prev_content, + }, event_id: "$" + testEventIndex++ + "-" + Math.random() + "-" + Math.random(), txn_id: "~" + Math.random(), redacts: opts.redacts, diff --git a/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/README.md b/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/README.md new file mode 100644 index 00000000000..df3ab87e55c --- /dev/null +++ b/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/README.md @@ -0,0 +1,10 @@ +## Dump of an empty libolm indexeddb cryptostore to test skipping migration + +A dump of an account which is almost completely empty, and totally unsuitable +for use as a real account. + +This dump was manually created by copying and editing full_account. + +Created to test +["Unable to restore session" error due due to half-initialised legacy indexeddb crypto store #27447](https://github.com/element-hq/element-web/issues/27447). +We should not launch the Rust migration code when we find a DB in this state. diff --git a/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/dump.json b/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/dump.json new file mode 100644 index 00000000000..10227c8bc43 --- /dev/null +++ b/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/dump.json @@ -0,0 +1,14 @@ +{ + "account": [], + "device_data": [], + "inbound_group_sessions": [], + "inbound_group_sessions_withheld": [], + "notified_error_devices": [], + "outgoingRoomKeyRequests": [], + "parked_shared_history": [], + "rooms": [], + "session_problems": [], + "sessions": [], + "sessions_needing_backup": [], + "shared_history_inbound_group_sessions": [] +} diff --git a/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/index.ts b/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/index.ts new file mode 100644 index 00000000000..db196e99424 --- /dev/null +++ b/spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/index.ts @@ -0,0 +1,35 @@ +/* +Copyright 2024 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 { DumpDataSetInfo } from "../index"; + +/** + * A key query response containing the current keys of the tested user. + * To be used during tests with fetchmock. + */ +const KEYS_QUERY_RESPONSE = { device_keys: { "@emptyuser:example.com": {} } }; + +/** + * A dataset containing the information for the tested user. + * To be used during tests. + */ +export const EMPTY_ACCOUNT_DATASET: DumpDataSetInfo = { + userId: "@emptyuser:example.com", + deviceId: "EMPTYDEVIC", + pickleKey: "+/bcdefghijklmnopqrstu1/zyxvutsrqponmlkjih2", + keyQueryResponse: KEYS_QUERY_RESPONSE, + dumpPath: "spec/test-utils/test_indexeddb_cryptostore_dump/empty_account/dump.json", +}; diff --git a/spec/test-utils/test_indexeddb_cryptostore_dump/full_account/index.ts b/spec/test-utils/test_indexeddb_cryptostore_dump/full_account/index.ts index 96aa258401d..3ea92d6b210 100644 --- a/spec/test-utils/test_indexeddb_cryptostore_dump/full_account/index.ts +++ b/spec/test-utils/test_indexeddb_cryptostore_dump/full_account/index.ts @@ -1,3 +1,19 @@ +/* +Copyright 2024 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 { DumpDataSetInfo } from "../index"; /** diff --git a/spec/test-utils/test_indexeddb_cryptostore_dump/no_cached_msk_dump/index.ts b/spec/test-utils/test_indexeddb_cryptostore_dump/no_cached_msk_dump/index.ts index bc4c8449fed..3d2a380d433 100644 --- a/spec/test-utils/test_indexeddb_cryptostore_dump/no_cached_msk_dump/index.ts +++ b/spec/test-utils/test_indexeddb_cryptostore_dump/no_cached_msk_dump/index.ts @@ -1,3 +1,19 @@ +/* +Copyright 2024 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 { KeyBackupInfo } from "../../../../src/crypto-api/keybackup"; import { DumpDataSetInfo } from "../index"; diff --git a/spec/test-utils/test_indexeddb_cryptostore_dump/unverified/index.ts b/spec/test-utils/test_indexeddb_cryptostore_dump/unverified/index.ts index b89a0f3caef..4499180b6da 100644 --- a/spec/test-utils/test_indexeddb_cryptostore_dump/unverified/index.ts +++ b/spec/test-utils/test_indexeddb_cryptostore_dump/unverified/index.ts @@ -1,3 +1,19 @@ +/* +Copyright 2024 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 { DumpDataSetInfo } from "../index"; /** diff --git a/spec/unit/autodiscovery.spec.ts b/spec/unit/autodiscovery.spec.ts index ceed8be1f57..e4c7c98b293 100644 --- a/spec/unit/autodiscovery.spec.ts +++ b/spec/unit/autodiscovery.spec.ts @@ -857,7 +857,7 @@ describe("AutoDiscovery", function () { const expected = { "m.homeserver": { state: AutoDiscoveryAction.FAIL_ERROR, - error: AutoDiscovery.ERROR_HOMESERVER_TOO_OLD, + error: AutoDiscovery.ERROR_UNSUPPORTED_HOMESERVER_SPEC_VERSION, base_url: "https://example.org", }, "m.identity_server": { diff --git a/spec/unit/event-timeline-set.spec.ts b/spec/unit/event-timeline-set.spec.ts index a817127569c..c89ddc4606e 100644 --- a/spec/unit/event-timeline-set.spec.ts +++ b/spec/unit/event-timeline-set.spec.ts @@ -136,11 +136,6 @@ describe("EventTimelineSet", () => { expect(eventsInLiveTimeline.length).toStrictEqual(1); expect(eventsInLiveTimeline[0]).toStrictEqual(duplicateMessageEvent); }); - - it("Make sure legacy overload passing options directly as parameters still works", () => { - expect(() => eventTimelineSet.addLiveEvent(messageEvent, DuplicateStrategy.Replace, false)).not.toThrow(); - expect(() => eventTimelineSet.addLiveEvent(messageEvent, DuplicateStrategy.Ignore, true)).not.toThrow(); - }); }); describe("addEventToTimeline", () => { diff --git a/spec/unit/matrix-client.spec.ts b/spec/unit/matrix-client.spec.ts index b83e841fcf6..fa9cd776902 100644 --- a/spec/unit/matrix-client.spec.ts +++ b/spec/unit/matrix-client.spec.ts @@ -1560,7 +1560,6 @@ describe("MatrixClient", function () { }, }, event_id: "$ev1", - user_id: "@alice:matrix.org", }); expect(rootEvent.isThreadRoot).toBe(true); diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index 6ca454ef82a..eb90b8bdfa0 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -22,7 +22,7 @@ import { mocked } from "jest-mock"; import { M_POLL_KIND_DISCLOSED, M_POLL_RESPONSE, M_POLL_START, Optional, PollStartEvent } from "matrix-events-sdk"; import * as utils from "../test-utils/test-utils"; -import { emitPromise } from "../test-utils/test-utils"; +import { emitPromise, IMessageOpts } from "../test-utils/test-utils"; import { Direction, DuplicateStrategy, @@ -54,7 +54,6 @@ import { Crypto } from "../../src/crypto"; import * as threadUtils from "../test-utils/thread"; import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../test-utils/client"; import { logger } from "../../src/logger"; -import { IMessageOpts } from "../test-utils/test-utils"; import { flushPromises } from "../test-utils/flushPromises"; import { KnownMembership } from "../../src/@types/membership"; @@ -339,24 +338,6 @@ describe("Room", function () { }), ]; - it("Make sure legacy overload passing options directly as parameters still works", async () => { - await expect(room.addLiveEvents(events, DuplicateStrategy.Replace, false)).resolves.not.toThrow(); - await expect(room.addLiveEvents(events, DuplicateStrategy.Ignore, true)).resolves.not.toThrow(); - await expect( - // @ts-ignore - room.addLiveEvents(events, "shouldfailbecauseinvalidduplicatestrategy", false), - ).rejects.toThrow(); - }); - - it("should throw if duplicateStrategy isn't 'replace' or 'ignore'", async function () { - return expect( - // @ts-ignore - room.addLiveEvents(events, { - duplicateStrategy: "foo", - }), - ).rejects.toThrow(); - }); - it("should replace a timeline event if dupe strategy is 'replace'", async function () { // make a duplicate const dupe = utils.mkMessage({ @@ -387,7 +368,7 @@ describe("Room", function () { expect(room.timeline[0]).toEqual(events[0]); // @ts-ignore await room.addLiveEvents([dupe], { - duplicateStrategy: "ignore", + duplicateStrategy: DuplicateStrategy.Ignore, }); expect(room.timeline[0]).toEqual(events[0]); }); diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index 1a1ff5525fc..57c1066d593 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -104,7 +104,7 @@ describe("initRustCrypto", () => { } as unknown as Mocked; } - it("passes through the store params", async () => { + it("passes through the store params (passphrase)", async () => { const mockStore = { free: jest.fn() } as unknown as StoreHandle; jest.spyOn(StoreHandle, "open").mockResolvedValue(mockStore); @@ -126,7 +126,30 @@ describe("initRustCrypto", () => { expect(OlmMachine.initFromStore).toHaveBeenCalledWith(expect.anything(), expect.anything(), mockStore); }); - it("suppresses the storePassphrase if storePrefix is unset", async () => { + it("passes through the store params (key)", async () => { + const mockStore = { free: jest.fn() } as unknown as StoreHandle; + jest.spyOn(StoreHandle, "openWithKey").mockResolvedValue(mockStore); + + const testOlmMachine = makeTestOlmMachine(); + jest.spyOn(OlmMachine, "initFromStore").mockResolvedValue(testOlmMachine); + + const storeKey = new Uint8Array(32); + await initRustCrypto({ + logger, + http: {} as MatrixClient["http"], + userId: TEST_USER, + deviceId: TEST_DEVICE_ID, + secretStorage: {} as ServerSideSecretStorage, + cryptoCallbacks: {} as CryptoCallbacks, + storePrefix: "storePrefix", + storeKey: storeKey, + }); + + expect(StoreHandle.openWithKey).toHaveBeenCalledWith("storePrefix", storeKey); + expect(OlmMachine.initFromStore).toHaveBeenCalledWith(expect.anything(), expect.anything(), mockStore); + }); + + it("suppresses the storePassphrase and storeKey if storePrefix is unset", async () => { const mockStore = { free: jest.fn() } as unknown as StoreHandle; jest.spyOn(StoreHandle, "open").mockResolvedValue(mockStore); @@ -141,10 +164,11 @@ describe("initRustCrypto", () => { secretStorage: {} as ServerSideSecretStorage, cryptoCallbacks: {} as CryptoCallbacks, storePrefix: null, + storeKey: new Uint8Array(), storePassphrase: "storePassphrase", }); - expect(StoreHandle.open).toHaveBeenCalledWith(undefined, undefined); + expect(StoreHandle.open).toHaveBeenCalledWith(); expect(OlmMachine.initFromStore).toHaveBeenCalledWith(expect.anything(), expect.anything(), mockStore); }); @@ -1395,14 +1419,15 @@ describe("RustCrypto", () => { const rustCrypto = await makeTestRustCrypto(); const olmMachine: OlmMachine = rustCrypto["olmMachine"]; + const backupVersion = testData.SIGNED_BACKUP_DATA.version!; await olmMachine.enableBackupV1( (testData.SIGNED_BACKUP_DATA.auth_data as Curve25519AuthData).public_key, - testData.SIGNED_BACKUP_DATA.version!, + backupVersion, ); // we import two keys: one "from backup", and one "from export" const [backedUpRoomKey, exportedRoomKey] = testData.MEGOLM_SESSION_DATA_ARRAY; - await rustCrypto.importBackedUpRoomKeys([backedUpRoomKey]); + await rustCrypto.importBackedUpRoomKeys([backedUpRoomKey], backupVersion); await rustCrypto.importRoomKeys([exportedRoomKey]); // we ask for the keys that should be backed up @@ -1437,16 +1462,17 @@ describe("RustCrypto", () => { const rustCrypto = await makeTestRustCrypto(); const olmMachine: OlmMachine = rustCrypto["olmMachine"]; + const backupVersion = testData.SIGNED_BACKUP_DATA.version!; await olmMachine.enableBackupV1( (testData.SIGNED_BACKUP_DATA.auth_data as Curve25519AuthData).public_key, - testData.SIGNED_BACKUP_DATA.version!, + backupVersion, ); const backup = Array.from(testData.MEGOLM_SESSION_DATA_ARRAY); // in addition to correct keys, we restore an invalid key backup.push({ room_id: "!roomid", session_id: "sessionid" } as IMegolmSessionData); const progressCallback = jest.fn(); - await rustCrypto.importBackedUpRoomKeys(backup, { progressCallback }); + await rustCrypto.importBackedUpRoomKeys(backup, backupVersion, { progressCallback }); expect(progressCallback).toHaveBeenCalledWith({ total: 3, successes: 0, diff --git a/src/@types/registration.ts b/src/@types/registration.ts index 90fc098e482..7bfb99f7d40 100644 --- a/src/@types/registration.ts +++ b/src/@types/registration.ts @@ -52,21 +52,13 @@ export interface RegisterRequest { */ initial_device_display_name?: string; /** - * @deprecated missing in the spec + * Guest users can also upgrade their account by going through the ordinary register flow, + * but specifying the additional POST parameter guest_access_token containing the guest’s access token. + * They are also required to specify the username parameter to the value of the local part of their username, + * which is otherwise optional. + * @see https://spec.matrix.org/v1.10/client-server-api/#guest-access */ guest_access_token?: string; - /** - * @deprecated missing in the spec - */ - x_show_msisdn?: boolean; - /** - * @deprecated missing in the spec - */ - bind_msisdn?: boolean; - /** - * @deprecated missing in the spec - */ - bind_email?: boolean; } /** diff --git a/src/autodiscovery.ts b/src/autodiscovery.ts index 29dac54bdb7..8f4f196682c 100644 --- a/src/autodiscovery.ts +++ b/src/autodiscovery.ts @@ -43,8 +43,6 @@ export enum AutoDiscoveryError { InvalidJson = "Invalid JSON", UnsupportedHomeserverSpecVersion = "The homeserver does not meet the version requirements", - /** @deprecated Replaced by `UnsupportedHomeserverSpecVersion` */ - HomeserverTooOld = UnsupportedHomeserverSpecVersion, // TODO: Implement when Sydent supports the `/versions` endpoint - https://github.com/matrix-org/sydent/issues/424 //IdentityServerTooOld = "The identity server does not meet the minimum version requirements", } @@ -91,9 +89,6 @@ export class AutoDiscovery { public static readonly ERROR_UNSUPPORTED_HOMESERVER_SPEC_VERSION = AutoDiscoveryError.UnsupportedHomeserverSpecVersion; - /** @deprecated Replaced by ERROR_UNSUPPORTED_HOMESERVER_SPEC_VERSION */ - public static readonly ERROR_HOMESERVER_TOO_OLD = AutoDiscovery.ERROR_UNSUPPORTED_HOMESERVER_SPEC_VERSION; - public static readonly ALL_ERRORS = Object.keys(AutoDiscoveryError) as AutoDiscoveryError[]; /** diff --git a/src/client.ts b/src/client.ts index 27485d076f8..72e28f52916 100644 --- a/src/client.ts +++ b/src/client.ts @@ -357,14 +357,14 @@ export interface ICreateClientOpts { deviceToImport?: IExportedDevice; /** - * Encryption key used for encrypting sensitive data (such as e2ee keys) in storage. + * Encryption key used for encrypting sensitive data (such as e2ee keys) in {@link ICreateClientOpts#cryptoStore}. * * This must be set to the same value every time the client is initialised for the same device. * - * If unset, either a hardcoded key or no encryption at all is used, depending on the Crypto implementation. - * - * No particular requirement is placed on the key data (it is fed into an HKDF to generate the actual encryption - * keys). + * This is only used for the legacy crypto implementation (as used by {@link MatrixClient#initCrypto}), + * but if you use the rust crypto implementation ({@link MatrixClient#initRustCrypto}) and the device + * previously used legacy crypto (so must be migrated), then this must still be provided, so that the + * data can be migrated from the legacy store. */ pickleKey?: string; @@ -1480,13 +1480,6 @@ export class MatrixClient extends TypedEventEmitter { + public async initRustCrypto( + args: { + useIndexedDB?: boolean; + storageKey?: Uint8Array; + storagePassword?: string; + } = {}, + ): Promise { if (this.cryptoBackend) { this.logger.warn("Attempt to re-initialise e2e encryption on MatrixClient"); return; @@ -2272,11 +2272,15 @@ export class MatrixClient extends TypedEventEmitter { + legacyMigrationProgressListener: (progress: number, total: number): void => { this.emit(CryptoEvent.LegacyCryptoStoreMigrationProgress, progress, total); }, }); @@ -2895,7 +2899,7 @@ export class MatrixClient extends TypedEventEmitter { if (!this.crypto) { @@ -3370,7 +3374,7 @@ export class MatrixClient extends TypedEventEmitter { if (!this.crypto) { @@ -3852,12 +3856,13 @@ export class MatrixClient extends TypedEventEmitter { this.logger.warn("Error caching session backup key:", e); }) @@ -3911,7 +3916,8 @@ export class MatrixClient extends TypedEventEmitter { // We have a chunk of decrypted keys: import them try { - await this.cryptoBackend!.importBackedUpRoomKeys(chunk, { + const backupVersion = backupInfo.version!; + await this.cryptoBackend!.importBackedUpRoomKeys(chunk, backupVersion, { untrusted, }); totalImported += chunk.length; @@ -3941,7 +3947,7 @@ export class MatrixClient extends TypedEventEmitter { - // backwards compat - if (bindThreepids === true) { - bindThreepids = { email: true }; - } else if (bindThreepids === null || bindThreepids === undefined || bindThreepids === false) { - bindThreepids = {}; - } if (sessionId) { auth.session = sessionId; } @@ -7912,27 +7912,12 @@ export class MatrixClient extends TypedEventEmitter; + importBackedUpRoomKeys(keys: IMegolmSessionData[], backupVersion: string, opts?: ImportRoomKeysOpts): Promise; } /** The methods which crypto implementations should expose to the Sync api diff --git a/src/crypto-api/keybackup.ts b/src/crypto-api/keybackup.ts index edb4908ec3a..71c47d6834f 100644 --- a/src/crypto-api/keybackup.ts +++ b/src/crypto-api/keybackup.ts @@ -63,7 +63,7 @@ export interface BackupTrustInfo { } /** - * The result of {@link CryptoApi.checkKeyBackupAndEnable}. + * The result of {@link Crypto.CryptoApi.checkKeyBackupAndEnable}. */ export interface KeyBackupCheck { backupInfo: KeyBackupInfo; diff --git a/src/crypto/index.ts b/src/crypto/index.ts index ff62c429c9f..4379c2e1272 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -643,7 +643,7 @@ export class Crypto extends TypedEventEmitter { const publicKeysOnDevice = Boolean(this.crossSigningInfo.getId()); @@ -1167,7 +1167,7 @@ export class Crypto extends TypedEventEmitter { // Delete existing ones @@ -1203,7 +1203,7 @@ export class Crypto extends TypedEventEmitter { await this.backupManager.deleteKeyBackupVersion(version); @@ -1350,7 +1350,7 @@ export class Crypto extends TypedEventEmitter { if (this.backupManager.getKeyBackupEnabled()) { @@ -1372,7 +1372,7 @@ export class Crypto extends TypedEventEmitter { const checkResult = await this.backupManager.checkKeyBackup(); @@ -1589,7 +1589,7 @@ export class Crypto extends TypedEventEmitter { return this.checkUserTrust(userId); @@ -1888,7 +1888,11 @@ export class Crypto extends TypedEventEmitter { + public importBackedUpRoomKeys( + keys: IMegolmSessionData[], + backupVersion: string, + opts: ImportRoomKeysOpts = {}, + ): Promise { opts.source = "backup"; return this.importRoomKeys(keys, opts); } @@ -1986,7 +1990,7 @@ export class Crypto extends TypedEventEmitter { if (!this.olmDevice.deviceCurve25519Key) { @@ -2340,7 +2344,7 @@ export class Crypto extends TypedEventEmitter { await this.setDeviceVerification(userId, deviceId, verified); @@ -2349,7 +2353,7 @@ export class Crypto extends TypedEventEmitter { await this.setDeviceVerified(this.userId, deviceId, true); @@ -2785,7 +2789,7 @@ export class Crypto extends TypedEventEmitter { const encryptionInfo = this.getEventEncryptionInfo(event); @@ -4268,7 +4272,7 @@ export class Crypto extends TypedEventEmitter { return this.isRoomEncrypted(roomId); diff --git a/src/matrix.ts b/src/matrix.ts index ed71f7dfcac..793a894e0d0 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -114,20 +114,6 @@ export { LocationAssetType } from "./@types/location"; */ export * as Crypto from "./crypto-api"; -/** - * Backwards compatibility re-export - * @internal - * @deprecated use {@link Crypto.CryptoApi} - */ -export type { CryptoApi } from "./crypto-api"; - -/** - * Backwards compatibility re-export - * @internal - * @deprecated use {@link Crypto.DeviceVerificationStatus} - */ -export { DeviceVerificationStatus } from "./crypto-api"; - let cryptoStoreFactory = (): CryptoStore => new MemoryCryptoStore(); /** diff --git a/src/models/MSC3089TreeSpace.ts b/src/models/MSC3089TreeSpace.ts index 76aae65588c..6dc1b6fbb63 100644 --- a/src/models/MSC3089TreeSpace.ts +++ b/src/models/MSC3089TreeSpace.ts @@ -35,7 +35,7 @@ import { ISendEventResponse } from "../@types/requests"; import { FileType } from "../http-api"; import { KnownMembership } from "../@types/membership"; import { RoomPowerLevelsEventContent, SpaceChildEventContent } from "../@types/state_events"; -import { EncryptedFile, FileContent } from "../@types/media"; +import type { EncryptedFile, FileContent } from "../@types/media"; /** * The recommended defaults for a tree space's power levels. Note that this diff --git a/src/models/event-timeline-set.ts b/src/models/event-timeline-set.ts index 38d47cd2147..e64d118fdd5 100644 --- a/src/models/event-timeline-set.ts +++ b/src/models/event-timeline-set.ts @@ -592,43 +592,8 @@ export class EventTimelineSet extends TypedEventEmitter { */ private threads = new Map(); - /** - * @deprecated This value is unreliable. It may not contain the last thread. - * Use {@link Room.getLastThread} instead. - */ - public lastThread?: Thread; - /** * A mapping of eventId to all visibility changes to apply * to the event, by chronological order, as per @@ -1382,32 +1376,6 @@ export class Room extends ReadReceipt { } } - /** - * Returns whether there are any devices in the room that are unverified - * - * Note: Callers should first check if crypto is enabled on this device. If it is - * disabled, then we aren't tracking room devices at all, so we can't answer this, and an - * error will be thrown. - * - * @returns the result - * - * @deprecated Not supported under rust crypto. Instead, call {@link Room.getEncryptionTargetMembers}, - * {@link CryptoApi.getUserDeviceInfo}, and {@link CryptoApi.getDeviceVerificationStatus}. - */ - public async hasUnverifiedDevices(): Promise { - if (!this.hasEncryptionStateEvent()) { - return false; - } - const e2eMembers = await this.getEncryptionTargetMembers(); - for (const member of e2eMembers) { - const devices = this.client.getStoredDevicesForUser(member.userId); - if (devices.some((device) => device.isUnverified())) { - return true; - } - } - return false; - } - /** * Return the timeline sets for this room. * @returns array of timeline sets for this room @@ -2458,15 +2426,6 @@ export class Room extends ReadReceipt { // and pass the event through this. thread.addEvents(events, false); - const isNewer = - this.lastThread?.rootEvent && - rootEvent?.localTimestamp && - this.lastThread.rootEvent?.localTimestamp < rootEvent?.localTimestamp; - - if (!this.lastThread || isNewer) { - this.lastThread = thread; - } - // We need to update the thread root events, but the thread may not be ready yet. // If it isn't, it will fire ThreadEvent.Update when it is and we'll call updateThreadRootEvents then. if (this.threadsReady && thread.initialEventsFetched) { @@ -2896,39 +2855,8 @@ export class Room extends ReadReceipt { * @param addLiveEventOptions - addLiveEvent options * @throws If `duplicateStrategy` is not falsey, 'replace' or 'ignore'. */ - public async addLiveEvents(events: MatrixEvent[], addLiveEventOptions?: IAddLiveEventOptions): Promise; - /** - * @deprecated In favor of the overload with `IAddLiveEventOptions` - */ - public async addLiveEvents( - events: MatrixEvent[], - duplicateStrategy?: DuplicateStrategy, - fromCache?: boolean, - ): Promise; - public async addLiveEvents( - events: MatrixEvent[], - duplicateStrategyOrOpts?: DuplicateStrategy | IAddLiveEventOptions, - fromCache = false, - ): Promise { - let duplicateStrategy: DuplicateStrategy | undefined = duplicateStrategyOrOpts as DuplicateStrategy; - let timelineWasEmpty: boolean | undefined = false; - if (typeof duplicateStrategyOrOpts === "object") { - ({ - duplicateStrategy, - fromCache = false, - /* roomState, (not used here) */ - timelineWasEmpty, - } = duplicateStrategyOrOpts); - } else if (duplicateStrategyOrOpts !== undefined) { - // Deprecation warning - // FIXME: Remove after 2023-06-01 (technical debt) - logger.warn( - "Overload deprecated: " + - "`Room.addLiveEvents(events, duplicateStrategy?, fromCache?)` " + - "is deprecated in favor of the overload with `Room.addLiveEvents(events, IAddLiveEventOptions)`", - ); - } - + public async addLiveEvents(events: MatrixEvent[], addLiveEventOptions?: IAddLiveEventOptions): Promise { + const { duplicateStrategy, fromCache, timelineWasEmpty = false } = addLiveEventOptions ?? {}; if (duplicateStrategy && ["replace", "ignore"].indexOf(duplicateStrategy) === -1) { throw new Error("duplicateStrategy MUST be either 'replace' or 'ignore'"); } @@ -3229,7 +3157,7 @@ export class Room extends ReadReceipt { content: strippedEvent.content, event_id: "$fake" + Date.now(), room_id: this.roomId, - user_id: this.myUserId, // technically a lie + sender: this.myUserId, // technically a lie }), ]); } diff --git a/src/rust-crypto/PerSessionKeyBackupDownloader.ts b/src/rust-crypto/PerSessionKeyBackupDownloader.ts index 7642d52f9d9..ad5a649c51f 100644 --- a/src/rust-crypto/PerSessionKeyBackupDownloader.ts +++ b/src/rust-crypto/PerSessionKeyBackupDownloader.ts @@ -57,10 +57,14 @@ class KeyDownloadRateLimitError extends Error { /** Details of a megolm session whose key we are trying to fetch. */ type SessionInfo = { roomId: string; megolmSessionId: string }; -/** Holds the current backup decryptor and version that should be used. */ +/** Holds the current backup decryptor and version that should be used. + * + * This is intended to be used as an immutable object (a new instance should be created if the configuration changes), + * and some of the logic relies on that, so the properties are marked as `readonly`. + */ type Configuration = { - backupVersion: string; - decryptor: BackupDecryptor; + readonly backupVersion: string; + readonly decryptor: BackupDecryptor; }; /** @@ -392,7 +396,7 @@ export class PerSessionKeyBackupDownloader { for (const k of keys) { k.room_id = sessionInfo.roomId; } - await this.backupManager.importBackedUpRoomKeys(keys); + await this.backupManager.importBackedUpRoomKeys(keys, configuration.backupVersion); } /** diff --git a/src/rust-crypto/backup.ts b/src/rust-crypto/backup.ts index 5c9c5772e2b..8eb84887448 100644 --- a/src/rust-crypto/backup.ts +++ b/src/rust-crypto/backup.ts @@ -239,7 +239,11 @@ export class RustBackupManager extends TypedEventEmitter { + public async importBackedUpRoomKeys( + keys: IMegolmSessionData[], + backupVersion: string, + opts?: ImportRoomKeysOpts, + ): Promise { const keysByRoom: Map> = new Map(); for (const key of keys) { const roomId = new RustSdkCryptoJs.RoomId(key.room_id); @@ -259,6 +263,7 @@ export class RustBackupManager extends TypedEventEmitter { + legacyStore.getAccount(txn, (acctPickle) => { + accountPickle = acctPickle; + }); + }); + if (!accountPickle) { + // This store is not properly set up. Nothing to migrate. + logger.debug("Legacy crypto store is not set up (no account found). Not migrating."); + return; + } + let migrationState = await legacyStore.getMigrationState(); if (migrationState >= MigrationState.MEGOLM_SESSIONS_MIGRATED) { diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 29373fe3b48..8cbfba4b0c5 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -865,7 +865,7 @@ export class RustCrypto extends TypedEventEmitter { return this.eventDecryptor.getEncryptionInfoForEvent(event); @@ -1217,8 +1217,12 @@ export class RustCrypto extends TypedEventEmitter { - return await this.backupManager.importBackedUpRoomKeys(keys, opts); + public async importBackedUpRoomKeys( + keys: IMegolmSessionData[], + backupVersion: string, + opts?: ImportRoomKeysOpts, + ): Promise { + return await this.backupManager.importBackedUpRoomKeys(keys, backupVersion, opts); } /** diff --git a/src/sync-accumulator.ts b/src/sync-accumulator.ts index 67d5e1d6802..eec811577b8 100644 --- a/src/sync-accumulator.ts +++ b/src/sync-accumulator.ts @@ -58,8 +58,6 @@ export interface IRoomEvent extends IMinimalEvent { event_id: string; sender: string; origin_server_ts: number; - /** @deprecated - legacy field */ - age?: number; } export interface IStateEvent extends IRoomEvent { @@ -498,7 +496,7 @@ export class SyncAccumulator { if (transformedEvent.unsigned !== undefined) { transformedEvent.unsigned = Object.assign({}, transformedEvent.unsigned); } - const age = e.unsigned ? e.unsigned.age : e.age; + const age = e.unsigned?.age; if (age !== undefined) transformedEvent._localTs = Date.now() - age; } else { transformedEvent = e; diff --git a/src/utils.ts b/src/utils.ts index 28e867eeda0..f3ad18d5735 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -748,12 +748,7 @@ export function safeSet, K extends keyof O>(obj: O, p } export function noUnsafeEventProps(event: Partial): boolean { - return !( - unsafeProp(event.room_id) || - unsafeProp(event.sender) || - unsafeProp(event.user_id) || - unsafeProp(event.event_id) - ); + return !(unsafeProp(event.room_id) || unsafeProp(event.sender) || unsafeProp(event.event_id)); } export class MapWithDefault extends Map { diff --git a/yarn.lock b/yarn.lock index 51c6c910d10..cf6d64c5b80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1772,10 +1772,10 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@matrix-org/matrix-sdk-crypto-wasm@^4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-4.9.0.tgz#9dfed83e33f760650596c4e5c520e5e4c53355d2" - integrity sha512-/bgA4QfE7qkK6GFr9hnhjAvRSebGrmEJxukU0ukbudZcYvbzymoBBM8j3HeULXZT8kbw8WH6z63txYTMCBSDOA== +"@matrix-org/matrix-sdk-crypto-wasm@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-5.0.0.tgz#f45a7bccaad218c05bcf9e7c8ca783c9d9a07af4" + integrity sha512-37ASjCKSTU5ycGfkP+LUXG4Ok6OAf6vE+1qU6uwWhe6FwadCS3vVWzJYd/3d9BQFwsx4GhFTIAXrW4iLG85rmQ== "@matrix-org/olm@3.2.15": version "3.2.15"