1
+ /*! coi-serviceworker v0.1.7 - Guido Zuidhof and contributors, licensed under MIT */
2
+ let coepCredentialless = false ;
3
+ if ( typeof window === 'undefined' ) {
4
+ self . addEventListener ( "install" , ( ) => self . skipWaiting ( ) ) ;
5
+ self . addEventListener ( "activate" , ( event ) => event . waitUntil ( self . clients . claim ( ) ) ) ;
6
+
7
+ self . addEventListener ( "message" , ( ev ) => {
8
+ if ( ! ev . data ) {
9
+ return ;
10
+ } else if ( ev . data . type === "deregister" ) {
11
+ self . registration
12
+ . unregister ( )
13
+ . then ( ( ) => {
14
+ return self . clients . matchAll ( ) ;
15
+ } )
16
+ . then ( clients => {
17
+ clients . forEach ( ( client ) => client . navigate ( client . url ) ) ;
18
+ } ) ;
19
+ } else if ( ev . data . type === "coepCredentialless" ) {
20
+ coepCredentialless = ev . data . value ;
21
+ }
22
+ } ) ;
23
+
24
+ self . addEventListener ( "fetch" , function ( event ) {
25
+ const r = event . request ;
26
+ if ( r . cache === "only-if-cached" && r . mode !== "same-origin" ) {
27
+ return ;
28
+ }
29
+
30
+ const request = ( coepCredentialless && r . mode === "no-cors" )
31
+ ? new Request ( r , {
32
+ credentials : "omit" ,
33
+ } )
34
+ : r ;
35
+ event . respondWith (
36
+ fetch ( request )
37
+ . then ( ( response ) => {
38
+ if ( response . status === 0 ) {
39
+ return response ;
40
+ }
41
+
42
+ const newHeaders = new Headers ( response . headers ) ;
43
+ newHeaders . set ( "Cross-Origin-Embedder-Policy" ,
44
+ coepCredentialless ? "credentialless" : "require-corp"
45
+ ) ;
46
+ if ( ! coepCredentialless ) {
47
+ newHeaders . set ( "Cross-Origin-Resource-Policy" , "cross-origin" ) ;
48
+ }
49
+ newHeaders . set ( "Cross-Origin-Opener-Policy" , "same-origin" ) ;
50
+
51
+ return new Response ( response . body , {
52
+ status : response . status ,
53
+ statusText : response . statusText ,
54
+ headers : newHeaders ,
55
+ } ) ;
56
+ } )
57
+ . catch ( ( e ) => console . error ( e ) )
58
+ ) ;
59
+ } ) ;
60
+
61
+ } else {
62
+ ( ( ) => {
63
+ const reloadedBySelf = window . sessionStorage . getItem ( "coiReloadedBySelf" ) ;
64
+ window . sessionStorage . removeItem ( "coiReloadedBySelf" ) ;
65
+ const coepDegrading = ( reloadedBySelf == "coepdegrade" ) ;
66
+
67
+ // You can customize the behavior of this script through a global `coi` variable.
68
+ const coi = {
69
+ shouldRegister : ( ) => ! reloadedBySelf ,
70
+ shouldDeregister : ( ) => false ,
71
+ coepCredentialless : ( ) => true ,
72
+ coepDegrade : ( ) => true ,
73
+ doReload : ( ) => window . location . reload ( ) ,
74
+ quiet : false ,
75
+ ...window . coi
76
+ } ;
77
+
78
+ const n = navigator ;
79
+ const controlling = n . serviceWorker && n . serviceWorker . controller ;
80
+
81
+ // Record the failure if the page is served by serviceWorker.
82
+ if ( controlling && ! window . crossOriginIsolated ) {
83
+ window . sessionStorage . setItem ( "coiCoepHasFailed" , "true" ) ;
84
+ }
85
+ const coepHasFailed = window . sessionStorage . getItem ( "coiCoepHasFailed" ) ;
86
+
87
+ if ( controlling ) {
88
+ // Reload only on the first failure.
89
+ const reloadToDegrade = coi . coepDegrade ( ) && ! (
90
+ coepDegrading || window . crossOriginIsolated
91
+ ) ;
92
+ n . serviceWorker . controller . postMessage ( {
93
+ type : "coepCredentialless" ,
94
+ value : ( reloadToDegrade || coepHasFailed && coi . coepDegrade ( ) )
95
+ ? false
96
+ : coi . coepCredentialless ( ) ,
97
+ } ) ;
98
+ if ( reloadToDegrade ) {
99
+ ! coi . quiet && console . log ( "Reloading page to degrade COEP." ) ;
100
+ window . sessionStorage . setItem ( "coiReloadedBySelf" , "coepdegrade" ) ;
101
+ coi . doReload ( "coepdegrade" ) ;
102
+ }
103
+
104
+ if ( coi . shouldDeregister ( ) ) {
105
+ n . serviceWorker . controller . postMessage ( { type : "deregister" } ) ;
106
+ }
107
+ }
108
+
109
+ // If we're already coi: do nothing. Perhaps it's due to this script doing its job, or COOP/COEP are
110
+ // already set from the origin server. Also if the browser has no notion of crossOriginIsolated, just give up here.
111
+ if ( window . crossOriginIsolated !== false || ! coi . shouldRegister ( ) ) return ;
112
+
113
+ if ( ! window . isSecureContext ) {
114
+ ! coi . quiet && console . log ( "COOP/COEP Service Worker not registered, a secure context is required." ) ;
115
+ return ;
116
+ }
117
+
118
+ // In some environments (e.g. Firefox private mode) this won't be available
119
+ if ( ! n . serviceWorker ) {
120
+ ! coi . quiet && console . error ( "COOP/COEP Service Worker not registered, perhaps due to private mode." ) ;
121
+ return ;
122
+ }
123
+
124
+ n . serviceWorker . register ( window . document . currentScript . src ) . then (
125
+ ( registration ) => {
126
+ ! coi . quiet && console . log ( "COOP/COEP Service Worker registered" , registration . scope ) ;
127
+
128
+ registration . addEventListener ( "updatefound" , ( ) => {
129
+ ! coi . quiet && console . log ( "Reloading page to make use of updated COOP/COEP Service Worker." ) ;
130
+ window . sessionStorage . setItem ( "coiReloadedBySelf" , "updatefound" ) ;
131
+ coi . doReload ( ) ;
132
+ } ) ;
133
+
134
+ // If the registration is active, but it's not controlling the page
135
+ if ( registration . active && ! n . serviceWorker . controller ) {
136
+ ! coi . quiet && console . log ( "Reloading page to make use of COOP/COEP Service Worker." ) ;
137
+ window . sessionStorage . setItem ( "coiReloadedBySelf" , "notcontrolling" ) ;
138
+ coi . doReload ( ) ;
139
+ }
140
+ } ,
141
+ ( err ) => {
142
+ ! coi . quiet && console . error ( "COOP/COEP Service Worker failed to register:" , err ) ;
143
+ }
144
+ ) ;
145
+ } ) ( ) ;
146
+ }
0 commit comments