Skip to content

Commit

Permalink
fix: handle helia-sw query from _redirects (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
SgtPooki authored Mar 5, 2024
1 parent 440bf91 commit cfd70a6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 14 deletions.
15 changes: 2 additions & 13 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import React, { useContext, useEffect } from 'react'
import React, { useContext } from 'react'
import Config from './components/config.tsx'
import { ConfigContext } from './context/config-context.tsx'
import HelperUi from './helper-ui.tsx'
import { isConfigPage } from './lib/is-config-page.ts'
import { isPathOrSubdomainRequest, findOriginIsolationRedirect } from './lib/path-or-subdomain.ts'
import { isPathOrSubdomainRequest } from './lib/path-or-subdomain.ts'
import RedirectPage from './redirectPage.tsx'

function App (): JSX.Element {
const { isConfigExpanded, setConfigExpanded } = useContext(ConfigContext)

useEffect(() => {
async function originEnforcement (): Promise<void> {
// enforce early when loaded before SW was registered
const originRedirect = await findOriginIsolationRedirect(window.location)
if (originRedirect !== null) {
window.location.replace(originRedirect)
}
}
void originEnforcement()
}, [])

if (isConfigPage()) {
setConfigExpanded(true)
return <Config />
Expand Down
42 changes: 41 additions & 1 deletion src/context/service-worker-context.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
/**
* @file This file contains the ServiceWorkerProvider component which is used to register the service worker,
* and provide the isServiceWorkerRegistered state to the rest of the app.
*
* URL / location logic dependent upon the service worker being registered should be handled here. Some examples of this are:
*
* Before the Service Worker is registered (e.g. first requests to root hosted domain or subdomains):
*
* 1. Being redirected from _redirects file to a ?helia-sw= url
* 2. The app is loaded because service worker is not yet registered, we need to reload the page so the service worker intercepts the request
*
* After the service worker is loaded. Usually any react code isn't loaded, but some edge cases are:
* 1. The page being loaded using some /ip[fn]s/<path> url, but subdomain isolation is supported, so we need to redirect to the isolated origin
*/
import React, { createContext, useEffect, useState } from 'react'
import { translateIpfsRedirectUrl } from '../lib/ipfs-hosted-redirect-utils.ts'
import { error } from '../lib/logger.ts'
import { findOriginIsolationRedirect } from '../lib/path-or-subdomain.ts'
import { registerServiceWorker } from '../service-worker-utils.ts'

export const ServiceWorkerContext = createContext({
Expand All @@ -9,8 +25,32 @@ export const ServiceWorkerContext = createContext({
export const ServiceWorkerProvider = ({ children }): JSX.Element => {
const [isServiceWorkerRegistered, setIsServiceWorkerRegistered] = useState(false)

const windowLocation = translateIpfsRedirectUrl(window.location.href)

useEffect(() => {
if (isServiceWorkerRegistered) {
/**
* The service worker is registered, now we need to check for "helia-sw" and origin isolation support
*/
if (windowLocation.href !== window.location.href) {
/**
* We're at a domain with ?helia-sw=, we can reload the page so the service worker will
* capture the request
*/
window.location.replace(windowLocation.href)
} else {
/**
* ?helia-sw= url handling is done, now we can check for origin isolation redirects
*/
void findOriginIsolationRedirect(windowLocation).then((originRedirect) => {
if (originRedirect !== null) {
window.location.replace(originRedirect)
}
})
}
/**
* The service worker is registered, we don't need to do any more work
*/
return
}
async function doWork (): Promise<void> {
Expand All @@ -32,7 +72,7 @@ export const ServiceWorkerProvider = ({ children }): JSX.Element => {
}
}
void doWork()
}, [])
}, [isServiceWorkerRegistered])

return (
<ServiceWorkerContext.Provider value={{ isServiceWorkerRegistered }}>
Expand Down
15 changes: 15 additions & 0 deletions src/lib/ipfs-hosted-redirect-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* If you host helia-service-worker-gateway on an IPFS domain, the redirects file will route some requests from
* `<domain>/<wildcard-splat>` to `https://<domain>/?helia-sw=<wildcard-splat>`.
*
* This function will check for "?helia-sw=" in the URL and modify the URL so that it works with the rest of our logic
*/
export function translateIpfsRedirectUrl (urlString: string): URL {
const url = new URL(urlString)
const heliaSw = url.searchParams.get('helia-sw')
if (heliaSw != null) {
url.searchParams.delete('helia-sw')
url.pathname = heliaSw
}
return url
}

0 comments on commit cfd70a6

Please sign in to comment.