Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
IPProtectionService:
"resource:///modules/ipprotection/IPProtectionService.sys.mjs",
IPProtectionStates:
"resource:///modules/ipprotection/IPProtectionService.sys.mjs",
});
const AUTOSTART_PREF = "browser.ipProtection.autoStartEnabled";
/**
* This class monitors the auto-start pref and if it sees a READY state, it
* calls `start()`. This is done only if the previous state was not a ACTIVE
* because, in that case, more likely the VPN on/off state is an user decision.
*/
class IPPAutoStart {
#shouldStartWhenReady = false;
constructor() {
XPCOMUtils.defineLazyPreferenceGetter(
this,
"autoStart",
AUTOSTART_PREF,
false,
(_pref, _oldVal, featureEnabled) => {
if (featureEnabled) {
this.init();
} else {
this.uninit();
}
}
);
}
init() {
if (this.autoStart && !this.handleEvent) {
this.handleEvent = this.#handleEvent.bind(this);
this.#shouldStartWhenReady = true;
lazy.IPProtectionService.addEventListener(
"IPProtectionService:StateChanged",
this.handleEvent
);
}
}
initOnStartupCompleted() {}
uninit() {
if (this.handleEvent) {
lazy.IPProtectionService.removeEventListener(
"IPProtectionService:StateChanged",
this.handleEvent
);
delete this.handleEvent;
this.#shouldStartWhenReady = false;
}
}
#handleEvent(_event) {
switch (lazy.IPProtectionService.state) {
case lazy.IPProtectionStates.UNINITIALIZED:
case lazy.IPProtectionStates.UNAVAILABLE:
case lazy.IPProtectionStates.UNAUTHENTICATED:
case lazy.IPProtectionStates.ENROLLING:
case lazy.IPProtectionStates.ERROR:
this.#shouldStartWhenReady = true;
break;
case lazy.IPProtectionStates.READY:
if (this.#shouldStartWhenReady) {
this.#shouldStartWhenReady = false;
lazy.IPProtectionService.start();
}
break;
default:
break;
}
}
}
/**
* This class monitors the startup phases and registers/unregisters the channel
* filter to avoid data leak. The activation of the VPN is done by the
* IPPAutoStart object above.
*/
class IPPEarlyStartupFilter {
#autoStartAndAtStartup = false;
constructor() {
this.handleEvent = this.#handleEvent.bind(this);
this.#autoStartAndAtStartup = Services.prefs.getBoolPref(
AUTOSTART_PREF,
false
);
}
init() {
if (this.#autoStartAndAtStartup) {
lazy.IPProtectionService.proxyManager.createChannelFilter();
lazy.IPProtectionService.addEventListener(
"IPProtectionService:StateChanged",
this.handleEvent
);
}
}
initOnStartupCompleted() {}
uninit() {
if (this.autoStartAndAtStartup) {
this.#autoStartAndAtStartup = false;
lazy.IPProtectionService.removeEventListener(
"IPProtectionService:StateChanged",
this.handleEvent
);
}
}
#cancelChannelFilter() {
lazy.IPProtectionService.proxyManager.cancelChannelFilter();
}
#handleEvent(_event) {
switch (lazy.IPProtectionService.state) {
case lazy.IPProtectionStates.UNAVAILABLE:
case lazy.IPProtectionStates.UNAUTHENTICATED:
case lazy.IPProtectionStates.ERROR:
// These states block the auto-start at startup.
this.#cancelChannelFilter();
this.uninit();
break;
case lazy.IPProtectionStates.ACTIVE:
// We have completed our task.
this.uninit();
break;
default:
// Let's ignoring any other state.
break;
}
}
}
const IPPAutoStartHelpers = [new IPPAutoStart(), new IPPEarlyStartupFilter()];
export { IPPAutoStartHelpers };