@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.
Files changed (62) hide show
  1. package/README.md +20 -11
  2. package/dist/OidcProvider.d.ts +2 -3
  3. package/dist/OidcProvider.d.ts.map +1 -1
  4. package/dist/OidcProvider.js +5 -4
  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/core/default-component/SilentCallback.component.d.ts.map +1 -1
  9. package/dist/core/default-component/SilentCallback.component.js +5 -19
  10. package/dist/core/default-component/SilentCallback.component.js.map +1 -1
  11. package/dist/core/default-component/SilentLogin.component.d.ts +4 -0
  12. package/dist/core/default-component/SilentLogin.component.d.ts.map +1 -0
  13. package/dist/core/default-component/{SilentSignin.component.js → SilentLogin.component.js} +3 -3
  14. package/dist/core/default-component/SilentLogin.component.js.map +1 -0
  15. package/dist/core/routes/OidcRoutes.d.ts +1 -1
  16. package/dist/core/routes/OidcRoutes.d.ts.map +1 -1
  17. package/dist/core/routes/OidcRoutes.js +5 -8
  18. package/dist/core/routes/OidcRoutes.js.map +1 -1
  19. package/dist/vanilla/checkSessionIFrame.d.ts +6 -6
  20. package/dist/vanilla/checkSessionIFrame.d.ts.map +1 -1
  21. package/dist/vanilla/checkSessionIFrame.js +1 -1
  22. package/dist/vanilla/checkSessionIFrame.js.map +1 -1
  23. package/dist/vanilla/oidc.d.ts +12 -12
  24. package/dist/vanilla/oidc.d.ts.map +1 -1
  25. package/dist/vanilla/oidc.js +342 -236
  26. package/dist/vanilla/oidc.js.map +1 -1
  27. package/package.json +2 -2
  28. package/src/oidc/OidcProvider.tsx +9 -10
  29. package/src/oidc/core/default-component/SilentCallback.component.tsx +1 -6
  30. package/src/oidc/core/default-component/{SilentSignin.component.tsx → SilentLogin.component.tsx} +2 -2
  31. package/src/oidc/core/routes/OidcRoutes.tsx +6 -10
  32. package/src/oidc/vanilla/OidcServiceWorker.js +21 -4
  33. package/src/oidc/vanilla/OidcTrustedDomains.js +7 -2
  34. package/src/oidc/vanilla/checkSessionIFrame.ts +7 -7
  35. package/src/oidc/vanilla/oidc.ts +238 -195
  36. package/dist/core/default-component/ServiceWorkerInstall.component.d.ts +0 -4
  37. package/dist/core/default-component/ServiceWorkerInstall.component.d.ts.map +0 -1
  38. package/dist/core/default-component/ServiceWorkerInstall.component.js +0 -131
  39. package/dist/core/default-component/ServiceWorkerInstall.component.js.map +0 -1
  40. package/dist/core/default-component/SilentSignin.component.d.ts +0 -4
  41. package/dist/core/default-component/SilentSignin.component.d.ts.map +0 -1
  42. package/dist/core/default-component/SilentSignin.component.js.map +0 -1
  43. package/src/App.css +0 -38
  44. package/src/App.specold.tsx +0 -46
  45. package/src/App.tsx +0 -96
  46. package/src/FetchUser.tsx +0 -53
  47. package/src/Home.tsx +0 -22
  48. package/src/MultiAuth.tsx +0 -116
  49. package/src/Profile.tsx +0 -77
  50. package/src/configurations.ts +0 -70
  51. package/src/index.css +0 -13
  52. package/src/index.tsx +0 -9
  53. package/src/logo.svg +0 -7
  54. package/src/oidc/core/default-component/ServiceWorkerInstall.component.tsx +0 -60
  55. package/src/override/AuthenticateError.component.tsx +0 -14
  56. package/src/override/Authenticating.component.tsx +0 -14
  57. package/src/override/Callback.component.tsx +0 -13
  58. package/src/override/Loading.component.tsx +0 -13
  59. package/src/override/ServiceWorkerNotSupported.component.tsx +0 -15
  60. package/src/override/SessionLost.component.tsx +0 -21
  61. package/src/override/style.ts +0 -10
  62. package/src/setupTests.js +0 -5
@@ -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
- response = await Promise.race([
28
- fetch(url, headers),
29
- new Promise((_, reject) => setTimeout(
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 === 'Timeout'
33
- || e.message === 'Network request failed' || e.message === "Failed to fetch") {
34
- if(numberRetry <=2) {
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
- silent_signin_uri?:string,
121
- silent_signin_timeout?:number,
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: 'same-origin'
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
- 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;
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
- silentSigninAsync_begin: "silentSigninAsync_begin",
263
- silentSigninAsync: "silentSigninAsync",
264
- silentSigninAsync_end: "silentSigninAsync_end",
265
- silentSigninAsync_error: "silentSigninAsync_error",
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
- const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond):
322
+ let fetchFromIssuerCache = null;
323
+ const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond, storage= window.sessionStorage):
282
324
  Promise<OidcAuthorizationServiceConfiguration> => {
283
- const fullUrl = `${openIdIssuerUrl}/${WELL_KNOWN_PATH}/${OPENID_CONFIGURATION}`;
325
+ const fullUrl = `${openIdIssuerUrl}/.well-known/openid-configuration`;
284
326
 
285
327
  const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
286
- const cacheJson = window.localStorage.getItem(localStorageKey);
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(cacheJson && (cacheJson.timestamp + oneHourMinisecond) > Date.now()){
291
- return new OidcAuthorizationServiceConfiguration(JSON.parse(cacheJson));
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
- this.configuration = configuration
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
- silentSigninCallbackFromIFrame(){
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
- silentSigninErrorCallbackFromIFrame(){
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
- async silentSigninAsync(extras:StringMap=null, state:string=null, scope:string=null) {
393
- if (!this.configuration.silent_redirect_uri || !this.configuration.silent_signin_uri) {
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.silentSigninAsync, {message:"wait because document is hidden"});
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.silentSigninAsync_begin, {});
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.silent_signin_uri + queries;
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.silentSigninAsync_end, {});
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.silentSigninAsync_error, result);
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.silent_signin_timeout ?? 12000
544
+ const silentSigninTimeout = configuration.silent_login_timeout ?? 12000
471
545
  setTimeout(() => {
472
546
  if (!isResolved) {
473
- self.publishEvent(eventNames.silentSigninAsync_error, "timeout");
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.silentSigninAsync_error, e);
555
+ self.publishEvent(eventNames.silentLoginAsync_error, e);
482
556
  reject(e);
483
557
  }
484
558
  });
485
559
  } catch (e) {
486
- this.publishEvent(eventNames.silentSigninAsync_error, e);
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
- if(this.initAsyncPromise){
503
- return this.initAsyncPromise;
504
- }
505
-
506
- this.initAsyncPromise = await fetchFromIssuer(authority, this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60);
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.silent_signin_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
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.silentSigninAsync({
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 localSilentSigninAsync= async (exception=null) => {
933
+ const localsilentLoginAsync= async () => {
881
934
  try {
882
- const silent_token_response = await this.silentSigninAsync();
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, exception);
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 localSilentSigninAsync();
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
- /*const tokenHandler = new BaseTokenRequestHandler(new FetchRequestor());
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
- extras
928
- });
974
+ };
929
975
 
930
-
931
- const token_response = await tokenHandler.performTokenRequest(oidcServerConfiguration, request);
932
- */
933
- const performTokenRequestAsync= async (url) => {
934
- const details = {
935
- client_id: clientId,
936
- redirect_uri: redirectUri,
937
- grant_type: GRANT_TYPE_REFRESH_TOKEN,
938
- refresh_token: refreshToken,
939
- };
940
-
941
- for (let [key, value] of Object.entries(extras)) {
942
- if (details[key] === undefined) {
943
- details[key] = value;
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
- // 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)
990
- const configuration = this.configuration;
991
- if(!this.tokens){
992
- return;
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
- else if (isLogin == null){
1004
- try {
1005
- this.publishEvent(eventNames.syncTokensAsync_begin, {});
1006
- this.syncTokensAsyncPromise = this.silentSigninAsync({prompt:"none"});
1007
- const silent_token_response = await this.syncTokensAsyncPromise;
1008
- if (silent_token_response && silent_token_response.tokens) {
1009
- this.tokens = await setTokensAsync(serviceWorker, silent_token_response.tokens);
1010
- } else{
1011
- this.publishEvent(eventNames.syncTokensAsync_error, null);
1012
- if(this.timeoutId){
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
- return;
1052
+ this.publishEvent(eventNames.syncTokensAsync_end, {});
1053
+ return null;
1017
1054
  }
1018
- } catch (exceptionSilent) {
1019
- console.error(exceptionSilent);
1020
- this.publishEvent(eventNames.syncTokensAsync_error, exceptionSilent);
1021
- if(this.timeoutId){
1022
- timer.clearTimeout(this.timeoutId);
1023
- this.timeoutId=null;
1024
- }
1025
- return;
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