@@ -5,7 +5,7 @@ import { getSubdomainParts } from './lib/get-subdomain-parts.js'
5
5
import { getVerifiedFetch } from './lib/get-verified-fetch.js'
6
6
import { isConfigPage } from './lib/is-config-page.js'
7
7
import { swLogger } from './lib/logger.js'
8
- import { findOriginIsolationRedirect } from './lib/path-or-subdomain.js'
8
+ import { findOriginIsolationRedirect , isPathGatewayRequest } from './lib/path-or-subdomain.js'
9
9
import type { VerifiedFetch } from '@helia/verified-fetch'
10
10
11
11
/**
@@ -42,6 +42,7 @@ interface StoreReponseInCacheOptions {
42
42
*/
43
43
interface LocalSwConfig {
44
44
installTimestamp : number
45
+ originIsolationWarningAccepted : boolean
45
46
}
46
47
47
48
/**
@@ -203,6 +204,13 @@ async function requestRouting (event: FetchEvent, url: URL): Promise<boolean> {
203
204
log . error ( 'sw-config reload request, error updating verifiedFetch' , err )
204
205
} ) )
205
206
return false
207
+ } else if ( isAcceptOriginIsolationWarningRequest ( event ) ) {
208
+ event . waitUntil ( setOriginIsolationWarningAccepted ( ) . then ( ( ) => {
209
+ log . trace ( 'origin isolation warning accepted' )
210
+ } ) . catch ( ( err ) => {
211
+ log . error ( 'origin isolation warning accepted, error' , err )
212
+ } ) )
213
+ return false
206
214
} else if ( isSwConfigGETRequest ( event ) ) {
207
215
log . trace ( 'sw-config GET request' )
208
216
event . waitUntil ( new Promise < void > ( ( resolve ) => {
@@ -301,6 +309,10 @@ function isSwConfigGETRequest (event: FetchEvent): boolean {
301
309
return event . request . url . includes ( '/#/ipfs-sw-config-get' )
302
310
}
303
311
312
+ function isAcceptOriginIsolationWarningRequest ( event : FetchEvent ) : boolean {
313
+ return event . request . url . includes ( '/#/ipfs-sw-accept-origin-isolation-warning' )
314
+ }
315
+
304
316
function isSwAssetRequest ( event : FetchEvent ) : boolean {
305
317
const isActualSwAsset = / ^ .+ \/ (?: i p f s - s w - ) .+ $ / . test ( event . request . url )
306
318
// if path is not set, then it's a request for index.html which we should consider a sw asset
@@ -430,8 +442,9 @@ async function storeReponseInCache ({ response, isMutable, cacheKey, event }: St
430
442
}
431
443
432
444
async function fetchHandler ( { path, request, event } : FetchHandlerArg ) : Promise < Response > {
445
+ const originalUrl = new URL ( request . url )
433
446
// test and enforce origin isolation before anything else is executed
434
- const originLocation = await findOriginIsolationRedirect ( new URL ( request . url ) , swLogger )
447
+ const originLocation = await findOriginIsolationRedirect ( originalUrl , swLogger )
435
448
if ( originLocation !== null ) {
436
449
const body = 'Gateway supports subdomain mode, redirecting to ensure Origin isolation..'
437
450
return new Response ( body , {
@@ -441,6 +454,18 @@ async function fetchHandler ({ path, request, event }: FetchHandlerArg): Promise
441
454
Location : originLocation
442
455
}
443
456
} )
457
+ } else if ( isPathGatewayRequest ( originalUrl ) && ! ( await getOriginIsolationWarningAccepted ( ) ) ) {
458
+ const newUrl = new URL ( originalUrl . href )
459
+ newUrl . pathname = '/'
460
+ newUrl . hash = '/ipfs-sw-origin-isolation-warning'
461
+ newUrl . searchParams . set ( 'helia-sw' , request . url )
462
+ return new Response ( 'Origin isolation is not supported, please accept the risk to continue.' , {
463
+ status : 307 ,
464
+ headers : {
465
+ 'Content-Type' : 'text/plain' ,
466
+ Location : newUrl . href
467
+ }
468
+ } )
444
469
}
445
470
446
471
/**
@@ -671,6 +696,30 @@ async function addInstallTimestampToConfig (): Promise<void> {
671
696
}
672
697
}
673
698
699
+ async function setOriginIsolationWarningAccepted ( ) : Promise < void > {
700
+ try {
701
+ const swidb = getSwConfig ( )
702
+ await swidb . open ( )
703
+ await swidb . put ( 'originIsolationWarningAccepted' , true )
704
+ swidb . close ( )
705
+ } catch ( e ) {
706
+ log . error ( 'addInstallTimestampToConfig error: ' , e )
707
+ }
708
+ }
709
+
710
+ async function getOriginIsolationWarningAccepted ( ) : Promise < boolean > {
711
+ try {
712
+ const swidb = getSwConfig ( )
713
+ await swidb . open ( )
714
+ const accepted = await swidb . get ( 'originIsolationWarningAccepted' )
715
+ swidb . close ( )
716
+ return accepted ?? false
717
+ } catch ( e ) {
718
+ log . error ( 'getOriginIsolationWarningAccepted error: ' , e )
719
+ return false
720
+ }
721
+ }
722
+
674
723
/**
675
724
* To be called on 'install' sw event. This will clear out the old swAssets cache,
676
725
* which is used for storing the service worker's css,js, and html assets.
0 commit comments