diff --git a/package.json b/package.json index 988a762..fa55bf9 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" 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 0000000..8535724 Binary files /dev/null and b/src/img/mozillavpn.png differ diff --git a/src/js/background/backgroundLogic.js b/src/js/background/backgroundLogic.js index f3ef957..f2395b4 100644 --- a/src/js/background/backgroundLogic.js +++ b/src/js/background/backgroundLogic.js @@ -28,6 +28,47 @@ const backgroundLogic = { return extensionInfo; }, + async getMullvadInfo() { + console.log("getMullvadInfo"); + const amIMullvadPath = "https://am.i.mullvad.net/json"; + console.log(`fetching ${amIMullvadPath}`); + const response = await fetch("https://am.i.mullvad.net/json", { + "credentials": "omit", + "headers": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "en-US,en;q=0.5", + "Host": "am.i.mullvad.net", + }, + "method": "GET", + "mode": "cors" + }); + // const response = await fetch(amIMullvadPath); + console.log(`response: ${response}`); + const responseJson = await response.json(); + console.log(`responseJson: ${responseJson}`); + return responseJson; + }, + + async getMullvadServers() { + console.log("getMullvadServers"); + const mullvadServersPath = "https://stage-vpn.guardian.nonprod.cloudops.mozgcp.net/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 +417,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..98e7cc9 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"; @@ -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..90f9e0f 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": { @@ -28,7 +28,9 @@ "tabs", "webRequestBlocking", "webRequest", - "proxy" + "proxy", + + "https://am.i.mullvad.net/*" ], "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.

+
+
+ +
+