This repository has been archived by the owner on May 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworker.js
87 lines (74 loc) · 2.43 KB
/
worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// This service worker may terminated at any time, so this cache may be reset.
let configCache = null;
const getConfig = async clientId => {
if (configCache) {
return configCache;
}
if (!clientId) {
return;
}
let client;
try {
client = await clients.get(clientId);
} catch {
return;
}
const messageChannel = new MessageChannel();
const messagePromise = new Promise((resolve, reject) => {
messageChannel.port1.onmessage = event => {
const config = event.data.error ? null : event.data;
resolve(config);
};
});
client.postMessage("get-configuration", [messageChannel.port2]);
const config = await messagePromise;
if (!config) {
return;
}
// Update cache
configCache = config;
return config;
};
const withAuthHeader = (headers, { username, password }) => {
const credentials = !password ? username : `${username}:${password}`;
const updatedHeaders = new Headers(headers);
updatedHeaders.append("Authorization", `Basic ${btoa(credentials)}`);
return updatedHeaders;
};
const proxyFetch = async ({ clientId, request }) => {
const config = await getConfig(clientId);
const options = {};
// Do not proxy if doing so would trigger a bug that can occur when Chrome Dev Tools is open.
// If a "username" is supplied, then the request.mode will not be 'same-origin', which will trigger this bug.
// https://stackoverflow.com/a/49719964
// https://bugs.chromium.org/p/chromium/issues/detail?id=823392
if (
request.cache === "only-if-cached" &&
(request.mode !== "same-origin" || (config && config.username))
) {
options.cache = "default";
}
if (config && config.username && request.url.startsWith(config.baseUrl)) {
options.headers = withAuthHeader(request.headers, config);
options.mode = "cors";
}
return fetch(request, options);
};
self.addEventListener("activate", event => {
event.waitUntil(self.clients.claim());
});
self.addEventListener("fetch", event => {
// Avoid a deadlock that can occur if this service worker attempts to fetch the script that has its configuration.
// This can occur when the browser is refreshed after this service worker is registered.
if (event.request.destination === "script") {
return;
}
event.respondWith(proxyFetch(event));
});
self.addEventListener("install", event => {
event.waitUntil(self.skipWaiting());
});
self.addEventListener("message", () => {
// Invalidate cache
configCache = null;
});