-
Notifications
You must be signed in to change notification settings - Fork 362
/
token.worker.ts
86 lines (72 loc) · 2.23 KB
/
token.worker.ts
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
import { MISSING_REFRESH_TOKEN_ERROR_MESSAGE } from './constants';
let refreshTokens = {};
const cacheKey = (audience, scope) => `${audience}|${scope}`;
const getRefreshToken = (audience, scope) =>
refreshTokens[cacheKey(audience, scope)];
const setRefreshToken = (refreshToken, audience, scope) =>
(refreshTokens[cacheKey(audience, scope)] = refreshToken);
const deleteRefreshToken = (audience, scope) =>
delete refreshTokens[cacheKey(audience, scope)];
const wait: any = time => new Promise(resolve => setTimeout(resolve, time));
const messageHandler = async ({
data: { url, timeout, audience, scope, ...opts },
ports: [port]
}) => {
let json;
try {
const body = JSON.parse(opts.body);
if (!body.refresh_token && body.grant_type === 'refresh_token') {
const refreshToken = getRefreshToken(audience, scope);
if (!refreshToken) {
throw new Error(MISSING_REFRESH_TOKEN_ERROR_MESSAGE);
}
opts.body = JSON.stringify({ ...body, refresh_token: refreshToken });
}
const abortController = new AbortController();
const { signal } = abortController;
let response;
try {
response = await Promise.race([
wait(timeout),
fetch(url, { ...opts, signal })
]);
} catch (error) {
// fetch error, reject `sendMessage` using `error` key so that we retry.
port.postMessage({
error: error.message
});
return;
}
if (!response) {
// If the request times out, abort it and let `fetchWithTimeout` raise the error.
abortController.abort();
return;
}
json = await response.json();
if (json.refresh_token) {
setRefreshToken(json.refresh_token, audience, scope);
delete json.refresh_token;
} else {
deleteRefreshToken(audience, scope);
}
port.postMessage({
ok: response.ok,
json
});
} catch (error) {
port.postMessage({
ok: false,
json: {
error_description: error.message
}
});
}
};
// Don't run `addEventListener` in our tests (this is replaced in rollup)
/* istanbul ignore else */
if (process.env.NODE_ENV === 'test') {
module.exports = { messageHandler };
} else {
// @ts-ignore
addEventListener('message', messageHandler);
}