Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 21ffc50

Browse files
t3chguyrichvdh
andauthored
Pass around MatrixClients instead of using MatrixClientPeg (#10984)
Co-authored-by: Richard van der Hoff <[email protected]>
1 parent b6b9ce3 commit 21ffc50

23 files changed

+152
-135
lines changed

src/DeviceListener.ts

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ limitations under the License.
1717
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
1818
import { logger } from "matrix-js-sdk/src/logger";
1919
import { CryptoEvent } from "matrix-js-sdk/src/crypto";
20-
import { ClientEvent, EventType, RoomStateEvent } from "matrix-js-sdk/src/matrix";
20+
import { ClientEvent, EventType, MatrixClient, RoomStateEvent } from "matrix-js-sdk/src/matrix";
2121
import { SyncState } from "matrix-js-sdk/src/sync";
2222
import { IKeyBackupInfo } from "matrix-js-sdk/src/crypto/keybackup";
2323

24-
import { MatrixClientPeg } from "./MatrixClientPeg";
2524
import dis from "./dispatcher/dispatcher";
2625
import {
2726
hideToast as hideBulkUnverifiedSessionsToast,
@@ -67,6 +66,8 @@ export default class DeviceListener {
6766
// The set of device IDs we're currently displaying toasts for
6867
private displayingToastsForDeviceIds = new Set<string>();
6968
private running = false;
69+
// The client with which the instance is running. Only set if `running` is true, otherwise undefined.
70+
private client?: MatrixClient;
7071
private shouldRecordClientInformation = false;
7172
private enableBulkUnverifiedSessionsReminder = true;
7273
private deviceClientInformationSettingWatcherRef: string | undefined;
@@ -76,16 +77,17 @@ export default class DeviceListener {
7677
return window.mxDeviceListener;
7778
}
7879

79-
public start(): void {
80+
public start(matrixClient: MatrixClient): void {
8081
this.running = true;
81-
MatrixClientPeg.get().on(CryptoEvent.WillUpdateDevices, this.onWillUpdateDevices);
82-
MatrixClientPeg.get().on(CryptoEvent.DevicesUpdated, this.onDevicesUpdated);
83-
MatrixClientPeg.get().on(CryptoEvent.DeviceVerificationChanged, this.onDeviceVerificationChanged);
84-
MatrixClientPeg.get().on(CryptoEvent.UserTrustStatusChanged, this.onUserTrustStatusChanged);
85-
MatrixClientPeg.get().on(CryptoEvent.KeysChanged, this.onCrossSingingKeysChanged);
86-
MatrixClientPeg.get().on(ClientEvent.AccountData, this.onAccountData);
87-
MatrixClientPeg.get().on(ClientEvent.Sync, this.onSync);
88-
MatrixClientPeg.get().on(RoomStateEvent.Events, this.onRoomStateEvents);
82+
this.client = matrixClient;
83+
this.client.on(CryptoEvent.WillUpdateDevices, this.onWillUpdateDevices);
84+
this.client.on(CryptoEvent.DevicesUpdated, this.onDevicesUpdated);
85+
this.client.on(CryptoEvent.DeviceVerificationChanged, this.onDeviceVerificationChanged);
86+
this.client.on(CryptoEvent.UserTrustStatusChanged, this.onUserTrustStatusChanged);
87+
this.client.on(CryptoEvent.KeysChanged, this.onCrossSingingKeysChanged);
88+
this.client.on(ClientEvent.AccountData, this.onAccountData);
89+
this.client.on(ClientEvent.Sync, this.onSync);
90+
this.client.on(RoomStateEvent.Events, this.onRoomStateEvents);
8991
this.shouldRecordClientInformation = SettingsStore.getValue("deviceClientInformationOptIn");
9092
// only configurable in config, so we don't need to watch the value
9193
this.enableBulkUnverifiedSessionsReminder = SettingsStore.getValue(UIFeature.BulkUnverifiedSessionsReminder);
@@ -101,18 +103,15 @@ export default class DeviceListener {
101103

102104
public stop(): void {
103105
this.running = false;
104-
if (MatrixClientPeg.get()) {
105-
MatrixClientPeg.get().removeListener(CryptoEvent.WillUpdateDevices, this.onWillUpdateDevices);
106-
MatrixClientPeg.get().removeListener(CryptoEvent.DevicesUpdated, this.onDevicesUpdated);
107-
MatrixClientPeg.get().removeListener(
108-
CryptoEvent.DeviceVerificationChanged,
109-
this.onDeviceVerificationChanged,
110-
);
111-
MatrixClientPeg.get().removeListener(CryptoEvent.UserTrustStatusChanged, this.onUserTrustStatusChanged);
112-
MatrixClientPeg.get().removeListener(CryptoEvent.KeysChanged, this.onCrossSingingKeysChanged);
113-
MatrixClientPeg.get().removeListener(ClientEvent.AccountData, this.onAccountData);
114-
MatrixClientPeg.get().removeListener(ClientEvent.Sync, this.onSync);
115-
MatrixClientPeg.get().removeListener(RoomStateEvent.Events, this.onRoomStateEvents);
106+
if (this.client) {
107+
this.client.removeListener(CryptoEvent.WillUpdateDevices, this.onWillUpdateDevices);
108+
this.client.removeListener(CryptoEvent.DevicesUpdated, this.onDevicesUpdated);
109+
this.client.removeListener(CryptoEvent.DeviceVerificationChanged, this.onDeviceVerificationChanged);
110+
this.client.removeListener(CryptoEvent.UserTrustStatusChanged, this.onUserTrustStatusChanged);
111+
this.client.removeListener(CryptoEvent.KeysChanged, this.onCrossSingingKeysChanged);
112+
this.client.removeListener(ClientEvent.AccountData, this.onAccountData);
113+
this.client.removeListener(ClientEvent.Sync, this.onSync);
114+
this.client.removeListener(RoomStateEvent.Events, this.onRoomStateEvents);
116115
}
117116
if (this.deviceClientInformationSettingWatcherRef) {
118117
SettingsStore.unwatchSetting(this.deviceClientInformationSettingWatcherRef);
@@ -128,6 +127,7 @@ export default class DeviceListener {
128127
this.keyBackupStatusChecked = false;
129128
this.ourDeviceIdsAtStart = null;
130129
this.displayingToastsForDeviceIds = new Set();
130+
this.client = undefined;
131131
}
132132

133133
/**
@@ -160,40 +160,44 @@ export default class DeviceListener {
160160
* @returns the set of device IDs
161161
*/
162162
private async getDeviceIds(): Promise<Set<string>> {
163-
const cli = MatrixClientPeg.get();
164-
const crypto = cli.getCrypto();
163+
const cli = this.client;
164+
const crypto = cli?.getCrypto();
165165
if (crypto === undefined) return new Set();
166166

167-
const userId = cli.getSafeUserId();
167+
const userId = cli!.getSafeUserId();
168168
const devices = await crypto.getUserDeviceInfo([userId]);
169169
return new Set(devices.get(userId)?.keys() ?? []);
170170
}
171171

172172
private onWillUpdateDevices = async (users: string[], initialFetch?: boolean): Promise<void> => {
173+
if (!this.client) return;
173174
// If we didn't know about *any* devices before (ie. it's fresh login),
174175
// then they are all pre-existing devices, so ignore this and set the
175176
// devicesAtStart list to the devices that we see after the fetch.
176177
if (initialFetch) return;
177178

178-
const myUserId = MatrixClientPeg.get().getUserId()!;
179+
const myUserId = this.client.getSafeUserId();
179180
if (users.includes(myUserId)) await this.ensureDeviceIdsAtStartPopulated();
180181

181182
// No need to do a recheck here: we just need to get a snapshot of our devices
182183
// before we download any new ones.
183184
};
184185

185186
private onDevicesUpdated = (users: string[]): void => {
186-
if (!users.includes(MatrixClientPeg.get().getUserId()!)) return;
187+
if (!this.client) return;
188+
if (!users.includes(this.client.getSafeUserId())) return;
187189
this.recheck();
188190
};
189191

190192
private onDeviceVerificationChanged = (userId: string): void => {
191-
if (userId !== MatrixClientPeg.get().getUserId()) return;
193+
if (!this.client) return;
194+
if (userId !== this.client.getUserId()) return;
192195
this.recheck();
193196
};
194197

195198
private onUserTrustStatusChanged = (userId: string): void => {
196-
if (userId !== MatrixClientPeg.get().getUserId()) return;
199+
if (!this.client) return;
200+
if (userId !== this.client.getUserId()) return;
197201
this.recheck();
198202
};
199203

@@ -239,13 +243,14 @@ export default class DeviceListener {
239243
// The server doesn't tell us when key backup is set up, so we poll
240244
// & cache the result
241245
private async getKeyBackupInfo(): Promise<IKeyBackupInfo | null> {
246+
if (!this.client) return null;
242247
const now = new Date().getTime();
243248
if (
244249
!this.keyBackupInfo ||
245250
!this.keyBackupFetchedAt ||
246251
this.keyBackupFetchedAt < now - KEY_BACKUP_POLL_INTERVAL
247252
) {
248-
this.keyBackupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
253+
this.keyBackupInfo = await this.client.getKeyBackupVersion();
249254
this.keyBackupFetchedAt = now;
250255
}
251256
return this.keyBackupInfo;
@@ -256,13 +261,13 @@ export default class DeviceListener {
256261
// modifying the state involved here, so don't add new toasts to setup.
257262
if (isSecretStorageBeingAccessed()) return false;
258263
// Show setup toasts once the user is in at least one encrypted room.
259-
const cli = MatrixClientPeg.get();
260-
return cli && cli.getRooms().some((r) => cli.isRoomEncrypted(r.roomId));
264+
const cli = this.client;
265+
return cli?.getRooms().some((r) => cli.isRoomEncrypted(r.roomId)) ?? false;
261266
}
262267

263268
private async recheck(): Promise<void> {
264-
if (!this.running) return; // we have been stopped
265-
const cli = MatrixClientPeg.get();
269+
if (!this.running || !this.client) return; // we have been stopped
270+
const cli = this.client;
266271

267272
// cross-signing support was added to Matrix in MSC1756, which landed in spec v1.1
268273
if (!(await cli.isVersionSupported("v1.1"))) return;
@@ -285,11 +290,11 @@ export default class DeviceListener {
285290
this.checkKeyBackupStatus();
286291
} else if (this.shouldShowSetupEncryptionToast()) {
287292
// make sure our keys are finished downloading
288-
await crypto.getUserDeviceInfo([cli.getUserId()!]);
293+
await crypto.getUserDeviceInfo([cli.getSafeUserId()]);
289294

290295
// cross signing isn't enabled - nag to enable it
291296
// There are 3 different toasts for:
292-
if (!(await crypto.getCrossSigningKeyId()) && cli.getStoredCrossSigningForUser(cli.getUserId()!)) {
297+
if (!(await crypto.getCrossSigningKeyId()) && cli.getStoredCrossSigningForUser(cli.getSafeUserId())) {
293298
// Cross-signing on account but this device doesn't trust the master key (verify this session)
294299
showSetupEncryptionToast(SetupKind.VERIFY_THIS_SESSION);
295300
this.checkKeyBackupStatus();
@@ -327,7 +332,9 @@ export default class DeviceListener {
327332

328333
const isCurrentDeviceTrusted =
329334
crossSigningReady &&
330-
Boolean((await crypto.getDeviceVerificationStatus(cli.getUserId()!, cli.deviceId!))?.crossSigningVerified);
335+
Boolean(
336+
(await crypto.getDeviceVerificationStatus(cli.getSafeUserId(), cli.deviceId!))?.crossSigningVerified,
337+
);
331338

332339
// as long as cross-signing isn't ready,
333340
// you can't see or dismiss any device toasts
@@ -336,7 +343,7 @@ export default class DeviceListener {
336343
for (const deviceId of devices) {
337344
if (deviceId === cli.deviceId) continue;
338345

339-
const deviceTrust = await crypto.getDeviceVerificationStatus(cli.getUserId()!, deviceId);
346+
const deviceTrust = await crypto.getDeviceVerificationStatus(cli.getSafeUserId(), deviceId);
340347
if (!deviceTrust?.crossSigningVerified && !this.dismissed.has(deviceId)) {
341348
if (this.ourDeviceIdsAtStart?.has(deviceId)) {
342349
oldUnverifiedDeviceIds.add(deviceId);
@@ -383,11 +390,11 @@ export default class DeviceListener {
383390
}
384391

385392
private checkKeyBackupStatus = async (): Promise<void> => {
386-
if (this.keyBackupStatusChecked) {
393+
if (this.keyBackupStatusChecked || !this.client) {
387394
return;
388395
}
389396
// returns null when key backup status hasn't finished being checked
390-
const isKeyBackupEnabled = MatrixClientPeg.get().getKeyBackupEnabled();
397+
const isKeyBackupEnabled = this.client.getKeyBackupEnabled();
391398
this.keyBackupStatusChecked = isKeyBackupEnabled !== null;
392399

393400
if (isKeyBackupEnabled === false) {
@@ -412,11 +419,12 @@ export default class DeviceListener {
412419
};
413420

414421
private updateClientInformation = async (): Promise<void> => {
422+
if (!this.client) return;
415423
try {
416424
if (this.shouldRecordClientInformation) {
417-
await recordClientInformation(MatrixClientPeg.get(), SdkConfig.get(), PlatformPeg.get() ?? undefined);
425+
await recordClientInformation(this.client, SdkConfig.get(), PlatformPeg.get() ?? undefined);
418426
} else {
419-
await removeClientInformation(MatrixClientPeg.get());
427+
await removeClientInformation(this.client);
420428
}
421429
} catch (error) {
422430
// this is a best effort operation

src/IdentityAuthClient.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export default class IdentityAuthClient {
129129
} catch (e) {
130130
if (e instanceof MatrixError && e.errcode === "M_TERMS_NOT_SIGNED") {
131131
logger.log("Identity server requires new terms to be agreed to");
132-
await startTermsFlow([new Service(SERVICE_TYPES.IS, identityServerUrl, token)]);
132+
await startTermsFlow(this.matrixClient, [new Service(SERVICE_TYPES.IS, identityServerUrl, token)]);
133133
return;
134134
}
135135
throw e;

src/Lifecycle.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ export async function hydrateSession(credentials: IMatrixClientCreds): Promise<M
553553
logger.warn("Clearing all data: Old session belongs to a different user/session");
554554
}
555555

556-
if (!credentials.pickleKey) {
556+
if (!credentials.pickleKey && credentials.deviceId !== undefined) {
557557
logger.info("Lifecycle#hydrateSession: Pickle key not provided - trying to get one");
558558
credentials.pickleKey =
559559
(await PlatformPeg.get()?.getPickleKey(credentials.userId, credentials.deviceId)) ?? undefined;
@@ -603,14 +603,14 @@ async function doSetLoggedIn(credentials: IMatrixClientCreds, clearStorageEnable
603603
}
604604

605605
MatrixClientPeg.replaceUsingCreds(credentials);
606+
const client = MatrixClientPeg.get();
606607

607608
setSentryUser(credentials.userId);
608609

609610
if (PosthogAnalytics.instance.isEnabled()) {
610-
PosthogAnalytics.instance.startListeningToSettingsChanges();
611+
PosthogAnalytics.instance.startListeningToSettingsChanges(client);
611612
}
612613

613-
const client = MatrixClientPeg.get();
614614
if (credentials.freshLogin && SettingsStore.getValue("feature_dehydration")) {
615615
// If we just logged in, try to rehydrate a device instead of using a
616616
// new device. If it succeeds, we'll get a new device ID, so make sure
@@ -825,7 +825,7 @@ async function startMatrixClient(client: MatrixClient, startSyncing = true): Pro
825825
SettingsStore.runMigrations();
826826

827827
// This needs to be started after crypto is set up
828-
DeviceListener.sharedInstance().start();
828+
DeviceListener.sharedInstance().start(client);
829829
// Similarly, don't start sending presence updates until we've started
830830
// the client
831831
if (!SettingsStore.getValue("lowBandwidth")) {

src/Livestream.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ limitations under the License.
1515
*/
1616

1717
import { ClientWidgetApi } from "matrix-widget-api";
18+
import { MatrixClient } from "matrix-js-sdk/src/matrix";
1819

19-
import { MatrixClientPeg } from "./MatrixClientPeg";
2020
import SdkConfig from "./SdkConfig";
2121
import { ElementWidgetActions } from "./stores/widgets/ElementWidgetActions";
2222

@@ -27,8 +27,8 @@ export function getConfigLivestreamUrl(): string | undefined {
2727
// Dummy rtmp URL used to signal that we want a special audio-only stream
2828
const AUDIOSTREAM_DUMMY_URL = "rtmp://audiostream.dummy/";
2929

30-
async function createLiveStream(roomId: string): Promise<void> {
31-
const openIdToken = await MatrixClientPeg.get().getOpenIdToken();
30+
async function createLiveStream(matrixClient: MatrixClient, roomId: string): Promise<void> {
31+
const openIdToken = await matrixClient.getOpenIdToken();
3232

3333
const url = getConfigLivestreamUrl() + "/createStream";
3434

@@ -47,8 +47,12 @@ async function createLiveStream(roomId: string): Promise<void> {
4747
return respBody["stream_id"];
4848
}
4949

50-
export async function startJitsiAudioLivestream(widgetMessaging: ClientWidgetApi, roomId: string): Promise<void> {
51-
const streamId = await createLiveStream(roomId);
50+
export async function startJitsiAudioLivestream(
51+
matrixClient: MatrixClient,
52+
widgetMessaging: ClientWidgetApi,
53+
roomId: string,
54+
): Promise<void> {
55+
const streamId = await createLiveStream(matrixClient, roomId);
5256

5357
await widgetMessaging.transport.send(ElementWidgetActions.StartLiveStream, {
5458
rtmpStreamKey: AUDIOSTREAM_DUMMY_URL + streamId,

src/PosthogAnalytics.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ export class PosthogAnalytics {
254254
};
255255
}
256256

257-
// eslint-disable-nextline no-unused-varsx
257+
// eslint-disable-nextline no-unused-vars
258258
private capture(eventName: string, properties: Properties, options?: IPostHogEventOptions): void {
259259
if (!this.enabled) {
260260
return;
@@ -375,12 +375,12 @@ export class PosthogAnalytics {
375375
this.registerSuperProperties(this.platformSuperProperties);
376376
}
377377

378-
public async updateAnonymityFromSettings(pseudonymousOptIn: boolean): Promise<void> {
378+
public async updateAnonymityFromSettings(client: MatrixClient, pseudonymousOptIn: boolean): Promise<void> {
379379
// Update this.anonymity based on the user's analytics opt-in settings
380380
const anonymity = pseudonymousOptIn ? Anonymity.Pseudonymous : Anonymity.Disabled;
381381
this.setAnonymity(anonymity);
382382
if (anonymity === Anonymity.Pseudonymous) {
383-
await this.identifyUser(MatrixClientPeg.get(), PosthogAnalytics.getRandomAnalyticsId);
383+
await this.identifyUser(client, PosthogAnalytics.getRandomAnalyticsId);
384384
if (MatrixClientPeg.currentUserIsJustRegistered()) {
385385
this.trackNewUserEvent();
386386
}
@@ -391,7 +391,7 @@ export class PosthogAnalytics {
391391
}
392392
}
393393

394-
public startListeningToSettingsChanges(): void {
394+
public startListeningToSettingsChanges(client: MatrixClient): void {
395395
// Listen to account data changes from sync so we can observe changes to relevant flags and update.
396396
// This is called -
397397
// * On page load, when the account data is first received by sync
@@ -404,7 +404,7 @@ export class PosthogAnalytics {
404404
"pseudonymousAnalyticsOptIn",
405405
null,
406406
(originalSettingName, changedInRoomId, atLevel, newValueAtLevel, newValue) => {
407-
this.updateAnonymityFromSettings(!!newValue);
407+
this.updateAnonymityFromSettings(client, !!newValue);
408408
},
409409
);
410410
}

0 commit comments

Comments
 (0)