From 4dea88fbf1d09b757175b494cb597274fc63f641 Mon Sep 17 00:00:00 2001 From: Emmanuel Krebs Date: Sat, 31 Aug 2024 19:40:12 +0200 Subject: [PATCH] fix: some invalid URLs (#168) closes #159 --- .github/workflows/ci.yml | 1 + bun.lockb | Bin 317740 -> 319572 bytes package.json | 1 + src/components/List/Item/index.tsx | 3 ++- src/components/List/index.tsx | 5 +++-- src/pages/contentScript/Page.tsx | 2 +- src/pages/serviceWorker.ts | 6 +++--- src/utils/__tests__/getUrl.test.ts | 16 +++++++++++++++ src/utils/badge.ts | 2 +- src/utils/currentUrlIsMatching.ts | 31 +++++++++++++++++------------ src/utils/getURL.ts | 8 ++++++++ tsconfig.json | 2 +- 12 files changed, 55 insertions(+), 22 deletions(-) create mode 100644 src/utils/__tests__/getUrl.test.ts create mode 100644 src/utils/getURL.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b2e817..ef49195 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,5 +19,6 @@ jobs: - run: bun run setup-ci - run: bun run type-check - run: bun run lint + - run: bun test - run: bun run build - run: bun run zip diff --git a/bun.lockb b/bun.lockb index 3d73d072e9263ab87852915457bde07560865d09..2cc932f31d4316b64b52ea6ea3a01c098ff205b8 100644 GIT binary patch delta 48461 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 delta 47532 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 CM`h0d diff --git a/package.json b/package.json index 8411290..1341f71 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@crxjs/vite-plugin": "^1.0.14", "@e-krebs/react-library": "^0.0.23", "@tailwindcss/typography": "^0.5.9", + "@types/bun": "^1.1.8", "@types/chrome": "^0.0.236", "@types/express": "^4.17.17", "@types/node": "^20.16.1", diff --git a/src/components/List/Item/index.tsx b/src/components/List/Item/index.tsx index 6b522cc..bfc429a 100644 --- a/src/components/List/Item/index.tsx +++ b/src/components/List/Item/index.tsx @@ -1,5 +1,6 @@ import { FC, useEffect, useRef, useState } from 'react'; +import { getUrl } from 'utils/getURL'; import { getIcon, IconAndPalette } from 'utils/icon'; import { ListItem } from 'utils/typings'; @@ -27,7 +28,7 @@ export const Item: FC = ({ useEffect(() => { const effect = async () => { - const iconAndPalette = await getIcon(new URL(url).hostname, logo); + const iconAndPalette = await getIcon(getUrl(url).hostname, logo); setIcon(iconAndPalette); }; effect(); diff --git a/src/components/List/index.tsx b/src/components/List/index.tsx index d1eacd0..4dac17f 100644 --- a/src/components/List/index.tsx +++ b/src/components/List/index.tsx @@ -14,6 +14,7 @@ import { filterTag, get, search } from 'utils/get'; import { getAllTags } from 'utils/getAllTags'; import { getLastTag, setLastTag } from 'utils/lastTag'; import { getActiveTab } from 'utils/getActiveTab'; +import { getUrl } from 'utils/getURL'; import { urlsAreMatching } from 'utils/currentUrlIsMatching'; import { SearchFilter } from './SearchFilter'; @@ -43,13 +44,13 @@ export const List: FC = () => { useEffect(() => { const initActiveTab = async () => { const url = await getActiveTab(); - setActiveTab(url ? new URL(url) : undefined); + setActiveTab(url ? getUrl(url) : undefined); }; initActiveTab(); }, []); const isMatching = useCallback( - (url: string) => activeTab !== undefined && urlsAreMatching(new URL(url), activeTab), + (url: string) => activeTab !== undefined && urlsAreMatching(url, activeTab), [activeTab] ); diff --git a/src/pages/contentScript/Page.tsx b/src/pages/contentScript/Page.tsx index 6b63602..2723128 100644 --- a/src/pages/contentScript/Page.tsx +++ b/src/pages/contentScript/Page.tsx @@ -69,7 +69,7 @@ export const Page = () => { setUrl(message.url); setAllTags(message.tags ?? []); setTags([]); - const listItem = await getMatchingListItem(new URL(message.url), [msgService]); + const listItem = await getMatchingListItem(message.url, [msgService]); setMatching(listItem ? { service: msgService, listItem } : undefined); setIsLoading(false); modalRef.current?.openModal(); diff --git a/src/pages/serviceWorker.ts b/src/pages/serviceWorker.ts index 5a9c15a..b94039e 100644 --- a/src/pages/serviceWorker.ts +++ b/src/pages/serviceWorker.ts @@ -24,7 +24,7 @@ const refreshBadge = async () => { ); }; -const refreshBadgeIfMatching = async (currentUrl: URL) => { +const refreshBadgeIfMatching = async (currentUrl: string) => { const services = getServices(); const isMatching = await currentUrlIsMatching(currentUrl, services); setBadgeColor(isMatching); @@ -47,14 +47,14 @@ const tabsUpdatedListener = async ( { active, url }: chrome.tabs.Tab ) => { if (active && url) { - await refreshBadgeIfMatching(new URL(url)); + await refreshBadgeIfMatching(url); } }; const tabsActivatedListener = async ({ tabId }: chrome.tabs.TabActiveInfo) => { const { url } = await chrome.tabs.get(tabId); if (url) { - await refreshBadgeIfMatching(new URL(url)); + await refreshBadgeIfMatching(url); } }; diff --git a/src/utils/__tests__/getUrl.test.ts b/src/utils/__tests__/getUrl.test.ts new file mode 100644 index 0000000..a3d452a --- /dev/null +++ b/src/utils/__tests__/getUrl.test.ts @@ -0,0 +1,16 @@ +import { describe, it, expect } from 'bun:test'; + +import { getUrl } from 'utils/getURL'; + +describe('getUrl', () => { + it('should work with simple urls', () => { + expect(getUrl('https://www.google.fr')).toEqual(new URL('https://www.google.fr')); + expect(getUrl('https://github.com/e-krebs/pile')).toEqual( + new URL('https://github.com/e-krebs/pile') + ); + }); + + it('should work with known edge cases', () => { + expect(getUrl('svg.wtf')).toEqual(new URL('https://svg.wtf')); + }); +}); diff --git a/src/utils/badge.ts b/src/utils/badge.ts index e2c7c76..ff13797 100644 --- a/src/utils/badge.ts +++ b/src/utils/badge.ts @@ -39,7 +39,7 @@ const updateBadgeInner = async (services: Service[], badgeValues: BadgeValues) = .reduce((a, b) => a + b); const url = await getActiveTab(); - const isMatching = url ? await currentUrlIsMatching(new URL(url), services) : false; + const isMatching = url ? await currentUrlIsMatching(url, services) : false; if (total > 0) { setBadgeColor(isMatching); diff --git a/src/utils/currentUrlIsMatching.ts b/src/utils/currentUrlIsMatching.ts index 72a8946..e7261a8 100644 --- a/src/utils/currentUrlIsMatching.ts +++ b/src/utils/currentUrlIsMatching.ts @@ -1,37 +1,38 @@ import { get } from './get'; +import { getUrl } from './getURL'; import type { Service } from './services'; import { ListItem } from './typings'; import { beautifyUrl } from './url'; export const getMatchingListItem = async ( - currentUrl: URL, + currentUrl: URL | string, services: Service[] ): Promise => { + const currentURL = typeof currentUrl === 'string' ? getUrl(currentUrl) : currentUrl; const matching = await Promise.all( services .map(async (service) => { const isConnected = await service.isConnected(); if (!isConnected) return; const { data } = await get(service); - return data.find((item) => { - const url = new URL(item.url); - return urlsAreMatching(url, currentUrl); - }); + return data.find((item) => urlsAreMatching(item.url, currentURL)); }) .flat() ); return matching.find((item) => item !== undefined); }; -export const currentUrlIsMatching = async (currentUrl: URL, services: Service[]): Promise => { +export const currentUrlIsMatching = async ( + currentUrl: URL | string, + services: Service[] +): Promise => { + const currentURL = typeof currentUrl === 'string' ? getUrl(currentUrl) : currentUrl; const matches = await Promise.all( services.map(async (service) => { const isConnected = await service.isConnected(); if (!isConnected) return false; const { data } = await get(service); - const matchingUrls = data - .map((i) => new URL(i.url)) - .filter((iUrl) => urlsAreMatching(iUrl, currentUrl)); + const matchingUrls = data.filter(({ url }) => urlsAreMatching(url, currentURL)); return matchingUrls.length > 0; }) ); @@ -39,7 +40,11 @@ export const currentUrlIsMatching = async (currentUrl: URL, services: Service[]) return isMatching; }; -export const urlsAreMatching = (url1: URL, url2: URL): boolean => - beautifyUrl(url1.origin) === beautifyUrl(url2.origin) && - beautifyUrl(url1.pathname) === beautifyUrl(url2.pathname) && - url1.search === url2.search; +export const urlsAreMatching = (url1: URL | string, url2: URL): boolean => { + const URL1 = typeof url1 === 'string' ? getUrl(url1) : url1; + return ( + beautifyUrl(URL1.origin) === beautifyUrl(url2.origin) && + beautifyUrl(URL1.pathname) === beautifyUrl(url2.pathname) && + url1.search === url2.search + ); +}; diff --git a/src/utils/getURL.ts b/src/utils/getURL.ts new file mode 100644 index 0000000..cab6118 --- /dev/null +++ b/src/utils/getURL.ts @@ -0,0 +1,8 @@ +export const getUrl = (url: string): URL => { + try { + return new URL(url); + } catch { + // very basic, should probably be improved + return new URL(`https://${url}`); + } +}; diff --git a/tsconfig.json b/tsconfig.json index 740057b..961ac4e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,7 @@ "skipLibCheck": true, "jsx": "react-jsx", "resolveJsonModule": true, - "types": ["chrome", "node"], + "types": ["chrome", "bun"], "baseUrl": "src", } }