@axa-fr/react-oidc 6.14.11 → 6.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/OidcServiceWorker.d.ts +50 -0
- package/dist/OidcServiceWorker.d.ts.map +1 -0
- package/dist/OidcServiceWorker.js +103 -140
- package/dist/OidcServiceWorker.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +6 -5
- package/src/oidc/vanilla/OidcServiceWorker.js +0 -529
- package/src/oidc/vanilla/OidcTrustedDomains.js +0 -15
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
declare const _self: ServiceWorkerGlobalScope & typeof globalThis;
|
|
2
|
+
declare let trustedDomains: any;
|
|
3
|
+
declare const scriptFilename = "OidcTrustedDomains.js";
|
|
4
|
+
declare const id: string;
|
|
5
|
+
declare const acceptAnyDomainToken = "*";
|
|
6
|
+
declare const keepAliveJsonFilename = "OidcKeepAliveServiceWorker.json";
|
|
7
|
+
declare const handleInstall: (event: any) => void;
|
|
8
|
+
declare const handleActivate: (event: any) => void;
|
|
9
|
+
declare let currentLoginCallbackConfigurationName: any;
|
|
10
|
+
declare const database: {
|
|
11
|
+
default: {
|
|
12
|
+
configurationName: string;
|
|
13
|
+
tokens: any;
|
|
14
|
+
status: any;
|
|
15
|
+
state: any;
|
|
16
|
+
codeVerifier: any;
|
|
17
|
+
nonce: any;
|
|
18
|
+
oidcServerConfiguration: any;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
declare const countLetter: (str: any, find: any) => number;
|
|
22
|
+
declare const b64DecodeUnicode: (str: string) => string;
|
|
23
|
+
declare const parseJwt: (token: any) => any;
|
|
24
|
+
declare const extractTokenPayload: (token: any) => any;
|
|
25
|
+
declare const computeTimeLeft: (refreshTimeBeforeTokensExpirationInSecond: any, expiresAt: any) => number;
|
|
26
|
+
declare const isTokensValid: (tokens: any) => boolean;
|
|
27
|
+
declare const isTokensOidcValid: (tokens: any, nonce: any, oidcServerConfiguration: any) => {
|
|
28
|
+
isValid: boolean;
|
|
29
|
+
reason: string;
|
|
30
|
+
};
|
|
31
|
+
declare const TokenRenewMode: {
|
|
32
|
+
access_token_or_id_token_invalid: string;
|
|
33
|
+
access_token_invalid: string;
|
|
34
|
+
id_token_invalid: string;
|
|
35
|
+
};
|
|
36
|
+
declare function hideTokens(currentDatabaseElement: any): (response: any) => any;
|
|
37
|
+
declare const getCurrentDatabasesTokenEndpoint: (database: any, url: any) => any[];
|
|
38
|
+
declare const openidWellknownUrlEndWith = "/.well-known/openid-configuration";
|
|
39
|
+
declare const getCurrentDatabaseDomain: (database: any, url: any) => any;
|
|
40
|
+
declare const serializeHeaders: (headers: any) => {};
|
|
41
|
+
declare const REFRESH_TOKEN = "REFRESH_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER";
|
|
42
|
+
declare const ACCESS_TOKEN = "ACCESS_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER";
|
|
43
|
+
declare const NONCE_TOKEN = "NONCE_SECURED_BY_OIDC_SERVICE_WORKER";
|
|
44
|
+
declare const CODE_VERIFIER = "CODE_VERIFIER_SECURED_BY_OIDC_SERVICE_WORKER";
|
|
45
|
+
declare const sleep: (ms: number) => Promise<unknown>;
|
|
46
|
+
declare const keepAliveAsync: (event: FetchEvent) => Promise<Response>;
|
|
47
|
+
declare const handleFetch: (event: FetchEvent | any) => Promise<void>;
|
|
48
|
+
declare const handleMessage: (event: ExtendableMessageEvent) => void;
|
|
49
|
+
declare const checkDomain: (domains: any, endpoint: any) => void;
|
|
50
|
+
//# sourceMappingURL=OidcServiceWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OidcServiceWorker.d.ts","sourceRoot":"","sources":["../service_worker/OidcServiceWorker.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,KAAK,8CAAuD,CAAC;AACnE,OAAO,CAAC,IAAI,cAAc,EAAE,GAAG,CAAC;AAEhC,QAAA,MAAM,cAAc,0BAA0B,CAAC;AAG/C,QAAA,MAAM,EAAE,QAAqD,CAAC;AAE9D,QAAA,MAAM,oBAAoB,MAAM,CAAC;AAEjC,QAAA,MAAM,qBAAqB,oCAAoC,CAAC;AAChE,QAAA,MAAM,aAAa,sBAGlB,CAAC;AAEF,QAAA,MAAM,cAAc,sBAGnB,CAAC;AAEF,QAAA,IAAI,qCAAqC,KAAO,CAAC;AACjD,QAAA,MAAM,QAAQ;;;;;;;;;;CAUb,CAAC;AAEF,QAAA,MAAM,WAAW,iCAEhB,CAAC;AAEF,QAAA,MAAM,gBAAgB,QAAS,MAAM,WAC6F,CAAC;AACnI,QAAA,MAAM,QAAQ,qBAAmG,CAAC;AAClH,QAAA,MAAM,mBAAmB,qBAcxB,CAAC;AAEF,QAAA,MAAM,eAAe,4EAGpB,CAAC;AAEF,QAAA,MAAM,aAAa,0BAKlB,CAAC;AAIF,QAAA,MAAM,iBAAiB;;;CA2BtB,CAAC;AAEF,QAAA,MAAM,cAAc;;;;CAInB,CAAC;AAEF,iBAAS,UAAU,CAAC,sBAAsB,KAAA,0BAoEzC;AAED,QAAA,MAAM,gCAAgC,oCAarC,CAAC;AAEF,QAAA,MAAM,yBAAyB,sCAAsC,CAAC;AACtE,QAAA,MAAM,wBAAwB,kCAmD7B,CAAC;AAEF,QAAA,MAAM,gBAAgB,sBAMrB,CAAC;AAEF,QAAA,MAAM,aAAa,iDAAiD,CAAC;AACrE,QAAA,MAAM,YAAY,gDAAgD,CAAC;AACnE,QAAA,MAAM,WAAW,yCAAyC,CAAC;AAC3D,QAAA,MAAM,aAAa,iDAAiD,CAAC;AAErE,QAAA,MAAM,KAAK,OAAQ,MAAM,qBAAoD,CAAC;AAE9E,QAAA,MAAM,cAAc,UAAiB,UAAU,sBAc9C,CAAC;AAEF,QAAA,MAAM,WAAW,UAAgB,UAAU,GAAC,GAAG,kBAuH9C,CAAC;AAEF,QAAA,MAAM,aAAa,UAAW,sBAAsB,SA+GnD,CAAC;AAOF,QAAA,MAAM,WAAW,uCAiBhB,CAAC"}
|
|
@@ -1,21 +1,17 @@
|
|
|
1
|
+
const _self = self;
|
|
1
2
|
const scriptFilename = 'OidcTrustedDomains.js'; /* global trustedDomains */
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
_self.importScripts(scriptFilename);
|
|
4
4
|
const id = Math.round(new Date().getTime() / 1000).toString();
|
|
5
|
-
|
|
6
5
|
const acceptAnyDomainToken = '*';
|
|
7
|
-
|
|
8
6
|
const keepAliveJsonFilename = 'OidcKeepAliveServiceWorker.json';
|
|
9
7
|
const handleInstall = (event) => {
|
|
10
8
|
console.log('[OidcServiceWorker] service worker installed ' + id);
|
|
11
|
-
event.waitUntil(
|
|
9
|
+
event.waitUntil(_self.skipWaiting());
|
|
12
10
|
};
|
|
13
|
-
|
|
14
11
|
const handleActivate = (event) => {
|
|
15
12
|
console.log('[OidcServiceWorker] service worker activated ' + id);
|
|
16
|
-
event.waitUntil(
|
|
13
|
+
event.waitUntil(_self.clients.claim());
|
|
17
14
|
};
|
|
18
|
-
|
|
19
15
|
let currentLoginCallbackConfigurationName = null;
|
|
20
16
|
const database = {
|
|
21
17
|
default: {
|
|
@@ -28,13 +24,10 @@ const database = {
|
|
|
28
24
|
oidcServerConfiguration: null,
|
|
29
25
|
},
|
|
30
26
|
};
|
|
31
|
-
|
|
32
27
|
const countLetter = (str, find) => {
|
|
33
28
|
return (str.split(find)).length - 1;
|
|
34
29
|
};
|
|
35
|
-
|
|
36
|
-
const b64DecodeUnicode = (str) =>
|
|
37
|
-
decodeURIComponent(Array.prototype.map.call(atob(str), (c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join(''));
|
|
30
|
+
const b64DecodeUnicode = (str) => decodeURIComponent(Array.prototype.map.call(atob(str), (c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join(''));
|
|
38
31
|
const parseJwt = (token) => JSON.parse(b64DecodeUnicode(token.split('.')[1].replace('-', '+').replace('_', '/')));
|
|
39
32
|
const extractTokenPayload = (token) => {
|
|
40
33
|
try {
|
|
@@ -43,27 +36,26 @@ const extractTokenPayload = (token) => {
|
|
|
43
36
|
}
|
|
44
37
|
if (countLetter(token, '.') === 2) {
|
|
45
38
|
return parseJwt(token);
|
|
46
|
-
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
47
41
|
return null;
|
|
48
42
|
}
|
|
49
|
-
}
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
50
45
|
console.warn(e);
|
|
51
46
|
}
|
|
52
47
|
return null;
|
|
53
48
|
};
|
|
54
|
-
|
|
55
49
|
const computeTimeLeft = (refreshTimeBeforeTokensExpirationInSecond, expiresAt) => {
|
|
56
50
|
const currentTimeUnixSecond = new Date().getTime() / 1000;
|
|
57
51
|
return Math.round(((expiresAt - refreshTimeBeforeTokensExpirationInSecond) - currentTimeUnixSecond));
|
|
58
52
|
};
|
|
59
|
-
|
|
60
53
|
const isTokensValid = (tokens) => {
|
|
61
54
|
if (!tokens) {
|
|
62
55
|
return false;
|
|
63
56
|
}
|
|
64
57
|
return computeTimeLeft(0, tokens.expiresAt) > 0;
|
|
65
58
|
};
|
|
66
|
-
|
|
67
59
|
// https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation (excluding rules #1, #4, #5, #7, #8, #12, and #13 which did not apply).
|
|
68
60
|
// https://github.com/openid/AppAuth-JS/issues/65
|
|
69
61
|
const isTokensOidcValid = (tokens, nonce, oidcServerConfiguration) => {
|
|
@@ -74,9 +66,7 @@ const isTokensOidcValid = (tokens, nonce, oidcServerConfiguration) => {
|
|
|
74
66
|
return { isValid: false, reason: 'Issuer does not match' };
|
|
75
67
|
}
|
|
76
68
|
// 3: The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience. The aud (audience) Claim MAY contain an array with more than one element. The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.
|
|
77
|
-
|
|
78
69
|
// 6: If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature. The Client MUST validate the signature of all other ID Tokens according to JWS [JWS] using the algorithm specified in the JWT alg Header Parameter. The Client MUST use the keys provided by the Issuer.
|
|
79
|
-
|
|
80
70
|
// 9: The current time MUST be before the time represented by the exp Claim.
|
|
81
71
|
const currentTimeUnixSecond = new Date().getTime() / 1000;
|
|
82
72
|
if (idTokenPayload.exp && idTokenPayload.exp < currentTimeUnixSecond) {
|
|
@@ -94,13 +84,11 @@ const isTokensOidcValid = (tokens, nonce, oidcServerConfiguration) => {
|
|
|
94
84
|
}
|
|
95
85
|
return { isValid: true, reason: '' };
|
|
96
86
|
};
|
|
97
|
-
|
|
98
87
|
const TokenRenewMode = {
|
|
99
88
|
access_token_or_id_token_invalid: 'access_token_or_id_token_invalid',
|
|
100
89
|
access_token_invalid: 'access_token_invalid',
|
|
101
90
|
id_token_invalid: 'id_token_invalid',
|
|
102
91
|
};
|
|
103
|
-
|
|
104
92
|
function hideTokens(currentDatabaseElement) {
|
|
105
93
|
const configurationName = currentDatabaseElement.configurationName;
|
|
106
94
|
return (response) => {
|
|
@@ -112,7 +100,6 @@ function hideTokens(currentDatabaseElement) {
|
|
|
112
100
|
const currentTimeUnixSecond = new Date().getTime() / 1000;
|
|
113
101
|
tokens.issued_at = currentTimeUnixSecond;
|
|
114
102
|
}
|
|
115
|
-
|
|
116
103
|
const accessTokenPayload = extractTokenPayload(tokens.access_token);
|
|
117
104
|
const secureTokens = {
|
|
118
105
|
...tokens,
|
|
@@ -120,7 +107,6 @@ function hideTokens(currentDatabaseElement) {
|
|
|
120
107
|
accessTokenPayload,
|
|
121
108
|
};
|
|
122
109
|
tokens.accessTokenPayload = accessTokenPayload;
|
|
123
|
-
|
|
124
110
|
let _idTokenPayload = null;
|
|
125
111
|
if (tokens.id_token) {
|
|
126
112
|
_idTokenPayload = extractTokenPayload(tokens.id_token);
|
|
@@ -134,43 +120,40 @@ function hideTokens(currentDatabaseElement) {
|
|
|
134
120
|
if (tokens.refresh_token) {
|
|
135
121
|
secureTokens.refresh_token = REFRESH_TOKEN + '_' + configurationName;
|
|
136
122
|
}
|
|
137
|
-
|
|
138
123
|
const idTokenExpiresAt = (_idTokenPayload && _idTokenPayload.exp) ? _idTokenPayload.exp : Number.MAX_VALUE;
|
|
139
124
|
const accessTokenExpiresAt = (accessTokenPayload && accessTokenPayload.exp) ? accessTokenPayload.exp : tokens.issued_at + tokens.expires_in;
|
|
140
|
-
|
|
141
125
|
let expiresAt;
|
|
142
126
|
const tokenRenewMode = currentDatabaseElement.oidcConfiguration.token_renew_mode;
|
|
143
127
|
if (tokenRenewMode === TokenRenewMode.access_token_invalid) {
|
|
144
128
|
expiresAt = accessTokenExpiresAt;
|
|
145
|
-
}
|
|
129
|
+
}
|
|
130
|
+
else if (tokenRenewMode === TokenRenewMode.id_token_invalid) {
|
|
146
131
|
expiresAt = idTokenExpiresAt;
|
|
147
|
-
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
148
134
|
expiresAt = idTokenExpiresAt < accessTokenExpiresAt ? idTokenExpiresAt : accessTokenExpiresAt;
|
|
149
135
|
}
|
|
150
136
|
secureTokens.expiresAt = expiresAt;
|
|
151
|
-
|
|
152
137
|
tokens.expiresAt = expiresAt;
|
|
153
138
|
const nonce = currentDatabaseElement.nonce ? currentDatabaseElement.nonce.nonce : null;
|
|
154
139
|
const { isValid, reason } = isTokensOidcValid(tokens, nonce, currentDatabaseElement.oidcServerConfiguration);
|
|
155
140
|
if (!isValid) {
|
|
156
141
|
throw Error(`Tokens are not OpenID valid, reason: ${reason}`);
|
|
157
142
|
}
|
|
158
|
-
|
|
159
143
|
// When refresh_token is not rotated we reuse ald refresh_token
|
|
160
144
|
if (currentDatabaseElement.tokens != null && 'refresh_token' in currentDatabaseElement.tokens && !('refresh_token' in tokens)) {
|
|
161
145
|
const refreshToken = currentDatabaseElement.tokens.refresh_token;
|
|
162
146
|
currentDatabaseElement.tokens = { ...tokens, refresh_token: refreshToken };
|
|
163
|
-
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
164
149
|
currentDatabaseElement.tokens = tokens;
|
|
165
150
|
}
|
|
166
|
-
|
|
167
151
|
currentDatabaseElement.status = 'LOGGED_IN';
|
|
168
152
|
const body = JSON.stringify(secureTokens);
|
|
169
153
|
return new Response(body, response);
|
|
170
154
|
});
|
|
171
155
|
};
|
|
172
156
|
}
|
|
173
|
-
|
|
174
157
|
const getCurrentDatabasesTokenEndpoint = (database, url) => {
|
|
175
158
|
const databases = [];
|
|
176
159
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -178,14 +161,14 @@ const getCurrentDatabasesTokenEndpoint = (database, url) => {
|
|
|
178
161
|
if (value) {
|
|
179
162
|
if (value.oidcServerConfiguration != null && url.startsWith(value.oidcServerConfiguration.tokenEndpoint)) {
|
|
180
163
|
databases.push(value);
|
|
181
|
-
}
|
|
164
|
+
}
|
|
165
|
+
else if (value.oidcServerConfiguration != null && value.oidcServerConfiguration.revocationEndpoint && url.startsWith(value.oidcServerConfiguration.revocationEndpoint)) {
|
|
182
166
|
databases.push(value);
|
|
183
167
|
}
|
|
184
168
|
}
|
|
185
169
|
}
|
|
186
170
|
return databases;
|
|
187
171
|
};
|
|
188
|
-
|
|
189
172
|
const openidWellknownUrlEndWith = '/.well-known/openid-configuration';
|
|
190
173
|
const getCurrentDatabaseDomain = (database, url) => {
|
|
191
174
|
if (url.endsWith(openidWellknownUrlEndWith)) {
|
|
@@ -193,42 +176,36 @@ const getCurrentDatabaseDomain = (database, url) => {
|
|
|
193
176
|
}
|
|
194
177
|
for (const [key, currentDatabase] of Object.entries(database)) {
|
|
195
178
|
const oidcServerConfiguration = currentDatabase.oidcServerConfiguration;
|
|
196
|
-
|
|
197
179
|
if (!oidcServerConfiguration) {
|
|
198
180
|
continue;
|
|
199
181
|
}
|
|
200
|
-
|
|
201
182
|
if (oidcServerConfiguration.tokenEndpoint && url === oidcServerConfiguration.tokenEndpoint) {
|
|
202
183
|
continue;
|
|
203
184
|
}
|
|
204
185
|
if (oidcServerConfiguration.revocationEndpoint && url === oidcServerConfiguration.revocationEndpoint) {
|
|
205
186
|
continue;
|
|
206
187
|
}
|
|
207
|
-
|
|
208
188
|
const domainsToSendTokens = oidcServerConfiguration.userInfoEndpoint
|
|
209
189
|
? [
|
|
210
190
|
oidcServerConfiguration.userInfoEndpoint, ...trustedDomains[key],
|
|
211
191
|
]
|
|
212
192
|
: [...trustedDomains[key]];
|
|
213
|
-
|
|
214
193
|
let hasToSendToken = false;
|
|
215
194
|
if (domainsToSendTokens.find((f) => f === acceptAnyDomainToken)) {
|
|
216
195
|
hasToSendToken = true;
|
|
217
|
-
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
218
198
|
for (let i = 0; i < domainsToSendTokens.length; i++) {
|
|
219
199
|
let domain = domainsToSendTokens[i];
|
|
220
|
-
|
|
221
200
|
if (typeof domain === 'string') {
|
|
222
201
|
domain = new RegExp(`^${domain}`);
|
|
223
202
|
}
|
|
224
|
-
|
|
225
203
|
if (domain.test?.(url)) {
|
|
226
204
|
hasToSendToken = true;
|
|
227
205
|
break;
|
|
228
206
|
}
|
|
229
207
|
}
|
|
230
208
|
}
|
|
231
|
-
|
|
232
209
|
if (hasToSendToken) {
|
|
233
210
|
if (!currentDatabase.tokens) {
|
|
234
211
|
return null;
|
|
@@ -236,10 +213,8 @@ const getCurrentDatabaseDomain = (database, url) => {
|
|
|
236
213
|
return currentDatabase;
|
|
237
214
|
}
|
|
238
215
|
}
|
|
239
|
-
|
|
240
216
|
return null;
|
|
241
217
|
};
|
|
242
|
-
|
|
243
218
|
const serializeHeaders = (headers) => {
|
|
244
219
|
const headersObj = {};
|
|
245
220
|
for (const key of headers.keys()) {
|
|
@@ -247,14 +222,11 @@ const serializeHeaders = (headers) => {
|
|
|
247
222
|
}
|
|
248
223
|
return headersObj;
|
|
249
224
|
};
|
|
250
|
-
|
|
251
225
|
const REFRESH_TOKEN = 'REFRESH_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER';
|
|
252
226
|
const ACCESS_TOKEN = 'ACCESS_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER';
|
|
253
227
|
const NONCE_TOKEN = 'NONCE_SECURED_BY_OIDC_SERVICE_WORKER';
|
|
254
228
|
const CODE_VERIFIER = 'CODE_VERIFIER_SECURED_BY_OIDC_SERVICE_WORKER';
|
|
255
|
-
|
|
256
229
|
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
257
|
-
|
|
258
230
|
const keepAliveAsync = async (event) => {
|
|
259
231
|
const originalRequest = event.request;
|
|
260
232
|
const isFromVanilla = originalRequest.headers.has('oidc-vanilla');
|
|
@@ -267,10 +239,8 @@ const keepAliveAsync = async (event) => {
|
|
|
267
239
|
await cache.put(event.request, response.clone());
|
|
268
240
|
}
|
|
269
241
|
}
|
|
270
|
-
|
|
271
242
|
return response;
|
|
272
243
|
};
|
|
273
|
-
|
|
274
244
|
const handleFetch = async (event) => {
|
|
275
245
|
const originalRequest = event.request;
|
|
276
246
|
const url = originalRequest.url;
|
|
@@ -278,7 +248,6 @@ const handleFetch = async (event) => {
|
|
|
278
248
|
event.respondWith(keepAliveAsync(event));
|
|
279
249
|
return;
|
|
280
250
|
}
|
|
281
|
-
|
|
282
251
|
const currentDatabaseForRequestAccessToken = getCurrentDatabaseDomain(database, originalRequest.url);
|
|
283
252
|
if (currentDatabaseForRequestAccessToken && currentDatabaseForRequestAccessToken.tokens && currentDatabaseForRequestAccessToken.tokens.access_token) {
|
|
284
253
|
while (currentDatabaseForRequestAccessToken.tokens && !isTokensValid(currentDatabaseForRequestAccessToken.tokens)) {
|
|
@@ -294,11 +263,9 @@ const handleFetch = async (event) => {
|
|
|
294
263
|
event.waitUntil(event.respondWith(fetch(newRequest)));
|
|
295
264
|
return;
|
|
296
265
|
}
|
|
297
|
-
|
|
298
266
|
if (event.request.method !== 'POST') {
|
|
299
267
|
return;
|
|
300
268
|
}
|
|
301
|
-
|
|
302
269
|
let currentDatabase = null;
|
|
303
270
|
const currentDatabases = getCurrentDatabasesTokenEndpoint(database, originalRequest.url);
|
|
304
271
|
const numberDatabase = currentDatabases.length;
|
|
@@ -310,7 +277,6 @@ const handleFetch = async (event) => {
|
|
|
310
277
|
let newBody = actualBody;
|
|
311
278
|
for (let i = 0; i < numberDatabase; i++) {
|
|
312
279
|
const currentDb = currentDatabases[i];
|
|
313
|
-
|
|
314
280
|
if (currentDb && currentDb.tokens != null) {
|
|
315
281
|
const keyRefreshToken = REFRESH_TOKEN + '_' + currentDb.configurationName;
|
|
316
282
|
if (actualBody.includes(keyRefreshToken)) {
|
|
@@ -340,13 +306,14 @@ const handleFetch = async (event) => {
|
|
|
340
306
|
integrity: clonedRequest.integrity,
|
|
341
307
|
});
|
|
342
308
|
if (currentDatabase.oidcServerConfiguration != null && currentDatabase.oidcServerConfiguration.revocationEndpoint && url.startsWith(currentDatabase.oidcServerConfiguration.revocationEndpoint)) {
|
|
343
|
-
return fetchPromise.then(async response => {
|
|
309
|
+
return fetchPromise.then(async (response) => {
|
|
344
310
|
const text = await response.text();
|
|
345
311
|
return new Response(text, response);
|
|
346
312
|
});
|
|
347
313
|
}
|
|
348
314
|
return fetchPromise.then(hideTokens(currentDatabase));
|
|
349
|
-
}
|
|
315
|
+
}
|
|
316
|
+
else if (actualBody.includes('code_verifier=') && currentLoginCallbackConfigurationName) {
|
|
350
317
|
currentDatabase = database[currentLoginCallbackConfigurationName];
|
|
351
318
|
currentLoginCallbackConfigurationName = null;
|
|
352
319
|
let newBody = actualBody;
|
|
@@ -356,7 +323,6 @@ const handleFetch = async (event) => {
|
|
|
356
323
|
newBody = newBody.replace(keyCodeVerifier, currentDatabase.codeVerifier);
|
|
357
324
|
}
|
|
358
325
|
}
|
|
359
|
-
|
|
360
326
|
return fetch(originalRequest, {
|
|
361
327
|
body: newBody,
|
|
362
328
|
method: clonedRequest.method,
|
|
@@ -375,14 +341,16 @@ const handleFetch = async (event) => {
|
|
|
375
341
|
response.then(r => {
|
|
376
342
|
if (r !== undefined) {
|
|
377
343
|
resolve(r);
|
|
378
|
-
}
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
379
346
|
console.log('success undefined');
|
|
380
347
|
reject(new Error('Response is undefined inside a success'));
|
|
381
348
|
}
|
|
382
349
|
}).catch(err => {
|
|
383
350
|
if (err !== undefined) {
|
|
384
351
|
reject(err);
|
|
385
|
-
}
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
386
354
|
console.log('error undefined');
|
|
387
355
|
reject(new Error('Response is undefined inside a error'));
|
|
388
356
|
}
|
|
@@ -391,36 +359,11 @@ const handleFetch = async (event) => {
|
|
|
391
359
|
event.waitUntil(event.respondWith(maPromesse));
|
|
392
360
|
}
|
|
393
361
|
};
|
|
394
|
-
|
|
395
|
-
self.addEventListener('install', handleInstall);
|
|
396
|
-
self.addEventListener('activate', handleActivate);
|
|
397
|
-
self.addEventListener('fetch', handleFetch);
|
|
398
|
-
|
|
399
|
-
const checkDomain = (domains, endpoint) => {
|
|
400
|
-
if (!endpoint) {
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const domain = domains.find((domain) => {
|
|
405
|
-
let testable = domain;
|
|
406
|
-
|
|
407
|
-
if (typeof domain === 'string') {
|
|
408
|
-
testable = new RegExp(`^${domain}`);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
return testable.test?.(endpoint);
|
|
412
|
-
});
|
|
413
|
-
if (!domain) {
|
|
414
|
-
throw new Error('Domain ' + endpoint + ' is not trusted, please add domain in ' + scriptFilename);
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
|
|
418
|
-
addEventListener('message', event => {
|
|
362
|
+
const handleMessage = (event) => {
|
|
419
363
|
const port = event.ports[0];
|
|
420
364
|
const data = event.data;
|
|
421
365
|
const configurationName = data.configurationName;
|
|
422
366
|
let currentDatabase = database[configurationName];
|
|
423
|
-
|
|
424
367
|
if (!currentDatabase) {
|
|
425
368
|
database[configurationName] = {
|
|
426
369
|
tokens: null,
|
|
@@ -436,7 +379,6 @@ addEventListener('message', event => {
|
|
|
436
379
|
trustedDomains[configurationName] = [];
|
|
437
380
|
}
|
|
438
381
|
}
|
|
439
|
-
|
|
440
382
|
switch (data.type) {
|
|
441
383
|
case 'clear':
|
|
442
384
|
currentDatabase.tokens = null;
|
|
@@ -446,78 +388,79 @@ addEventListener('message', event => {
|
|
|
446
388
|
port.postMessage({ configurationName });
|
|
447
389
|
return;
|
|
448
390
|
case 'init':
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
currentDatabase.oidcServerConfiguration = oidcServerConfiguration;
|
|
459
|
-
currentDatabase.oidcConfiguration = data.data.oidcConfiguration;
|
|
460
|
-
const where = data.data.where;
|
|
461
|
-
if (where === 'loginCallbackAsync' || where === 'tryKeepExistingSessionAsync') {
|
|
462
|
-
currentLoginCallbackConfigurationName = configurationName;
|
|
463
|
-
} else {
|
|
464
|
-
currentLoginCallbackConfigurationName = null;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
if (!currentDatabase.tokens) {
|
|
468
|
-
port.postMessage({
|
|
469
|
-
tokens: null,
|
|
470
|
-
status: currentDatabase.status,
|
|
471
|
-
configurationName,
|
|
472
|
-
});
|
|
473
|
-
} else {
|
|
474
|
-
const tokens = {
|
|
475
|
-
...currentDatabase.tokens,
|
|
476
|
-
access_token: ACCESS_TOKEN + '_' + configurationName,
|
|
477
|
-
};
|
|
478
|
-
if (tokens.refresh_token) {
|
|
479
|
-
tokens.refresh_token = REFRESH_TOKEN + '_' + configurationName;
|
|
391
|
+
{
|
|
392
|
+
const oidcServerConfiguration = data.data.oidcServerConfiguration;
|
|
393
|
+
const domains = trustedDomains[configurationName];
|
|
394
|
+
if (!domains.find(f => f === acceptAnyDomainToken)) {
|
|
395
|
+
checkDomain(domains, oidcServerConfiguration.tokenEndpoint);
|
|
396
|
+
checkDomain(domains, oidcServerConfiguration.revocationEndpoint);
|
|
397
|
+
checkDomain(domains, oidcServerConfiguration.userInfoEndpoint);
|
|
398
|
+
checkDomain(domains, oidcServerConfiguration.issuer);
|
|
480
399
|
}
|
|
481
|
-
|
|
482
|
-
|
|
400
|
+
currentDatabase.oidcServerConfiguration = oidcServerConfiguration;
|
|
401
|
+
currentDatabase.oidcConfiguration = data.data.oidcConfiguration;
|
|
402
|
+
const where = data.data.where;
|
|
403
|
+
if (where === 'loginCallbackAsync' || where === 'tryKeepExistingSessionAsync') {
|
|
404
|
+
currentLoginCallbackConfigurationName = configurationName;
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
currentLoginCallbackConfigurationName = null;
|
|
408
|
+
}
|
|
409
|
+
if (!currentDatabase.tokens) {
|
|
410
|
+
port.postMessage({
|
|
411
|
+
tokens: null,
|
|
412
|
+
status: currentDatabase.status,
|
|
413
|
+
configurationName,
|
|
414
|
+
});
|
|
483
415
|
}
|
|
484
|
-
|
|
485
|
-
tokens
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
416
|
+
else {
|
|
417
|
+
const tokens = {
|
|
418
|
+
...currentDatabase.tokens,
|
|
419
|
+
access_token: ACCESS_TOKEN + '_' + configurationName,
|
|
420
|
+
};
|
|
421
|
+
if (tokens.refresh_token) {
|
|
422
|
+
tokens.refresh_token = REFRESH_TOKEN + '_' + configurationName;
|
|
423
|
+
}
|
|
424
|
+
if (tokens.idTokenPayload && tokens.idTokenPayload.nonce && currentDatabase.nonce != null) {
|
|
425
|
+
tokens.idTokenPayload.nonce = NONCE_TOKEN + '_' + configurationName;
|
|
426
|
+
}
|
|
427
|
+
port.postMessage({
|
|
428
|
+
tokens,
|
|
429
|
+
status: currentDatabase.status,
|
|
430
|
+
configurationName,
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
return;
|
|
489
434
|
}
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
435
|
case 'setState':
|
|
493
436
|
currentDatabase.state = data.data.state;
|
|
494
437
|
port.postMessage({ configurationName });
|
|
495
438
|
return;
|
|
496
439
|
case 'getState':
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
440
|
+
{
|
|
441
|
+
const state = currentDatabase.state;
|
|
442
|
+
port.postMessage({ configurationName, state });
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
502
445
|
case 'setCodeVerifier':
|
|
503
446
|
currentDatabase.codeVerifier = data.data.codeVerifier;
|
|
504
447
|
port.postMessage({ configurationName });
|
|
505
448
|
return;
|
|
506
449
|
case 'getCodeVerifier':
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
450
|
+
{
|
|
451
|
+
port.postMessage({ configurationName, codeVerifier: CODE_VERIFIER + '_' + configurationName });
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
511
454
|
case 'setSessionState':
|
|
512
455
|
currentDatabase.sessionState = data.data.sessionState;
|
|
513
456
|
port.postMessage({ configurationName });
|
|
514
457
|
return;
|
|
515
458
|
case 'getSessionState':
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
459
|
+
{
|
|
460
|
+
const sessionState = currentDatabase.sessionState;
|
|
461
|
+
port.postMessage({ configurationName, sessionState });
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
521
464
|
case 'setNonce':
|
|
522
465
|
currentDatabase.nonce = data.data.nonce;
|
|
523
466
|
port.postMessage({ configurationName });
|
|
@@ -526,4 +469,24 @@ addEventListener('message', event => {
|
|
|
526
469
|
currentDatabase.items = { ...data.data };
|
|
527
470
|
port.postMessage({ configurationName });
|
|
528
471
|
}
|
|
529
|
-
}
|
|
472
|
+
};
|
|
473
|
+
_self.addEventListener('install', handleInstall);
|
|
474
|
+
_self.addEventListener('activate', handleActivate);
|
|
475
|
+
_self.addEventListener('fetch', handleFetch);
|
|
476
|
+
_self.addEventListener('message', handleMessage);
|
|
477
|
+
const checkDomain = (domains, endpoint) => {
|
|
478
|
+
if (!endpoint) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
const domain = domains.find((domain) => {
|
|
482
|
+
let testable = domain;
|
|
483
|
+
if (typeof domain === 'string') {
|
|
484
|
+
testable = new RegExp(`^${domain}`);
|
|
485
|
+
}
|
|
486
|
+
return testable.test?.(endpoint);
|
|
487
|
+
});
|
|
488
|
+
if (!domain) {
|
|
489
|
+
throw new Error('Domain ' + endpoint + ' is not trusted, please add domain in ' + scriptFilename);
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
//# sourceMappingURL=OidcServiceWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OidcServiceWorker.js","sourceRoot":"","sources":["../service_worker/OidcServiceWorker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"program":{"fileNames":["../node_modules/typescript/lib/lib.es5.d.ts","../node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/typescript/lib/lib.webworker.d.ts","../node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/typescript/lib/lib.es2020.number.d.ts","../service_worker/OidcServiceWorker.ts"],"fileInfos":[{"version":"f20c05dbfe50a208301d2a1da37b9931bce0466eb5a1f4fe240971b4ecc82b67","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","e6b724280c694a9f588847f754198fb96c43d805f065c3a5b28bbc9594541c84","1fc5ab7a764205c68fa10d381b08417795fc73111d6dd16b5b1ed36badb743d9",{"version":"adb09ec0a64fc17dbbc4a228b3b18aa5f01db3440a6b0cbb02354df58674d584","affectsGlobalScope":true},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true},{"version":"0d5f52b3174bee6edb81260ebcd792692c32c81fd55499d69531496f3f2b25e7","affectsGlobalScope":true},{"version":"55f400eec64d17e888e278f4def2f254b41b89515d3b88ad75d5e05f019daddd","affectsGlobalScope":true},{"version":"181f1784c6c10b751631b24ce60c7f78b20665db4550b335be179217bacc0d5f","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"75ec0bdd727d887f1b79ed6619412ea72ba3c81d92d0787ccb64bab18d261f14","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true},{"version":"d7f680a43f8cd12a6b6122c07c54ba40952b0c8aa140dcfcf32eb9e6cb028596","affectsGlobalScope":true},{"version":"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"775d9c9fd150d5de79e0450f35bc8b8f94ae64e3eb5da12725ff2a649dccc777","affectsGlobalScope":true},{"version":"b248e32ca52e8f5571390a4142558ae4f203ae2f94d5bac38a3084d529ef4e58","affectsGlobalScope":true},{"version":"c8648c6a45ed117b1ac0ec2e3ac967535fb32f2cdc1a4cb181b26a6a57b84046","signature":"ecb3be179a45513f769a30ba4cee2c2c535533d307fc8cc1ddc28a4cf5947eeb","affectsGlobalScope":true}],"options":{"composite":true,"declarationMap":true,"module":6,"outDir":"./","rootDir":"../service_worker","sourceMap":true,"strict":false,"target":7},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[10,9,2,11,12,13,14,15,16,17,18,3,4,22,19,20,21,23,24,25,5,26,27,28,29,6,30,31,32,33,7,34,39,40,35,36,37,38,1,8,41],"latestChangedDtsFile":"./OidcServiceWorker.d.ts"},"version":"4.8.2"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axa-fr/react-oidc",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.15.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"jsnext:main": "dist/index.js",
|
|
@@ -30,14 +30,15 @@
|
|
|
30
30
|
"next"
|
|
31
31
|
],
|
|
32
32
|
"scripts": {
|
|
33
|
-
"copy": "copyfiles -f ./
|
|
34
|
-
"start": "npm run copy && cross-env PORT=4200 react-scripts start",
|
|
35
|
-
"build": "npm run copy && react-scripts build",
|
|
33
|
+
"copy": "copyfiles -f ./dist/OidcServiceWorker.js ./public && copyfiles -f -soft ./dist/OidcTrustedDomains.js ./public",
|
|
34
|
+
"start": "npm run build:service-worker && npm run copy && cross-env PORT=4200 react-scripts start",
|
|
35
|
+
"build": "npm run build:service-worker && npm run copy && react-scripts build",
|
|
36
36
|
"test": "react-scripts test --coverage",
|
|
37
37
|
"eject": "react-scripts eject",
|
|
38
38
|
"clean": "rimraf dist",
|
|
39
|
-
"prepare": "npm run clean && tsc --build \"./tsconfig.json\" && copyfiles -f ./src/oidc/vanilla/OidcServiceWorker.js ./dist && copyfiles -f ./src/oidc/vanilla/OidcTrustedDomains.js ./dist",
|
|
40
39
|
"postinstall": "node ./bin/copy.js",
|
|
40
|
+
"build:service-worker": "tsc --build \"./service_worker/tsconfig.json\" && copyfiles -f ./service_worker/OidcTrustedDomains.js ./dist",
|
|
41
|
+
"prepare": "npm run clean && tsc --build \"./tsconfig.json\" && npm run build:service-worker",
|
|
41
42
|
"lint": "eslint src"
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|
|
@@ -1,529 +0,0 @@
|
|
|
1
|
-
const scriptFilename = 'OidcTrustedDomains.js'; /* global trustedDomains */
|
|
2
|
-
this.importScripts(scriptFilename);
|
|
3
|
-
|
|
4
|
-
const id = Math.round(new Date().getTime() / 1000).toString();
|
|
5
|
-
|
|
6
|
-
const acceptAnyDomainToken = '*';
|
|
7
|
-
|
|
8
|
-
const keepAliveJsonFilename = 'OidcKeepAliveServiceWorker.json';
|
|
9
|
-
const handleInstall = (event) => {
|
|
10
|
-
console.log('[OidcServiceWorker] service worker installed ' + id);
|
|
11
|
-
event.waitUntil(self.skipWaiting());
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const handleActivate = (event) => {
|
|
15
|
-
console.log('[OidcServiceWorker] service worker activated ' + id);
|
|
16
|
-
event.waitUntil(self.clients.claim());
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
let currentLoginCallbackConfigurationName = null;
|
|
20
|
-
const database = {
|
|
21
|
-
default: {
|
|
22
|
-
configurationName: 'default',
|
|
23
|
-
tokens: null,
|
|
24
|
-
status: null,
|
|
25
|
-
state: null,
|
|
26
|
-
codeVerifier: null,
|
|
27
|
-
nonce: null,
|
|
28
|
-
oidcServerConfiguration: null,
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const countLetter = (str, find) => {
|
|
33
|
-
return (str.split(find)).length - 1;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const b64DecodeUnicode = (str) =>
|
|
37
|
-
decodeURIComponent(Array.prototype.map.call(atob(str), (c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join(''));
|
|
38
|
-
const parseJwt = (token) => JSON.parse(b64DecodeUnicode(token.split('.')[1].replace('-', '+').replace('_', '/')));
|
|
39
|
-
const extractTokenPayload = (token) => {
|
|
40
|
-
try {
|
|
41
|
-
if (!token) {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
if (countLetter(token, '.') === 2) {
|
|
45
|
-
return parseJwt(token);
|
|
46
|
-
} else {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
} catch (e) {
|
|
50
|
-
console.warn(e);
|
|
51
|
-
}
|
|
52
|
-
return null;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const computeTimeLeft = (refreshTimeBeforeTokensExpirationInSecond, expiresAt) => {
|
|
56
|
-
const currentTimeUnixSecond = new Date().getTime() / 1000;
|
|
57
|
-
return Math.round(((expiresAt - refreshTimeBeforeTokensExpirationInSecond) - currentTimeUnixSecond));
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const isTokensValid = (tokens) => {
|
|
61
|
-
if (!tokens) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
return computeTimeLeft(0, tokens.expiresAt) > 0;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation (excluding rules #1, #4, #5, #7, #8, #12, and #13 which did not apply).
|
|
68
|
-
// https://github.com/openid/AppAuth-JS/issues/65
|
|
69
|
-
const isTokensOidcValid = (tokens, nonce, oidcServerConfiguration) => {
|
|
70
|
-
if (tokens.idTokenPayload) {
|
|
71
|
-
const idTokenPayload = tokens.idTokenPayload;
|
|
72
|
-
// 2: The Issuer Identifier for the OpenID Provider (which is typically obtained during Discovery) MUST exactly match the value of the iss (issuer) Claim.
|
|
73
|
-
if (oidcServerConfiguration.issuer !== idTokenPayload.iss) {
|
|
74
|
-
return { isValid: false, reason: 'Issuer does not match' };
|
|
75
|
-
}
|
|
76
|
-
// 3: The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience. The aud (audience) Claim MAY contain an array with more than one element. The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.
|
|
77
|
-
|
|
78
|
-
// 6: If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature. The Client MUST validate the signature of all other ID Tokens according to JWS [JWS] using the algorithm specified in the JWT alg Header Parameter. The Client MUST use the keys provided by the Issuer.
|
|
79
|
-
|
|
80
|
-
// 9: The current time MUST be before the time represented by the exp Claim.
|
|
81
|
-
const currentTimeUnixSecond = new Date().getTime() / 1000;
|
|
82
|
-
if (idTokenPayload.exp && idTokenPayload.exp < currentTimeUnixSecond) {
|
|
83
|
-
return { isValid: false, reason: 'Token expired' };
|
|
84
|
-
}
|
|
85
|
-
// 10: The iat Claim can be used to reject tokens that were issued too far away from the current time, limiting the amount of time that nonces need to be stored to prevent attacks. The acceptable range is Client specific.
|
|
86
|
-
const timeInSevenDays = 60 * 60 * 24 * 7;
|
|
87
|
-
if (idTokenPayload.iat && (idTokenPayload.iat + timeInSevenDays) < currentTimeUnixSecond) {
|
|
88
|
-
return { isValid: false, reason: 'Token is used from too long time' };
|
|
89
|
-
}
|
|
90
|
-
// 11: If a nonce value was sent in the Authentication Request, a nonce Claim MUST be present and its value checked to verify that it is the same value as the one that was sent in the Authentication Request. The Client SHOULD check the nonce value for replay attacks. The precise method for detecting replay attacks is Client specific.
|
|
91
|
-
if (idTokenPayload.nonce && idTokenPayload.nonce !== nonce) {
|
|
92
|
-
return { isValid: false, reason: 'Nonce does not match' };
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return { isValid: true, reason: '' };
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const TokenRenewMode = {
|
|
99
|
-
access_token_or_id_token_invalid: 'access_token_or_id_token_invalid',
|
|
100
|
-
access_token_invalid: 'access_token_invalid',
|
|
101
|
-
id_token_invalid: 'id_token_invalid',
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
function hideTokens(currentDatabaseElement) {
|
|
105
|
-
const configurationName = currentDatabaseElement.configurationName;
|
|
106
|
-
return (response) => {
|
|
107
|
-
if (response.status !== 200) {
|
|
108
|
-
return response;
|
|
109
|
-
}
|
|
110
|
-
return response.json().then(tokens => {
|
|
111
|
-
if (!tokens.issued_at) {
|
|
112
|
-
const currentTimeUnixSecond = new Date().getTime() / 1000;
|
|
113
|
-
tokens.issued_at = currentTimeUnixSecond;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const accessTokenPayload = extractTokenPayload(tokens.access_token);
|
|
117
|
-
const secureTokens = {
|
|
118
|
-
...tokens,
|
|
119
|
-
access_token: ACCESS_TOKEN + '_' + configurationName,
|
|
120
|
-
accessTokenPayload,
|
|
121
|
-
};
|
|
122
|
-
tokens.accessTokenPayload = accessTokenPayload;
|
|
123
|
-
|
|
124
|
-
let _idTokenPayload = null;
|
|
125
|
-
if (tokens.id_token) {
|
|
126
|
-
_idTokenPayload = extractTokenPayload(tokens.id_token);
|
|
127
|
-
tokens.idTokenPayload = { ..._idTokenPayload };
|
|
128
|
-
if (_idTokenPayload.nonce && currentDatabaseElement.nonce != null) {
|
|
129
|
-
const keyNonce = NONCE_TOKEN + '_' + currentDatabaseElement.configurationName;
|
|
130
|
-
_idTokenPayload.nonce = keyNonce;
|
|
131
|
-
}
|
|
132
|
-
secureTokens.idTokenPayload = _idTokenPayload;
|
|
133
|
-
}
|
|
134
|
-
if (tokens.refresh_token) {
|
|
135
|
-
secureTokens.refresh_token = REFRESH_TOKEN + '_' + configurationName;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const idTokenExpiresAt = (_idTokenPayload && _idTokenPayload.exp) ? _idTokenPayload.exp : Number.MAX_VALUE;
|
|
139
|
-
const accessTokenExpiresAt = (accessTokenPayload && accessTokenPayload.exp) ? accessTokenPayload.exp : tokens.issued_at + tokens.expires_in;
|
|
140
|
-
|
|
141
|
-
let expiresAt;
|
|
142
|
-
const tokenRenewMode = currentDatabaseElement.oidcConfiguration.token_renew_mode;
|
|
143
|
-
if (tokenRenewMode === TokenRenewMode.access_token_invalid) {
|
|
144
|
-
expiresAt = accessTokenExpiresAt;
|
|
145
|
-
} else if (tokenRenewMode === TokenRenewMode.id_token_invalid) {
|
|
146
|
-
expiresAt = idTokenExpiresAt;
|
|
147
|
-
} else {
|
|
148
|
-
expiresAt = idTokenExpiresAt < accessTokenExpiresAt ? idTokenExpiresAt : accessTokenExpiresAt;
|
|
149
|
-
}
|
|
150
|
-
secureTokens.expiresAt = expiresAt;
|
|
151
|
-
|
|
152
|
-
tokens.expiresAt = expiresAt;
|
|
153
|
-
const nonce = currentDatabaseElement.nonce ? currentDatabaseElement.nonce.nonce : null;
|
|
154
|
-
const { isValid, reason } = isTokensOidcValid(tokens, nonce, currentDatabaseElement.oidcServerConfiguration);
|
|
155
|
-
if (!isValid) {
|
|
156
|
-
throw Error(`Tokens are not OpenID valid, reason: ${reason}`);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// When refresh_token is not rotated we reuse ald refresh_token
|
|
160
|
-
if (currentDatabaseElement.tokens != null && 'refresh_token' in currentDatabaseElement.tokens && !('refresh_token' in tokens)) {
|
|
161
|
-
const refreshToken = currentDatabaseElement.tokens.refresh_token;
|
|
162
|
-
currentDatabaseElement.tokens = { ...tokens, refresh_token: refreshToken };
|
|
163
|
-
} else {
|
|
164
|
-
currentDatabaseElement.tokens = tokens;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
currentDatabaseElement.status = 'LOGGED_IN';
|
|
168
|
-
const body = JSON.stringify(secureTokens);
|
|
169
|
-
return new Response(body, response);
|
|
170
|
-
});
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const getCurrentDatabasesTokenEndpoint = (database, url) => {
|
|
175
|
-
const databases = [];
|
|
176
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
177
|
-
for (const [key, value] of Object.entries(database)) {
|
|
178
|
-
if (value) {
|
|
179
|
-
if (value.oidcServerConfiguration != null && url.startsWith(value.oidcServerConfiguration.tokenEndpoint)) {
|
|
180
|
-
databases.push(value);
|
|
181
|
-
} else if (value.oidcServerConfiguration != null && value.oidcServerConfiguration.revocationEndpoint && url.startsWith(value.oidcServerConfiguration.revocationEndpoint)) {
|
|
182
|
-
databases.push(value);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return databases;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
const openidWellknownUrlEndWith = '/.well-known/openid-configuration';
|
|
190
|
-
const getCurrentDatabaseDomain = (database, url) => {
|
|
191
|
-
if (url.endsWith(openidWellknownUrlEndWith)) {
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
for (const [key, currentDatabase] of Object.entries(database)) {
|
|
195
|
-
const oidcServerConfiguration = currentDatabase.oidcServerConfiguration;
|
|
196
|
-
|
|
197
|
-
if (!oidcServerConfiguration) {
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (oidcServerConfiguration.tokenEndpoint && url === oidcServerConfiguration.tokenEndpoint) {
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
if (oidcServerConfiguration.revocationEndpoint && url === oidcServerConfiguration.revocationEndpoint) {
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const domainsToSendTokens = oidcServerConfiguration.userInfoEndpoint
|
|
209
|
-
? [
|
|
210
|
-
oidcServerConfiguration.userInfoEndpoint, ...trustedDomains[key],
|
|
211
|
-
]
|
|
212
|
-
: [...trustedDomains[key]];
|
|
213
|
-
|
|
214
|
-
let hasToSendToken = false;
|
|
215
|
-
if (domainsToSendTokens.find((f) => f === acceptAnyDomainToken)) {
|
|
216
|
-
hasToSendToken = true;
|
|
217
|
-
} else {
|
|
218
|
-
for (let i = 0; i < domainsToSendTokens.length; i++) {
|
|
219
|
-
let domain = domainsToSendTokens[i];
|
|
220
|
-
|
|
221
|
-
if (typeof domain === 'string') {
|
|
222
|
-
domain = new RegExp(`^${domain}`);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (domain.test?.(url)) {
|
|
226
|
-
hasToSendToken = true;
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (hasToSendToken) {
|
|
233
|
-
if (!currentDatabase.tokens) {
|
|
234
|
-
return null;
|
|
235
|
-
}
|
|
236
|
-
return currentDatabase;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return null;
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
const serializeHeaders = (headers) => {
|
|
244
|
-
const headersObj = {};
|
|
245
|
-
for (const key of headers.keys()) {
|
|
246
|
-
headersObj[key] = headers.get(key);
|
|
247
|
-
}
|
|
248
|
-
return headersObj;
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
const REFRESH_TOKEN = 'REFRESH_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER';
|
|
252
|
-
const ACCESS_TOKEN = 'ACCESS_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER';
|
|
253
|
-
const NONCE_TOKEN = 'NONCE_SECURED_BY_OIDC_SERVICE_WORKER';
|
|
254
|
-
const CODE_VERIFIER = 'CODE_VERIFIER_SECURED_BY_OIDC_SERVICE_WORKER';
|
|
255
|
-
|
|
256
|
-
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
257
|
-
|
|
258
|
-
const keepAliveAsync = async (event) => {
|
|
259
|
-
const originalRequest = event.request;
|
|
260
|
-
const isFromVanilla = originalRequest.headers.has('oidc-vanilla');
|
|
261
|
-
const init = { status: 200, statusText: 'oidc-service-worker' };
|
|
262
|
-
const response = new Response('{}', init);
|
|
263
|
-
if (!isFromVanilla) {
|
|
264
|
-
for (let i = 0; i < 240; i++) {
|
|
265
|
-
await sleep(1000 + Math.floor(Math.random() * 1000));
|
|
266
|
-
const cache = await caches.open('oidc_dummy_cache');
|
|
267
|
-
await cache.put(event.request, response.clone());
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return response;
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
const handleFetch = async (event) => {
|
|
275
|
-
const originalRequest = event.request;
|
|
276
|
-
const url = originalRequest.url;
|
|
277
|
-
if (originalRequest.url.includes(keepAliveJsonFilename)) {
|
|
278
|
-
event.respondWith(keepAliveAsync(event));
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const currentDatabaseForRequestAccessToken = getCurrentDatabaseDomain(database, originalRequest.url);
|
|
283
|
-
if (currentDatabaseForRequestAccessToken && currentDatabaseForRequestAccessToken.tokens && currentDatabaseForRequestAccessToken.tokens.access_token) {
|
|
284
|
-
while (currentDatabaseForRequestAccessToken.tokens && !isTokensValid(currentDatabaseForRequestAccessToken.tokens)) {
|
|
285
|
-
await sleep(200);
|
|
286
|
-
}
|
|
287
|
-
const newRequest = new Request(originalRequest, {
|
|
288
|
-
headers: {
|
|
289
|
-
...serializeHeaders(originalRequest.headers),
|
|
290
|
-
authorization: 'Bearer ' + currentDatabaseForRequestAccessToken.tokens.access_token,
|
|
291
|
-
},
|
|
292
|
-
mode: currentDatabaseForRequestAccessToken.oidcConfiguration.service_worker_convert_all_requests_to_cors ? 'cors' : originalRequest.mode,
|
|
293
|
-
});
|
|
294
|
-
event.waitUntil(event.respondWith(fetch(newRequest)));
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (event.request.method !== 'POST') {
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
let currentDatabase = null;
|
|
303
|
-
const currentDatabases = getCurrentDatabasesTokenEndpoint(database, originalRequest.url);
|
|
304
|
-
const numberDatabase = currentDatabases.length;
|
|
305
|
-
if (numberDatabase > 0) {
|
|
306
|
-
const maPromesse = new Promise((resolve, reject) => {
|
|
307
|
-
const clonedRequest = originalRequest.clone();
|
|
308
|
-
const response = clonedRequest.text().then(actualBody => {
|
|
309
|
-
if (actualBody.includes(REFRESH_TOKEN) || actualBody.includes(ACCESS_TOKEN)) {
|
|
310
|
-
let newBody = actualBody;
|
|
311
|
-
for (let i = 0; i < numberDatabase; i++) {
|
|
312
|
-
const currentDb = currentDatabases[i];
|
|
313
|
-
|
|
314
|
-
if (currentDb && currentDb.tokens != null) {
|
|
315
|
-
const keyRefreshToken = REFRESH_TOKEN + '_' + currentDb.configurationName;
|
|
316
|
-
if (actualBody.includes(keyRefreshToken)) {
|
|
317
|
-
newBody = newBody.replace(keyRefreshToken, encodeURIComponent(currentDb.tokens.refresh_token));
|
|
318
|
-
currentDatabase = currentDb;
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
const keyAccessToken = ACCESS_TOKEN + '_' + currentDb.configurationName;
|
|
322
|
-
if (actualBody.includes(keyAccessToken)) {
|
|
323
|
-
newBody = newBody.replace(keyAccessToken, encodeURIComponent(currentDb.tokens.access_token));
|
|
324
|
-
currentDatabase = currentDb;
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
const fetchPromise = fetch(originalRequest, {
|
|
330
|
-
body: newBody,
|
|
331
|
-
method: clonedRequest.method,
|
|
332
|
-
headers: {
|
|
333
|
-
...serializeHeaders(originalRequest.headers),
|
|
334
|
-
},
|
|
335
|
-
mode: clonedRequest.mode,
|
|
336
|
-
cache: clonedRequest.cache,
|
|
337
|
-
redirect: clonedRequest.redirect,
|
|
338
|
-
referrer: clonedRequest.referrer,
|
|
339
|
-
credentials: clonedRequest.credentials,
|
|
340
|
-
integrity: clonedRequest.integrity,
|
|
341
|
-
});
|
|
342
|
-
if (currentDatabase.oidcServerConfiguration != null && currentDatabase.oidcServerConfiguration.revocationEndpoint && url.startsWith(currentDatabase.oidcServerConfiguration.revocationEndpoint)) {
|
|
343
|
-
return fetchPromise.then(async response => {
|
|
344
|
-
const text = await response.text();
|
|
345
|
-
return new Response(text, response);
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
return fetchPromise.then(hideTokens(currentDatabase));
|
|
349
|
-
} else if (actualBody.includes('code_verifier=') && currentLoginCallbackConfigurationName) {
|
|
350
|
-
currentDatabase = database[currentLoginCallbackConfigurationName];
|
|
351
|
-
currentLoginCallbackConfigurationName = null;
|
|
352
|
-
let newBody = actualBody;
|
|
353
|
-
if (currentDatabase && currentDatabase.codeVerifier != null) {
|
|
354
|
-
const keyCodeVerifier = CODE_VERIFIER + '_' + currentDatabase.configurationName;
|
|
355
|
-
if (actualBody.includes(keyCodeVerifier)) {
|
|
356
|
-
newBody = newBody.replace(keyCodeVerifier, currentDatabase.codeVerifier);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return fetch(originalRequest, {
|
|
361
|
-
body: newBody,
|
|
362
|
-
method: clonedRequest.method,
|
|
363
|
-
headers: {
|
|
364
|
-
...serializeHeaders(originalRequest.headers),
|
|
365
|
-
},
|
|
366
|
-
mode: clonedRequest.mode,
|
|
367
|
-
cache: clonedRequest.cache,
|
|
368
|
-
redirect: clonedRequest.redirect,
|
|
369
|
-
referrer: clonedRequest.referrer,
|
|
370
|
-
credentials: clonedRequest.credentials,
|
|
371
|
-
integrity: clonedRequest.integrity,
|
|
372
|
-
}).then(hideTokens(currentDatabase));
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
response.then(r => {
|
|
376
|
-
if (r !== undefined) {
|
|
377
|
-
resolve(r);
|
|
378
|
-
} else {
|
|
379
|
-
console.log('success undefined');
|
|
380
|
-
reject(new Error('Response is undefined inside a success'));
|
|
381
|
-
}
|
|
382
|
-
}).catch(err => {
|
|
383
|
-
if (err !== undefined) {
|
|
384
|
-
reject(err);
|
|
385
|
-
} else {
|
|
386
|
-
console.log('error undefined');
|
|
387
|
-
reject(new Error('Response is undefined inside a error'));
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
event.waitUntil(event.respondWith(maPromesse));
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
self.addEventListener('install', handleInstall);
|
|
396
|
-
self.addEventListener('activate', handleActivate);
|
|
397
|
-
self.addEventListener('fetch', handleFetch);
|
|
398
|
-
|
|
399
|
-
const checkDomain = (domains, endpoint) => {
|
|
400
|
-
if (!endpoint) {
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const domain = domains.find((domain) => {
|
|
405
|
-
let testable = domain;
|
|
406
|
-
|
|
407
|
-
if (typeof domain === 'string') {
|
|
408
|
-
testable = new RegExp(`^${domain}`);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
return testable.test?.(endpoint);
|
|
412
|
-
});
|
|
413
|
-
if (!domain) {
|
|
414
|
-
throw new Error('Domain ' + endpoint + ' is not trusted, please add domain in ' + scriptFilename);
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
|
|
418
|
-
addEventListener('message', event => {
|
|
419
|
-
const port = event.ports[0];
|
|
420
|
-
const data = event.data;
|
|
421
|
-
const configurationName = data.configurationName;
|
|
422
|
-
let currentDatabase = database[configurationName];
|
|
423
|
-
|
|
424
|
-
if (!currentDatabase) {
|
|
425
|
-
database[configurationName] = {
|
|
426
|
-
tokens: null,
|
|
427
|
-
state: null,
|
|
428
|
-
codeVerifier: null,
|
|
429
|
-
oidcServerConfiguration: null,
|
|
430
|
-
oidcConfiguration: null,
|
|
431
|
-
status: null,
|
|
432
|
-
configurationName,
|
|
433
|
-
};
|
|
434
|
-
currentDatabase = database[configurationName];
|
|
435
|
-
if (!trustedDomains[configurationName]) {
|
|
436
|
-
trustedDomains[configurationName] = [];
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
switch (data.type) {
|
|
441
|
-
case 'clear':
|
|
442
|
-
currentDatabase.tokens = null;
|
|
443
|
-
currentDatabase.state = null;
|
|
444
|
-
currentDatabase.codeVerifier = null;
|
|
445
|
-
currentDatabase.status = data.data.status;
|
|
446
|
-
port.postMessage({ configurationName });
|
|
447
|
-
return;
|
|
448
|
-
case 'init':
|
|
449
|
-
{
|
|
450
|
-
const oidcServerConfiguration = data.data.oidcServerConfiguration;
|
|
451
|
-
const domains = trustedDomains[configurationName];
|
|
452
|
-
if (!domains.find(f => f === acceptAnyDomainToken)) {
|
|
453
|
-
checkDomain(domains, oidcServerConfiguration.tokenEndpoint);
|
|
454
|
-
checkDomain(domains, oidcServerConfiguration.revocationEndpoint);
|
|
455
|
-
checkDomain(domains, oidcServerConfiguration.userInfoEndpoint);
|
|
456
|
-
checkDomain(domains, oidcServerConfiguration.issuer);
|
|
457
|
-
}
|
|
458
|
-
currentDatabase.oidcServerConfiguration = oidcServerConfiguration;
|
|
459
|
-
currentDatabase.oidcConfiguration = data.data.oidcConfiguration;
|
|
460
|
-
const where = data.data.where;
|
|
461
|
-
if (where === 'loginCallbackAsync' || where === 'tryKeepExistingSessionAsync') {
|
|
462
|
-
currentLoginCallbackConfigurationName = configurationName;
|
|
463
|
-
} else {
|
|
464
|
-
currentLoginCallbackConfigurationName = null;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
if (!currentDatabase.tokens) {
|
|
468
|
-
port.postMessage({
|
|
469
|
-
tokens: null,
|
|
470
|
-
status: currentDatabase.status,
|
|
471
|
-
configurationName,
|
|
472
|
-
});
|
|
473
|
-
} else {
|
|
474
|
-
const tokens = {
|
|
475
|
-
...currentDatabase.tokens,
|
|
476
|
-
access_token: ACCESS_TOKEN + '_' + configurationName,
|
|
477
|
-
};
|
|
478
|
-
if (tokens.refresh_token) {
|
|
479
|
-
tokens.refresh_token = REFRESH_TOKEN + '_' + configurationName;
|
|
480
|
-
}
|
|
481
|
-
if (tokens.idTokenPayload && tokens.idTokenPayload.nonce && currentDatabase.nonce != null) {
|
|
482
|
-
tokens.idTokenPayload.nonce = NONCE_TOKEN + '_' + configurationName;
|
|
483
|
-
}
|
|
484
|
-
port.postMessage({
|
|
485
|
-
tokens,
|
|
486
|
-
status: currentDatabase.status,
|
|
487
|
-
configurationName,
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
|
-
case 'setState':
|
|
493
|
-
currentDatabase.state = data.data.state;
|
|
494
|
-
port.postMessage({ configurationName });
|
|
495
|
-
return;
|
|
496
|
-
case 'getState':
|
|
497
|
-
{
|
|
498
|
-
const state = currentDatabase.state;
|
|
499
|
-
port.postMessage({ configurationName, state });
|
|
500
|
-
return;
|
|
501
|
-
}
|
|
502
|
-
case 'setCodeVerifier':
|
|
503
|
-
currentDatabase.codeVerifier = data.data.codeVerifier;
|
|
504
|
-
port.postMessage({ configurationName });
|
|
505
|
-
return;
|
|
506
|
-
case 'getCodeVerifier':
|
|
507
|
-
{
|
|
508
|
-
port.postMessage({ configurationName, codeVerifier: CODE_VERIFIER + '_' + configurationName });
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
case 'setSessionState':
|
|
512
|
-
currentDatabase.sessionState = data.data.sessionState;
|
|
513
|
-
port.postMessage({ configurationName });
|
|
514
|
-
return;
|
|
515
|
-
case 'getSessionState':
|
|
516
|
-
{
|
|
517
|
-
const sessionState = currentDatabase.sessionState;
|
|
518
|
-
port.postMessage({ configurationName, sessionState });
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
case 'setNonce':
|
|
522
|
-
currentDatabase.nonce = data.data.nonce;
|
|
523
|
-
port.postMessage({ configurationName });
|
|
524
|
-
return;
|
|
525
|
-
default:
|
|
526
|
-
currentDatabase.items = { ...data.data };
|
|
527
|
-
port.postMessage({ configurationName });
|
|
528
|
-
}
|
|
529
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// Add bellow trusted domains, access tokens will automatically injected to be send to
|
|
2
|
-
// trusted domain can also be a path like https://www.myapi.com/users,
|
|
3
|
-
// then all subroute like https://www.myapi.com/useers/1 will be authorized to send access_token to.
|
|
4
|
-
|
|
5
|
-
// Domains used by OIDC server must be also declared here
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
|
-
const trustedDomains = {
|
|
8
|
-
default: ['https://demo.duendesoftware.com', 'https://kdhttps.auth0.com'],
|
|
9
|
-
config_classic: ['https://demo.duendesoftware.com'],
|
|
10
|
-
config_without_silent_login: ['https://demo.duendesoftware.com'],
|
|
11
|
-
config_without_refresh_token: ['https://demo.duendesoftware.com'],
|
|
12
|
-
config_without_refresh_token_silent_login: ['https://demo.duendesoftware.com'],
|
|
13
|
-
config_google: ['https://oauth2.googleapis.com', 'https://openidconnect.googleapis.com'],
|
|
14
|
-
config_with_hash: ['https://demo.duendesoftware.com'],
|
|
15
|
-
};
|