@axa-fr/react-oidc 6.0.0-alpha9 → 6.0.0-beta2
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 +12 -9
- package/dist/OidcProvider.d.ts +2 -3
- package/dist/OidcProvider.d.ts.map +1 -1
- package/dist/OidcProvider.js +5 -4
- package/dist/OidcProvider.js.map +1 -1
- package/dist/OidcServiceWorker.js +4 -2
- package/dist/core/default-component/SilentCallback.component.d.ts.map +1 -1
- package/dist/core/default-component/SilentCallback.component.js +5 -19
- package/dist/core/default-component/SilentCallback.component.js.map +1 -1
- package/dist/core/default-component/SilentLogin.component.d.ts +4 -0
- package/dist/core/default-component/SilentLogin.component.d.ts.map +1 -0
- package/dist/core/default-component/{SilentSignin.component.js → SilentLogin.component.js} +3 -3
- package/dist/core/default-component/SilentLogin.component.js.map +1 -0
- package/dist/core/routes/OidcRoutes.d.ts +1 -1
- package/dist/core/routes/OidcRoutes.d.ts.map +1 -1
- package/dist/core/routes/OidcRoutes.js +5 -5
- 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 +10 -9
- package/dist/vanilla/oidc.d.ts.map +1 -1
- package/dist/vanilla/oidc.js +183 -139
- package/dist/vanilla/oidc.js.map +1 -1
- package/package.json +2 -2
- package/src/oidc/OidcProvider.tsx +9 -10
- package/src/oidc/core/default-component/SilentCallback.component.tsx +1 -6
- package/src/oidc/core/default-component/{SilentSignin.component.tsx → SilentLogin.component.tsx} +2 -2
- package/src/oidc/core/routes/OidcRoutes.tsx +6 -6
- package/src/oidc/vanilla/OidcServiceWorker.js +4 -2
- package/src/oidc/vanilla/checkSessionIFrame.ts +7 -7
- package/src/oidc/vanilla/oidc.ts +122 -118
- package/dist/core/default-component/SilentSignin.component.d.ts +0 -4
- package/dist/core/default-component/SilentSignin.component.d.ts.map +0 -1
- package/dist/core/default-component/SilentSignin.component.js.map +0 -1
- package/src/App.css +0 -38
- package/src/App.specold.tsx +0 -46
- package/src/App.tsx +0 -96
- package/src/FetchUser.tsx +0 -53
- package/src/Home.tsx +0 -22
- package/src/MultiAuth.tsx +0 -116
- package/src/Profile.tsx +0 -77
- package/src/configurations.ts +0 -70
- package/src/index.css +0 -13
- package/src/index.tsx +0 -9
- package/src/logo.svg +0 -7
- package/src/override/AuthenticateError.component.tsx +0 -14
- package/src/override/Authenticating.component.tsx +0 -14
- package/src/override/Callback.component.tsx +0 -13
- package/src/override/Loading.component.tsx +0 -13
- package/src/override/ServiceWorkerNotSupported.component.tsx +0 -15
- package/src/override/SessionLost.component.tsx +0 -21
- package/src/override/style.ts +0 -10
- package/src/setupTests.js +0 -5
package/src/oidc/vanilla/oidc.ts
CHANGED
|
@@ -20,18 +20,55 @@ 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 result = await response.json();
|
|
50
|
+
return { success : true,
|
|
51
|
+
data : {
|
|
52
|
+
accessToken: result.access_token,
|
|
53
|
+
expiresIn: result.expires_in,
|
|
54
|
+
idToken: result.id_token,
|
|
55
|
+
refreshToken: result.refresh_token,
|
|
56
|
+
scope: result.scope,
|
|
57
|
+
tokenType: result.token_type,
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
23
61
|
|
|
24
62
|
const internalFetch = async (url, headers, numberRetry=0) => {
|
|
25
63
|
let response;
|
|
26
64
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
() => reject(new Error('Timeout')), 10000))]);
|
|
65
|
+
let controller = new AbortController();
|
|
66
|
+
setTimeout(() => controller.abort(), 10000);
|
|
67
|
+
response = await fetch(url, {...headers, signal: controller.signal});
|
|
31
68
|
} catch (e) {
|
|
32
|
-
if (e.message === '
|
|
33
|
-
|| e.message === 'Network request failed'
|
|
34
|
-
if(numberRetry <=
|
|
69
|
+
if (e.message === 'AbortError'
|
|
70
|
+
|| e.message === 'Network request failed') {
|
|
71
|
+
if(numberRetry <=1) {
|
|
35
72
|
return await internalFetch(url, headers, numberRetry + 1);
|
|
36
73
|
}
|
|
37
74
|
else {
|
|
@@ -117,8 +154,8 @@ export interface AuthorityConfiguration {
|
|
|
117
154
|
client_id: string,
|
|
118
155
|
redirect_uri: string,
|
|
119
156
|
silent_redirect_uri?:string,
|
|
120
|
-
|
|
121
|
-
|
|
157
|
+
silent_login_uri?:string,
|
|
158
|
+
silent_login_timeout?:number,
|
|
122
159
|
scope: string,
|
|
123
160
|
authority: string,
|
|
124
161
|
authority_time_cache_wellknowurl_in_second?: number,
|
|
@@ -206,7 +243,7 @@ const userInfoAsync = async (oidc) => {
|
|
|
206
243
|
const res = await fetch(url, {
|
|
207
244
|
headers: {
|
|
208
245
|
authorization: `Bearer ${accessToken}`,
|
|
209
|
-
credentials: '
|
|
246
|
+
credentials: 'include'
|
|
210
247
|
}
|
|
211
248
|
});
|
|
212
249
|
|
|
@@ -259,31 +296,26 @@ const eventNames = {
|
|
|
259
296
|
tryKeepExistingSessionAsync_begin: "tryKeepExistingSessionAsync_begin",
|
|
260
297
|
tryKeepExistingSessionAsync_end: "tryKeepExistingSessionAsync_end",
|
|
261
298
|
tryKeepExistingSessionAsync_error: "tryKeepExistingSessionAsync_error",
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
299
|
+
silentLoginAsync_begin: "silentLoginAsync_begin",
|
|
300
|
+
silentLoginAsync: "silentLoginAsync",
|
|
301
|
+
silentLoginAsync_end: "silentLoginAsync_end",
|
|
302
|
+
silentLoginAsync_error: "silentLoginAsync_error",
|
|
266
303
|
syncTokensAsync_begin: "syncTokensAsync_begin",
|
|
267
304
|
syncTokensAsync_end: "syncTokensAsync_end",
|
|
268
305
|
syncTokensAsync_error: "syncTokensAsync_error"
|
|
269
|
-
|
|
270
306
|
}
|
|
271
307
|
|
|
272
308
|
const getRandomInt = (max) => {
|
|
273
309
|
return Math.floor(Math.random() * max);
|
|
274
310
|
}
|
|
275
311
|
|
|
276
|
-
const WELL_KNOWN_PATH = '.well-known';
|
|
277
|
-
const OPENID_CONFIGURATION = 'openid-configuration';
|
|
278
|
-
|
|
279
|
-
|
|
280
312
|
const oneHourSecond = 60 * 60;
|
|
281
313
|
const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond):
|
|
282
314
|
Promise<OidcAuthorizationServiceConfiguration> => {
|
|
283
|
-
const fullUrl = `${openIdIssuerUrl}
|
|
315
|
+
const fullUrl = `${openIdIssuerUrl}/.well-known/openid-configuration`;
|
|
284
316
|
|
|
285
317
|
const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
|
|
286
|
-
const cacheJson = window.
|
|
318
|
+
const cacheJson = window.sessionStorage.getItem(localStorageKey);
|
|
287
319
|
|
|
288
320
|
const oneHourMinisecond = 1000 * timeCacheSecond;
|
|
289
321
|
// @ts-ignore
|
|
@@ -297,9 +329,8 @@ const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHou
|
|
|
297
329
|
return null;
|
|
298
330
|
}
|
|
299
331
|
|
|
300
|
-
|
|
301
332
|
const result = await response.json();
|
|
302
|
-
window.
|
|
333
|
+
window.sessionStorage.setItem(localStorageKey, JSON.stringify({result, timestamp:Date.now()}));
|
|
303
334
|
|
|
304
335
|
return new OidcAuthorizationServiceConfiguration(result);
|
|
305
336
|
}
|
|
@@ -329,7 +360,12 @@ export class Oidc {
|
|
|
329
360
|
private session?: any;
|
|
330
361
|
private checkSessionIFrame: CheckSessionIFrame;
|
|
331
362
|
constructor(configuration:OidcConfiguration, configurationName="default") {
|
|
332
|
-
|
|
363
|
+
let silent_login_uri = configuration.silent_login_uri;
|
|
364
|
+
if(configuration.silent_redirect_uri && !configuration.silent_login_uri){
|
|
365
|
+
silent_login_uri = `${configuration.silent_redirect_uri}-login`;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
this.configuration = {...configuration, silent_login_uri};
|
|
333
369
|
this.configurationName= configurationName;
|
|
334
370
|
this.tokens = null
|
|
335
371
|
this.userInfo = null;
|
|
@@ -346,6 +382,7 @@ export class Oidc {
|
|
|
346
382
|
this.removeEventSubscription.bind(this);
|
|
347
383
|
this.publishEvent.bind(this);
|
|
348
384
|
this.destroyAsync.bind(this);
|
|
385
|
+
this.logoutAsync.bind(this);
|
|
349
386
|
}
|
|
350
387
|
|
|
351
388
|
subscriveEvents(func){
|
|
@@ -377,29 +414,40 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
377
414
|
}
|
|
378
415
|
static eventNames = eventNames;
|
|
379
416
|
|
|
380
|
-
|
|
381
|
-
if (this.configuration.silent_redirect_uri) {
|
|
417
|
+
_silentLoginCallbackFromIFrame(){
|
|
418
|
+
if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
|
|
382
419
|
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
383
420
|
window.top.postMessage(`${this.configurationName}_oidc_tokens:${JSON.stringify({tokens:this.tokens, sessionState:queryParams.session_state})}`, window.location.origin);
|
|
384
421
|
}
|
|
385
422
|
}
|
|
386
|
-
|
|
387
|
-
if (this.configuration.silent_redirect_uri) {
|
|
423
|
+
_silentLoginErrorCallbackFromIFrame() {
|
|
424
|
+
if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
|
|
388
425
|
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
389
|
-
window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error:queryParams.error})}`, window.location.origin);
|
|
426
|
+
window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error: queryParams.error})}`, window.location.origin);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async silentLoginCallBackAsync() {
|
|
431
|
+
try {
|
|
432
|
+
await this.loginCallbackAsync(true);
|
|
433
|
+
this._silentLoginCallbackFromIFrame();
|
|
434
|
+
} catch (error) {
|
|
435
|
+
console.error(error)
|
|
436
|
+
this._silentLoginErrorCallbackFromIFrame();
|
|
390
437
|
}
|
|
391
438
|
}
|
|
392
|
-
|
|
393
|
-
|
|
439
|
+
|
|
440
|
+
async silentLoginAsync(extras:StringMap=null, state:string=null, scope:string=null) {
|
|
441
|
+
if (!this.configuration.silent_redirect_uri || !this.configuration.silent_login_uri) {
|
|
394
442
|
return Promise.resolve(null);
|
|
395
443
|
}
|
|
396
444
|
while (document.hidden) {
|
|
397
445
|
await sleepAsync(1000);
|
|
398
|
-
this.publishEvent(eventNames.
|
|
446
|
+
this.publishEvent(eventNames.silentLoginAsync, {message:"wait because document is hidden"});
|
|
399
447
|
}
|
|
400
448
|
|
|
401
449
|
try {
|
|
402
|
-
this.publishEvent(eventNames.
|
|
450
|
+
this.publishEvent(eventNames.silentLoginAsync_begin, {});
|
|
403
451
|
const configuration = this.configuration
|
|
404
452
|
let queries = "";
|
|
405
453
|
|
|
@@ -426,7 +474,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
426
474
|
}
|
|
427
475
|
}
|
|
428
476
|
}
|
|
429
|
-
const link = configuration.
|
|
477
|
+
const link = configuration.silent_login_uri + queries;
|
|
430
478
|
const idx = link.indexOf("/", link.indexOf("//") + 2);
|
|
431
479
|
const iFrameOrigin = link.substr(0, idx);
|
|
432
480
|
const iframe = document.createElement('iframe');
|
|
@@ -451,14 +499,14 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
451
499
|
if (!isResolved) {
|
|
452
500
|
if(data.startsWith(key)) {
|
|
453
501
|
const result = JSON.parse(e.data.replace(key, ''));
|
|
454
|
-
self.publishEvent(eventNames.
|
|
502
|
+
self.publishEvent(eventNames.silentLoginAsync_end, {});
|
|
455
503
|
iframe.remove();
|
|
456
504
|
isResolved = true;
|
|
457
505
|
resolve(result);
|
|
458
506
|
}
|
|
459
507
|
else if(data.startsWith(key_error)) {
|
|
460
508
|
const result = JSON.parse(e.data.replace(key_error, ''));
|
|
461
|
-
self.publishEvent(eventNames.
|
|
509
|
+
self.publishEvent(eventNames.silentLoginAsync_error, result);
|
|
462
510
|
iframe.remove();
|
|
463
511
|
isResolved = true;
|
|
464
512
|
reject(result);
|
|
@@ -467,10 +515,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
467
515
|
}
|
|
468
516
|
}
|
|
469
517
|
};
|
|
470
|
-
const silentSigninTimeout = configuration.
|
|
518
|
+
const silentSigninTimeout = configuration.silent_login_timeout ?? 12000
|
|
471
519
|
setTimeout(() => {
|
|
472
520
|
if (!isResolved) {
|
|
473
|
-
self.publishEvent(eventNames.
|
|
521
|
+
self.publishEvent(eventNames.silentLoginAsync_error, "timeout");
|
|
474
522
|
iframe.remove();
|
|
475
523
|
isResolved = true;
|
|
476
524
|
reject("timeout");
|
|
@@ -478,12 +526,12 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
478
526
|
}, silentSigninTimeout);
|
|
479
527
|
} catch (e) {
|
|
480
528
|
iframe.remove();
|
|
481
|
-
self.publishEvent(eventNames.
|
|
529
|
+
self.publishEvent(eventNames.silentLoginAsync_error, e);
|
|
482
530
|
reject(e);
|
|
483
531
|
}
|
|
484
532
|
});
|
|
485
533
|
} catch (e) {
|
|
486
|
-
this.publishEvent(eventNames.
|
|
534
|
+
this.publishEvent(eventNames.silentLoginAsync_error, e);
|
|
487
535
|
throw e;
|
|
488
536
|
}
|
|
489
537
|
}
|
|
@@ -673,12 +721,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
673
721
|
this.loginPromise = null;
|
|
674
722
|
return result;
|
|
675
723
|
});
|
|
676
|
-
|
|
677
724
|
}
|
|
678
725
|
|
|
679
726
|
async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin=false){
|
|
680
727
|
return new Promise((resolve:Function, reject) => {
|
|
681
|
-
if (this.configuration.
|
|
728
|
+
if (this.configuration.silent_login_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
|
|
682
729
|
const checkSessionCallback = () => {
|
|
683
730
|
this.checkSessionIFrame.stop();
|
|
684
731
|
|
|
@@ -689,7 +736,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
689
736
|
const idToken = this.tokens.idToken;
|
|
690
737
|
// @ts-ignore
|
|
691
738
|
const idTokenPayload = this.tokens.idTokenPayload;
|
|
692
|
-
this.
|
|
739
|
+
this.silentLoginAsync({
|
|
693
740
|
prompt: "none",
|
|
694
741
|
id_token_hint: idToken,
|
|
695
742
|
scope: "openid"
|
|
@@ -871,15 +918,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
871
918
|
}
|
|
872
919
|
|
|
873
920
|
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
921
|
|
|
880
|
-
const
|
|
922
|
+
const localsilentLoginAsync= async () => {
|
|
881
923
|
try {
|
|
882
|
-
const silent_token_response = await this.
|
|
924
|
+
const silent_token_response = await this.silentLoginAsync();
|
|
883
925
|
if (silent_token_response) {
|
|
884
926
|
return silent_token_response.tokens;
|
|
885
927
|
}
|
|
@@ -890,13 +932,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
890
932
|
timer.clearTimeout(this.timeoutId);
|
|
891
933
|
this.timeoutId=null;
|
|
892
934
|
}
|
|
893
|
-
this.publishEvent(eventNames.refreshTokensAsync_error,
|
|
935
|
+
this.publishEvent(eventNames.refreshTokensAsync_error, {message: "refresh token and silent refresh failed"});
|
|
894
936
|
return null;
|
|
895
937
|
}
|
|
896
|
-
|
|
897
|
-
try{
|
|
898
|
-
this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken});
|
|
899
|
-
|
|
938
|
+
|
|
900
939
|
const configuration = this.configuration;
|
|
901
940
|
const clientId = configuration.client_id;
|
|
902
941
|
const redirectUri = configuration.redirect_uri;
|
|
@@ -904,10 +943,9 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
904
943
|
|
|
905
944
|
if(!refreshToken)
|
|
906
945
|
{
|
|
907
|
-
return await
|
|
946
|
+
return await localsilentLoginAsync();
|
|
908
947
|
}
|
|
909
948
|
|
|
910
|
-
|
|
911
949
|
let extras = {};
|
|
912
950
|
if(configuration.token_request_extras) {
|
|
913
951
|
for (let [key, value] of Object.entries(configuration.token_request_extras)) {
|
|
@@ -915,73 +953,39 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
915
953
|
}
|
|
916
954
|
}
|
|
917
955
|
const oidcServerConfiguration = await this.initAsync(authority, configuration.authority_configuration);
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
// use the token response to make a request for an access token
|
|
921
|
-
const request = new TokenRequest({
|
|
956
|
+
|
|
957
|
+
const details = {
|
|
922
958
|
client_id: clientId,
|
|
923
959
|
redirect_uri: redirectUri,
|
|
924
960
|
grant_type: GRANT_TYPE_REFRESH_TOKEN,
|
|
925
|
-
code: undefined,
|
|
926
961
|
refresh_token: refreshToken,
|
|
927
|
-
|
|
928
|
-
});
|
|
962
|
+
};
|
|
929
963
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
};
|
|
940
|
-
|
|
941
|
-
for (let [key, value] of Object.entries(extras)) {
|
|
942
|
-
if (details[key] === undefined) {
|
|
943
|
-
details[key] = value;
|
|
964
|
+
let index = 0;
|
|
965
|
+
while (index <=2) {
|
|
966
|
+
try {
|
|
967
|
+
this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken, tryNumber: index});
|
|
968
|
+
if(index > 1) {
|
|
969
|
+
while (document.hidden) {
|
|
970
|
+
await sleepAsync(1000);
|
|
971
|
+
this.publishEvent(eventNames.refreshTokensAsync, {message: "wait because document is hidden"});
|
|
972
|
+
}
|
|
944
973
|
}
|
|
974
|
+
const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint, details, extras)
|
|
975
|
+
if (tokenResponse.success) {
|
|
976
|
+
this.publishEvent(eventNames.refreshTokensAsync_end, {success: tokenResponse.success});
|
|
977
|
+
return tokenResponse.data;
|
|
978
|
+
} else {
|
|
979
|
+
this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "bad request" , tokenResponse: tokenResponse});
|
|
980
|
+
return await localsilentLoginAsync();
|
|
981
|
+
}
|
|
982
|
+
} catch (exception) {
|
|
983
|
+
console.error(exception);
|
|
984
|
+
this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "exception" ,exception: exception.message});
|
|
945
985
|
}
|
|
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
|
-
};
|
|
986
|
+
index++;
|
|
974
987
|
}
|
|
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
|
-
}
|
|
988
|
+
|
|
985
989
|
}
|
|
986
990
|
|
|
987
991
|
syncTokensAsyncPromise=null;
|
|
@@ -1003,12 +1007,12 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
1003
1007
|
else if (isLogin == null){
|
|
1004
1008
|
try {
|
|
1005
1009
|
this.publishEvent(eventNames.syncTokensAsync_begin, {});
|
|
1006
|
-
this.syncTokensAsyncPromise = this.
|
|
1010
|
+
this.syncTokensAsyncPromise = this.silentLoginAsync({prompt:"none"});
|
|
1007
1011
|
const silent_token_response = await this.syncTokensAsyncPromise;
|
|
1008
1012
|
if (silent_token_response && silent_token_response.tokens) {
|
|
1009
1013
|
this.tokens = await setTokensAsync(serviceWorker, silent_token_response.tokens);
|
|
1010
1014
|
} else{
|
|
1011
|
-
this.publishEvent(eventNames.syncTokensAsync_error,
|
|
1015
|
+
this.publishEvent(eventNames.syncTokensAsync_error, {message:"no token found in result"});
|
|
1012
1016
|
if(this.timeoutId){
|
|
1013
1017
|
timer.clearTimeout(this.timeoutId);
|
|
1014
1018
|
this.timeoutId=null;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SilentSignin.component.d.ts","sourceRoot":"","sources":["../../../src/oidc/core/default-component/SilentSignin.component.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAY,aAAa,EAAC,MAAM,OAAO,CAAC;AAKtD,QAAA,MAAM,YAAY,EAAE,aAAa,CAAC,GAAG,CA2BnC,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SilentSignin.component.js","sourceRoot":"","sources":["../../../src/oidc/core/default-component/SilentSignin.component.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAsD;AACtD,4DAAsC;AACtC,yDAA0E;AAG1E,IAAM,YAAY,GAAuB,CAAC,UAAC,EAAoB;QAAnB,iBAAiB,uBAAA;IACzD,IAAM,WAAW,GAAG,IAAA,6CAA+B,EAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE1E,IAAM,OAAO,GAAI,cAAI,CAAC,GAAG,CAAC;IAC1B,IAAM,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAExC,IAAI,MAAM,GAAG,IAAI,CAAC;IAElB,KAAyB,UAA2B,EAA3B,KAAA,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAA3B,cAA2B,EAA3B,IAA2B,EAAE;QAA7C,IAAA,WAAY,EAAX,GAAG,QAAA,EAAE,KAAK,QAAA;QAChB,IAAG,GAAG,KAAK,OAAO,IAAI,GAAG,IAAI,OAAO,EAAC;YACjC,SAAS;SACZ;QACD,IAAG,MAAM,KAAK,IAAI,EAAC;YACf,MAAM,GAAG,EAAE,CAAC;SACf;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;KACvB;IAED,IAAA,iBAAS,EAAC;QACN,IAAG,CAAC,IAAI,CAAC,MAAM,EAAC;YACZ,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;SACnF;QACD,OAAO;QACP,CAAC,CAAA;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,6DAAK,CAAC;AACjB,CAAC,CAAC,CAAC;AAEH,kBAAe,YAAY,CAAC"}
|
package/src/App.css
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
.App {
|
|
2
|
-
text-align: center;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.App-logo {
|
|
6
|
-
height: 40vmin;
|
|
7
|
-
pointer-events: none;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
11
|
-
.App-logo {
|
|
12
|
-
animation: App-logo-spin infinite 20s linear;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.App-header {
|
|
17
|
-
background-color: #282c34;
|
|
18
|
-
min-height: 100vh;
|
|
19
|
-
display: flex;
|
|
20
|
-
flex-direction: column;
|
|
21
|
-
align-items: center;
|
|
22
|
-
justify-content: center;
|
|
23
|
-
font-size: calc(10px + 2vmin);
|
|
24
|
-
color: white;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.App-link {
|
|
28
|
-
color: #61dafb;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@keyframes App-logo-spin {
|
|
32
|
-
from {
|
|
33
|
-
transform: rotate(0deg);
|
|
34
|
-
}
|
|
35
|
-
to {
|
|
36
|
-
transform: rotate(360deg);
|
|
37
|
-
}
|
|
38
|
-
}
|
package/src/App.specold.tsx
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// __tests__/fetch.test.js
|
|
2
|
-
/*import React from 'react'
|
|
3
|
-
import {rest} from 'msw'
|
|
4
|
-
import {setupServer} from 'msw/node'
|
|
5
|
-
import {render, fireEvent, waitFor, screen} from '@testing-library/react'
|
|
6
|
-
import '@testing-library/jest-dom'
|
|
7
|
-
import App from "./App";
|
|
8
|
-
import {act} from "react-dom/test-utils";
|
|
9
|
-
|
|
10
|
-
const server = setupServer(
|
|
11
|
-
rest.get('http://api/.well-known/openid-configuration', (req, res, ctx) => {
|
|
12
|
-
return res( ctx.status(200),ctx.json({
|
|
13
|
-
"issuer":"https://demo.identityserver.io",
|
|
14
|
-
"jwks_uri":"https://demo.identityserver.io/.well-known/openid-configuration/jwks",
|
|
15
|
-
"authorization_endpoint":"https://demo.identityserver.io/connect/authorize",
|
|
16
|
-
"token_endpoint":"https://demo.identityserver.io/connect/token",
|
|
17
|
-
"userinfo_endpoint":"https://demo.identityserver.io/connect/userinfo",
|
|
18
|
-
"end_session_endpoint":"https://demo.identityserver.io/connect/endsession",
|
|
19
|
-
"check_session_iframe":"https://demo.identityserver.io/connect/checksession",
|
|
20
|
-
"revocation_endpoint":"https://demo.identityserver.io/connect/revocation",
|
|
21
|
-
"introspection_endpoint":"https://demo.identityserver.io/connect/introspect",
|
|
22
|
-
"device_authorization_endpoint":"https://demo.identityserver.io/connect/deviceauthorization","frontchannel_logout_supported":true,"frontchannel_logout_session_supported":true,"backchannel_logout_supported":true,"backchannel_logout_session_supported":true,"scopes_supported":["openid","profile","email","api","api.scope1","api.scope2","scope2","policyserver.runtime","policyserver.management","offline_access"],"claims_supported":["sub","name","family_name","given_name","middle_name","nickname","preferred_username","profile","picture","website","gender","birthdate","zoneinfo","locale","updated_at","email","email_verified"],"grant_types_supported":["authorization_code","client_credentials","refresh_token","implicit","password","urn:ietf:params:oauth:grant-type:device_code"],"response_types_supported":["code","token","id_token","id_token token","code id_token","code token","code id_token token"],"response_modes_supported":["form_post","query","fragment"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"id_token_signing_alg_values_supported":["RS256"],"subject_types_supported":["public"],"code_challenge_methods_supported":["plain","S256"],"request_parameter_supported":true}))
|
|
23
|
-
}),
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
beforeAll(() => server.listen())
|
|
27
|
-
afterEach(() => server.resetHandlers())
|
|
28
|
-
afterAll(() => server.close())
|
|
29
|
-
|
|
30
|
-
test('Load home page then login should log', async () => {
|
|
31
|
-
|
|
32
|
-
const configuration = {
|
|
33
|
-
client_id: 'interactive.public.short',
|
|
34
|
-
redirect_uri: 'http://localhost:4200/authentication/callback',
|
|
35
|
-
scope: 'openid profile email api offline_access',
|
|
36
|
-
authority: 'http://api',
|
|
37
|
-
refresh_time_before_tokens_expiration_in_second: 70,
|
|
38
|
-
};
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
const {debug, getByText, rerender} = render(<App configuration={configuration}/>);
|
|
41
|
-
await waitFor(() => getByText('React Demo Application protected by OpenId Connect'));
|
|
42
|
-
fireEvent.click(screen.getByText('Login'));
|
|
43
|
-
await waitFor(() => getByText('Authentification en cours'));
|
|
44
|
-
|
|
45
|
-
})
|
|
46
|
-
*/
|
package/src/App.tsx
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import React, {useReducer} from 'react';
|
|
2
|
-
import {BrowserRouter, Route, Link, Routes} from 'react-router-dom';
|
|
3
|
-
import { Home } from "./Home";
|
|
4
|
-
import { Profile, SecureProfile } from "./Profile";
|
|
5
|
-
import { configurationAuth0, configurationIdentityServer, configurationIdentityServerWithoutDiscovery } from './configurations';
|
|
6
|
-
import { withOidcSecure, OidcProvider } from "./oidc";
|
|
7
|
-
import {FetchUserHoc, FetchUserHook} from "./FetchUser";
|
|
8
|
-
import { MultiAuthContainer } from "./MultiAuth";
|
|
9
|
-
|
|
10
|
-
const OidcSecureHoc = withOidcSecure(Profile);
|
|
11
|
-
|
|
12
|
-
function reducer(state, action) {
|
|
13
|
-
switch (action.type) {
|
|
14
|
-
case 'event':
|
|
15
|
-
return [{...action.data, date:Date.now()}, ...state]
|
|
16
|
-
default:
|
|
17
|
-
throw new Error();
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function App() {
|
|
22
|
-
const [show, setShow] = React.useState(false);
|
|
23
|
-
const [events, dispatch] = useReducer(reducer, []);
|
|
24
|
-
|
|
25
|
-
const onEvent=(configurationName, eventName, data )=>{
|
|
26
|
-
// console.log(`oidc:${configurationName}:${eventName}`, data);
|
|
27
|
-
dispatch({type: 'event', data: {name: `oidc:${configurationName}:${eventName}`, data}})
|
|
28
|
-
}
|
|
29
|
-
return (<>
|
|
30
|
-
|
|
31
|
-
<OidcProvider configuration={configurationIdentityServer} onEvent={onEvent}>
|
|
32
|
-
<BrowserRouter>
|
|
33
|
-
<nav className="navbar navbar-expand-lg navbar-dark bg-primary">
|
|
34
|
-
<a className="navbar-brand" href="/">@axa-fr/react-oidc</a>
|
|
35
|
-
<button className="navbar-toggler" type="button" onClick={() => setShow(!show)} data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
|
36
|
-
<span className="navbar-toggler-icon"/>
|
|
37
|
-
</button>
|
|
38
|
-
<div style={show ? { display: "block" } : { display: 'none' }} className="collapse navbar-collapse" id="navbarNav">
|
|
39
|
-
<ul className="navbar-nav">
|
|
40
|
-
<li className="nav-item">
|
|
41
|
-
<Link className="nav-link" to="/">Home</Link>
|
|
42
|
-
</li>
|
|
43
|
-
<li className="nav-item">
|
|
44
|
-
<Link className="nav-link" to="/profile">Profile</Link>
|
|
45
|
-
</li>
|
|
46
|
-
<li className="nav-item">
|
|
47
|
-
<Link className="nav-link" to="/profile-secure-component">Secure Profile Component</Link>
|
|
48
|
-
</li>
|
|
49
|
-
<li className="nav-item">
|
|
50
|
-
<Link className="nav-link" to="/profile-secure-hoc">Secure Profile Hoc</Link>
|
|
51
|
-
</li>
|
|
52
|
-
<li className="nav-item">
|
|
53
|
-
<Link className="nav-link" to="/user-fetch-secure-hoc">Secure User Fetch Hoc</Link>
|
|
54
|
-
</li>
|
|
55
|
-
<li className="nav-item">
|
|
56
|
-
<Link className="nav-link" to="/user-fetch-secure-hook">Secure User Fetch Hook</Link>
|
|
57
|
-
</li>
|
|
58
|
-
<li className="nav-item">
|
|
59
|
-
<Link className="nav-link" to="/multi-auth">Multi Auth</Link>
|
|
60
|
-
</li>
|
|
61
|
-
</ul>
|
|
62
|
-
</div>
|
|
63
|
-
</nav>
|
|
64
|
-
|
|
65
|
-
<div>
|
|
66
|
-
<Routes>
|
|
67
|
-
<Route path="/" element={<Home></Home>} />
|
|
68
|
-
<Route path="/profile" element={<Profile></Profile>} />
|
|
69
|
-
<Route path="/profile-secure-component" element={<SecureProfile></SecureProfile>} />
|
|
70
|
-
<Route path="/profile-secure-hoc" element={<OidcSecureHoc></OidcSecureHoc>} />
|
|
71
|
-
<Route path="/user-fetch-secure-hoc" element={<FetchUserHoc></FetchUserHoc>} />
|
|
72
|
-
<Route path="/user-fetch-secure-hook" element={<FetchUserHook></FetchUserHook>} />
|
|
73
|
-
<Route path="/multi-auth/*" element={<MultiAuthContainer></MultiAuthContainer>} />
|
|
74
|
-
</Routes>
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
</BrowserRouter>
|
|
78
|
-
</OidcProvider>
|
|
79
|
-
<div className="container-fluid mt-3">
|
|
80
|
-
<div className="card">
|
|
81
|
-
<div className="card-body" >
|
|
82
|
-
<h5 className="card-title">Default configuration Events</h5>
|
|
83
|
-
<div style={{"overflowX": "hidden", "overflowY": "scroll", "maxHeight": "400px"}}>
|
|
84
|
-
{events.map(e => {
|
|
85
|
-
const date = new Date(e.date);
|
|
86
|
-
const dateFormated = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
|
|
87
|
-
return <p>{dateFormated} {e.name}: { JSON.stringify(e.data)}</p>
|
|
88
|
-
})}
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
</div></>
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export default App;
|