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

Commit 9895a8f

Browse files
authored
Disable ICE fallback based on well-known configuration (#111)
* Refactor MatrixClientBackedController.ts Signed-off-by: Michael Telatynski <[email protected]> * Disable ICE fallback based on well-known configuration Signed-off-by: Michael Telatynski <[email protected]> * Add tests Signed-off-by: Michael Telatynski <[email protected]> --------- Signed-off-by: Michael Telatynski <[email protected]>
1 parent 8a263ac commit 9895a8f

File tree

7 files changed

+119
-15
lines changed

7 files changed

+119
-15
lines changed

src/LegacyCallHandler.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,6 @@ export default class LegacyCallHandler extends EventEmitter {
765765
cancelButton: _t("action|ok"),
766766
onFinished: (allow) => {
767767
SettingsStore.setValue("fallbackICEServerAllowed", null, SettingLevel.DEVICE, allow);
768-
cli.setFallbackICEServerAllowed(!!allow);
769768
},
770769
},
771770
undefined,

src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx

+1-5
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,6 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
112112
this.context.setForceTURN(!p2p);
113113
};
114114

115-
private changeFallbackICEServerAllowed = (allow: boolean): void => {
116-
this.context.setFallbackICEServerAllowed(allow);
117-
};
118-
119115
private renderDeviceOptions(devices: Array<MediaDeviceInfo>, category: MediaDeviceKindEnum): Array<JSX.Element> {
120116
return devices.map((d) => {
121117
return (
@@ -226,7 +222,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
226222
server: new URL(FALLBACK_ICE_SERVER).pathname,
227223
})}
228224
level={SettingLevel.DEVICE}
229-
onChange={this.changeFallbackICEServerAllowed}
225+
hideIfCannotSet
230226
/>
231227
</SettingsSubsection>
232228
</SettingsSection>

src/settings/Settings.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import ServerSupportUnstableFeatureController from "./controllers/ServerSupportU
3737
import { WatchManager } from "./WatchManager";
3838
import { CustomTheme } from "../theme";
3939
import AnalyticsController from "./controllers/AnalyticsController";
40+
import FallbackIceServerController from "./controllers/FallbackIceServerController";
4041

4142
export const defaultWatchManager = new WatchManager();
4243

@@ -980,6 +981,7 @@ export const SETTINGS: { [setting: string]: ISetting } = {
980981
description: _td("settings|voip|enable_fallback_ice_server_description"),
981982
// This is a tri-state value, where `null` means "prompt the user".
982983
default: null,
984+
controller: new FallbackIceServerController(),
983985
},
984986
"showImages": {
985987
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
Copyright 2024 New Vector Ltd.
3+
4+
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
5+
Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
import { ClientEvent, IClientWellKnown, MatrixClient } from "matrix-js-sdk/src/matrix";
9+
10+
import { SettingLevel } from "../SettingLevel";
11+
import SettingsStore from "../SettingsStore.ts";
12+
import MatrixClientBackedController from "./MatrixClientBackedController.ts";
13+
14+
/**
15+
* Settings controller for the fallback ICE server setting.
16+
* This setting may be forcibly disabled by well-known value ["io.element.voip"]["disable_fallback_ice"].
17+
* This controller will update the MatrixClient's knowledge when the setting is changed.
18+
*/
19+
export default class FallbackIceServerController extends MatrixClientBackedController {
20+
private disabled = false;
21+
22+
public constructor() {
23+
super();
24+
}
25+
26+
private checkWellKnown = (wellKnown: IClientWellKnown): void => {
27+
this.disabled = !!wellKnown["io.element.voip"]?.["disable_fallback_ice"];
28+
};
29+
30+
protected async initMatrixClient(newClient: MatrixClient, oldClient?: MatrixClient): Promise<void> {
31+
oldClient?.off(ClientEvent.ClientWellKnown, this.checkWellKnown);
32+
newClient.on(ClientEvent.ClientWellKnown, this.checkWellKnown);
33+
const wellKnown = newClient.getClientWellKnown();
34+
if (wellKnown) this.checkWellKnown(wellKnown);
35+
}
36+
37+
public getValueOverride(): any {
38+
if (this.disabled) {
39+
return false;
40+
}
41+
42+
return null; // no override
43+
}
44+
45+
public get settingDisabled(): boolean | string {
46+
return this.disabled;
47+
}
48+
49+
public onChange(_level: SettingLevel, _roomId: string | null, _newValue: any): void {
50+
this.client?.setFallbackICEServerAllowed(!!SettingsStore.getValue("fallbackICEServerAllowed"));
51+
}
52+
}

src/settings/controllers/MatrixClientBackedController.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ import SettingController from "./SettingController";
1818
* This class performs no logic and should be overridden.
1919
*/
2020
export default abstract class MatrixClientBackedController extends SettingController {
21-
private static _matrixClient: MatrixClient;
21+
private static _matrixClient?: MatrixClient;
2222
private static instances: MatrixClientBackedController[] = [];
2323

2424
public static set matrixClient(client: MatrixClient) {
2525
const oldClient = MatrixClientBackedController._matrixClient;
2626
MatrixClientBackedController._matrixClient = client;
2727

2828
for (const instance of MatrixClientBackedController.instances) {
29-
instance.initMatrixClient(oldClient, client);
29+
instance.initMatrixClient(client, oldClient);
3030
}
3131
}
3232

@@ -36,9 +36,9 @@ export default abstract class MatrixClientBackedController extends SettingContro
3636
MatrixClientBackedController.instances.push(this);
3737
}
3838

39-
public get client(): MatrixClient {
39+
public get client(): MatrixClient | undefined {
4040
return MatrixClientBackedController._matrixClient;
4141
}
4242

43-
protected abstract initMatrixClient(oldClient: MatrixClient, newClient: MatrixClient): void;
43+
protected abstract initMatrixClient(newClient: MatrixClient, oldClient?: MatrixClient): void;
4444
}

src/settings/controllers/ServerSupportUnstableFeatureController.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
66
Please see LICENSE files in the repository root for full details.
77
*/
88

9-
import { MatrixClient } from "matrix-js-sdk/src/matrix";
10-
119
import { SettingLevel } from "../SettingLevel";
1210
import MatrixClientBackedController from "./MatrixClientBackedController";
1311
import { WatchManager } from "../WatchManager";
@@ -53,9 +51,9 @@ export default class ServerSupportUnstableFeatureController extends MatrixClient
5351
this.watchers.notifyUpdate(this.settingName, null, level, settingValue);
5452
}
5553

56-
protected async initMatrixClient(oldClient: MatrixClient, newClient: MatrixClient): Promise<void> {
54+
protected async initMatrixClient(): Promise<void> {
5755
// Check for stable version support first
58-
if (this.stableVersion && (await this.client.isVersionSupported(this.stableVersion))) {
56+
if (this.stableVersion && (await this.client!.isVersionSupported(this.stableVersion))) {
5957
this.disabled = false;
6058
return;
6159
}
@@ -66,7 +64,7 @@ export default class ServerSupportUnstableFeatureController extends MatrixClient
6664
for (const featureGroup of this.unstableFeatureGroups) {
6765
const featureSupportList = await Promise.all(
6866
featureGroup.map(async (feature) => {
69-
const isFeatureSupported = await this.client.doesServerSupportUnstableFeature(feature);
67+
const isFeatureSupported = await this.client!.doesServerSupportUnstableFeature(feature);
7068
return isFeatureSupported;
7169
}),
7270
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright 2024 New Vector Ltd.
3+
4+
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
5+
Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
import fetchMockJest from "fetch-mock-jest";
9+
import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/matrix";
10+
11+
import { SettingLevel } from "../../../src/settings/SettingLevel";
12+
import FallbackIceServerController from "../../../src/settings/controllers/FallbackIceServerController.ts";
13+
import MatrixClientBackedController from "../../../src/settings/controllers/MatrixClientBackedController.ts";
14+
import SettingsStore from "../../../src/settings/SettingsStore.ts";
15+
16+
describe("FallbackIceServerController", () => {
17+
beforeEach(() => {
18+
fetchMockJest.get("https://matrix.org/_matrix/client/versions", { versions: ["v1.4"] });
19+
});
20+
21+
afterEach(() => {
22+
jest.restoreAllMocks();
23+
});
24+
25+
it("should update MatrixClient's state when the setting is updated", async () => {
26+
const client = new MatrixClient({
27+
baseUrl: "https://matrix.org",
28+
userId: "@alice:matrix.org",
29+
accessToken: "token",
30+
});
31+
MatrixClientBackedController.matrixClient = client;
32+
33+
expect(client.isFallbackICEServerAllowed()).toBeFalsy();
34+
await SettingsStore.setValue("fallbackICEServerAllowed", null, SettingLevel.DEVICE, true);
35+
expect(client.isFallbackICEServerAllowed()).toBeTruthy();
36+
});
37+
38+
it("should force the setting to be disabled if disable_fallback_ice=true", async () => {
39+
const controller = new FallbackIceServerController();
40+
const client = new MatrixClient({
41+
baseUrl: "https://matrix.org",
42+
userId: "@alice:matrix.org",
43+
accessToken: "token",
44+
});
45+
MatrixClientBackedController.matrixClient = client;
46+
expect(controller.settingDisabled).toBeFalsy();
47+
48+
client["clientWellKnown"] = {
49+
"io.element.voip": {
50+
disable_fallback_ice: true,
51+
},
52+
};
53+
client.emit(ClientEvent.ClientWellKnown, client["clientWellKnown"]);
54+
55+
expect(controller.settingDisabled).toBeTruthy();
56+
});
57+
});

0 commit comments

Comments
 (0)