Skip to content

Commit dd2feb0

Browse files
committed
Merge branch 'develop' into gsouquet/stuck-notifications-edits
2 parents 9dbde34 + 1ebcac3 commit dd2feb0

19 files changed

+4254
-4070
lines changed

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ out
2121

2222
.vscode
2323
.vscode/
24+
25+
# This file is owned, parsed, and generated by allchange, which doesn't comply with prettier
26+
/CHANGELOG.md

CHANGELOG.md

Lines changed: 4016 additions & 4027 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "matrix-js-sdk",
3-
"version": "22.0.0",
3+
"version": "23.0.0",
44
"description": "Matrix Client-Server SDK for Javascript",
55
"engines": {
66
"node": ">=16.0.0"

post-release.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ if [ "$(git branch -lr | grep origin/develop -c)" -ge 1 ]; then
2121
# to the TypeScript source.
2222
src_value=$(jq -r ".matrix_src_$i" package.json)
2323
if [ "$src_value" != "null" ]; then
24-
jq ".$i = .matrix_src_$i" package.json > package.json.new && mv package.json.new package.json
24+
jq ".$i = .matrix_src_$i" package.json > package.json.new && mv package.json.new package.json && yarn prettier --write package.json
2525
else
26-
jq "del(.$i)" package.json > package.json.new && mv package.json.new package.json
26+
jq "del(.$i)" package.json > package.json.new && mv package.json.new package.json && yarn prettier --write package.json
2727
fi
2828
fi
2929
done

release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ for i in main typings
184184
do
185185
lib_value=$(jq -r ".matrix_lib_$i" package.json)
186186
if [ "$lib_value" != "null" ]; then
187-
jq ".$i = .matrix_lib_$i" package.json > package.json.new && mv package.json.new package.json
187+
jq ".$i = .matrix_lib_$i" package.json > package.json.new && mv package.json.new package.json && yarn prettier --write package.json
188188
fi
189189
done
190190

spec/integ/sliding-sync.spec.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,102 @@ describe("SlidingSync", () => {
14181418
await httpBackend!.flushAllExpected();
14191419
slidingSync.stop();
14201420
});
1421+
1422+
it("should not be possible to add/modify an already added custom subscription", async () => {
1423+
const slidingSync = new SlidingSync(proxyBaseUrl, [], defaultSub, client!, 1);
1424+
slidingSync.addCustomSubscription(customSubName1, customSub1);
1425+
slidingSync.addCustomSubscription(customSubName1, customSub2);
1426+
slidingSync.useCustomSubscription(roomA, customSubName1);
1427+
slidingSync.modifyRoomSubscriptions(new Set<string>([roomA]));
1428+
1429+
httpBackend!
1430+
.when("POST", syncUrl)
1431+
.check(function (req) {
1432+
const body = req.data;
1433+
logger.log("custom subs", body);
1434+
expect(body.room_subscriptions).toBeTruthy();
1435+
expect(body.room_subscriptions[roomA]).toEqual(customSub1);
1436+
})
1437+
.respond(200, {
1438+
pos: "b",
1439+
lists: [],
1440+
extensions: {},
1441+
rooms: {},
1442+
});
1443+
slidingSync.start();
1444+
await httpBackend!.flushAllExpected();
1445+
slidingSync.stop();
1446+
});
1447+
1448+
it("should change the custom subscription if they are different", async () => {
1449+
const slidingSync = new SlidingSync(proxyBaseUrl, [], defaultSub, client!, 1);
1450+
slidingSync.addCustomSubscription(customSubName1, customSub1);
1451+
slidingSync.addCustomSubscription(customSubName2, customSub2);
1452+
slidingSync.useCustomSubscription(roomA, customSubName1);
1453+
slidingSync.modifyRoomSubscriptions(new Set<string>([roomA]));
1454+
1455+
httpBackend!
1456+
.when("POST", syncUrl)
1457+
.check(function (req) {
1458+
const body = req.data;
1459+
logger.log("custom subs", body);
1460+
expect(body.room_subscriptions).toBeTruthy();
1461+
expect(body.room_subscriptions[roomA]).toEqual(customSub1);
1462+
expect(body.unsubscribe_rooms).toBeUndefined();
1463+
})
1464+
.respond(200, {
1465+
pos: "b",
1466+
lists: [],
1467+
extensions: {},
1468+
rooms: {},
1469+
});
1470+
slidingSync.start();
1471+
await httpBackend!.flushAllExpected();
1472+
1473+
// using the same subscription doesn't unsub nor changes subscriptions
1474+
slidingSync.useCustomSubscription(roomA, customSubName1);
1475+
slidingSync.modifyRoomSubscriptions(new Set<string>([roomA]));
1476+
1477+
httpBackend!
1478+
.when("POST", syncUrl)
1479+
.check(function (req) {
1480+
const body = req.data;
1481+
logger.log("custom subs", body);
1482+
expect(body.room_subscriptions).toBeUndefined();
1483+
expect(body.unsubscribe_rooms).toBeUndefined();
1484+
})
1485+
.respond(200, {
1486+
pos: "b",
1487+
lists: [],
1488+
extensions: {},
1489+
rooms: {},
1490+
});
1491+
slidingSync.start();
1492+
await httpBackend!.flushAllExpected();
1493+
1494+
// Changing the subscription works
1495+
slidingSync.useCustomSubscription(roomA, customSubName2);
1496+
slidingSync.modifyRoomSubscriptions(new Set<string>([roomA]));
1497+
1498+
httpBackend!
1499+
.when("POST", syncUrl)
1500+
.check(function (req) {
1501+
const body = req.data;
1502+
logger.log("custom subs", body);
1503+
expect(body.room_subscriptions).toBeTruthy();
1504+
expect(body.room_subscriptions[roomA]).toEqual(customSub2);
1505+
expect(body.unsubscribe_rooms).toBeUndefined();
1506+
})
1507+
.respond(200, {
1508+
pos: "b",
1509+
lists: [],
1510+
extensions: {},
1511+
rooms: {},
1512+
});
1513+
slidingSync.start();
1514+
await httpBackend!.flushAllExpected();
1515+
slidingSync.stop();
1516+
});
14211517
});
14221518

14231519
describe("extensions", () => {

spec/unit/event-timeline-set.spec.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
} from "../../src";
3131
import { FeatureSupport, Thread } from "../../src/models/thread";
3232
import { ReEmitter } from "../../src/ReEmitter";
33+
import { eventMapperFor } from "../../src/event-mapper";
3334

3435
describe("EventTimelineSet", () => {
3536
const roomId = "!foo:bar";
@@ -206,6 +207,7 @@ describe("EventTimelineSet", () => {
206207

207208
it("should allow edits to be added to thread timeline", async () => {
208209
jest.spyOn(client, "supportsExperimentalThreads").mockReturnValue(true);
210+
jest.spyOn(client, "getEventMapper").mockReturnValue(eventMapperFor(client, {}));
209211
Thread.hasServerSideSupport = FeatureSupport.Stable;
210212

211213
const sender = "@alice:matrix.org";
@@ -233,6 +235,25 @@ describe("EventTimelineSet", () => {
233235
sender,
234236
});
235237

238+
root.setUnsigned({
239+
"m.relations": {
240+
[RelationType.Thread]: {
241+
count: 1,
242+
latest_event: {
243+
content: threadReply.getContent(),
244+
origin_server_ts: 5,
245+
room_id: room.roomId,
246+
sender,
247+
type: EventType.RoomMessage,
248+
event_id: threadReply.getId()!,
249+
user_id: sender,
250+
age: 1,
251+
},
252+
current_user_participated: true,
253+
},
254+
},
255+
});
256+
236257
const editToThreadReply = utils.mkEvent({
237258
event: true,
238259
content: {
@@ -251,9 +272,6 @@ describe("EventTimelineSet", () => {
251272
sender,
252273
});
253274

254-
const thread = room.createThread(root.getId()!, root, [threadReply, editToThreadReply], false);
255-
256-
jest.spyOn(thread, "processEvent").mockResolvedValue();
257275
jest.spyOn(client, "paginateEventTimeline").mockImplementation(async () => {
258276
thread.timelineSet.getLiveTimeline().addEvent(threadReply, { toStartOfTimeline: true });
259277
return true;
@@ -262,6 +280,7 @@ describe("EventTimelineSet", () => {
262280
events: [],
263281
});
264282

283+
const thread = room.createThread(root.getId()!, root, [threadReply, editToThreadReply], false);
265284
thread.once(RoomEvent.TimelineReset, () => {
266285
const lastEvent = thread.timeline.at(-1)!;
267286
expect(lastEvent.getContent().body).toBe(" * edit");

spec/unit/rust-crypto.spec.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import "fake-indexeddb/auto";
18+
import { IDBFactory } from "fake-indexeddb";
19+
20+
import { RustCrypto } from "../../src/rust-crypto/rust-crypto";
21+
import { initRustCrypto } from "../../src/rust-crypto";
22+
23+
afterEach(() => {
24+
// reset fake-indexeddb after each test, to make sure we don't leak connections
25+
// cf https://github.com/dumbmatter/fakeIndexedDB#wipingresetting-the-indexeddb-for-a-fresh-state
26+
// eslint-disable-next-line no-global-assign
27+
indexedDB = new IDBFactory();
28+
});
29+
30+
describe("RustCrypto", () => {
31+
const TEST_USER = "@alice:example.com";
32+
const TEST_DEVICE_ID = "TEST_DEVICE";
33+
34+
let rustCrypto: RustCrypto;
35+
36+
beforeEach(async () => {
37+
rustCrypto = (await initRustCrypto(TEST_USER, TEST_DEVICE_ID)) as RustCrypto;
38+
});
39+
40+
describe(".exportRoomKeys", () => {
41+
it("should return a list", async () => {
42+
const keys = await rustCrypto.exportRoomKeys();
43+
expect(Array.isArray(keys)).toBeTruthy();
44+
});
45+
});
46+
});

src/@types/crypto.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,29 @@ export interface IEventDecryptionResult {
4444
claimedEd25519Key?: string;
4545
untrusted?: boolean;
4646
}
47+
48+
interface Extensible {
49+
[key: string]: any;
50+
}
51+
52+
/* eslint-disable camelcase */
53+
54+
/** The result of a call to {@link MatrixClient.exportRoomKeys} */
55+
export interface IMegolmSessionData extends Extensible {
56+
/** Sender's Curve25519 device key */
57+
sender_key: string;
58+
/** Devices which forwarded this session to us (normally empty). */
59+
forwarding_curve25519_key_chain: string[];
60+
/** Other keys the sender claims. */
61+
sender_claimed_keys: Record<string, string>;
62+
/** Room this session is used in */
63+
room_id: string;
64+
/** Unique id for the session */
65+
session_id: string;
66+
/** Base64'ed key data */
67+
session_key: string;
68+
algorithm?: string;
69+
untrusted?: boolean;
70+
}
71+
72+
/* eslint-enable camelcase */

src/client.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ limitations under the License.
2020

2121
import { EmoteEvent, IPartialEvent, MessageEvent, NoticeEvent, Optional } from "matrix-events-sdk";
2222

23+
import type { IMegolmSessionData } from "./@types/crypto";
2324
import { ISyncStateData, SyncApi, SyncState } from "./sync";
2425
import {
2526
EventStatus,
@@ -74,7 +75,6 @@ import {
7475
ICryptoCallbacks,
7576
IBootstrapCrossSigningOpts,
7677
ICheckOwnCrossSigningTrustOpts,
77-
IMegolmSessionData,
7878
isCryptoAvailable,
7979
VerificationMethod,
8080
IRoomKeyRequestBody,
@@ -3034,10 +3034,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
30343034
* session export objects
30353035
*/
30363036
public exportRoomKeys(): Promise<IMegolmSessionData[]> {
3037-
if (!this.crypto) {
3037+
if (!this.cryptoBackend) {
30383038
return Promise.reject(new Error("End-to-end encryption disabled"));
30393039
}
3040-
return this.crypto.exportRoomKeys();
3040+
return this.cryptoBackend.exportRoomKeys();
30413041
}
30423042

30433043
/**

src/common-crypto/CryptoBackend.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import type { IEventDecryptionResult } from "../@types/crypto";
17+
import type { IEventDecryptionResult, IMegolmSessionData } from "../@types/crypto";
1818
import { MatrixEvent } from "../models/event";
1919

2020
/**
@@ -60,4 +60,14 @@ export interface CryptoBackend {
6060
* Rejects with an error if there is a problem decrypting the event.
6161
*/
6262
decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult>;
63+
64+
/**
65+
* Get a list containing all of the room keys
66+
*
67+
* This should be encrypted before returning it to the user.
68+
*
69+
* @returns a promise which resolves to a list of
70+
* session export objects
71+
*/
72+
exportRoomKeys(): Promise<IMegolmSessionData[]>;
6373
}

src/crypto/OlmDevice.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ import { IndexedDBCryptoStore } from "./store/indexeddb-crypto-store";
2121
import * as algorithms from "./algorithms";
2222
import { CryptoStore, IProblem, ISessionInfo, IWithheld } from "./store/base";
2323
import { IOlmDevice, IOutboundGroupSessionKey } from "./algorithms/megolm";
24-
import { IMegolmSessionData } from "./index";
25-
import { OlmGroupSessionExtraData } from "../@types/crypto";
24+
import { IMegolmSessionData, OlmGroupSessionExtraData } from "../@types/crypto";
2625
import { IMessage } from "./algorithms/olm";
2726

2827
// The maximum size of an event is 65K, and we base64 the content, so this is a

src/crypto/algorithms/base.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ limitations under the License.
1818
* Internal module. Defines the base classes of the encryption implementations
1919
*/
2020

21+
import type { IMegolmSessionData } from "../../@types/crypto";
2122
import { MatrixClient } from "../../client";
2223
import { Room } from "../../models/room";
2324
import { OlmDevice } from "../OlmDevice";
2425
import { IContent, MatrixEvent, RoomMember } from "../../matrix";
25-
import { Crypto, IEncryptedContent, IEventDecryptionResult, IMegolmSessionData, IncomingRoomKeyRequest } from "..";
26+
import { Crypto, IEncryptedContent, IEventDecryptionResult, IncomingRoomKeyRequest } from "..";
2627
import { DeviceInfo } from "../deviceinfo";
2728
import { IRoomEncryption } from "../RoomList";
2829

src/crypto/algorithms/megolm.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ limitations under the License.
2020

2121
import { v4 as uuidv4 } from "uuid";
2222

23-
import type { IEventDecryptionResult } from "../../@types/crypto";
23+
import type { IEventDecryptionResult, IMegolmSessionData } from "../../@types/crypto";
2424
import { logger } from "../../logger";
2525
import * as olmlib from "../olmlib";
2626
import {
@@ -39,7 +39,7 @@ import { IOlmSessionResult } from "../olmlib";
3939
import { DeviceInfoMap } from "../DeviceList";
4040
import { IContent, MatrixEvent } from "../../models/event";
4141
import { EventType, MsgType, ToDeviceMessageId } from "../../@types/event";
42-
import { IMegolmEncryptedContent, IMegolmSessionData, IncomingRoomKeyRequest, IEncryptedContent } from "../index";
42+
import { IMegolmEncryptedContent, IncomingRoomKeyRequest, IEncryptedContent } from "../index";
4343
import { RoomKeyRequestState } from "../OutgoingRoomKeyRequestManager";
4444
import { OlmGroupSessionExtraData } from "../../@types/crypto";
4545
import { MatrixError } from "../../http-api";

src/crypto/backup.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818
* Classes for dealing with key backup.
1919
*/
2020

21+
import type { IMegolmSessionData } from "../@types/crypto";
2122
import { MatrixClient } from "../client";
2223
import { logger } from "../logger";
2324
import { MEGOLM_ALGORITHM, verifySignature } from "./olmlib";
@@ -36,7 +37,7 @@ import {
3637
IKeyBackupSession,
3738
} from "./keybackup";
3839
import { UnstableValue } from "../NamespacedValue";
39-
import { CryptoEvent, IMegolmSessionData } from "./index";
40+
import { CryptoEvent } from "./index";
4041
import { crypto } from "./crypto";
4142
import { HTTPError, MatrixError } from "../http-api";
4243

0 commit comments

Comments
 (0)