From 0a6d2f3dcc3dc2e421187604b4dbbd3df41cbed0 Mon Sep 17 00:00:00 2001 From: Daniel Norman <1992255+2color@users.noreply.github.com> Date: Sat, 9 Mar 2024 01:31:49 +0100 Subject: [PATCH] fix: code cleanup, dep removal, & miscellaneous (#89) * refactor: remove unused helia andu se verified fetch * chore: remove empty line * fix: load config iframe using a hash fragment fixes #88 * fix: load default config initially * chore: fix linting errors * chore: remove unused deps * chore: re-add needed @helia/ipns dependency * fix: set verifiedFetch when sw is activated * chore: remove lib/heliaFetch and cleanup sw.ts (#95) * fix: config loading on subdomains waits for updated config (#94) * fix: config loading on subdomains waits for updated config * fix: remove event.waitUtil inside channel.onmessagefrom the activate event is fired when the service worker is first activated, and then the channel.onmessagefrom event listener is set up. by the time the channel receives any messages, the event passed to activate will be done, and waitUntil has no effect (and throws an error) * fix: service worker handles being disposed of * fix: preload request from redirect page is handled by sw * chore: better trace logging for config updates --------- Co-authored-by: Daniel N <2color@users.noreply.github.com> Co-authored-by: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> --- package-lock.json | 53 +------- package.json | 9 +- src/components/config.tsx | 14 +- src/get-helia.ts | 36 ++--- src/lib/common.ts | 1 + src/lib/config-db.ts | 13 +- src/lib/content-type-parser.ts | 47 +++++++ src/lib/heliaFetch.ts | 167 ----------------------- src/lib/is-config-page.ts | 2 +- src/redirectPage.tsx | 22 ++- src/sw.ts | 242 ++++++++++++++++++--------------- 11 files changed, 224 insertions(+), 382 deletions(-) create mode 100644 src/lib/content-type-parser.ts delete mode 100644 src/lib/heliaFetch.ts diff --git a/package-lock.json b/package-lock.json index ae2ab1af..77f590f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,18 +10,11 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@helia/block-brokers": "^2.0.1", - "@helia/http": "^1.0.0", - "@helia/interface": "^4.0.0", - "@helia/ipns": "^6.0.0", - "@helia/routers": "^1.0.0", + "@helia/ipns": "^6.0.1", "@helia/verified-fetch": "^1.1.0", "@libp2p/logger": "^4.0.6", "@sgtpooki/file-type": "^1.0.1", - "blockstore-idb": "^1.1.8", - "datastore-idb": "^2.1.8", "debug": "^4.3.4", - "mime-types": "^2.1.35", "multiformats": "^11.0.2", "react": "^18.2.0", "react-dom": "^18.2.0" @@ -6563,23 +6556,6 @@ "version": "13.0.1", "license": "Apache-2.0 OR MIT" }, - "node_modules/blockstore-idb": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/blockstore-idb/-/blockstore-idb-1.1.8.tgz", - "integrity": "sha512-pW3aXuexGBhTo02Fs7pmYnwKpp2AGBLs1VWGY+IzHOF43S4Ue2HPn8N39OcJrGpqweIjofqZfWuwgnEDnelbXA==", - "dependencies": { - "blockstore-core": "^4.0.0", - "idb": "^8.0.0", - "interface-blockstore": "^5.0.0", - "interface-store": "^5.0.0", - "multiformats": "^13.0.1" - } - }, - "node_modules/blockstore-idb/node_modules/multiformats": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.1.0.tgz", - "integrity": "sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ==" - }, "node_modules/blork": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/blork/-/blork-9.3.0.tgz", @@ -8337,26 +8313,6 @@ "it-all": "^3.0.0" } }, - "node_modules/datastore-idb": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/datastore-idb/-/datastore-idb-2.1.8.tgz", - "integrity": "sha512-L3k4kRLlP8YuUUuZsNxmRA9lu8RasEekgE8uLzivNOksWr/v/+ExxVvjZutOHDVlky5/spwJ5MKvB8GHfq7Fgw==", - "dependencies": { - "datastore-core": "^9.0.0", - "idb": "^8.0.0", - "interface-datastore": "^8.0.0", - "it-filter": "^3.0.4", - "it-sort": "^3.0.4" - } - }, - "node_modules/datastore-idb/node_modules/it-sort": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/it-sort/-/it-sort-3.0.4.tgz", - "integrity": "sha512-tvnC93JZZWjX4UxALy0asow0dzXabkoaRbrPJKClTKhNCqw4gzHr+H5axf1gohcthedRRkqd/ae+wl7WqoxFhw==", - "dependencies": { - "it-all": "^3.0.0" - } - }, "node_modules/date-fns": { "version": "1.30.1", "dev": true, @@ -12462,11 +12418,6 @@ "postcss": "^8.1.0" } }, - "node_modules/idb": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.0.tgz", - "integrity": "sha512-l//qvlAKGmQO31Qn7xdzagVPPaHTxXx199MhrAFuVBTPqydcPYBWjkrbv4Y0ktB+GmWOiwHl237UUOrLmQxLvw==" - }, "node_modules/ieee754": { "version": "1.2.1", "funding": [ @@ -15579,6 +15530,7 @@ }, "node_modules/mime-db": { "version": "1.52.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -15586,6 +15538,7 @@ }, "node_modules/mime-types": { "version": "2.1.35", + "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" diff --git a/package.json b/package.json index 7155c4db..70f830b5 100644 --- a/package.json +++ b/package.json @@ -32,18 +32,11 @@ } }, "dependencies": { - "@helia/block-brokers": "^2.0.1", - "@helia/http": "^1.0.0", - "@helia/interface": "^4.0.0", - "@helia/ipns": "^6.0.0", - "@helia/routers": "^1.0.0", + "@helia/ipns": "^6.0.1", "@helia/verified-fetch": "^1.1.0", "@libp2p/logger": "^4.0.6", "@sgtpooki/file-type": "^1.0.1", - "blockstore-idb": "^1.1.8", - "datastore-idb": "^2.1.8", "debug": "^4.3.4", - "mime-types": "^2.1.35", "multiformats": "^11.0.2", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/src/components/config.tsx b/src/components/config.tsx index 9bfcfa8f..9775863c 100644 --- a/src/components/config.tsx +++ b/src/components/config.tsx @@ -3,7 +3,8 @@ import { ConfigContext } from '../context/config-context.tsx' import { HeliaServiceWorkerCommsChannel } from '../lib/channel.ts' import { getConfig, loadConfigFromLocalStorage } from '../lib/config-db.ts' import { LOCAL_STORAGE_KEYS } from '../lib/local-storage.ts' -import { Collapsible } from './collapsible' +import { trace } from '../lib/logger.ts' +import { Collapsible } from './collapsible.tsx' import LocalStorageInput from './local-storage-input.tsx' import { LocalStorageToggle } from './local-storage-toggle' import { ServiceWorkerReadyButton } from './sw-ready-button.tsx' @@ -45,15 +46,16 @@ export default (): JSX.Element | null => { } // we get the iframe origin from a query parameter called 'origin', if this is loaded in an iframe // TODO: why we need this origin here? where is targetOrigin used? - const targetOrigin = decodeURIComponent(window.location.search.split('origin=')[1]) + const targetOrigin = decodeURIComponent(window.location.hash.split('@origin=')[1]) const config = await getConfig() - + trace('config-page: postMessage config to origin ', config, origin) /** * The reload page in the parent window is listening for this message, and then it passes a RELOAD_CONFIG message to the service worker */ window.parent?.postMessage({ source: 'helia-sw-config-iframe', target: 'PARENT', action: 'RELOAD_CONFIG', config }, { targetOrigin }) + trace('config-page: RELOAD_CONFIG sent to parent window') }, []) useEffect(() => { @@ -66,9 +68,11 @@ export default (): JSX.Element | null => { const saveConfig = useCallback(async () => { try { await loadConfigFromLocalStorage() + trace('config-page: sending RELOAD_CONFIG to service worker') // update the BASE_URL service worker - // TODO: use channel.messageAndWaitForResponse to ensure that the config is loaded before proceeding. - channel.postMessage({ target: 'SW', action: 'RELOAD_CONFIG' }) + await channel.messageAndWaitForResponse('SW', { target: 'SW', action: 'RELOAD_CONFIG' }) + // base_domain service worker is updated + trace('config-page: RELOAD_CONFIG_SUCCESS for %s', window.location.origin) // update the ..BASE_URL service worker await postFromIframeToParentSw() setConfigExpanded(false) diff --git a/src/get-helia.ts b/src/get-helia.ts index 6568b771..a4cfa9bf 100644 --- a/src/get-helia.ts +++ b/src/get-helia.ts @@ -1,30 +1,20 @@ -import { trustlessGateway } from '@helia/block-brokers' -import { createHeliaHTTP } from '@helia/http' -import { delegatedHTTPRouting } from '@helia/routers' -import { IDBBlockstore } from 'blockstore-idb' -import { IDBDatastore } from 'datastore-idb' +import { dnsJsonOverHttps } from '@helia/ipns/dns-resolvers' +import { createVerifiedFetch, type VerifiedFetch } from '@helia/verified-fetch' import { getConfig } from './lib/config-db.ts' -import { trace } from './lib/logger.ts' -import type { Helia } from '@helia/interface' +import { contentTypeParser } from './lib/content-type-parser.ts' +import { log } from './lib/logger.ts' -export async function getHelia (): Promise { +export async function getVerifiedFetch (): Promise { const config = await getConfig() - trace(`config-debug: got config for sw location ${self.location.origin}`, config) - const blockstore = new IDBBlockstore('./helia-sw/blockstore') - const datastore = new IDBDatastore('./helia-sw/datastore') - await blockstore.open() - await datastore.open() + log(`config-debug: got config for sw location ${self.location.origin}`, config) - const helia = await createHeliaHTTP({ - blockstore, - datastore, - blockBrokers: [ - trustlessGateway({ - gateways: [...config.gateways, 'https://trustless-gateway.link'] - }) - ], - routers: [...config.routers, 'https://delegated-ipfs.dev'].map(rUrl => delegatedHTTPRouting(rUrl)) + const verifiedFetch = await createVerifiedFetch({ + gateways: config.gateways ?? ['https://trustless-gateway.link'], + routers: config.routers ?? ['https://delegated-ipfs.dev'], + dnsResolvers: ['https://delegated-ipfs.dev/dns-query'].map(dnsJsonOverHttps) + }, { + contentTypeParser }) - return helia + return verifiedFetch } diff --git a/src/lib/common.ts b/src/lib/common.ts index 61c338db..0c3486cc 100644 --- a/src/lib/common.ts +++ b/src/lib/common.ts @@ -7,4 +7,5 @@ export enum COLORS { export enum ChannelActions { RELOAD_CONFIG = 'RELOAD_CONFIG', + RELOAD_CONFIG_SUCCESS = 'RELOAD_CONFIG_SUCCESS' } diff --git a/src/lib/config-db.ts b/src/lib/config-db.ts index 49708aec..9c526fdd 100644 --- a/src/lib/config-db.ts +++ b/src/lib/config-db.ts @@ -54,8 +54,8 @@ export async function loadConfigFromLocalStorage (): Promise { if (typeof globalThis.localStorage !== 'undefined') { const db = await openDatabase() const localStorage = globalThis.localStorage - const localStorageGatewaysString = localStorage.getItem(LOCAL_STORAGE_KEYS.config.gateways) ?? '[]' - const localStorageRoutersString = localStorage.getItem(LOCAL_STORAGE_KEYS.config.routers) ?? '[]' + const localStorageGatewaysString = localStorage.getItem(LOCAL_STORAGE_KEYS.config.gateways) ?? '["https://trustless-gateway.link"]' + const localStorageRoutersString = localStorage.getItem(LOCAL_STORAGE_KEYS.config.routers) ?? '["https://delegated-ipfs.dev"]' const autoReload = localStorage.getItem(LOCAL_STORAGE_KEYS.config.autoReload) === 'true' const debug = localStorage.getItem(LOCAL_STORAGE_KEYS.config.debug) ?? '' const gateways = JSON.parse(localStorageGatewaysString) @@ -71,8 +71,9 @@ export async function loadConfigFromLocalStorage (): Promise { } export async function setConfig (config: ConfigDb): Promise { - log('config-debug: setting config', config) - debugLib.enable(config.debug ?? '') + debugLib.enable(config.debug ?? '') // set debug level first. + log('config-debug: setting config %O for domain %s', config, window.location.origin) + const db = await openDatabase() await setInDatabase(db, 'gateways', config.gateways) await setInDatabase(db, 'routers', config.routers) @@ -84,8 +85,8 @@ export async function setConfig (config: ConfigDb): Promise { export async function getConfig (): Promise { const db = await openDatabase() - const gateways = await getFromDatabase(db, 'gateways') ?? [] - const routers = await getFromDatabase(db, 'routers') ?? [] + const gateways = await getFromDatabase(db, 'gateways') ?? ['https://trustless-gateway.link'] + const routers = await getFromDatabase(db, 'routers') ?? ['https://delegated-ipfs.dev'] const autoReload = await getFromDatabase(db, 'autoReload') ?? false const debug = await getFromDatabase(db, 'debug') ?? '' debugLib.enable(debug) diff --git a/src/lib/content-type-parser.ts b/src/lib/content-type-parser.ts new file mode 100644 index 00000000..ea8db9d5 --- /dev/null +++ b/src/lib/content-type-parser.ts @@ -0,0 +1,47 @@ +import { type ContentTypeParser } from '@helia/verified-fetch' +import { fileTypeFromBuffer } from '@sgtpooki/file-type' + +// default from verified-fetch is application/octect-stream, which forces a download. This is not what we want for MANY file types. +export const defaultMimeType = 'text/html' + +export const contentTypeParser: ContentTypeParser = async (bytes, fileName) => { + const detectedType = (await fileTypeFromBuffer(bytes))?.mime + if (detectedType != null) { + return detectedType + } + if (fileName == null) { + // no other way to determine file-type. + return defaultMimeType + } + + // no need to include file-types listed at https://github.com/SgtPooki/file-type#supported-file-types + switch (fileName.split('.').pop()) { + case 'css': + return 'text/css' + case 'html': + return 'text/html' + case 'js': + return 'application/javascript' + case 'json': + return 'application/json' + case 'txt': + return 'text/plain' + case 'woff2': + return 'font/woff2' + // see bottom of https://github.com/SgtPooki/file-type#supported-file-types + case 'svg': + return 'image/svg+xml' + case 'csv': + return 'text/csv' + case 'doc': + return 'application/msword' + case 'xls': + return 'application/vnd.ms-excel' + case 'ppt': + return 'application/vnd.ms-powerpoint' + case 'msi': + return 'application/x-msdownload' + default: + return defaultMimeType + } +} diff --git a/src/lib/heliaFetch.ts b/src/lib/heliaFetch.ts deleted file mode 100644 index 24135a61..00000000 --- a/src/lib/heliaFetch.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { dnsJsonOverHttps } from '@helia/ipns/dns-resolvers' -import { createVerifiedFetch, type ContentTypeParser } from '@helia/verified-fetch' -import { fileTypeFromBuffer } from '@sgtpooki/file-type' -import { getConfig } from './config-db.ts' -import { trace } from './logger.ts' -import type { Helia } from '@helia/interface' - -export interface HeliaFetchOptions { - path: string - helia: Helia - signal?: AbortSignal - headers?: Headers - id?: string | null - protocol?: string | null -} - -// default from verified-fetch is application/octect-stream, which forces a download. This is not what we want for MANY file types. -const defaultMimeType = 'text/html' -const contentTypeParser: ContentTypeParser = async (bytes, fileName) => { - const detectedType = (await fileTypeFromBuffer(bytes))?.mime - if (detectedType != null) { - return detectedType - } - if (fileName == null) { - // no other way to determine file-type. - return defaultMimeType - } - - // no need to include file-types listed at https://github.com/SgtPooki/file-type#supported-file-types - switch (fileName.split('.').pop()) { - case 'css': - return 'text/css' - case 'html': - return 'text/html' - case 'js': - return 'application/javascript' - case 'json': - return 'application/json' - case 'txt': - return 'text/plain' - case 'woff2': - return 'font/woff2' - // see bottom of https://github.com/SgtPooki/file-type#supported-file-types - case 'svg': - return 'image/svg+xml' - case 'csv': - return 'text/csv' - case 'doc': - return 'application/msword' - case 'xls': - return 'application/vnd.ms-excel' - case 'ppt': - return 'application/vnd.ms-powerpoint' - case 'msi': - return 'application/x-msdownload' - default: - return defaultMimeType - } -} - -// Check for **/*.css/fonts/**/*.ttf urls */ -const cssPathRegex = /(?.*\.css)(?.*\.(ttf|otf|woff|woff2){1})$/ - -/** - * Maps relative paths to font-faces from css files to the correct path from the root. - * - * e.g. in a css file (like specs.ipfs.tech's /ipns/specs.ipfs.tech/css/ipseity.min.css), you will find lines like: - * ``` - * @font-face { - * font-family: 'Plex'; - * font-style: normal; - * font-weight: 100; - * src: local('IBM Plex Sans'), - * local('IBM-Plex-Sans'), - * url('/fonts/IBMPlexSans-Thin.ttf') format('opentype'); - * } - * ``` - * which results in a request to `/ipns/specs.ipfs.tech/css/ipseity.min.css/fonts/IBMPlexSans-Thin.ttf`. Instead, - * we want to request `/ipns/specs.ipfs.tech/fonts/IBMPlexSans-Thin.ttf`. - * - * /ipns/blog.libp2p.io/assets/css/0.styles.4520169f.css/fonts/Montserrat-Medium.d8478173.woff - */ -function changeCssFontPath (path: string): string { - const match = path.match(cssPathRegex) - if (match == null) { - trace(`changeCssFontPath: No match for ${path}`) - return path - } - const { cssPath, fontPath } = match.groups as { cssPath?: string, fontPath?: string } - if (cssPath == null || fontPath == null) { - trace(`changeCssFontPath: No groups for ${path}`, match.groups) - return path - } - - trace(`changeCssFontPath: Changing font path from ${path} to ${fontPath}`) - return fontPath -} - -/** - * Test files: - * bafkreienxxjqg3jomg5b75k7547dgf7qlbd3qpxy2kbg537ck3rol4mcve - text - https://bafkreienxxjqg3jomg5b75k7547dgf7qlbd3qpxy2kbg537ck3rol4mcve.ipfs.w3s.link/?filename=test.txt - * bafkreicafxt3zr4cshf7qteztjzl62ouxqrofu647e44wt7s2iaqjn7bra - image/jpeg - http://127.0.0.1:8080/ipfs/bafkreicafxt3zr4cshf7qteztjzl62ouxqrofu647e44wt7s2iaqjn7bra?filename=bafkreicafxt3zr4cshf7qteztjzl62ouxqrofu647e44wt7s2iaqjn7bra - * broken - QmY7fzZEpgDUqZ7BEePSS5JxxezDj3Zy36EEpWSmKmv5mo - image/jpeg - http://127.0.0.1:8080/ipfs/QmY7fzZEpgDUqZ7BEePSS5JxxezDj3Zy36EEpWSmKmv5mo?filename=QmY7fzZEpgDUqZ7BEePSS5JxxezDj3Zy36EEpWSmKmv5mo - * web3_storageLogo.svg - bafkreif4ufrfpfcmqn5ltjvmeisgv4k7ykqz2mjygpngtwt4bijxosidqa - image/svg+xml - https://bafkreif4ufrfpfcmqn5ltjvmeisgv4k7ykqz2mjygpngtwt4bijxosidqa.ipfs.dweb.link/?filename=Web3.Storage-logo.svg - * broken - bafybeiekildl23opzqcsufewlbadhbabs6pyqg35tzpfavgtjyhchyikxa - video/quicktime - https://bafybeiekildl23opzqcsufewlbadhbabs6pyqg35tzpfavgtjyhchyikxa.ipfs.dweb.link - * stock_skateboarder.webm - bafkreiezuss4xkt5gu256vjccx7vocoksxk77vwmdrpwoumfbbxcy2zowq - video/webm (147.78 KiB) - https://bafkreiezuss4xkt5gu256vjccx7vocoksxk77vwmdrpwoumfbbxcy2zowq.ipfs.dweb.link - * bafybeierkpfmf4vhtdiujgahfptiyriykoetxf3rmd3vcxsdemincpjoyu - video/mp4 (2.80 MiB) - https://bafybeierkpfmf4vhtdiujgahfptiyriykoetxf3rmd3vcxsdemincpjoyu.ipfs.dweb.link - * bugbunny.mov - bafybeidsp6fva53dexzjycntiucts57ftecajcn5omzfgjx57pqfy3kwbq - video/mp4 (2.80 MiB) - https://bafybeieekpb73vggby3m35mnpre3pngdcdnnu47u25ehsz4r3xbmqum6nu.ipfs.w3s.link/ipfs/bafybeidsp6fva53dexzjycntiucts57ftecajcn5omzfgjx57pqfy3kwbq?filename=BugBunny.mov - * ipfs.tech website - QmeUdoMyahuQUPHS2odrZEL6yk2HnNfBJ147BeLXsZuqLJ - text/html - https://QmeUdoMyahuQUPHS2odrZEL6yk2HnNfBJ147BeLXsZuqLJ.ipfs.w3s.link - */ - -/** - * heliaFetch should have zero awareness of whether it's being used inside a service worker or not. - * - * The `path` supplied should be either: - * * /ipfs/CID (https://docs.ipfs.tech/concepts/content-addressing/) - * * /ipns/DNSLink (https://dnslink.dev/) - * * /ipns/IPNSName (https://specs.ipfs.tech/ipns/ipns-record/#ipns-name) - * - * Things to do: - * * TODO: implement as much of the gateway spec as possible. - * * TODO: why we would be better than ipfs.io/other-gateway - * * TODO: have error handling that renders 404/500/other if the request is bad. - * - */ -export async function heliaFetch ({ path, helia, signal, headers, id, protocol }: HeliaFetchOptions): Promise { - const config = await getConfig() - const verifiedFetch = await createVerifiedFetch({ - gateways: [...config.gateways, 'https://trustless-gateway.link'], - routers: [...config.routers, 'https://delegated-ipfs.dev'], - dnsResolvers: ['https://delegated-ipfs.dev/dns-query'].map(dnsJsonOverHttps) - }, { - contentTypeParser - }) - - let verifiedFetchUrl: string - - if (id != null && protocol != null) { - verifiedFetchUrl = `${protocol}://${id}${path}` - } else { - const pathParts = path.split('/') - - let pathPartIndex = 0 - let namespaceString = pathParts[pathPartIndex++] - if (namespaceString === '') { - // we have a prefixed '/' in the path, use the new index instead - namespaceString = pathParts[pathPartIndex++] - } - if (namespaceString !== 'ipfs' && namespaceString !== 'ipns') { - throw new Error(`only /ipfs or /ipns namespaces supported got ${namespaceString}`) - } - const pathRootString = pathParts[pathPartIndex++] - const contentPath = pathParts.slice(pathPartIndex++).join('/') - verifiedFetchUrl = `${namespaceString}://${pathRootString}/${changeCssFontPath(contentPath)}` - } - - // eslint-disable-next-line no-console - console.log('verifiedFetch for ', verifiedFetchUrl) - return verifiedFetch(verifiedFetchUrl, { - signal, - headers, - // TODO redirect: 'manual', // enable when http urls are supported by verified-fetch: https://github.com/ipfs-shipyard/helia-service-worker-gateway/issues/62#issuecomment-1977661456 - onProgress: (e) => { - trace(`${e.type}: `, e.detail) - } - }) -} diff --git a/src/lib/is-config-page.ts b/src/lib/is-config-page.ts index 2f31ab6e..a152e98d 100644 --- a/src/lib/is-config-page.ts +++ b/src/lib/is-config-page.ts @@ -1,5 +1,5 @@ export function isConfigPage (): boolean { const isConfigPathname = window.location.pathname === '/config' - const isConfigHashPath = window.location.hash === '#/config' // needed for _redirects and IPFS hosted sw gateways + const isConfigHashPath = window.location.hash.startsWith('#/config') // needed for _redirects and IPFS hosted sw gateways return isConfigPathname || isConfigHashPath } diff --git a/src/redirectPage.tsx b/src/redirectPage.tsx index 77f9f63a..4970a7ac 100644 --- a/src/redirectPage.tsx +++ b/src/redirectPage.tsx @@ -4,13 +4,13 @@ import { ServiceWorkerContext } from './context/service-worker-context.tsx' import { HeliaServiceWorkerCommsChannel } from './lib/channel.ts' import { setConfig, type ConfigDb } from './lib/config-db.ts' import { getSubdomainParts } from './lib/get-subdomain-parts' -import { error } from './lib/logger.ts' +import { error, trace } from './lib/logger.ts' const ConfigIframe = (): JSX.Element => { const { parentDomain } = getSubdomainParts(window.location.href) const portString = window.location.port === '' ? '' : `:${window.location.port}` - const iframeSrc = `${window.location.protocol}//${parentDomain}${portString}/config?origin=${encodeURIComponent(window.location.origin)}` + const iframeSrc = `${window.location.protocol}//${parentDomain}${portString}#/config@origin=${encodeURIComponent(window.location.origin)}` return (