@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.
- package/README.md +21 -11
- package/dist/OidcProvider.d.ts +3 -3
- package/dist/OidcProvider.d.ts.map +1 -1
- package/dist/OidcProvider.js +15 -7
- package/dist/OidcProvider.js.map +1 -1
- package/dist/OidcServiceWorker.js +21 -4
- package/dist/OidcTrustedDomains.js +7 -2
- package/dist/ReactOidc.d.ts.map +1 -1
- package/dist/ReactOidc.js +3 -2
- package/dist/ReactOidc.js.map +1 -1
- 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 +14 -12
- package/dist/vanilla/oidc.d.ts.map +1 -1
- package/dist/vanilla/oidc.js +289 -169
- package/dist/vanilla/oidc.js.map +1 -1
- package/package.json +1 -1
- package/src/oidc/OidcProvider.tsx +18 -10
- package/src/oidc/ReactOidc.tsx +3 -2
- 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 +202 -139
- 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/oidc/core/default-component/ServiceWorkerInstall.component.tsx +0 -60
package/src/oidc/vanilla/oidc.ts
CHANGED
|
@@ -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
|
|
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:
|
|
54
|
-
expiresIn:
|
|
55
|
-
idToken:
|
|
56
|
-
refreshToken:
|
|
57
|
-
scope:
|
|
58
|
-
tokenType:
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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 === '
|
|
76
|
+
if (e.message === 'AbortError'
|
|
72
77
|
|| e.message === 'Network request failed') {
|
|
73
|
-
if(numberRetry <=
|
|
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
|
-
|
|
160
|
-
|
|
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: '
|
|
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
|
-
|
|
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
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
|
|
323
|
+
let fetchFromIssuerCache = null;
|
|
324
|
+
const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond, storage= window.sessionStorage):
|
|
321
325
|
Promise<OidcAuthorizationServiceConfiguration> => {
|
|
322
|
-
const fullUrl = `${openIdIssuerUrl}
|
|
326
|
+
const fullUrl = `${openIdIssuerUrl}/.well-known/openid-configuration`;
|
|
323
327
|
|
|
324
328
|
const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
|
|
325
|
-
|
|
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(
|
|
330
|
-
return new OidcAuthorizationServiceConfiguration(
|
|
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
|
-
|
|
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
|
-
|
|
420
|
-
if (this.configuration.silent_redirect_uri && this.configuration.
|
|
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
|
-
|
|
426
|
-
if (this.configuration.silent_redirect_uri && this.configuration.
|
|
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
|
-
|
|
432
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
545
|
+
const silentSigninTimeout = configuration.silent_login_timeout ?? 12000
|
|
510
546
|
setTimeout(() => {
|
|
511
547
|
if (!isResolved) {
|
|
512
|
-
self.publishEvent(eventNames.
|
|
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.
|
|
556
|
+
self.publishEvent(eventNames.silentLoginAsync_error, e);
|
|
521
557
|
reject(e);
|
|
522
558
|
}
|
|
523
559
|
});
|
|
524
560
|
} catch (e) {
|
|
525
|
-
this.publishEvent(eventNames.
|
|
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
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
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.
|
|
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.
|
|
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
|
|
934
|
+
const localsilentLoginAsync= async () => {
|
|
915
935
|
try {
|
|
916
|
-
const
|
|
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
|
|
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 <=
|
|
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
|
|
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
|
-
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
|
|
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
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1024
|
-
this.
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
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
|
-
|
|
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 +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"}
|