From ae0c09d4b1204e1e8b33a55613df0a399e790cee Mon Sep 17 00:00:00 2001 From: Max Korsunov Date: Fri, 26 Jul 2024 14:48:20 +0200 Subject: [PATCH 1/4] fix(extension): #107: allow http for localhost --- apps/extension/public/manifest.json | 4 ++-- apps/extension/src/senders/validate.ts | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/extension/public/manifest.json b/apps/extension/public/manifest.json index 6c29dfef..84e36016 100644 --- a/apps/extension/public/manifest.json +++ b/apps/extension/public/manifest.json @@ -16,7 +16,7 @@ }, "content_scripts": [ { - "matches": ["https://*/*"], + "matches": ["https://*/*", "http://localhost:*/*"], "js": [ "injected-connection-port.js", "injected-disconnect-listener.js", @@ -25,7 +25,7 @@ "run_at": "document_start" }, { - "matches": ["https://*/*"], + "matches": ["https://*/*", "http://localhost:*/*"], "js": ["injected-penumbra-global.js"], "run_at": "document_start", "world": "MAIN" diff --git a/apps/extension/src/senders/validate.ts b/apps/extension/src/senders/validate.ts index c7d3feb4..40a2dfeb 100644 --- a/apps/extension/src/senders/validate.ts +++ b/apps/extension/src/senders/validate.ts @@ -13,6 +13,10 @@ type ValidSender = chrome.runtime.MessageSender & { url: `${ValidProtocol}//${string}/${string}`; }; +const isException = (url: URL): boolean => { + return url.protocol === 'http:' && url.hostname === 'localhost'; +}; + export const assertValidSender = (sender?: chrome.runtime.MessageSender) => { if (!sender) { throw new Error('Sender undefined'); @@ -34,7 +38,8 @@ export const assertValidSender = (sender?: chrome.runtime.MessageSender) => { if (parsedOrigin.origin !== sender.origin) { throw new Error('Sender origin is invalid'); } - if (!(parsedOrigin.protocol in ValidProtocol)) { + + if (!(parsedOrigin.protocol in ValidProtocol || isException(parsedOrigin))) { throw new Error(`Sender protocol is not ${Object.values(ValidProtocol).join(',')}`); } From f0198bb535c6d78701ce4e513b6bc910aef15507 Mon Sep 17 00:00:00 2001 From: Max Korsunov Date: Mon, 29 Jul 2024 14:56:24 +0200 Subject: [PATCH 2/4] fix(extension): #107: allow http for localhost only for dev environment --- apps/extension/src/senders/validate.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/extension/src/senders/validate.ts b/apps/extension/src/senders/validate.ts index 40a2dfeb..ddf3cbd2 100644 --- a/apps/extension/src/senders/validate.ts +++ b/apps/extension/src/senders/validate.ts @@ -6,16 +6,12 @@ type ValidSender = chrome.runtime.MessageSender & { frameId: 0; documentId: string; tab: chrome.tabs.Tab & { id: number }; - - // the relationship between origin and url is pretty complex. - // just rely on the browser's tools. - origin: `${ValidProtocol}//${string}`; - url: `${ValidProtocol}//${string}/${string}`; + origin: string; + url: string; }; -const isException = (url: URL): boolean => { - return url.protocol === 'http:' && url.hostname === 'localhost'; -}; +const isHttpLocalhost = (url: URL): boolean => + url.protocol === 'http:' && url.hostname === 'localhost'; export const assertValidSender = (sender?: chrome.runtime.MessageSender) => { if (!sender) { @@ -39,7 +35,12 @@ export const assertValidSender = (sender?: chrome.runtime.MessageSender) => { throw new Error('Sender origin is invalid'); } - if (!(parsedOrigin.protocol in ValidProtocol || isException(parsedOrigin))) { + if ( + !( + parsedOrigin.protocol in ValidProtocol || + (globalThis.__DEV__ && isHttpLocalhost(parsedOrigin)) + ) + ) { throw new Error(`Sender protocol is not ${Object.values(ValidProtocol).join(',')}`); } From e792473160e4a0d6a0af64618617c35e8cd96f71 Mon Sep 17 00:00:00 2001 From: Max Korsunov Date: Mon, 12 Aug 2024 17:50:59 +0200 Subject: [PATCH 3/4] fix(extension): #107: fix matching urls in the manifest --- apps/extension/public/manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/extension/public/manifest.json b/apps/extension/public/manifest.json index abb2370f..92d1527e 100644 --- a/apps/extension/public/manifest.json +++ b/apps/extension/public/manifest.json @@ -16,12 +16,12 @@ }, "content_scripts": [ { - "matches": ["https://*/*", "http://localhost:*/*"], + "matches": ["https://*/*", "http://localhost/*"], "js": ["injected-connection-port.js", "injected-request-listener.js"], "run_at": "document_start" }, { - "matches": ["https://*/*", "http://localhost:*/*"], + "matches": ["https://*/*", "http://localhost/*"], "js": ["injected-penumbra-global.js"], "run_at": "document_start", "world": "MAIN" From e0840f513cf8bc52cc9e6c4640ad29f461b290c0 Mon Sep 17 00:00:00 2001 From: Max Korsunov Date: Tue, 13 Aug 2024 15:19:47 +0200 Subject: [PATCH 4/4] fix(extension): #107: add more test cases --- apps/extension/src/senders/validate.test.ts | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/apps/extension/src/senders/validate.test.ts b/apps/extension/src/senders/validate.test.ts index 8df6f0f9..bb88c23b 100644 --- a/apps/extension/src/senders/validate.test.ts +++ b/apps/extension/src/senders/validate.test.ts @@ -99,6 +99,36 @@ describe('assertValidSender', () => { expect(() => assertValidSender(invalidProtocol)).toThrow('Sender protocol is not'); }); + it(`throws if sender protocol is http and origin is localhost but not in dev mode`, () => { + globalThis.__DEV__ = true; + const localhostSender: chrome.runtime.MessageSender = { + ...mockValid, + origin: 'http://localhost:8000', + url: 'http://localhost:8000/index.html', + }; + expect(assertValidSender(localhostSender)).toMatchObject(localhostSender); + }); + + it(`succeeds if sender protocol is http and origin is localhost in dev mode`, () => { + globalThis.__DEV__ = true; + const localhostSender: chrome.runtime.MessageSender = { + ...mockValid, + origin: 'http://localhost', + url: 'http://localhost/index.html', + }; + expect(assertValidSender(localhostSender)).toMatchObject(localhostSender); + }); + + it(`succeeds if sender protocol is http and origin is localhost with port specified in dev mode`, () => { + globalThis.__DEV__ = true; + const localhostSender: chrome.runtime.MessageSender = { + ...mockValid, + origin: 'http://localhost:8000', + url: 'http://localhost:8000/index.html', + }; + expect(assertValidSender(localhostSender)).toMatchObject(localhostSender); + }); + it('throws if sender has no URL', () => { const urlless: chrome.runtime.MessageSender = { ...mockValid,