From a115c7e4254666b3183812bb08efcc4f0915ad7a Mon Sep 17 00:00:00 2001 From: Sebastian Streich Date: Mon, 9 Dec 2024 14:09:21 +0100 Subject: [PATCH] FXVPN-12 Allow manipulation of client settings --- src/background/vpncontroller/states.js | 5 +++ src/background/vpncontroller/vpncontroller.js | 18 ++++++++++ .../vpncontroller/vpncontroller.test.mjs | 34 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/background/vpncontroller/states.js b/src/background/vpncontroller/states.js index 62f302ce..dbb253c4 100644 --- a/src/background/vpncontroller/states.js +++ b/src/background/vpncontroller/states.js @@ -20,6 +20,7 @@ export const REQUEST_TYPES = [ "session_start", "session_stop", "interventions", + "settings", ]; export class VPNState { @@ -214,3 +215,7 @@ export class vpnStatusResponse { version: "2.25.0", }; } + +export class VPNSettings { + extensionTelemetryEnabled = false; +} diff --git a/src/background/vpncontroller/vpncontroller.js b/src/background/vpncontroller/vpncontroller.js index 25618dd3..35cc3153 100644 --- a/src/background/vpncontroller/vpncontroller.js +++ b/src/background/vpncontroller/vpncontroller.js @@ -27,6 +27,7 @@ import { StateVPNClosed, StateVPNSignedOut, StateVPNNeedsUpdate, + VPNSettings, } from "./states.js"; const log = Logger.logger("TabHandler"); @@ -47,6 +48,7 @@ export class VPNController extends Component { postToApp: PropertyType.Function, isolationKey: PropertyType.Bindable, featureList: PropertyType.Bindable, + settings: PropertyType.Bindable, }; get state() { @@ -66,6 +68,9 @@ export class VPNController extends Component { get interventions() { return this.#mInterventions; } + get settings() { + return this.#settings.readOnly; + } initNativeMessaging() { log("initNativeMessaging"); @@ -188,6 +193,17 @@ export class VPNController extends Component { ...new FeatureFlags(), ...response.featurelist, }); + break; + case "settings": + const settings = new VPNSettings(); + // Copy over all values that we expect to be in VPNSettings + Object.keys(settings).forEach((k) => { + if (response.settings[k]) { + settings[k] = response.settings[k]; + } + }); + this.#settings.set(settings); + break; default: console.log("Unexpected Message type: " + response.t); } @@ -210,6 +226,7 @@ export class VPNController extends Component { this.postToApp("status"); this.postToApp("servers"); this.postToApp("disabled_apps"); + this.postToApp("settings"); }); return; } @@ -247,6 +264,7 @@ export class VPNController extends Component { #isExcluded = property(false); #mInterventions = property([]); + #settings = property(new VPNSettings()); } export function isSplitTunnled( diff --git a/tests/jest/background/vpncontroller/vpncontroller.test.mjs b/tests/jest/background/vpncontroller/vpncontroller.test.mjs index aa987241..5d8e6cae 100644 --- a/tests/jest/background/vpncontroller/vpncontroller.test.mjs +++ b/tests/jest/background/vpncontroller/vpncontroller.test.mjs @@ -8,6 +8,8 @@ import { isSplitTunnled, ServerCity, ServerCountry, + VPNController, + VPNSettings, vpnStatusResponse, } from "../../../../src/background/vpncontroller"; @@ -178,3 +180,35 @@ describe("fromVPNStatusResponse", () => { expect(result.state).toBe("NeedsUpdate"); }); }); + +describe("IPC::Settings", () => { + it("can handle a setting response", async () => { + const target = new VPNController({ registerObserver: () => {} }); + // The Value should be the default one. + expect(target.settings.value.extensionTelemetryEnabled).toBe( + new VPNSettings().extensionTelemetryEnabled + ); + // The VPN Client may at any point push new data + const message = { + t: "settings", + settings: { + extensionTelemetryEnabled: true, + }, + }; + await target.handleResponse(message); + expect(target.settings.value.extensionTelemetryEnabled).toBe( + message.settings.extensionTelemetryEnabled + ); + }); + it("ignores unknown settings", async () => { + const target = new VPNController({ registerObserver: () => {} }); + const message = { + t: "settings", + settings: { + thisSettingDoesNotExist: true, + }, + }; + await target.handleResponse(message); + expect(target.settings.value["thisSettingDoesNotExist"]).toBe(undefined); + }); +});