@axa-fr/react-oidc 6.0.0-alpha8 → 6.0.0-beta1

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 (52) hide show
  1. package/README.md +15 -8
  2. package/dist/OidcProvider.d.ts +1 -2
  3. package/dist/OidcProvider.d.ts.map +1 -1
  4. package/dist/OidcProvider.js +1 -1
  5. package/dist/OidcProvider.js.map +1 -1
  6. package/dist/core/default-component/SilentCallback.component.js +2 -2
  7. package/dist/core/default-component/SilentCallback.component.js.map +1 -1
  8. package/dist/core/default-component/SilentLogin.component.d.ts +4 -0
  9. package/dist/core/default-component/SilentLogin.component.d.ts.map +1 -0
  10. package/dist/core/default-component/{SilentSignin.component.js → SilentLogin.component.js} +3 -3
  11. package/dist/core/default-component/SilentLogin.component.js.map +1 -0
  12. package/dist/core/routes/OidcRoutes.d.ts +1 -1
  13. package/dist/core/routes/OidcRoutes.d.ts.map +1 -1
  14. package/dist/core/routes/OidcRoutes.js +5 -5
  15. package/dist/core/routes/OidcRoutes.js.map +1 -1
  16. package/dist/vanilla/checkSessionIFrame.d.ts +6 -6
  17. package/dist/vanilla/checkSessionIFrame.d.ts.map +1 -1
  18. package/dist/vanilla/checkSessionIFrame.js +1 -1
  19. package/dist/vanilla/checkSessionIFrame.js.map +1 -1
  20. package/dist/vanilla/oidc.d.ts +9 -9
  21. package/dist/vanilla/oidc.d.ts.map +1 -1
  22. package/dist/vanilla/oidc.js +156 -135
  23. package/dist/vanilla/oidc.js.map +1 -1
  24. package/package.json +2 -2
  25. package/src/oidc/OidcProvider.tsx +2 -3
  26. package/src/oidc/core/default-component/SilentCallback.component.tsx +2 -2
  27. package/src/oidc/core/default-component/{SilentSignin.component.tsx → SilentLogin.component.tsx} +2 -2
  28. package/src/oidc/core/routes/OidcRoutes.tsx +6 -6
  29. package/src/oidc/vanilla/checkSessionIFrame.ts +7 -7
  30. package/src/oidc/vanilla/oidc.ts +105 -110
  31. package/dist/core/default-component/SilentSignin.component.d.ts +0 -4
  32. package/dist/core/default-component/SilentSignin.component.d.ts.map +0 -1
  33. package/dist/core/default-component/SilentSignin.component.js.map +0 -1
  34. package/src/App.css +0 -38
  35. package/src/App.specold.tsx +0 -46
  36. package/src/App.tsx +0 -96
  37. package/src/FetchUser.tsx +0 -53
  38. package/src/Home.tsx +0 -22
  39. package/src/MultiAuth.tsx +0 -116
  40. package/src/Profile.tsx +0 -77
  41. package/src/configurations.ts +0 -70
  42. package/src/index.css +0 -13
  43. package/src/index.tsx +0 -9
  44. package/src/logo.svg +0 -7
  45. package/src/override/AuthenticateError.component.tsx +0 -14
  46. package/src/override/Authenticating.component.tsx +0 -14
  47. package/src/override/Callback.component.tsx +0 -13
  48. package/src/override/Loading.component.tsx +0 -13
  49. package/src/override/ServiceWorkerNotSupported.component.tsx +0 -15
  50. package/src/override/SessionLost.component.tsx +0 -21
  51. package/src/override/style.ts +0 -10
  52. package/src/setupTests.js +0 -5
@@ -20,18 +20,56 @@ 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
+
26
+ for (let [key, value] of Object.entries(extras)) {
27
+ if (details[key] === undefined) {
28
+ details[key] = value;
29
+ }
30
+ }
31
+
32
+ let formBody = [];
33
+ for (const property in details) {
34
+ const encodedKey = encodeURIComponent(property);
35
+ const encodedValue = encodeURIComponent(details[property]);
36
+ formBody.push(`${encodedKey}=${encodedValue}`);
37
+ }
38
+ const formBodyString = formBody.join("&");
39
+
40
+ const response = await internalFetch(url, {
41
+ method: 'POST',
42
+ headers: {
43
+ 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
44
+ },
45
+ body: formBodyString,
46
+ });
47
+ if(response.status !== 200){
48
+ return {success:false, status: response.status}
49
+ }
50
+ const result = await response.json();
51
+ return { success : true,
52
+ data : {
53
+ accessToken: result.access_token,
54
+ expiresIn: result.expires_in,
55
+ idToken: result.id_token,
56
+ refreshToken: result.refresh_token,
57
+ scope: result.scope,
58
+ tokenType: result.token_type,
59
+ }
60
+ };
61
+ }
23
62
 
24
63
  const internalFetch = async (url, headers, numberRetry=0) => {
25
64
  let response;
26
65
  try {
27
- response = await Promise.race([
28
- fetch(url, headers),
29
- new Promise((_, reject) => setTimeout(
30
- () => reject(new Error('Timeout')), 10000))]);
66
+ let controller = new AbortController();
67
+ setTimeout(() => controller.abort(), 10000);
68
+ response = await fetch(url, {...headers, signal: controller.signal});
31
69
  } catch (e) {
32
- if (e.message === 'Timeout'
33
- || e.message === 'Network request failed' || e.message === "Failed to fetch") {
34
- if(numberRetry <=2) {
70
+ if (e.message === 'AbortError'
71
+ || e.message === 'Network request failed') {
72
+ if(numberRetry <=1) {
35
73
  return await internalFetch(url, headers, numberRetry + 1);
36
74
  }
37
75
  else {
@@ -117,8 +155,8 @@ export interface AuthorityConfiguration {
117
155
  client_id: string,
118
156
  redirect_uri: string,
119
157
  silent_redirect_uri?:string,
120
- silent_signin_uri?:string,
121
- silent_signin_timeout?:number,
158
+ silent_login_uri?:string,
159
+ silent_login_timeout?:number,
122
160
  scope: string,
123
161
  authority: string,
124
162
  authority_time_cache_wellknowurl_in_second?: number,
@@ -205,7 +243,8 @@ const userInfoAsync = async (oidc) => {
205
243
  const fetchUserInfo = async (accessToken) => {
206
244
  const res = await fetch(url, {
207
245
  headers: {
208
- authorization: `Bearer ${accessToken}`
246
+ authorization: `Bearer ${accessToken}`,
247
+ credentials: 'same-origin'
209
248
  }
210
249
  });
211
250
 
@@ -258,10 +297,10 @@ const eventNames = {
258
297
  tryKeepExistingSessionAsync_begin: "tryKeepExistingSessionAsync_begin",
259
298
  tryKeepExistingSessionAsync_end: "tryKeepExistingSessionAsync_end",
260
299
  tryKeepExistingSessionAsync_error: "tryKeepExistingSessionAsync_error",
261
- silentSigninAsync_begin: "silentSigninAsync_begin",
262
- silentSigninAsync: "silentSigninAsync",
263
- silentSigninAsync_end: "silentSigninAsync_end",
264
- silentSigninAsync_error: "silentSigninAsync_error",
300
+ silentLoginAsync_begin: "silentLoginAsync_begin",
301
+ silentLoginAsync: "silentLoginAsync",
302
+ silentLoginAsync_end: "silentLoginAsync_end",
303
+ silentLoginAsync_error: "silentLoginAsync_error",
265
304
  syncTokensAsync_begin: "syncTokensAsync_begin",
266
305
  syncTokensAsync_end: "syncTokensAsync_end",
267
306
  syncTokensAsync_error: "syncTokensAsync_error"
@@ -282,7 +321,7 @@ const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHou
282
321
  const fullUrl = `${openIdIssuerUrl}/${WELL_KNOWN_PATH}/${OPENID_CONFIGURATION}`;
283
322
 
284
323
  const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
285
- const cacheJson = window.localStorage.getItem(localStorageKey);
324
+ const cacheJson = window.sessionStorage.getItem(localStorageKey);
286
325
 
287
326
  const oneHourMinisecond = 1000 * timeCacheSecond;
288
327
  // @ts-ignore
@@ -296,9 +335,8 @@ const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHou
296
335
  return null;
297
336
  }
298
337
 
299
-
300
338
  const result = await response.json();
301
- window.localStorage.setItem(localStorageKey, JSON.stringify({result, timestamp:Date.now()}));
339
+ window.sessionStorage.setItem(localStorageKey, JSON.stringify({result, timestamp:Date.now()}));
302
340
 
303
341
  return new OidcAuthorizationServiceConfiguration(result);
304
342
  }
@@ -345,6 +383,7 @@ export class Oidc {
345
383
  this.removeEventSubscription.bind(this);
346
384
  this.publishEvent.bind(this);
347
385
  this.destroyAsync.bind(this);
386
+ this.logoutAsync.bind(this);
348
387
  }
349
388
 
350
389
  subscriveEvents(func){
@@ -376,29 +415,29 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
376
415
  }
377
416
  static eventNames = eventNames;
378
417
 
379
- silentSigninCallbackFromIFrame(){
380
- if (this.configuration.silent_redirect_uri) {
418
+ silentLoginCallbackFromIFrame(){
419
+ if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
381
420
  const queryParams = getParseQueryStringFromLocation(window.location.href);
382
421
  window.top.postMessage(`${this.configurationName}_oidc_tokens:${JSON.stringify({tokens:this.tokens, sessionState:queryParams.session_state})}`, window.location.origin);
383
422
  }
384
423
  }
385
- silentSigninErrorCallbackFromIFrame(){
386
- if (this.configuration.silent_redirect_uri) {
424
+ silentLoginErrorCallbackFromIFrame(){
425
+ if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
387
426
  const queryParams = getParseQueryStringFromLocation(window.location.href);
388
427
  window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error:queryParams.error})}`, window.location.origin);
389
428
  }
390
429
  }
391
- async silentSigninAsync(extras:StringMap=null, state:string=null, scope:string=null) {
392
- if (!this.configuration.silent_redirect_uri || !this.configuration.silent_signin_uri) {
430
+ async silentLoginAsync(extras:StringMap=null, state:string=null, scope:string=null) {
431
+ if (!this.configuration.silent_redirect_uri || !this.configuration.silent_login_uri) {
393
432
  return Promise.resolve(null);
394
433
  }
395
434
  while (document.hidden) {
396
435
  await sleepAsync(1000);
397
- this.publishEvent(eventNames.silentSigninAsync, {message:"wait because document is hidden"});
436
+ this.publishEvent(eventNames.silentLoginAsync, {message:"wait because document is hidden"});
398
437
  }
399
438
 
400
439
  try {
401
- this.publishEvent(eventNames.silentSigninAsync_begin, {});
440
+ this.publishEvent(eventNames.silentLoginAsync_begin, {});
402
441
  const configuration = this.configuration
403
442
  let queries = "";
404
443
 
@@ -425,7 +464,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
425
464
  }
426
465
  }
427
466
  }
428
- const link = configuration.silent_signin_uri + queries;
467
+ const link = configuration.silent_login_uri + queries;
429
468
  const idx = link.indexOf("/", link.indexOf("//") + 2);
430
469
  const iFrameOrigin = link.substr(0, idx);
431
470
  const iframe = document.createElement('iframe');
@@ -450,14 +489,14 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
450
489
  if (!isResolved) {
451
490
  if(data.startsWith(key)) {
452
491
  const result = JSON.parse(e.data.replace(key, ''));
453
- self.publishEvent(eventNames.silentSigninAsync_end, {});
492
+ self.publishEvent(eventNames.silentLoginAsync_end, {});
454
493
  iframe.remove();
455
494
  isResolved = true;
456
495
  resolve(result);
457
496
  }
458
497
  else if(data.startsWith(key_error)) {
459
498
  const result = JSON.parse(e.data.replace(key_error, ''));
460
- self.publishEvent(eventNames.silentSigninAsync_error, result);
499
+ self.publishEvent(eventNames.silentLoginAsync_error, result);
461
500
  iframe.remove();
462
501
  isResolved = true;
463
502
  reject(result);
@@ -466,10 +505,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
466
505
  }
467
506
  }
468
507
  };
469
- const silentSigninTimeout = configuration.silent_signin_timeout ?? 12000
508
+ const silentSigninTimeout = configuration.silent_login_timeout ?? 12000
470
509
  setTimeout(() => {
471
510
  if (!isResolved) {
472
- self.publishEvent(eventNames.silentSigninAsync_error, "timeout");
511
+ self.publishEvent(eventNames.silentLoginAsync_error, "timeout");
473
512
  iframe.remove();
474
513
  isResolved = true;
475
514
  reject("timeout");
@@ -477,12 +516,12 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
477
516
  }, silentSigninTimeout);
478
517
  } catch (e) {
479
518
  iframe.remove();
480
- self.publishEvent(eventNames.silentSigninAsync_error, e);
519
+ self.publishEvent(eventNames.silentLoginAsync_error, e);
481
520
  reject(e);
482
521
  }
483
522
  });
484
523
  } catch (e) {
485
- this.publishEvent(eventNames.silentSigninAsync_error, e);
524
+ this.publishEvent(eventNames.silentLoginAsync_error, e);
486
525
  throw e;
487
526
  }
488
527
  }
@@ -672,12 +711,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
672
711
  this.loginPromise = null;
673
712
  return result;
674
713
  });
675
-
676
714
  }
677
715
 
678
716
  async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin=false){
679
717
  return new Promise((resolve:Function, reject) => {
680
- if (this.configuration.silent_signin_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
718
+ if (this.configuration.silent_login_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
681
719
  const checkSessionCallback = () => {
682
720
  this.checkSessionIFrame.stop();
683
721
 
@@ -688,7 +726,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
688
726
  const idToken = this.tokens.idToken;
689
727
  // @ts-ignore
690
728
  const idTokenPayload = this.tokens.idTokenPayload;
691
- this.silentSigninAsync({
729
+ this.silentLoginAsync({
692
730
  prompt: "none",
693
731
  id_token_hint: idToken,
694
732
  scope: "openid"
@@ -870,15 +908,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
870
908
  }
871
909
 
872
910
  async refreshTokensAsync(refreshToken) {
873
-
874
- /*while (document.hidden) {
875
- await sleepAsync(1000);
876
- this.publishEvent(eventNames.refreshTokensAsync, {message:"wait because document is hidden"});
877
- }*/
878
911
 
879
- const localSilentSigninAsync= async (exception=null) => {
912
+ const localsilentLoginAsync= async () => {
880
913
  try {
881
- const silent_token_response = await this.silentSigninAsync();
914
+ const silent_token_response = await this.silentLoginAsync();
882
915
  if (silent_token_response) {
883
916
  return silent_token_response.tokens;
884
917
  }
@@ -889,13 +922,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
889
922
  timer.clearTimeout(this.timeoutId);
890
923
  this.timeoutId=null;
891
924
  }
892
- this.publishEvent(eventNames.refreshTokensAsync_error, exception);
925
+ this.publishEvent(eventNames.refreshTokensAsync_error, {message: "refresh token and silent refresh failed"});
893
926
  return null;
894
927
  }
895
-
896
- try{
897
- this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken});
898
-
928
+
899
929
  const configuration = this.configuration;
900
930
  const clientId = configuration.client_id;
901
931
  const redirectUri = configuration.redirect_uri;
@@ -903,10 +933,9 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
903
933
 
904
934
  if(!refreshToken)
905
935
  {
906
- return await localSilentSigninAsync();
936
+ return await localsilentLoginAsync();
907
937
  }
908
938
 
909
-
910
939
  let extras = {};
911
940
  if(configuration.token_request_extras) {
912
941
  for (let [key, value] of Object.entries(configuration.token_request_extras)) {
@@ -914,73 +943,39 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
914
943
  }
915
944
  }
916
945
  const oidcServerConfiguration = await this.initAsync(authority, configuration.authority_configuration);
917
-
918
- /*const tokenHandler = new BaseTokenRequestHandler(new FetchRequestor());
919
- // use the token response to make a request for an access token
920
- const request = new TokenRequest({
946
+
947
+ const details = {
921
948
  client_id: clientId,
922
949
  redirect_uri: redirectUri,
923
950
  grant_type: GRANT_TYPE_REFRESH_TOKEN,
924
- code: undefined,
925
951
  refresh_token: refreshToken,
926
- extras
927
- });
952
+ };
928
953
 
929
-
930
- const token_response = await tokenHandler.performTokenRequest(oidcServerConfiguration, request);
931
- */
932
- const performTokenRequestAsync= async (url) => {
933
- const details = {
934
- client_id: clientId,
935
- redirect_uri: redirectUri,
936
- grant_type: GRANT_TYPE_REFRESH_TOKEN,
937
- refresh_token: refreshToken,
938
- };
939
-
940
- for (let [key, value] of Object.entries(extras)) {
941
- if (details[key] === undefined) {
942
- details[key] = value;
954
+ let index = 0;
955
+ while (index <=2) {
956
+ try {
957
+ this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken, tryNumber: index});
958
+ if(index > 1) {
959
+ while (document.hidden) {
960
+ await sleepAsync(1000);
961
+ this.publishEvent(eventNames.refreshTokensAsync, {message: "wait because document is hidden"});
962
+ }
943
963
  }
964
+ const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint, details, extras)
965
+ if (tokenResponse.success) {
966
+ this.publishEvent(eventNames.refreshTokensAsync_end, {success: tokenResponse.success});
967
+ return tokenResponse.data;
968
+ } else {
969
+ this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "bad request" , tokenResponse: tokenResponse});
970
+ return await localsilentLoginAsync();
971
+ }
972
+ } catch (exception) {
973
+ console.error(exception);
974
+ this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "exception" ,exception: exception.message});
944
975
  }
945
-
946
- let formBody = [];
947
- for (const property in details) {
948
- const encodedKey = encodeURIComponent(property);
949
- const encodedValue = encodeURIComponent(details[property]);
950
- formBody.push(`${encodedKey}=${encodedValue}`);
951
- }
952
- const formBodyString = formBody.join("&");
953
-
954
- const response = await internalFetch(url, {
955
- method: 'POST',
956
- headers: {
957
- 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
958
- },
959
- body: formBodyString,
960
- });
961
- if(response.status >= 299){
962
- throw new Error("Error refreshing token");
963
- }
964
- const result = await response.json();
965
- return {
966
- accessToken: result.access_token,
967
- expiresIn: result.expires_in,
968
- idToken: result.id_token,
969
- refreshToken: result.refresh_token,
970
- scope: result.scope,
971
- tokenType: result.token_type,
972
- };
976
+ index++;
973
977
  }
974
-
975
- const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint)
976
-
977
- this.publishEvent(eventNames.refreshTokensAsync_end, {message:"success"});
978
- return tokenResponse;
979
- } catch(exception) {
980
- console.error(exception);
981
- this.publishEvent(eventNames.refreshTokensAsync_silent_error, exception);
982
- return await localSilentSigninAsync(exception);
983
- }
978
+
984
979
  }
985
980
 
986
981
  syncTokensAsyncPromise=null;
@@ -1002,12 +997,12 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1002
997
  else if (isLogin == null){
1003
998
  try {
1004
999
  this.publishEvent(eventNames.syncTokensAsync_begin, {});
1005
- this.syncTokensAsyncPromise = this.silentSigninAsync({prompt:"none"});
1000
+ this.syncTokensAsyncPromise = this.silentLoginAsync({prompt:"none"});
1006
1001
  const silent_token_response = await this.syncTokensAsyncPromise;
1007
1002
  if (silent_token_response && silent_token_response.tokens) {
1008
1003
  this.tokens = await setTokensAsync(serviceWorker, silent_token_response.tokens);
1009
1004
  } else{
1010
- this.publishEvent(eventNames.syncTokensAsync_error, null);
1005
+ this.publishEvent(eventNames.syncTokensAsync_error, {message:"no token found in result"});
1011
1006
  if(this.timeoutId){
1012
1007
  timer.clearTimeout(this.timeoutId);
1013
1008
  this.timeoutId=null;
@@ -1,4 +0,0 @@
1
- import { ComponentType } from 'react';
2
- declare const SilentSignin: ComponentType<any>;
3
- export default SilentSignin;
4
- //# sourceMappingURL=SilentSignin.component.d.ts.map
@@ -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
- }
@@ -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;
package/src/FetchUser.tsx DELETED
@@ -1,53 +0,0 @@
1
- import React, {useEffect, useState} from 'react';
2
-
3
- import {useOidcFetch, withOidcFetch} from "./oidc/FetchToken";
4
- import {OidcSecure} from "./oidc";
5
-
6
- const DisplayUserInfo = ({ fetch }) => {
7
- const [oidcUser, setOidcUser] = useState(null);
8
- const [isLoading, setLoading] = useState(true);
9
-
10
- useEffect(() => {
11
- const fetchUserInfoAsync = async () => {
12
- const res = await fetch("https://demo.duendesoftware.com/connect/userinfo");
13
- if (res.status != 200) {
14
- return null;
15
- }
16
- return res.json();
17
- };
18
- let isMounted = true;
19
- fetchUserInfoAsync().then((userInfo) => {
20
- if(isMounted) {
21
- setLoading(false);
22
- setOidcUser(userInfo)
23
- }
24
- })
25
- return () => {
26
- isMounted = false;
27
- };
28
- },[]);
29
-
30
- if(isLoading){
31
- return <>Loading</>;
32
- }
33
-
34
- return (
35
- <div className="container mt-3">
36
- <div className="card text-white bg-success mb-3">
37
- <div className="card-body">
38
- <h5 className="card-title">User information</h5>
39
- {oidcUser != null && <p className="card-text">{JSON.stringify(oidcUser)}</p>}
40
- </div>
41
- </div>
42
- </div>
43
- )
44
- };
45
-
46
- const UserInfoWithFetchHoc = withOidcFetch(fetch)(DisplayUserInfo);
47
-
48
- export const FetchUserHoc= () => <OidcSecure><UserInfoWithFetchHoc/></OidcSecure>;
49
-
50
- export const FetchUserHook= () => {
51
- const {fetch} = useOidcFetch();
52
- return <OidcSecure><DisplayUserInfo fetch={fetch} /></OidcSecure>
53
- }