diff --git a/README.md b/README.md index a8750c0..4bf7d3d 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ npm install ### Build -#### Including depdencies +#### Including dependencies For testing the extension in the browser, you'll need to ensure that the 3rd party dependencies have been copied to the source directory. This is performed by the following grunt task: @@ -103,7 +103,7 @@ In both cases the extension will intercept the URL, remove the identifier and pa existing tabs/windows open to the requested URL, the URL is handled as normal. If one already exists it will open to that existing tab instead. In the case of `refreshsametab.morphic.org`, it will also trigger the page to reload. -For example, `http://opensametab.morphic.org/en.wikipedia.org/wiki/URL` will open `https://en.wikipedia.org/wiki/URL`. +For example, `http://opensametab.morphic.org/redirect/https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FURL` will open `https://en.wikipedia.org/wiki/URL`. #### Caveats diff --git a/src/background/openURLs.js b/src/background/openURLs.js index 0f41e04..b58dc8f 100644 --- a/src/background/openURLs.js +++ b/src/background/openURLs.js @@ -17,8 +17,7 @@ const openURLs = {}; openURLs.openTab = async (url, refresh) => { - const urlObj = new URL(url); - const queryURL = urlObj.href.replace(urlObj.protocol, "*:"); + const queryURL = url.href.replace(url.protocol, "*:"); let [matchedTab] = await browser.tabs.query({url: queryURL}); let [loadingTab] = await browser.tabs.query({"status": "loading", "windowId": browser.windows.WINDOW_ID_CURRENT}); @@ -37,7 +36,7 @@ openURLs.openTab = async (url, refresh) => { browser.tabs.reload(matchedTab.id); } } else { - browser.tabs.update(loadingTab.id, {url}); + browser.tabs.update(loadingTab.id, {url: url.href}); } }; @@ -53,12 +52,23 @@ openURLs.getFilter = identifiers => { }; openURLs.handleRequest = details => { - const refresh = details.url.indexOf(openURLs.identifiers.refreshTab) >= 0; - const url = details.url.replace(`${openURLs.identifiers[refresh ? "refreshTab" : "openTab"]}/`, ""); + const url = new URL(details.url); + const refresh = url.hostname.indexOf(openURLs.identifiers.refreshTab) >= 0; + // URL will look like: "http://opensametab.morphic.org/redirect/https%3A%2F%2Fexample.com%2F" + const destination = url.pathname.replace(/^\/(redirect\/)?(.*)/, (match, c1, c2) => decodeURIComponent(c2)); - openURLs.openTab(url, refresh); + let destinationUrl; + try { + destinationUrl = new URL(destination); + } catch (e) { + // ignored + } + + if (destinationUrl) { + openURLs.openTab(destinationUrl, refresh); + } - return {cancel: true}; + return {cancel: !!destinationUrl}; }; openURLs.bindListener = () => { diff --git a/tests/js/openURLsTests.js b/tests/js/openURLsTests.js index c868a94..4b16151 100644 --- a/tests/js/openURLsTests.js +++ b/tests/js/openURLsTests.js @@ -96,7 +96,7 @@ blankTab: { id: 1 }, - url: "https://actual.org/url", + url: new URL("https://actual.org/url"), queryURL: "*://actual.org/url" }; @@ -134,7 +134,7 @@ jqUnit.assertTrue("Tab isn't highlighted", browser.tabs.highlight.notCalled); jqUnit.assertTrue("Loading tab isnt' removed", browser.tabs.remove.notCalled); jqUnit.assertTrue("Tab isn't reloaded", browser.tabs.reload.notCalled); - let isUpdatedCalled = browser.tabs.update.calledOnceWithExactly(loadingTab.id, {url: openTabTestsProps.url}); + let isUpdatedCalled = browser.tabs.update.calledOnceWithExactly(loadingTab.id, {url: openTabTestsProps.url.href}); jqUnit.assertTrue("Loading tab is updated with correct URL", isUpdatedCalled); } @@ -151,29 +151,38 @@ const handlestRequestTestCases = [{ name: "Open same tab", details: { - url: "https://opensametab.morphic.org/actual.org/url" + url: "https://opensametab.morphic.org/redirect/https%3A%2F%2Factual.org/url" }, expected: { response: {cancel: true}, - args: ["https://actual.org/url", false] + args: [new URL("https://actual.org/url"), false] } }, { name: "Refresh tab", details: { - url: "http://refreshsametab.morphic.org/actual.org/url" + url: "http://refreshsametab.morphic.org/redirect/http%3A%2F%2Factual.org/url" }, expected: { response: {cancel: true}, - args: ["http://actual.org/url", true] + args: [new URL("http://actual.org/url"), true] } }, { name: "Unfiltered URL", details: { - url: "http://morphic.org/actual.org/url" + url: "http://morphic.org/redirect/https%3A%2F%2Factual.org/url" }, expected: { response: {cancel: true}, - args: ["http://morphic.org/actual.org/url", false] + args: [new URL("http://morphic.org/redirect/https%3A%2F%2Factual.org/url"), false] + } + }, { + name: "Bad URL", + details: { + url: "http://morphic.org/redirect/stupid" + }, + expected: { + response: {cancel: false}, + args: null } }]; @@ -184,7 +193,7 @@ let response = openURLs.handleRequest(testCase.details); jqUnit.assertDeepEq(`${testCase.name}: the response is returned correctly`, testCase.expected.response, response); - let isOpenTabCalledProperly = openTabStub.calledOnceWithExactly.apply(openTabStub, testCase.expected.args); + let isOpenTabCalledProperly = !testCase.expected.args || openTabStub.calledOnceWithExactly.apply(openTabStub, testCase.expected.args); jqUnit.assertTrue(`${testCase.name}: the openURLs.openTab method was called with the correct args`, isOpenTabCalledProperly); // clean up