@axa-fr/react-oidc 6.0.0-alpha9 → 6.0.0-beta10
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/README.md +20 -11
- package/dist/OidcProvider.d.ts +2 -3
- package/dist/OidcProvider.d.ts.map +1 -1
- package/dist/OidcProvider.js +5 -4
- package/dist/OidcProvider.js.map +1 -1
- package/dist/OidcServiceWorker.js +21 -4
- package/dist/OidcTrustedDomains.js +7 -2
- package/dist/core/default-component/SilentCallback.component.d.ts.map +1 -1
- package/dist/core/default-component/SilentCallback.component.js +5 -19
- package/dist/core/default-component/SilentCallback.component.js.map +1 -1
- package/dist/core/default-component/SilentLogin.component.d.ts +4 -0
- package/dist/core/default-component/SilentLogin.component.d.ts.map +1 -0
- package/dist/core/default-component/{SilentSignin.component.js → SilentLogin.component.js} +3 -3
- package/dist/core/default-component/SilentLogin.component.js.map +1 -0
- package/dist/core/routes/OidcRoutes.d.ts +1 -1
- package/dist/core/routes/OidcRoutes.d.ts.map +1 -1
- package/dist/core/routes/OidcRoutes.js +5 -8
- package/dist/core/routes/OidcRoutes.js.map +1 -1
- package/dist/vanilla/checkSessionIFrame.d.ts +6 -6
- package/dist/vanilla/checkSessionIFrame.d.ts.map +1 -1
- package/dist/vanilla/checkSessionIFrame.js +1 -1
- package/dist/vanilla/checkSessionIFrame.js.map +1 -1
- package/dist/vanilla/oidc.d.ts +12 -12
- package/dist/vanilla/oidc.d.ts.map +1 -1
- package/dist/vanilla/oidc.js +342 -236
- package/dist/vanilla/oidc.js.map +1 -1
- package/package.json +2 -2
- package/src/oidc/OidcProvider.tsx +9 -10
- package/src/oidc/core/default-component/SilentCallback.component.tsx +1 -6
- package/src/oidc/core/default-component/{SilentSignin.component.tsx → SilentLogin.component.tsx} +2 -2
- package/src/oidc/core/routes/OidcRoutes.tsx +6 -10
- package/src/oidc/vanilla/OidcServiceWorker.js +21 -4
- package/src/oidc/vanilla/OidcTrustedDomains.js +7 -2
- package/src/oidc/vanilla/checkSessionIFrame.ts +7 -7
- package/src/oidc/vanilla/oidc.ts +238 -195
- package/dist/core/default-component/ServiceWorkerInstall.component.d.ts +0 -4
- package/dist/core/default-component/ServiceWorkerInstall.component.d.ts.map +0 -1
- package/dist/core/default-component/ServiceWorkerInstall.component.js +0 -131
- package/dist/core/default-component/ServiceWorkerInstall.component.js.map +0 -1
- package/dist/core/default-component/SilentSignin.component.d.ts +0 -4
- package/dist/core/default-component/SilentSignin.component.d.ts.map +0 -1
- package/dist/core/default-component/SilentSignin.component.js.map +0 -1
- package/src/App.css +0 -38
- package/src/App.specold.tsx +0 -46
- package/src/App.tsx +0 -96
- package/src/FetchUser.tsx +0 -53
- package/src/Home.tsx +0 -22
- package/src/MultiAuth.tsx +0 -116
- package/src/Profile.tsx +0 -77
- package/src/configurations.ts +0 -70
- package/src/index.css +0 -13
- package/src/index.tsx +0 -9
- package/src/logo.svg +0 -7
- package/src/oidc/core/default-component/ServiceWorkerInstall.component.tsx +0 -60
- package/src/override/AuthenticateError.component.tsx +0 -14
- package/src/override/Authenticating.component.tsx +0 -14
- package/src/override/Callback.component.tsx +0 -13
- package/src/override/Loading.component.tsx +0 -13
- package/src/override/ServiceWorkerNotSupported.component.tsx +0 -15
- package/src/override/SessionLost.component.tsx +0 -21
- package/src/override/style.ts +0 -10
- package/src/setupTests.js +0 -5
package/src/oidc/vanilla/oidc.ts
CHANGED
|
@@ -20,18 +20,62 @@ import {CheckSessionIFrame} from "./checkSessionIFrame"
|
|
|
20
20
|
import {getParseQueryStringFromLocation} from "./route-utils";
|
|
21
21
|
import {AuthorizationServiceConfigurationJson} from "@openid/appauth/src/authorization_service_configuration";
|
|
22
22
|
|
|
23
|
+
const performTokenRequestAsync= async (url, details, extras) => {
|
|
24
|
+
|
|
25
|
+
for (let [key, value] of Object.entries(extras)) {
|
|
26
|
+
if (details[key] === undefined) {
|
|
27
|
+
details[key] = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let formBody = [];
|
|
32
|
+
for (const property in details) {
|
|
33
|
+
const encodedKey = encodeURIComponent(property);
|
|
34
|
+
const encodedValue = encodeURIComponent(details[property]);
|
|
35
|
+
formBody.push(`${encodedKey}=${encodedValue}`);
|
|
36
|
+
}
|
|
37
|
+
const formBodyString = formBody.join("&");
|
|
38
|
+
|
|
39
|
+
const response = await internalFetch(url, {
|
|
40
|
+
method: 'POST',
|
|
41
|
+
headers: {
|
|
42
|
+
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
43
|
+
},
|
|
44
|
+
body: formBodyString,
|
|
45
|
+
});
|
|
46
|
+
if(response.status !== 200){
|
|
47
|
+
return {success:false, status: response.status}
|
|
48
|
+
}
|
|
49
|
+
const tokens = await response.json();
|
|
50
|
+
|
|
51
|
+
if(!tokens.issued_at) {
|
|
52
|
+
const currentTimeUnixSecond = new Date().getTime() /1000;
|
|
53
|
+
tokens.issued_at = currentTimeUnixSecond;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return { success : true,
|
|
57
|
+
data : {
|
|
58
|
+
accessToken: tokens.access_token,
|
|
59
|
+
expiresIn: tokens.expires_in,
|
|
60
|
+
idToken: tokens.id_token,
|
|
61
|
+
refreshToken: tokens.refresh_token,
|
|
62
|
+
scope: tokens.scope,
|
|
63
|
+
tokenType: tokens.token_type,
|
|
64
|
+
issuedAt: tokens.issued_at
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
23
68
|
|
|
24
69
|
const internalFetch = async (url, headers, numberRetry=0) => {
|
|
25
70
|
let response;
|
|
26
71
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
() => reject(new Error('Timeout')), 10000))]);
|
|
72
|
+
let controller = new AbortController();
|
|
73
|
+
setTimeout(() => controller.abort(), 10000);
|
|
74
|
+
response = await fetch(url, {...headers, signal: controller.signal});
|
|
31
75
|
} catch (e) {
|
|
32
|
-
if (e.message === '
|
|
33
|
-
|| e.message === 'Network request failed'
|
|
34
|
-
if(numberRetry <=
|
|
76
|
+
if (e.message === 'AbortError'
|
|
77
|
+
|| e.message === 'Network request failed') {
|
|
78
|
+
if(numberRetry <=1) {
|
|
35
79
|
return await internalFetch(url, headers, numberRetry + 1);
|
|
36
80
|
}
|
|
37
81
|
else {
|
|
@@ -117,8 +161,8 @@ export interface AuthorityConfiguration {
|
|
|
117
161
|
client_id: string,
|
|
118
162
|
redirect_uri: string,
|
|
119
163
|
silent_redirect_uri?:string,
|
|
120
|
-
|
|
121
|
-
|
|
164
|
+
silent_login_uri?:string,
|
|
165
|
+
silent_login_timeout?:number,
|
|
122
166
|
scope: string,
|
|
123
167
|
authority: string,
|
|
124
168
|
authority_time_cache_wellknowurl_in_second?: number,
|
|
@@ -172,9 +216,9 @@ const autoRenewTokens = (oidc, refreshToken, expiresAt) => {
|
|
|
172
216
|
oidc.timeoutId = autoRenewTokens(oidc, tokens.refreshToken, oidc.tokens.expiresAt);
|
|
173
217
|
}
|
|
174
218
|
} else{
|
|
175
|
-
await oidc.syncTokensAsync();
|
|
176
|
-
if(oidc.timeoutId) {
|
|
177
|
-
oidc.timeoutId = autoRenewTokens(oidc, refreshToken, expiresAt);
|
|
219
|
+
const tokens = await oidc.syncTokensAsync();
|
|
220
|
+
if(tokens && oidc.timeoutId) {
|
|
221
|
+
oidc.timeoutId = autoRenewTokens(oidc, tokens.refreshToken, tokens.expiresAt);
|
|
178
222
|
}
|
|
179
223
|
}
|
|
180
224
|
}, 1000);
|
|
@@ -187,7 +231,6 @@ const getLoginParams = (configurationName, redirectUri) => {
|
|
|
187
231
|
return JSON.parse(sessionStorage[getLoginSessionKey(configurationName, redirectUri)]);
|
|
188
232
|
}
|
|
189
233
|
|
|
190
|
-
|
|
191
234
|
const userInfoAsync = async (oidc) => {
|
|
192
235
|
if(oidc.userInfo != null){
|
|
193
236
|
return oidc.userInfo;
|
|
@@ -206,7 +249,7 @@ const userInfoAsync = async (oidc) => {
|
|
|
206
249
|
const res = await fetch(url, {
|
|
207
250
|
headers: {
|
|
208
251
|
authorization: `Bearer ${accessToken}`,
|
|
209
|
-
credentials: '
|
|
252
|
+
credentials: 'include'
|
|
210
253
|
}
|
|
211
254
|
});
|
|
212
255
|
|
|
@@ -236,7 +279,10 @@ const setTokensAsync = async (serviceWorker, tokens) =>{
|
|
|
236
279
|
accessTokenPayload = extractAccessTokenPayload(tokens);
|
|
237
280
|
}
|
|
238
281
|
const _idTokenPayload = idTokenPayload(tokens.idToken);
|
|
239
|
-
|
|
282
|
+
|
|
283
|
+
const idTokenExipreAt =(_idTokenPayload && _idTokenPayload.exp) ? _idTokenPayload.exp: Number.MAX_VALUE;
|
|
284
|
+
const accessTokenExpiresAt = (accessTokenPayload && accessTokenPayload.exp)? accessTokenPayload.exp : tokens.issuedAt + tokens.expiresIn;
|
|
285
|
+
const expiresAt = idTokenExipreAt < accessTokenExpiresAt ? idTokenExipreAt : accessTokenExpiresAt;
|
|
240
286
|
return {...tokens, idTokenPayload: _idTokenPayload, accessTokenPayload, expiresAt};
|
|
241
287
|
}
|
|
242
288
|
|
|
@@ -259,48 +305,50 @@ const eventNames = {
|
|
|
259
305
|
tryKeepExistingSessionAsync_begin: "tryKeepExistingSessionAsync_begin",
|
|
260
306
|
tryKeepExistingSessionAsync_end: "tryKeepExistingSessionAsync_end",
|
|
261
307
|
tryKeepExistingSessionAsync_error: "tryKeepExistingSessionAsync_error",
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
308
|
+
silentLoginAsync_begin: "silentLoginAsync_begin",
|
|
309
|
+
silentLoginAsync: "silentLoginAsync",
|
|
310
|
+
silentLoginAsync_end: "silentLoginAsync_end",
|
|
311
|
+
silentLoginAsync_error: "silentLoginAsync_error",
|
|
266
312
|
syncTokensAsync_begin: "syncTokensAsync_begin",
|
|
267
313
|
syncTokensAsync_end: "syncTokensAsync_end",
|
|
268
314
|
syncTokensAsync_error: "syncTokensAsync_error"
|
|
269
|
-
|
|
270
315
|
}
|
|
271
316
|
|
|
272
317
|
const getRandomInt = (max) => {
|
|
273
318
|
return Math.floor(Math.random() * max);
|
|
274
319
|
}
|
|
275
320
|
|
|
276
|
-
const WELL_KNOWN_PATH = '.well-known';
|
|
277
|
-
const OPENID_CONFIGURATION = 'openid-configuration';
|
|
278
|
-
|
|
279
|
-
|
|
280
321
|
const oneHourSecond = 60 * 60;
|
|
281
|
-
|
|
322
|
+
let fetchFromIssuerCache = null;
|
|
323
|
+
const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond, storage= window.sessionStorage):
|
|
282
324
|
Promise<OidcAuthorizationServiceConfiguration> => {
|
|
283
|
-
const fullUrl = `${openIdIssuerUrl}
|
|
325
|
+
const fullUrl = `${openIdIssuerUrl}/.well-known/openid-configuration`;
|
|
284
326
|
|
|
285
327
|
const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
|
|
286
|
-
|
|
287
|
-
|
|
328
|
+
if(!fetchFromIssuerCache && storage) {
|
|
329
|
+
const cacheJson = storage.getItem(localStorageKey);
|
|
330
|
+
if(cacheJson){
|
|
331
|
+
fetchFromIssuerCache = JSON.parse(cacheJson);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
288
334
|
const oneHourMinisecond = 1000 * timeCacheSecond;
|
|
289
335
|
// @ts-ignore
|
|
290
|
-
if(
|
|
291
|
-
return new OidcAuthorizationServiceConfiguration(
|
|
336
|
+
if(fetchFromIssuerCache && (fetchFromIssuerCache.timestamp + oneHourMinisecond) > Date.now()){
|
|
337
|
+
return new OidcAuthorizationServiceConfiguration(fetchFromIssuerCache.result);
|
|
292
338
|
}
|
|
293
|
-
|
|
294
339
|
const response = await fetch(fullUrl);
|
|
295
340
|
|
|
296
341
|
if (response.status != 200) {
|
|
297
342
|
return null;
|
|
298
343
|
}
|
|
299
344
|
|
|
300
|
-
|
|
301
345
|
const result = await response.json();
|
|
302
|
-
window.localStorage.setItem(localStorageKey, JSON.stringify({result, timestamp:Date.now()}));
|
|
303
346
|
|
|
347
|
+
const timestamp = Date.now();
|
|
348
|
+
fetchFromIssuerCache = {result, timestamp};
|
|
349
|
+
if(storage) {
|
|
350
|
+
storage.setItem(localStorageKey, JSON.stringify({result, timestamp}));
|
|
351
|
+
}
|
|
304
352
|
return new OidcAuthorizationServiceConfiguration(result);
|
|
305
353
|
}
|
|
306
354
|
|
|
@@ -329,7 +377,12 @@ export class Oidc {
|
|
|
329
377
|
private session?: any;
|
|
330
378
|
private checkSessionIFrame: CheckSessionIFrame;
|
|
331
379
|
constructor(configuration:OidcConfiguration, configurationName="default") {
|
|
332
|
-
|
|
380
|
+
let silent_login_uri = configuration.silent_login_uri;
|
|
381
|
+
if(configuration.silent_redirect_uri && !configuration.silent_login_uri){
|
|
382
|
+
silent_login_uri = `${configuration.silent_redirect_uri.replace("-callback", "").replace("callback", "")}-login`;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
this.configuration = {...configuration, silent_login_uri};
|
|
333
386
|
this.configurationName= configurationName;
|
|
334
387
|
this.tokens = null
|
|
335
388
|
this.userInfo = null;
|
|
@@ -346,6 +399,9 @@ export class Oidc {
|
|
|
346
399
|
this.removeEventSubscription.bind(this);
|
|
347
400
|
this.publishEvent.bind(this);
|
|
348
401
|
this.destroyAsync.bind(this);
|
|
402
|
+
this.logoutAsync.bind(this);
|
|
403
|
+
|
|
404
|
+
this.initAsync(this.configuration.authority, this.configuration.authority_configuration);
|
|
349
405
|
}
|
|
350
406
|
|
|
351
407
|
subscriveEvents(func){
|
|
@@ -377,29 +433,47 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
377
433
|
}
|
|
378
434
|
static eventNames = eventNames;
|
|
379
435
|
|
|
380
|
-
|
|
381
|
-
if (this.configuration.silent_redirect_uri) {
|
|
436
|
+
_silentLoginCallbackFromIFrame(){
|
|
437
|
+
if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
|
|
382
438
|
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
383
439
|
window.top.postMessage(`${this.configurationName}_oidc_tokens:${JSON.stringify({tokens:this.tokens, sessionState:queryParams.session_state})}`, window.location.origin);
|
|
384
440
|
}
|
|
385
441
|
}
|
|
386
|
-
|
|
387
|
-
if (this.configuration.silent_redirect_uri) {
|
|
442
|
+
_silentLoginErrorCallbackFromIFrame() {
|
|
443
|
+
if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
|
|
388
444
|
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
389
|
-
window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error:queryParams.error})}`, window.location.origin);
|
|
445
|
+
window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error: queryParams.error})}`, window.location.origin);
|
|
390
446
|
}
|
|
391
447
|
}
|
|
392
|
-
|
|
393
|
-
|
|
448
|
+
|
|
449
|
+
async silentLoginCallBackAsync() {
|
|
450
|
+
try {
|
|
451
|
+
await this.loginCallbackAsync(true);
|
|
452
|
+
this._silentLoginCallbackFromIFrame();
|
|
453
|
+
} catch (error) {
|
|
454
|
+
console.error(error)
|
|
455
|
+
this._silentLoginErrorCallbackFromIFrame();
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
async silentLoginAsync(extras:StringMap=null, state:string=null, scope:string=null) {
|
|
460
|
+
if (!this.configuration.silent_redirect_uri || !this.configuration.silent_login_uri) {
|
|
394
461
|
return Promise.resolve(null);
|
|
395
462
|
}
|
|
396
463
|
while (document.hidden) {
|
|
397
464
|
await sleepAsync(1000);
|
|
398
|
-
this.publishEvent(eventNames.
|
|
465
|
+
this.publishEvent(eventNames.silentLoginAsync, {message:"wait because document is hidden"});
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
let numberTryOnline = 6;
|
|
469
|
+
while (!navigator.onLine && numberTryOnline > 0) {
|
|
470
|
+
await sleepAsync(1000);
|
|
471
|
+
numberTryOnline--;
|
|
472
|
+
this.publishEvent(eventNames.refreshTokensAsync, {message: `wait because navigator is offline try ${numberTryOnline}` });
|
|
399
473
|
}
|
|
400
474
|
|
|
401
475
|
try {
|
|
402
|
-
this.publishEvent(eventNames.
|
|
476
|
+
this.publishEvent(eventNames.silentLoginAsync_begin, {});
|
|
403
477
|
const configuration = this.configuration
|
|
404
478
|
let queries = "";
|
|
405
479
|
|
|
@@ -426,7 +500,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
426
500
|
}
|
|
427
501
|
}
|
|
428
502
|
}
|
|
429
|
-
const link = configuration.
|
|
503
|
+
const link = configuration.silent_login_uri + queries;
|
|
430
504
|
const idx = link.indexOf("/", link.indexOf("//") + 2);
|
|
431
505
|
const iFrameOrigin = link.substr(0, idx);
|
|
432
506
|
const iframe = document.createElement('iframe');
|
|
@@ -451,43 +525,42 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
451
525
|
if (!isResolved) {
|
|
452
526
|
if(data.startsWith(key)) {
|
|
453
527
|
const result = JSON.parse(e.data.replace(key, ''));
|
|
454
|
-
self.publishEvent(eventNames.
|
|
528
|
+
self.publishEvent(eventNames.silentLoginAsync_end, {});
|
|
455
529
|
iframe.remove();
|
|
456
530
|
isResolved = true;
|
|
457
531
|
resolve(result);
|
|
458
532
|
}
|
|
459
533
|
else if(data.startsWith(key_error)) {
|
|
460
534
|
const result = JSON.parse(e.data.replace(key_error, ''));
|
|
461
|
-
self.publishEvent(eventNames.
|
|
535
|
+
self.publishEvent(eventNames.silentLoginAsync_error, result);
|
|
462
536
|
iframe.remove();
|
|
463
537
|
isResolved = true;
|
|
464
|
-
reject(result);
|
|
538
|
+
reject(new Error("oidc_"+result.error));
|
|
465
539
|
}
|
|
466
540
|
}
|
|
467
541
|
}
|
|
468
542
|
}
|
|
469
543
|
};
|
|
470
|
-
const silentSigninTimeout = configuration.
|
|
544
|
+
const silentSigninTimeout = configuration.silent_login_timeout ?? 12000
|
|
471
545
|
setTimeout(() => {
|
|
472
546
|
if (!isResolved) {
|
|
473
|
-
self.publishEvent(eventNames.
|
|
547
|
+
self.publishEvent(eventNames.silentLoginAsync_error, {reason: "timeout"});
|
|
474
548
|
iframe.remove();
|
|
475
549
|
isResolved = true;
|
|
476
|
-
reject("timeout");
|
|
550
|
+
reject(new Error("timeout"));
|
|
477
551
|
}
|
|
478
552
|
}, silentSigninTimeout);
|
|
479
553
|
} catch (e) {
|
|
480
554
|
iframe.remove();
|
|
481
|
-
self.publishEvent(eventNames.
|
|
555
|
+
self.publishEvent(eventNames.silentLoginAsync_error, e);
|
|
482
556
|
reject(e);
|
|
483
557
|
}
|
|
484
558
|
});
|
|
485
559
|
} catch (e) {
|
|
486
|
-
this.publishEvent(eventNames.
|
|
560
|
+
this.publishEvent(eventNames.silentLoginAsync_error, e);
|
|
487
561
|
throw e;
|
|
488
562
|
}
|
|
489
563
|
}
|
|
490
|
-
initAsyncPromise = null;
|
|
491
564
|
async initAsync(authority:string, authorityConfiguration:AuthorityConfiguration) {
|
|
492
565
|
if (authorityConfiguration != null) {
|
|
493
566
|
return new OidcAuthorizationServiceConfiguration( {
|
|
@@ -499,12 +572,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
499
572
|
check_session_iframe:authorityConfiguration.check_session_iframe,
|
|
500
573
|
});
|
|
501
574
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
return this.initAsyncPromise;
|
|
575
|
+
|
|
576
|
+
const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName);
|
|
577
|
+
const storage = serviceWorker ? window.localStorage : null;
|
|
578
|
+
const initAsyncPromise = await fetchFromIssuer(authority, this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60, storage);
|
|
579
|
+
return initAsyncPromise;
|
|
508
580
|
}
|
|
509
581
|
|
|
510
582
|
tryKeepExistingSessionPromise = null;
|
|
@@ -534,13 +606,15 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
534
606
|
expiresIn: tokens.expires_in,
|
|
535
607
|
idToken: tokens.id_token,
|
|
536
608
|
scope: tokens.scope,
|
|
537
|
-
tokenType: tokens.token_type
|
|
609
|
+
tokenType: tokens.token_type,
|
|
610
|
+
issuedAt: tokens.issued_at
|
|
538
611
|
}
|
|
539
612
|
this.tokens = await setTokensAsync(serviceWorker, reformattedToken);
|
|
540
613
|
this.serviceWorker = serviceWorker;
|
|
541
614
|
// @ts-ignore
|
|
542
615
|
this.timeoutId = autoRenewTokens(this, this.tokens.refreshToken, this.tokens.expiresAt);
|
|
543
616
|
const sessionState = await serviceWorker.getSessionStateAsync();
|
|
617
|
+
// @ts-ignore
|
|
544
618
|
await this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, configuration.client_id, sessionState);
|
|
545
619
|
this.publishEvent(eventNames.tryKeepExistingSessionAsync_end, {
|
|
546
620
|
success: true,
|
|
@@ -568,6 +642,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
568
642
|
// @ts-ignore
|
|
569
643
|
this.timeoutId = autoRenewTokens(this, tokens.refreshToken, this.tokens.expiresAt);
|
|
570
644
|
const sessionState = session.getSessionState();
|
|
645
|
+
// @ts-ignore
|
|
571
646
|
await this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, configuration.client_id, sessionState);
|
|
572
647
|
this.publishEvent(eventNames.tryKeepExistingSessionAsync_end, {
|
|
573
648
|
success: true,
|
|
@@ -621,23 +696,6 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
621
696
|
|
|
622
697
|
let serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
|
|
623
698
|
const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
|
|
624
|
-
/*if (serviceWorker && installServiceWorker) {
|
|
625
|
-
const isServiceWorkerProxyActive = await serviceWorker.isServiceWorkerProxyActiveAsync();
|
|
626
|
-
if (!isServiceWorkerProxyActive) {
|
|
627
|
-
const isUnregistered = await serviceWorker.unregisterAsync();
|
|
628
|
-
console.log("isUnregistered")
|
|
629
|
-
console.log(isUnregistered)
|
|
630
|
-
if(isUnregistered){
|
|
631
|
-
serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
|
|
632
|
-
}
|
|
633
|
-
const extrasQueries = extras != null ? {...extras}: {};
|
|
634
|
-
extrasQueries.callbackPath = url;
|
|
635
|
-
extrasQueries.state = state;
|
|
636
|
-
const queryString = buildQueries(extrasQueries);
|
|
637
|
-
window.location.href = `${redirectUri}/service-worker-install${queryString}`;
|
|
638
|
-
//return;
|
|
639
|
-
}
|
|
640
|
-
}*/
|
|
641
699
|
let storage;
|
|
642
700
|
if (serviceWorker) {
|
|
643
701
|
serviceWorker.startKeepAliveServiceWorker();
|
|
@@ -673,12 +731,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
673
731
|
this.loginPromise = null;
|
|
674
732
|
return result;
|
|
675
733
|
});
|
|
676
|
-
|
|
677
734
|
}
|
|
678
735
|
|
|
679
736
|
async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin=false){
|
|
680
737
|
return new Promise((resolve:Function, reject) => {
|
|
681
|
-
if (this.configuration.
|
|
738
|
+
if (this.configuration.silent_login_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
|
|
682
739
|
const checkSessionCallback = () => {
|
|
683
740
|
this.checkSessionIFrame.stop();
|
|
684
741
|
|
|
@@ -689,7 +746,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
689
746
|
const idToken = this.tokens.idToken;
|
|
690
747
|
// @ts-ignore
|
|
691
748
|
const idTokenPayload = this.tokens.idTokenPayload;
|
|
692
|
-
this.
|
|
749
|
+
this.silentLoginAsync({
|
|
693
750
|
prompt: "none",
|
|
694
751
|
id_token_hint: idToken,
|
|
695
752
|
scope: "openid"
|
|
@@ -841,6 +898,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
841
898
|
clearTimeout(timeoutId);
|
|
842
899
|
this.timeoutId=null;
|
|
843
900
|
const loginParams = getLoginParams(this.configurationName, redirectUri);
|
|
901
|
+
// @ts-ignore
|
|
844
902
|
this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, clientId, sessionState, isSilentSignin).then(() =>{
|
|
845
903
|
this.publishEvent(eventNames.loginCallbackAsync_end, {});
|
|
846
904
|
resolve({
|
|
@@ -871,15 +929,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
871
929
|
}
|
|
872
930
|
|
|
873
931
|
async refreshTokensAsync(refreshToken) {
|
|
874
|
-
|
|
875
|
-
/*while (document.hidden) {
|
|
876
|
-
await sleepAsync(1000);
|
|
877
|
-
this.publishEvent(eventNames.refreshTokensAsync, {message:"wait because document is hidden"});
|
|
878
|
-
}*/
|
|
879
932
|
|
|
880
|
-
const
|
|
933
|
+
const localsilentLoginAsync= async () => {
|
|
881
934
|
try {
|
|
882
|
-
const
|
|
935
|
+
const loginParams = getLoginParams(this.configurationName, configuration.redirect_uri);
|
|
936
|
+
const silent_token_response = await this.silentLoginAsync(loginParams.extras, loginParams.state);
|
|
883
937
|
if (silent_token_response) {
|
|
884
938
|
return silent_token_response.tokens;
|
|
885
939
|
}
|
|
@@ -890,13 +944,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
890
944
|
timer.clearTimeout(this.timeoutId);
|
|
891
945
|
this.timeoutId=null;
|
|
892
946
|
}
|
|
893
|
-
this.publishEvent(eventNames.refreshTokensAsync_error,
|
|
947
|
+
this.publishEvent(eventNames.refreshTokensAsync_error, {message: "refresh token and silent refresh failed"});
|
|
894
948
|
return null;
|
|
895
949
|
}
|
|
896
|
-
|
|
897
|
-
try{
|
|
898
|
-
this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken});
|
|
899
|
-
|
|
950
|
+
|
|
900
951
|
const configuration = this.configuration;
|
|
901
952
|
const clientId = configuration.client_id;
|
|
902
953
|
const redirectUri = configuration.redirect_uri;
|
|
@@ -904,10 +955,9 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
904
955
|
|
|
905
956
|
if(!refreshToken)
|
|
906
957
|
{
|
|
907
|
-
return await
|
|
958
|
+
return await localsilentLoginAsync();
|
|
908
959
|
}
|
|
909
960
|
|
|
910
|
-
|
|
911
961
|
let extras = {};
|
|
912
962
|
if(configuration.token_request_extras) {
|
|
913
963
|
for (let [key, value] of Object.entries(configuration.token_request_extras)) {
|
|
@@ -915,126 +965,119 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
915
965
|
}
|
|
916
966
|
}
|
|
917
967
|
const oidcServerConfiguration = await this.initAsync(authority, configuration.authority_configuration);
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
// use the token response to make a request for an access token
|
|
921
|
-
const request = new TokenRequest({
|
|
968
|
+
|
|
969
|
+
const details = {
|
|
922
970
|
client_id: clientId,
|
|
923
971
|
redirect_uri: redirectUri,
|
|
924
972
|
grant_type: GRANT_TYPE_REFRESH_TOKEN,
|
|
925
|
-
code: undefined,
|
|
926
973
|
refresh_token: refreshToken,
|
|
927
|
-
|
|
928
|
-
});
|
|
974
|
+
};
|
|
929
975
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
976
|
+
let index = 0;
|
|
977
|
+
while (index <=4) {
|
|
978
|
+
try {
|
|
979
|
+
this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken, tryNumber: index});
|
|
980
|
+
if(index > 1) {
|
|
981
|
+
while (document.hidden) {
|
|
982
|
+
await sleepAsync(1000);
|
|
983
|
+
this.publishEvent(eventNames.refreshTokensAsync, {message: "wait because document is hidden"});
|
|
984
|
+
}
|
|
985
|
+
let numberTryOnline = 6;
|
|
986
|
+
while (!navigator.onLine && numberTryOnline > 0) {
|
|
987
|
+
await sleepAsync(1000);
|
|
988
|
+
numberTryOnline--;
|
|
989
|
+
this.publishEvent(eventNames.refreshTokensAsync, {message: `wait because navigator is offline try ${numberTryOnline}` });
|
|
990
|
+
}
|
|
944
991
|
}
|
|
992
|
+
const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint, details, extras)
|
|
993
|
+
if (tokenResponse.success) {
|
|
994
|
+
this.publishEvent(eventNames.refreshTokensAsync_end, {success: tokenResponse.success});
|
|
995
|
+
return tokenResponse.data;
|
|
996
|
+
} else {
|
|
997
|
+
this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "bad request" , tokenResponse: tokenResponse});
|
|
998
|
+
return await localsilentLoginAsync();
|
|
999
|
+
}
|
|
1000
|
+
} catch (exception) {
|
|
1001
|
+
console.error(exception);
|
|
1002
|
+
this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "exception" ,exception: exception.message});
|
|
945
1003
|
}
|
|
946
|
-
|
|
947
|
-
let formBody = [];
|
|
948
|
-
for (const property in details) {
|
|
949
|
-
const encodedKey = encodeURIComponent(property);
|
|
950
|
-
const encodedValue = encodeURIComponent(details[property]);
|
|
951
|
-
formBody.push(`${encodedKey}=${encodedValue}`);
|
|
952
|
-
}
|
|
953
|
-
const formBodyString = formBody.join("&");
|
|
954
|
-
|
|
955
|
-
const response = await internalFetch(url, {
|
|
956
|
-
method: 'POST',
|
|
957
|
-
headers: {
|
|
958
|
-
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
959
|
-
},
|
|
960
|
-
body: formBodyString,
|
|
961
|
-
});
|
|
962
|
-
if(response.status >= 299){
|
|
963
|
-
throw new Error("Error refreshing token");
|
|
964
|
-
}
|
|
965
|
-
const result = await response.json();
|
|
966
|
-
return {
|
|
967
|
-
accessToken: result.access_token,
|
|
968
|
-
expiresIn: result.expires_in,
|
|
969
|
-
idToken: result.id_token,
|
|
970
|
-
refreshToken: result.refresh_token,
|
|
971
|
-
scope: result.scope,
|
|
972
|
-
tokenType: result.token_type,
|
|
973
|
-
};
|
|
1004
|
+
index++;
|
|
974
1005
|
}
|
|
975
|
-
|
|
976
|
-
const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint)
|
|
977
|
-
|
|
978
|
-
this.publishEvent(eventNames.refreshTokensAsync_end, {message:"success"});
|
|
979
|
-
return tokenResponse;
|
|
980
|
-
} catch(exception) {
|
|
981
|
-
console.error(exception);
|
|
982
|
-
this.publishEvent(eventNames.refreshTokensAsync_silent_error, exception);
|
|
983
|
-
return await localSilentSigninAsync(exception);
|
|
984
|
-
}
|
|
1006
|
+
|
|
985
1007
|
}
|
|
986
1008
|
|
|
987
1009
|
syncTokensAsyncPromise=null;
|
|
988
1010
|
async syncTokensAsync() {
|
|
989
|
-
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
|
|
996
|
-
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
|
|
997
|
-
if (serviceWorker) {
|
|
998
|
-
const { isLogin } = await serviceWorker.initAsync(oidcServerConfiguration, "syncTokensAsync");
|
|
999
|
-
if(isLogin == false){
|
|
1000
|
-
this.publishEvent(eventNames.logout_from_another_tab, {});
|
|
1001
|
-
await this.destroyAsync();
|
|
1011
|
+
|
|
1012
|
+
const localSyncTokensAsync = async () => {
|
|
1013
|
+
// Service Worker can be killed by the browser (when it wants,for example after 10 seconds of inactivity, so we retreieve the session if it happen)
|
|
1014
|
+
const configuration = this.configuration;
|
|
1015
|
+
if (!this.tokens) {
|
|
1016
|
+
return null;
|
|
1002
1017
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1018
|
+
|
|
1019
|
+
const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
|
|
1020
|
+
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
|
|
1021
|
+
if (serviceWorker) {
|
|
1022
|
+
const {isLogin} = await serviceWorker.initAsync(oidcServerConfiguration, "syncTokensAsync");
|
|
1023
|
+
if (isLogin == false) {
|
|
1024
|
+
this.publishEvent(eventNames.logout_from_another_tab, {});
|
|
1025
|
+
await this.destroyAsync();
|
|
1026
|
+
return null;
|
|
1027
|
+
} else if (isLogin == null) {
|
|
1028
|
+
try {
|
|
1029
|
+
this.publishEvent(eventNames.syncTokensAsync_begin, {});
|
|
1030
|
+
const loginParams = getLoginParams(this.configurationName, configuration.redirect_uri);
|
|
1031
|
+
const silent_token_response = await this.silentLoginAsync({...loginParams.extras,prompt: "none"}, loginParams.state);
|
|
1032
|
+
if (silent_token_response && silent_token_response.tokens) {
|
|
1033
|
+
this.tokens = await setTokensAsync(serviceWorker, silent_token_response.tokens);
|
|
1034
|
+
this.publishEvent(eventNames.syncTokensAsync_end, {});
|
|
1035
|
+
return this.tokens;
|
|
1036
|
+
} else {
|
|
1037
|
+
this.publishEvent(eventNames.syncTokensAsync_error, {message: "no token found in result"});
|
|
1038
|
+
if (this.timeoutId) {
|
|
1039
|
+
timer.clearTimeout(this.timeoutId);
|
|
1040
|
+
this.timeoutId = null;
|
|
1041
|
+
}
|
|
1042
|
+
this.publishEvent(eventNames.syncTokensAsync_end, {});
|
|
1043
|
+
return null;
|
|
1044
|
+
}
|
|
1045
|
+
} catch (exceptionSilent) {
|
|
1046
|
+
console.error(exceptionSilent);
|
|
1047
|
+
this.publishEvent(eventNames.syncTokensAsync_error, exceptionSilent);
|
|
1048
|
+
if (this.timeoutId) {
|
|
1013
1049
|
timer.clearTimeout(this.timeoutId);
|
|
1014
|
-
this.timeoutId=null;
|
|
1050
|
+
this.timeoutId = null;
|
|
1015
1051
|
}
|
|
1016
|
-
|
|
1052
|
+
this.publishEvent(eventNames.syncTokensAsync_end, {});
|
|
1053
|
+
return null;
|
|
1017
1054
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1055
|
+
|
|
1056
|
+
}
|
|
1057
|
+
} else {
|
|
1058
|
+
const session = initSession(this.configurationName, configuration.redirect_uri, configuration.storage ?? sessionStorage);
|
|
1059
|
+
const {tokens} = await session.initAsync();
|
|
1060
|
+
if (!tokens) {
|
|
1061
|
+
this.publishEvent(eventNames.logout_from_another_tab, {});
|
|
1062
|
+
await this.destroyAsync();
|
|
1063
|
+
return null;
|
|
1026
1064
|
}
|
|
1027
|
-
this.syncTokensAsyncPromise = null;
|
|
1028
|
-
this.publishEvent(eventNames.syncTokensAsync_end, {});
|
|
1029
|
-
}
|
|
1030
|
-
} else {
|
|
1031
|
-
const session = initSession(this.configurationName, configuration.redirect_uri, configuration.storage ?? sessionStorage);
|
|
1032
|
-
const {tokens} = await session.initAsync();
|
|
1033
|
-
if(!tokens){
|
|
1034
|
-
this.publishEvent(eventNames.logout_from_another_tab, {});
|
|
1035
|
-
await this.destroyAsync();
|
|
1036
1065
|
}
|
|
1066
|
+
return this.tokens;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
if(this.syncTokensAsyncPromise){
|
|
1070
|
+
return this.syncTokensAsyncPromise;
|
|
1037
1071
|
}
|
|
1072
|
+
|
|
1073
|
+
this.syncTokensAsyncPromise = localSyncTokensAsync().then(result =>{
|
|
1074
|
+
if(this.syncTokensAsyncPromise){
|
|
1075
|
+
this.syncTokensAsyncPromise = null;
|
|
1076
|
+
}
|
|
1077
|
+
return result;
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
return this.syncTokensAsyncPromise
|
|
1038
1081
|
}
|
|
1039
1082
|
|
|
1040
1083
|
|