@axa-fr/react-oidc 6.0.0-beta0 → 6.0.0-beta11

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.
Files changed (47) hide show
  1. package/README.md +21 -11
  2. package/dist/OidcProvider.d.ts +3 -3
  3. package/dist/OidcProvider.d.ts.map +1 -1
  4. package/dist/OidcProvider.js +15 -7
  5. package/dist/OidcProvider.js.map +1 -1
  6. package/dist/OidcServiceWorker.js +21 -4
  7. package/dist/OidcTrustedDomains.js +7 -2
  8. package/dist/ReactOidc.d.ts.map +1 -1
  9. package/dist/ReactOidc.js +3 -2
  10. package/dist/ReactOidc.js.map +1 -1
  11. package/dist/core/default-component/SilentCallback.component.d.ts.map +1 -1
  12. package/dist/core/default-component/SilentCallback.component.js +5 -19
  13. package/dist/core/default-component/SilentCallback.component.js.map +1 -1
  14. package/dist/core/default-component/SilentLogin.component.d.ts +4 -0
  15. package/dist/core/default-component/SilentLogin.component.d.ts.map +1 -0
  16. package/dist/core/default-component/{SilentSignin.component.js → SilentLogin.component.js} +3 -3
  17. package/dist/core/default-component/SilentLogin.component.js.map +1 -0
  18. package/dist/core/routes/OidcRoutes.d.ts +1 -1
  19. package/dist/core/routes/OidcRoutes.d.ts.map +1 -1
  20. package/dist/core/routes/OidcRoutes.js +5 -8
  21. package/dist/core/routes/OidcRoutes.js.map +1 -1
  22. package/dist/vanilla/checkSessionIFrame.d.ts +6 -6
  23. package/dist/vanilla/checkSessionIFrame.d.ts.map +1 -1
  24. package/dist/vanilla/checkSessionIFrame.js +1 -1
  25. package/dist/vanilla/checkSessionIFrame.js.map +1 -1
  26. package/dist/vanilla/oidc.d.ts +14 -12
  27. package/dist/vanilla/oidc.d.ts.map +1 -1
  28. package/dist/vanilla/oidc.js +289 -169
  29. package/dist/vanilla/oidc.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/oidc/OidcProvider.tsx +18 -10
  32. package/src/oidc/ReactOidc.tsx +3 -2
  33. package/src/oidc/core/default-component/SilentCallback.component.tsx +1 -6
  34. package/src/oidc/core/default-component/{SilentSignin.component.tsx → SilentLogin.component.tsx} +2 -2
  35. package/src/oidc/core/routes/OidcRoutes.tsx +6 -10
  36. package/src/oidc/vanilla/OidcServiceWorker.js +21 -4
  37. package/src/oidc/vanilla/OidcTrustedDomains.js +7 -2
  38. package/src/oidc/vanilla/checkSessionIFrame.ts +7 -7
  39. package/src/oidc/vanilla/oidc.ts +202 -139
  40. package/dist/core/default-component/ServiceWorkerInstall.component.d.ts +0 -4
  41. package/dist/core/default-component/ServiceWorkerInstall.component.d.ts.map +0 -1
  42. package/dist/core/default-component/ServiceWorkerInstall.component.js +0 -131
  43. package/dist/core/default-component/ServiceWorkerInstall.component.js.map +0 -1
  44. package/dist/core/default-component/SilentSignin.component.d.ts +0 -4
  45. package/dist/core/default-component/SilentSignin.component.d.ts.map +0 -1
  46. package/dist/core/default-component/SilentSignin.component.js.map +0 -1
  47. package/src/oidc/core/default-component/ServiceWorkerInstall.component.tsx +0 -60
@@ -21,8 +21,7 @@ import {getParseQueryStringFromLocation} from "./route-utils";
21
21
  import {AuthorizationServiceConfigurationJson} from "@openid/appauth/src/authorization_service_configuration";
22
22
 
23
23
  const performTokenRequestAsync= async (url, details, extras) => {
24
-
25
-
24
+
26
25
  for (let [key, value] of Object.entries(extras)) {
27
26
  if (details[key] === undefined) {
28
27
  details[key] = value;
@@ -47,15 +46,22 @@ const performTokenRequestAsync= async (url, details, extras) => {
47
46
  if(response.status !== 200){
48
47
  return {success:false, status: response.status}
49
48
  }
50
- const result = await response.json();
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
+
51
56
  return { success : true,
52
57
  data : {
53
- accessToken: result.access_token,
54
- expiresIn: result.expires_in,
55
- idToken: result.id_token,
56
- refreshToken: result.refresh_token,
57
- scope: result.scope,
58
- tokenType: result.token_type,
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
59
65
  }
60
66
  };
61
67
  }
@@ -63,14 +69,13 @@ const performTokenRequestAsync= async (url, details, extras) => {
63
69
  const internalFetch = async (url, headers, numberRetry=0) => {
64
70
  let response;
65
71
  try {
66
- response = await Promise.race([
67
- fetch(url, headers),
68
- new Promise((_, reject) => setTimeout(
69
- () => reject(new Error('Timeout')), 10000))]);
72
+ let controller = new AbortController();
73
+ setTimeout(() => controller.abort(), 10000);
74
+ response = await fetch(url, {...headers, signal: controller.signal});
70
75
  } catch (e) {
71
- if (e.message === 'Timeout'
76
+ if (e.message === 'AbortError'
72
77
  || e.message === 'Network request failed') {
73
- if(numberRetry <=2) {
78
+ if(numberRetry <=1) {
74
79
  return await internalFetch(url, headers, numberRetry + 1);
75
80
  }
76
81
  else {
@@ -156,8 +161,8 @@ export interface AuthorityConfiguration {
156
161
  client_id: string,
157
162
  redirect_uri: string,
158
163
  silent_redirect_uri?:string,
159
- silent_signin_uri?:string,
160
- silent_signin_timeout?:number,
164
+ silent_login_uri?:string,
165
+ silent_login_timeout?:number,
161
166
  scope: string,
162
167
  authority: string,
163
168
  authority_time_cache_wellknowurl_in_second?: number,
@@ -211,9 +216,9 @@ const autoRenewTokens = (oidc, refreshToken, expiresAt) => {
211
216
  oidc.timeoutId = autoRenewTokens(oidc, tokens.refreshToken, oidc.tokens.expiresAt);
212
217
  }
213
218
  } else{
214
- await oidc.syncTokensAsync();
215
- if(oidc.timeoutId) {
216
- 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);
217
222
  }
218
223
  }
219
224
  }, 1000);
@@ -226,7 +231,6 @@ const getLoginParams = (configurationName, redirectUri) => {
226
231
  return JSON.parse(sessionStorage[getLoginSessionKey(configurationName, redirectUri)]);
227
232
  }
228
233
 
229
-
230
234
  const userInfoAsync = async (oidc) => {
231
235
  if(oidc.userInfo != null){
232
236
  return oidc.userInfo;
@@ -245,7 +249,7 @@ const userInfoAsync = async (oidc) => {
245
249
  const res = await fetch(url, {
246
250
  headers: {
247
251
  authorization: `Bearer ${accessToken}`,
248
- credentials: 'same-origin'
252
+ credentials: 'include'
249
253
  }
250
254
  });
251
255
 
@@ -275,7 +279,10 @@ const setTokensAsync = async (serviceWorker, tokens) =>{
275
279
  accessTokenPayload = extractAccessTokenPayload(tokens);
276
280
  }
277
281
  const _idTokenPayload = idTokenPayload(tokens.idToken);
278
- const expiresAt = (_idTokenPayload && _idTokenPayload.exp) ? _idTokenPayload.exp : tokens.issuedAt + tokens.expiresIn;
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;
279
286
  return {...tokens, idTokenPayload: _idTokenPayload, accessTokenPayload, expiresAt};
280
287
  }
281
288
 
@@ -283,6 +290,7 @@ const eventNames = {
283
290
  service_worker_not_supported_by_browser: "service_worker_not_supported_by_browser",
284
291
  token_aquired: "token_aquired",
285
292
  logout_from_another_tab: "logout_from_another_tab",
293
+ logout_from_same_tab: "logout_from_same_tab",
286
294
  token_renewed: "token_renewed",
287
295
  token_timer: "token_timer",
288
296
  loginAsync_begin:"loginAsync_begin",
@@ -298,48 +306,50 @@ const eventNames = {
298
306
  tryKeepExistingSessionAsync_begin: "tryKeepExistingSessionAsync_begin",
299
307
  tryKeepExistingSessionAsync_end: "tryKeepExistingSessionAsync_end",
300
308
  tryKeepExistingSessionAsync_error: "tryKeepExistingSessionAsync_error",
301
- silentSigninAsync_begin: "silentSigninAsync_begin",
302
- silentSigninAsync: "silentSigninAsync",
303
- silentSigninAsync_end: "silentSigninAsync_end",
304
- silentSigninAsync_error: "silentSigninAsync_error",
309
+ silentLoginAsync_begin: "silentLoginAsync_begin",
310
+ silentLoginAsync: "silentLoginAsync",
311
+ silentLoginAsync_end: "silentLoginAsync_end",
312
+ silentLoginAsync_error: "silentLoginAsync_error",
305
313
  syncTokensAsync_begin: "syncTokensAsync_begin",
306
314
  syncTokensAsync_end: "syncTokensAsync_end",
307
315
  syncTokensAsync_error: "syncTokensAsync_error"
308
-
309
316
  }
310
317
 
311
318
  const getRandomInt = (max) => {
312
319
  return Math.floor(Math.random() * max);
313
320
  }
314
321
 
315
- const WELL_KNOWN_PATH = '.well-known';
316
- const OPENID_CONFIGURATION = 'openid-configuration';
317
-
318
-
319
322
  const oneHourSecond = 60 * 60;
320
- const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond):
323
+ let fetchFromIssuerCache = null;
324
+ const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond, storage= window.sessionStorage):
321
325
  Promise<OidcAuthorizationServiceConfiguration> => {
322
- const fullUrl = `${openIdIssuerUrl}/${WELL_KNOWN_PATH}/${OPENID_CONFIGURATION}`;
326
+ const fullUrl = `${openIdIssuerUrl}/.well-known/openid-configuration`;
323
327
 
324
328
  const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
325
- const cacheJson = window.localStorage.getItem(localStorageKey);
326
-
329
+ if(!fetchFromIssuerCache && storage) {
330
+ const cacheJson = storage.getItem(localStorageKey);
331
+ if(cacheJson){
332
+ fetchFromIssuerCache = JSON.parse(cacheJson);
333
+ }
334
+ }
327
335
  const oneHourMinisecond = 1000 * timeCacheSecond;
328
336
  // @ts-ignore
329
- if(cacheJson && (cacheJson.timestamp + oneHourMinisecond) > Date.now()){
330
- return new OidcAuthorizationServiceConfiguration(JSON.parse(cacheJson));
337
+ if(fetchFromIssuerCache && (fetchFromIssuerCache.timestamp + oneHourMinisecond) > Date.now()){
338
+ return new OidcAuthorizationServiceConfiguration(fetchFromIssuerCache.result);
331
339
  }
332
-
333
340
  const response = await fetch(fullUrl);
334
341
 
335
342
  if (response.status != 200) {
336
343
  return null;
337
344
  }
338
345
 
339
-
340
346
  const result = await response.json();
341
- window.localStorage.setItem(localStorageKey, JSON.stringify({result, timestamp:Date.now()}));
342
347
 
348
+ const timestamp = Date.now();
349
+ fetchFromIssuerCache = {result, timestamp};
350
+ if(storage) {
351
+ storage.setItem(localStorageKey, JSON.stringify({result, timestamp}));
352
+ }
343
353
  return new OidcAuthorizationServiceConfiguration(result);
344
354
  }
345
355
 
@@ -368,7 +378,12 @@ export class Oidc {
368
378
  private session?: any;
369
379
  private checkSessionIFrame: CheckSessionIFrame;
370
380
  constructor(configuration:OidcConfiguration, configurationName="default") {
371
- this.configuration = configuration
381
+ let silent_login_uri = configuration.silent_login_uri;
382
+ if(configuration.silent_redirect_uri && !configuration.silent_login_uri){
383
+ silent_login_uri = `${configuration.silent_redirect_uri.replace("-callback", "").replace("callback", "")}-login`;
384
+ }
385
+
386
+ this.configuration = {...configuration, silent_login_uri};
372
387
  this.configurationName= configurationName;
373
388
  this.tokens = null
374
389
  this.userInfo = null;
@@ -385,6 +400,9 @@ export class Oidc {
385
400
  this.removeEventSubscription.bind(this);
386
401
  this.publishEvent.bind(this);
387
402
  this.destroyAsync.bind(this);
403
+ this.logoutAsync.bind(this);
404
+
405
+ this.initAsync(this.configuration.authority, this.configuration.authority_configuration);
388
406
  }
389
407
 
390
408
  subscriveEvents(func){
@@ -416,29 +434,47 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
416
434
  }
417
435
  static eventNames = eventNames;
418
436
 
419
- silentSigninCallbackFromIFrame(){
420
- if (this.configuration.silent_redirect_uri && this.configuration.silent_signin_uri) {
437
+ _silentLoginCallbackFromIFrame(){
438
+ if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
421
439
  const queryParams = getParseQueryStringFromLocation(window.location.href);
422
440
  window.top.postMessage(`${this.configurationName}_oidc_tokens:${JSON.stringify({tokens:this.tokens, sessionState:queryParams.session_state})}`, window.location.origin);
423
441
  }
424
442
  }
425
- silentSigninErrorCallbackFromIFrame(){
426
- if (this.configuration.silent_redirect_uri && this.configuration.silent_signin_uri) {
443
+ _silentLoginErrorCallbackFromIFrame() {
444
+ if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
427
445
  const queryParams = getParseQueryStringFromLocation(window.location.href);
428
- window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error:queryParams.error})}`, window.location.origin);
446
+ window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error: queryParams.error})}`, window.location.origin);
447
+ }
448
+ }
449
+
450
+ async silentLoginCallBackAsync() {
451
+ try {
452
+ await this.loginCallbackAsync(true);
453
+ this._silentLoginCallbackFromIFrame();
454
+ } catch (error) {
455
+ console.error(error)
456
+ this._silentLoginErrorCallbackFromIFrame();
429
457
  }
430
458
  }
431
- async silentSigninAsync(extras:StringMap=null, state:string=null, scope:string=null) {
432
- if (!this.configuration.silent_redirect_uri || !this.configuration.silent_signin_uri) {
459
+
460
+ async silentLoginAsync(extras:StringMap=null, state:string=null, scope:string=null) {
461
+ if (!this.configuration.silent_redirect_uri || !this.configuration.silent_login_uri) {
433
462
  return Promise.resolve(null);
434
463
  }
435
464
  while (document.hidden) {
436
465
  await sleepAsync(1000);
437
- this.publishEvent(eventNames.silentSigninAsync, {message:"wait because document is hidden"});
466
+ this.publishEvent(eventNames.silentLoginAsync, {message:"wait because document is hidden"});
467
+ }
468
+
469
+ let numberTryOnline = 6;
470
+ while (!navigator.onLine && numberTryOnline > 0) {
471
+ await sleepAsync(1000);
472
+ numberTryOnline--;
473
+ this.publishEvent(eventNames.refreshTokensAsync, {message: `wait because navigator is offline try ${numberTryOnline}` });
438
474
  }
439
475
 
440
476
  try {
441
- this.publishEvent(eventNames.silentSigninAsync_begin, {});
477
+ this.publishEvent(eventNames.silentLoginAsync_begin, {});
442
478
  const configuration = this.configuration
443
479
  let queries = "";
444
480
 
@@ -465,7 +501,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
465
501
  }
466
502
  }
467
503
  }
468
- const link = configuration.silent_signin_uri + queries;
504
+ const link = configuration.silent_login_uri + queries;
469
505
  const idx = link.indexOf("/", link.indexOf("//") + 2);
470
506
  const iFrameOrigin = link.substr(0, idx);
471
507
  const iframe = document.createElement('iframe');
@@ -490,43 +526,42 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
490
526
  if (!isResolved) {
491
527
  if(data.startsWith(key)) {
492
528
  const result = JSON.parse(e.data.replace(key, ''));
493
- self.publishEvent(eventNames.silentSigninAsync_end, {});
529
+ self.publishEvent(eventNames.silentLoginAsync_end, {});
494
530
  iframe.remove();
495
531
  isResolved = true;
496
532
  resolve(result);
497
533
  }
498
534
  else if(data.startsWith(key_error)) {
499
535
  const result = JSON.parse(e.data.replace(key_error, ''));
500
- self.publishEvent(eventNames.silentSigninAsync_error, result);
536
+ self.publishEvent(eventNames.silentLoginAsync_error, result);
501
537
  iframe.remove();
502
538
  isResolved = true;
503
- reject(result);
539
+ reject(new Error("oidc_"+result.error));
504
540
  }
505
541
  }
506
542
  }
507
543
  }
508
544
  };
509
- const silentSigninTimeout = configuration.silent_signin_timeout ?? 12000
545
+ const silentSigninTimeout = configuration.silent_login_timeout ?? 12000
510
546
  setTimeout(() => {
511
547
  if (!isResolved) {
512
- self.publishEvent(eventNames.silentSigninAsync_error, "timeout");
548
+ self.publishEvent(eventNames.silentLoginAsync_error, {reason: "timeout"});
513
549
  iframe.remove();
514
550
  isResolved = true;
515
- reject("timeout");
551
+ reject(new Error("timeout"));
516
552
  }
517
553
  }, silentSigninTimeout);
518
554
  } catch (e) {
519
555
  iframe.remove();
520
- self.publishEvent(eventNames.silentSigninAsync_error, e);
556
+ self.publishEvent(eventNames.silentLoginAsync_error, e);
521
557
  reject(e);
522
558
  }
523
559
  });
524
560
  } catch (e) {
525
- this.publishEvent(eventNames.silentSigninAsync_error, e);
561
+ this.publishEvent(eventNames.silentLoginAsync_error, e);
526
562
  throw e;
527
563
  }
528
564
  }
529
- initAsyncPromise = null;
530
565
  async initAsync(authority:string, authorityConfiguration:AuthorityConfiguration) {
531
566
  if (authorityConfiguration != null) {
532
567
  return new OidcAuthorizationServiceConfiguration( {
@@ -538,12 +573,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
538
573
  check_session_iframe:authorityConfiguration.check_session_iframe,
539
574
  });
540
575
  }
541
- if(this.initAsyncPromise){
542
- return this.initAsyncPromise;
543
- }
544
-
545
- this.initAsyncPromise = await fetchFromIssuer(authority, this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60);
546
- return this.initAsyncPromise;
576
+
577
+ const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName);
578
+ const storage = serviceWorker ? window.localStorage : null;
579
+ const initAsyncPromise = await fetchFromIssuer(authority, this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60, storage);
580
+ return initAsyncPromise;
547
581
  }
548
582
 
549
583
  tryKeepExistingSessionPromise = null;
@@ -573,13 +607,15 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
573
607
  expiresIn: tokens.expires_in,
574
608
  idToken: tokens.id_token,
575
609
  scope: tokens.scope,
576
- tokenType: tokens.token_type
610
+ tokenType: tokens.token_type,
611
+ issuedAt: tokens.issued_at
577
612
  }
578
613
  this.tokens = await setTokensAsync(serviceWorker, reformattedToken);
579
614
  this.serviceWorker = serviceWorker;
580
615
  // @ts-ignore
581
616
  this.timeoutId = autoRenewTokens(this, this.tokens.refreshToken, this.tokens.expiresAt);
582
617
  const sessionState = await serviceWorker.getSessionStateAsync();
618
+ // @ts-ignore
583
619
  await this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, configuration.client_id, sessionState);
584
620
  this.publishEvent(eventNames.tryKeepExistingSessionAsync_end, {
585
621
  success: true,
@@ -607,6 +643,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
607
643
  // @ts-ignore
608
644
  this.timeoutId = autoRenewTokens(this, tokens.refreshToken, this.tokens.expiresAt);
609
645
  const sessionState = session.getSessionState();
646
+ // @ts-ignore
610
647
  await this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, configuration.client_id, sessionState);
611
648
  this.publishEvent(eventNames.tryKeepExistingSessionAsync_end, {
612
649
  success: true,
@@ -660,23 +697,6 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
660
697
 
661
698
  let serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
662
699
  const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
663
- /*if (serviceWorker && installServiceWorker) {
664
- const isServiceWorkerProxyActive = await serviceWorker.isServiceWorkerProxyActiveAsync();
665
- if (!isServiceWorkerProxyActive) {
666
- const isUnregistered = await serviceWorker.unregisterAsync();
667
- console.log("isUnregistered")
668
- console.log(isUnregistered)
669
- if(isUnregistered){
670
- serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
671
- }
672
- const extrasQueries = extras != null ? {...extras}: {};
673
- extrasQueries.callbackPath = url;
674
- extrasQueries.state = state;
675
- const queryString = buildQueries(extrasQueries);
676
- window.location.href = `${redirectUri}/service-worker-install${queryString}`;
677
- //return;
678
- }
679
- }*/
680
700
  let storage;
681
701
  if (serviceWorker) {
682
702
  serviceWorker.startKeepAliveServiceWorker();
@@ -712,12 +732,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
712
732
  this.loginPromise = null;
713
733
  return result;
714
734
  });
715
-
716
735
  }
717
736
 
718
737
  async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin=false){
719
738
  return new Promise((resolve:Function, reject) => {
720
- if (this.configuration.silent_signin_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
739
+ if (this.configuration.silent_login_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
721
740
  const checkSessionCallback = () => {
722
741
  this.checkSessionIFrame.stop();
723
742
 
@@ -728,7 +747,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
728
747
  const idToken = this.tokens.idToken;
729
748
  // @ts-ignore
730
749
  const idTokenPayload = this.tokens.idTokenPayload;
731
- this.silentSigninAsync({
750
+ this.silentLoginAsync({
732
751
  prompt: "none",
733
752
  id_token_hint: idToken,
734
753
  scope: "openid"
@@ -747,7 +766,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
747
766
  console.debug("SessionMonitor._callback: Different subject signed into OP:", iFrameIdTokenPayload.sub);
748
767
  }
749
768
  }).catch((e) => {
750
- this.publishEvent(eventNames.logout_from_another_tab, {});
769
+ this.publishEvent(eventNames.logout_from_another_tab, {message : "SessionMonitor"});
751
770
  this.destroyAsync();
752
771
  });
753
772
  };
@@ -880,6 +899,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
880
899
  clearTimeout(timeoutId);
881
900
  this.timeoutId=null;
882
901
  const loginParams = getLoginParams(this.configurationName, redirectUri);
902
+ // @ts-ignore
883
903
  this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, clientId, sessionState, isSilentSignin).then(() =>{
884
904
  this.publishEvent(eventNames.loginCallbackAsync_end, {});
885
905
  resolve({
@@ -911,9 +931,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
911
931
 
912
932
  async refreshTokensAsync(refreshToken) {
913
933
 
914
- const localSilentSigninAsync= async () => {
934
+ const localsilentLoginAsync= async () => {
915
935
  try {
916
- const silent_token_response = await this.silentSigninAsync();
936
+ const loginParams = getLoginParams(this.configurationName, configuration.redirect_uri);
937
+ const silent_token_response = await this.silentLoginAsync(loginParams.extras, loginParams.state);
917
938
  if (silent_token_response) {
918
939
  return silent_token_response.tokens;
919
940
  }
@@ -935,7 +956,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
935
956
 
936
957
  if(!refreshToken)
937
958
  {
938
- return await localSilentSigninAsync();
959
+ return await localsilentLoginAsync();
939
960
  }
940
961
 
941
962
  let extras = {};
@@ -954,7 +975,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
954
975
  };
955
976
 
956
977
  let index = 0;
957
- while (index <=2) {
978
+ while (index <=4) {
958
979
  try {
959
980
  this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken, tryNumber: index});
960
981
  if(index > 1) {
@@ -962,6 +983,12 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
962
983
  await sleepAsync(1000);
963
984
  this.publishEvent(eventNames.refreshTokensAsync, {message: "wait because document is hidden"});
964
985
  }
986
+ let numberTryOnline = 6;
987
+ while (!navigator.onLine && numberTryOnline > 0) {
988
+ await sleepAsync(1000);
989
+ numberTryOnline--;
990
+ this.publishEvent(eventNames.refreshTokensAsync, {message: `wait because navigator is offline try ${numberTryOnline}` });
991
+ }
965
992
  }
966
993
  const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint, details, extras)
967
994
  if (tokenResponse.success) {
@@ -969,11 +996,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
969
996
  return tokenResponse.data;
970
997
  } else {
971
998
  this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "bad request" , tokenResponse: tokenResponse});
972
- return await localSilentSigninAsync();
999
+ return await localsilentLoginAsync();
973
1000
  }
974
1001
  } catch (exception) {
975
1002
  console.error(exception);
976
- this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "exception" ,exception: exception});
1003
+ this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "exception" ,exception: exception.message});
977
1004
  }
978
1005
  index++;
979
1006
  }
@@ -982,55 +1009,75 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
982
1009
 
983
1010
  syncTokensAsyncPromise=null;
984
1011
  async syncTokensAsync() {
985
- // 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)
986
- const configuration = this.configuration;
987
- if(!this.tokens){
988
- return;
989
- }
990
-
991
- const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
992
- const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
993
- if (serviceWorker) {
994
- const { isLogin } = await serviceWorker.initAsync(oidcServerConfiguration, "syncTokensAsync");
995
- if(isLogin == false){
996
- this.publishEvent(eventNames.logout_from_another_tab, {});
997
- await this.destroyAsync();
1012
+
1013
+ const localSyncTokensAsync = async () => {
1014
+ // 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)
1015
+ const configuration = this.configuration;
1016
+ if (!this.tokens) {
1017
+ return null;
998
1018
  }
999
- else if (isLogin == null){
1000
- try {
1001
- this.publishEvent(eventNames.syncTokensAsync_begin, {});
1002
- this.syncTokensAsyncPromise = this.silentSigninAsync({prompt:"none"});
1003
- const silent_token_response = await this.syncTokensAsyncPromise;
1004
- if (silent_token_response && silent_token_response.tokens) {
1005
- this.tokens = await setTokensAsync(serviceWorker, silent_token_response.tokens);
1006
- } else{
1007
- this.publishEvent(eventNames.syncTokensAsync_error, {message:"no token found in result"});
1008
- if(this.timeoutId){
1019
+
1020
+ const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
1021
+ const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
1022
+ if (serviceWorker) {
1023
+ const {isLogin} = await serviceWorker.initAsync(oidcServerConfiguration, "syncTokensAsync");
1024
+ if (isLogin == false) {
1025
+ this.publishEvent(eventNames.logout_from_another_tab, {"message": "service worker syncTokensAsync"});
1026
+ await this.destroyAsync();
1027
+ return null;
1028
+ } else if (isLogin == null) {
1029
+ try {
1030
+ this.publishEvent(eventNames.syncTokensAsync_begin, {});
1031
+ const loginParams = getLoginParams(this.configurationName, configuration.redirect_uri);
1032
+ const silent_token_response = await this.silentLoginAsync({...loginParams.extras,prompt: "none"}, loginParams.state);
1033
+ if (silent_token_response && silent_token_response.tokens) {
1034
+ this.tokens = await setTokensAsync(serviceWorker, silent_token_response.tokens);
1035
+ this.publishEvent(eventNames.syncTokensAsync_end, {});
1036
+ return this.tokens;
1037
+ } else {
1038
+ this.publishEvent(eventNames.syncTokensAsync_error, {message: "no token found in result"});
1039
+ if (this.timeoutId) {
1040
+ timer.clearTimeout(this.timeoutId);
1041
+ this.timeoutId = null;
1042
+ }
1043
+ this.publishEvent(eventNames.syncTokensAsync_end, {});
1044
+ return null;
1045
+ }
1046
+ } catch (exceptionSilent) {
1047
+ console.error(exceptionSilent);
1048
+ this.publishEvent(eventNames.syncTokensAsync_error, exceptionSilent);
1049
+ if (this.timeoutId) {
1009
1050
  timer.clearTimeout(this.timeoutId);
1010
- this.timeoutId=null;
1051
+ this.timeoutId = null;
1011
1052
  }
1012
- return;
1013
- }
1014
- } catch (exceptionSilent) {
1015
- console.error(exceptionSilent);
1016
- this.publishEvent(eventNames.syncTokensAsync_error, exceptionSilent);
1017
- if(this.timeoutId){
1018
- timer.clearTimeout(this.timeoutId);
1019
- this.timeoutId=null;
1053
+ this.publishEvent(eventNames.syncTokensAsync_end, {});
1054
+ return null;
1020
1055
  }
1021
- return;
1022
1056
  }
1023
- this.syncTokensAsyncPromise = null;
1024
- this.publishEvent(eventNames.syncTokensAsync_end, {});
1025
- }
1026
- } else {
1027
- const session = initSession(this.configurationName, configuration.redirect_uri, configuration.storage ?? sessionStorage);
1028
- const {tokens} = await session.initAsync();
1029
- if(!tokens){
1030
- this.publishEvent(eventNames.logout_from_another_tab, {});
1031
- await this.destroyAsync();
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, {"message": "session syncTokensAsync"});
1062
+ await this.destroyAsync();
1063
+ return null;
1064
+ }
1032
1065
  }
1066
+ return this.tokens;
1067
+ }
1068
+
1069
+ if(this.syncTokensAsyncPromise){
1070
+ return this.syncTokensAsyncPromise;
1033
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
1034
1081
  }
1035
1082
 
1036
1083
 
@@ -1065,7 +1112,14 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1065
1112
  this.tokens = null;
1066
1113
  this.userInfo = null;
1067
1114
  this.events = [];
1068
-
1115
+ }
1116
+
1117
+ async logoutSameTabAsync(sub){
1118
+ // @ts-ignore
1119
+ if(this.configuration.monitor_session && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
1120
+ this.publishEvent(eventNames.logout_from_same_tab, {"message": sub});
1121
+ await this.destroyAsync();
1122
+ }
1069
1123
  }
1070
1124
 
1071
1125
  async logoutAsync(callbackPathOrUrl: string | undefined = undefined, extras: StringMap = null) {
@@ -1084,7 +1138,16 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1084
1138
  const url = isUri ? callbackPathOrUrl : window.location.origin + path;
1085
1139
  // @ts-ignore
1086
1140
  const idToken = this.tokens ? this.tokens.idToken : "";
1087
- await this.destroyAsync();
1141
+ // @ts-ignore
1142
+ const sub = this.tokens && this.tokens.idTokenPayload ? this.tokens.idTokenPayload.sub : null;
1143
+ await this.destroyAsync();
1144
+ for (const [key, oidc] of Object.entries(oidcDatabase)) {
1145
+ if(oidc !== this) {
1146
+ // @ts-ignore
1147
+ await oidc.logoutSameTabAsync(sub);
1148
+ }
1149
+ }
1150
+
1088
1151
  if(oidcServerConfiguration.endSessionEndpoint) {
1089
1152
  let extraQueryString = "";
1090
1153
  if(extras){
@@ -1,4 +0,0 @@
1
- import { ComponentType } from 'react';
2
- declare const ServiceWorkerInstall: ComponentType<any>;
3
- export default ServiceWorkerInstall;
4
- //# sourceMappingURL=ServiceWorkerInstall.component.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ServiceWorkerInstall.component.d.ts","sourceRoot":"","sources":["../../../src/oidc/core/default-component/ServiceWorkerInstall.component.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAsB,aAAa,EAAC,MAAM,OAAO,CAAC;AAMhE,QAAA,MAAM,oBAAoB,EAAE,aAAa,CAAC,GAAG,CAmD5C,CAAC;AAEF,eAAe,oBAAoB,CAAC"}