From 5b8c361c83481b600ef08ee4ffa2c059193ee7a1 Mon Sep 17 00:00:00 2001 From: luke crouch Date: Thu, 18 Feb 2021 09:07:07 -0600 Subject: [PATCH] start mozilla vpn integration --- package.json | 4 +- src/css/popup.css | 15 ++++++ src/img/mozillavpn.png | Bin 0 -> 5082 bytes src/js/background/backgroundLogic.js | 43 ++++++++++++++++- src/js/background/messageHandler.js | 6 +++ src/js/popup.js | 66 ++++++++++++++++++++++++--- src/js/proxified-containers.js | 2 +- src/manifest.json | 9 ++-- src/popup.html | 23 ++++++++++ 9 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 src/img/mozillavpn.png diff --git a/package.json b/package.json index 988a762..3ec9677 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testpilot-containers", "title": "Multi-Account Containers", "description": "Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.", - "version": "8.0.0", + "version": "9.0.0", "author": "Andrea Marchesini, Luke Crouch and Jonathan Kingston", "bugs": { "url": "https://github.com/mozilla/multi-account-containers/issues" @@ -25,7 +25,7 @@ "stylelint": "^13.5.0", "stylelint-config-standard": "^20.0.0", "stylelint-order": "^4.0.0", - "web-ext": "^5.4.1", + "web-ext": "^5.5.0", "webextensions-jsdom": "^1.2.1" }, "homepage": "https://github.com/mozilla/multi-account-containers#readme", diff --git a/src/css/popup.css b/src/css/popup.css index 4dfb8dc..b3fc879 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -839,6 +839,21 @@ hr { padding-inline-start: 17px; } +.mozilla-proxy-btn { + background-color: black; + background-image: url("/img/mozillavpn.png"); + background-repeat: no-repeat; + background-size: 2em 2em; + border: 0; + border-radius: 2px; + color: white; + cursor: pointer; + height: 30px; + inline-size: 100%; + line-height: 30px; + text-align: center; +} + .delete-btn { background-color: rgba(12, 12, 13, 0.1); border: 0; diff --git a/src/img/mozillavpn.png b/src/img/mozillavpn.png new file mode 100644 index 0000000000000000000000000000000000000000..85357249be3a79c603050d007adb2312519dec84 GIT binary patch literal 5082 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 literal 0 HcmV?d00001 diff --git a/src/js/background/backgroundLogic.js b/src/js/background/backgroundLogic.js index f3ef957..2711ef4 100644 --- a/src/js/background/backgroundLogic.js +++ b/src/js/background/backgroundLogic.js @@ -22,12 +22,51 @@ const backgroundLogic = { }, async getExtensionInfo() { - const manifestPath = browser.extension.getURL("manifest.json"); + const manifestPath = browser.runtime.getURL("manifest.json"); const response = await fetch(manifestPath); const extensionInfo = await response.json(); return extensionInfo; }, + async getMullvadInfo() { + const amIMullvadPath = "https://am.i.mullvad.net/json"; + + // TODO: Add some sort of error catching + const mullvadFetchData = await fetch(amIMullvadPath) + .then((response) => response.json()) + .then(data => { + return data; + }); + + return await mullvadFetchData; + }, + + async getMullvadServers() { + const port = browser.runtime.connectNative("mozillavpnnp"); + + port.onMessage.addListener(response => { + console.log("Received message: " + JSON.stringify(response)); + }); + + port.postMessage({t: "servers"}); + console.log("getMullvadServers"); + const mullvadServersPath = "https://stage-vpn.guardian.nonprod.cloudops.mozgcp.net:443/api/v1/vpn/servers"; + console.log(`mullvadServersPath: ${mullvadServersPath}`); + const response = await fetch(mullvadServersPath, { + "credentials": "omit", + "headers": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "en-US,en;q=0.5", + "Host": "stage-vpn.guardian.nonprod.cloudops.mozgcp.net", + }, + "method": "GET", + "mode": "cors" + }); + console.log(`response: ${response}`); + return await response.json(); + }, + getUserContextIdFromCookieStoreId(cookieStoreId) { if (!cookieStoreId) { return false; @@ -376,4 +415,4 @@ const backgroundLogic = { }; -backgroundLogic.init(); \ No newline at end of file +backgroundLogic.init(); diff --git a/src/js/background/messageHandler.js b/src/js/background/messageHandler.js index b3270e5..d140bfd 100644 --- a/src/js/background/messageHandler.js +++ b/src/js/background/messageHandler.js @@ -106,6 +106,12 @@ const messageHandler = { return assignManager._setOrRemoveAssignment(tab.id, m.url, m.newUserContextId, m.value); }); break; + case "getMullvadInfo": + response = await backgroundLogic.getMullvadInfo(); + break; + case "getMullvadServers": + response = await backgroundLogic.getMullvadServers(); + break; } return response; }); diff --git a/src/js/popup.js b/src/js/popup.js index 6c0d7ab..d1a3018 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -29,6 +29,7 @@ const ALWAYS_OPEN_IN_PICKER = "always-open-in"; const P_CONTAINER_INFO = "containerInfo"; const P_CONTAINER_EDIT = "containerEdit"; const P_CONTAINER_DELETE = "containerDelete"; +const P_CONTAINER_MOZ_VPN_PROXY = "containerMozVpnProxy"; const P_CONTAINERS_ACHIEVEMENT = "containersAchievement"; const P_CONTAINER_ASSIGNMENTS = "containerAssignments"; @@ -41,7 +42,7 @@ function addRemoveSiteIsolation() { } async function getExtensionInfo() { - const manifestPath = browser.extension.getURL("manifest.json"); + const manifestPath = browser.runtime.getURL("manifest.json"); const response = await fetch(manifestPath); const extensionInfo = await response.json(); return extensionInfo; @@ -265,9 +266,6 @@ const Logic = { const panelElement = document.querySelector(this.getPanelSelector(panelItem)); if (!panelElement.classList.contains("hide")) { panelElement.classList.add("hide"); - if ("unregister" in panelItem) { - panelItem.unregister(); - } } }); const panelEl = document.querySelector(this.getPanelSelector(this._panels[panel])); @@ -665,9 +663,6 @@ Logic.registerPanel(P_CONTAINERS_LIST, { }, - unregister() { - }, - // This method is called when the panel is shown. async prepare() { const fragment = document.createDocumentFragment(); @@ -1463,6 +1458,12 @@ Logic.registerPanel(P_CONTAINER_EDIT, { Utils.addEnterHandler(deleteButton, () => { Logic.showPanel(P_CONTAINER_DELETE, identity); }); + + const mozillaVpnButton = document.getElementById("mozilla-proxy-button"); + Utils.addEnterHandler(mozillaVpnButton, () => { + Logic.showPanel(P_CONTAINER_MOZ_VPN_PROXY, identity); + }); + return Promise.resolve(null); }, @@ -1517,6 +1518,57 @@ Logic.registerPanel(P_CONTAINER_DELETE, { }, }); +// P_CONTAINER_MOZ_VPN_PROXY: Choose a Mozilla VPN Proxy node +// ---------------------------------------------------------------------------- + +Logic.registerPanel(P_CONTAINER_MOZ_VPN_PROXY, { + panelSelector: "#moz-vpn-proxy-panel", + + // This method is called when the object is registered. + initialize() { + Utils.addEnterHandler(document.querySelector("#choose-moz-vpn-proxy-cancel-link"), () => { + Logic.showPreviousPanel(); + }); + Utils.addEnterHandler(document.querySelector("#close-moz-vpn-proxy-panel"), () => { + Logic.showPreviousPanel(); + }); + Utils.addEnterHandler(document.querySelector("#choose-moz-vpn-proxy-ok-link"), async () => { + try { + alert("assign the proxy to the container here!"); + Logic.showPanel(P_CONTAINER_INFO, Logic.currentIdentity()); + } catch (e) { + Logic.showPanel(P_CONTAINER_INFO, Logic.currentIdentity()); + } + }); + }, + + // This method is called when the panel is shown. + async prepare() { + const serversListEl = document.getElementById("choose-moz-vpn-proxy-server-list"); + const promoEl = document.getElementById("choose-moz-vpn-proxy-promo"); + const mullvadInfo = await browser.runtime.sendMessage({ + method: "getMullvadInfo" + }); + console.log(`mullvadInfo: ${mullvadInfo}`); + console.log(`mullvadInfo.mullvad_exit_ip: ${mullvadInfo.mullvad_exit_ip}`); + if (mullvadInfo.mullvad_exit_ip) { + const mullvadServers = await browser.runtime.sendMessage({ + method: "getMullvadServers" + }); + const serversUl = document.createElement("ul"); + for (const country of mullvadServers.countries) { + const serverLi = document.createElement("li"); + serverLi.innerHtml = Utils.escaped`${country.name}`; + serversUl.appendChild(serverLi); + } + serversListEl.appendChild(serversUl); + promoEl.classList.add("hide"); + serversListEl.classList.remove("hide"); + return Promise.resolve(null); + } + } +}); + // P_CONTAINERS_ACHIEVEMENT: Page for achievement. // ---------------------------------------------------------------------------- diff --git a/src/js/proxified-containers.js b/src/js/proxified-containers.js index 795ae8e..4008df2 100644 --- a/src/js/proxified-containers.js +++ b/src/js/proxified-containers.js @@ -111,7 +111,7 @@ proxifiedContainers = { //Parses a proxy description string of the format type://host[:port] or type://username:password@host[:port] (port is optional) parseProxy(proxy_str) { - const proxyRegexp = /(?(https?)|(socks4?)):\/\/(\b(?\w+):(?\w+)@)?(?((?:\d{1,3}\.){3}\d{1,3}\b)|(\b(\w+)(\.(\w+))+))(:(?\d+))?/; + const proxyRegexp = /(?(https?)|(socks4?)):\/\/(\b(?\w+):(?\w+)@)?(?((?:\d{1,3}\.){3}\d{1,3}\b)|(\b([\w.-]+)(\.([\w.-]+))+))(:(?\d+))?/; if (proxyRegexp.test(proxy_str) !== true) { return false; } diff --git a/src/manifest.json b/src/manifest.json index e2bbc1e..f993c8f 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Firefox Multi-Account Containers", - "version": "8.0.0", + "version": "9.0.0", "incognito": "not_allowed", "description": "Multi-Account Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.", "icons": { @@ -10,7 +10,7 @@ }, "applications": { "gecko": { - "id": "@testpilot-containers", + "id": "vpn@mozilla.org", "strict_min_version": "67.0" } }, @@ -24,11 +24,14 @@ "history", "idle", "management", + "nativeMessaging", "storage", "tabs", "webRequestBlocking", "webRequest", - "proxy" + "proxy", + + "https://stage-vpn.guardian.nonprod.cloudops.mozgcp.net:443/*" ], "optional_permissions": [ "bookmarks" diff --git a/src/popup.html b/src/popup.html index 878e4ef..a806be8 100644 --- a/src/popup.html +++ b/src/popup.html @@ -301,6 +301,7 @@
Proxy (Optional) + Use Mozilla VPN
@@ -360,6 +361,28 @@ +
+

+ Mozilla VPN Proxies +

+ +
+
+
+

Select a proxy server

+
+
+

Mozilla VPN

+

You aren't connected to Mozilla VPN.

+

Connect to Mozilla VPN to use its proxy.

+
+
+ +
+