Skip to content

Commit

Permalink
basti/refactorVPNController (#56)
Browse files Browse the repository at this point in the history
So the idea is to remove the `VPNState(oldstate)` pattern. 
I originally chose this pattern as we only had one message-pipe thing
and it would have been mindbogglingly annyoing to write `getServers`
`getInfoX` etc commands. So if we only had an immutable sum type for the
state i could avoid some complexity :)
This however meant that we were creating a new immutable copy of the
serverlist even if just the connection status changed.


Given we now have property's and ipc none of those reasons exists, i can
now easily have multiple fields that push info as they come in.
So i think it's nicer to have `postToApp(servers) -> will update
VPNController.servers-> will notify property subscribers`.
  • Loading branch information
strseb authored Sep 4, 2024
1 parent 3581830 commit 036a604
Show file tree
Hide file tree
Showing 10 changed files with 378 additions and 242 deletions.
10 changes: 2 additions & 8 deletions src/background/vpncontroller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,5 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

export {
VPNState,
StateVPNEnabled,
StateVPNUnavailable,
StateVPNDisabled,
REQUEST_TYPES,
} from "./states.js";
export { VPNController } from "./vpncontroller.js";
export * from "./states.js";
export * from "./vpncontroller.js";
114 changes: 40 additions & 74 deletions src/background/vpncontroller/states.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

// @ts-check

const MOZILLA_VPN_SERVERS_KEY = "mozillaVpnServers";

/**
* Commands we know we can send
* to the vpn
Expand Down Expand Up @@ -46,62 +44,6 @@ export class VPNState {
* Timestamp since the VPN connection was established
*/
connectedSince = 0;
/**
* Constructs state of another state, moving
* non essential data.
*
* @param {VPNState?} other
*/
constructor(other) {
if (!other) {
return;
}
if (other.servers) {
this.servers = [...other.servers];
}
if (other.isExcluded != null) {
this.isExcluded = other.isExcluded;
}
this.exitServerCity = other.exitServerCity;
this.exitServerCountry = other.exitServerCountry;
}

/**
* Takes a state, fetches data from storage and then
* constructs a copy with the data included.
*
* @param {VPNState} state - The state to replicate
* @param {browser.storage.StorageArea} storage - The storage area to look for
* @param {String} key - The key to put the state in
* @returns {Promise<VPNState>} - Returns a copy of the state, or the same in case of missing data.
*/
static async fromStorage(
state = new StateVPNUnavailable(null),
storage = browser.storage.local,
key = MOZILLA_VPN_SERVERS_KEY
) {
const { mozillaVpnServers } = await storage.get(MOZILLA_VPN_SERVERS_KEY);
if (typeof mozillaVpnServers === "undefined") {
await storage.set({ [MOZILLA_VPN_SERVERS_KEY]: [] });
return state;
}
// @ts-ignore
return new state.constructor({
servers: mozillaVpnServers,
});
}
/** Puts a state's data into storage, to make sure we can recreate it next time using
* @param {VPNState} state - The state to replicate
* @param {browser.storage.StorageArea} storage - The storage area to look for
*/
static putIntoStorage(
state = new StateVPNUnavailable(null),
storage = browser.storage.local,
key = MOZILLA_VPN_SERVERS_KEY
) {
// @ts-ignore
storage.set({ [key]: state.servers });
}
}

/**
Expand All @@ -122,6 +64,17 @@ export class StateVPNDisabled extends VPNState {
state = "Disabled";
alive = true;
connected = false;

/**
*
* @param {ServerCity | undefined} exitServerCity
* @param {ServerCountry | undefined } exitServerCountry
*/
constructor(exitServerCity, exitServerCountry) {
super();
this.exitServerCity = exitServerCity;
this.exitServerCountry = exitServerCountry;
}
}

/**
Expand All @@ -131,25 +84,17 @@ export class StateVPNDisabled extends VPNState {
export class StateVPNEnabled extends VPNState {
/**
*
* @param {VPNState} other -
* @param {string|boolean} aloophole - False if loophole is not supported,
* @param {ServerCity | undefined} exitServerCity
* @param {ServerCountry | undefined } exitServerCountry
*/
constructor(other, aloophole, connectedSince) {
super(other);
if (other) {
this.loophole = other.loophole;
this.exitServerCity = other.exitServerCity;
this.exitServerCountry = other.exitServerCountry;
this.connectedSince = other.connectedSince;
}
if (aloophole) {
this.loophole = aloophole;
}
if (connectedSince) {
this.connectedSince = connectedSince;
}
constructor(exitServerCity, exitServerCountry, aloophole, connectedSince) {
super();
this.exitServerCity = exitServerCity;
this.exitServerCountry = exitServerCountry;
this.loophole = aloophole;
this.connectedSince = connectedSince;
}

state = "Enabled";
alive = true;
connected = true;
Expand Down Expand Up @@ -180,3 +125,24 @@ export class ServerCountry {
code = "";
name = "";
}

// This is what the client response when calling status
export class vpnStatusResponse {
t = "status";
status = {
location: {
exit_country_code: "",
exit_city_name: "",
entry_country_code: "",
entry_city_name: "",
},
authenticated: false,
connectedSince: "0",
app: "MozillaVPN::CustomState",
vpn: "Controller::StateOn",
localProxy: {
available: false,
url: "https://localhost:8080",
},
};
}
Loading

0 comments on commit 036a604

Please sign in to comment.