@axa-fr/react-oidc 6.11.2 → 6.11.4-alpha0

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.
@@ -22,102 +22,13 @@ import {
22
22
  computeTimeLeft,
23
23
  isTokensOidcValid,
24
24
  isTokensValid,
25
- parseOriginalTokens,
26
25
  setTokens, TokenRenewMode,
27
26
  Tokens,
28
27
  } from './parseTokens';
28
+ import { performRevocationRequestAsync, performTokenRequestAsync, TOKEN_TYPE } from './requests';
29
29
  import { getParseQueryStringFromLocation } from './route-utils';
30
30
  import timer from './timer';
31
31
 
32
- const TOKEN_TYPE = {
33
- refresh_token: 'refresh_token',
34
- access_token: 'access_token',
35
- };
36
-
37
- const performRevocationRequestAsync = async (url, token, token_type = TOKEN_TYPE.refresh_token, client_id, timeoutMs = 10000) => {
38
- const details = {
39
- token,
40
- token_type_hint: token_type,
41
- client_id,
42
- };
43
-
44
- const formBody = [];
45
- for (const property in details) {
46
- const encodedKey = encodeURIComponent(property);
47
- const encodedValue = encodeURIComponent(details[property]);
48
- formBody.push(`${encodedKey}=${encodedValue}`);
49
- }
50
- const formBodyString = formBody.join('&');
51
-
52
- const response = await internalFetch(url, {
53
- method: 'POST',
54
- headers: {
55
- 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
56
- },
57
- body: formBodyString,
58
- }, timeoutMs);
59
- if (response.status !== 200) {
60
- return { success: false };
61
- }
62
- return {
63
- success: true,
64
- };
65
- };
66
-
67
- const performTokenRequestAsync = async (url, details, extras, oldTokens, tokenRenewMode: string, timeoutMs = 10000) => {
68
- for (const [key, value] of Object.entries(extras)) {
69
- if (details[key] === undefined) {
70
- details[key] = value;
71
- }
72
- }
73
-
74
- const formBody = [];
75
- for (const property in details) {
76
- const encodedKey = encodeURIComponent(property);
77
- const encodedValue = encodeURIComponent(details[property]);
78
- formBody.push(`${encodedKey}=${encodedValue}`);
79
- }
80
- const formBodyString = formBody.join('&');
81
-
82
- const response = await internalFetch(url, {
83
- method: 'POST',
84
- headers: {
85
- 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
86
- },
87
- body: formBodyString,
88
- }, timeoutMs);
89
- if (response.status !== 200) {
90
- return { success: false, status: response.status };
91
- }
92
- const tokens = await response.json();
93
- return {
94
- success: true,
95
- data: parseOriginalTokens(tokens, oldTokens, tokenRenewMode),
96
- };
97
- };
98
-
99
- const internalFetch = async (url, headers, numberRetry = 0, timeoutMs = 10000) => {
100
- let response;
101
- try {
102
- const controller = new AbortController();
103
- setTimeout(() => controller.abort(), timeoutMs);
104
- response = await fetch(url, { ...headers, signal: controller.signal });
105
- } catch (e) {
106
- if (e.message === 'AbortError' ||
107
- e.message === 'Network request failed') {
108
- if (numberRetry <= 1) {
109
- return await internalFetch(url, headers, numberRetry + 1, timeoutMs);
110
- } else {
111
- throw e;
112
- }
113
- } else {
114
- console.error(e.message);
115
- throw e; // rethrow other unexpected errors
116
- }
117
- }
118
- return response;
119
- };
120
-
121
32
  const randomString = function(length) {
122
33
  let text = '';
123
34
  const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
@@ -209,9 +120,9 @@ async function renewTokensAndStartTimerAsync(oidc, refreshToken, forceRefresh =
209
120
  const updateTokens = (tokens) => { oidc.tokens = tokens; };
210
121
  const { tokens, status } = await oidc.synchroniseTokensAsync(refreshToken, 0, forceRefresh, extras, updateTokens);
211
122
 
212
- const serviceWorker = await initWorkerAsync(oidc.configuration.service_worker_relative_url, oidc.configurationName, oidc.configuration.redirect_uri);
123
+ const serviceWorker = await initWorkerAsync(oidc.configuration.service_worker_relative_url, oidc.configurationName);
213
124
  if (!serviceWorker) {
214
- const session = initSession(oidc.configurationName, oidc.configuration.redirect_uri, oidc.configuration.storage);
125
+ const session = initSession(oidc.configurationName, oidc.configuration.storage);
215
126
  await session.setTokens(oidc.tokens);
216
127
  }
217
128
 
@@ -534,7 +445,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
534
445
  });
535
446
  }
536
447
 
537
- const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName, this.configuration.redirect_uri);
448
+ const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName);
538
449
  const storage = serviceWorker ? window.localStorage : null;
539
450
  return await fetchFromIssuer(authority, this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60, storage);
540
451
  };
@@ -559,7 +470,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
559
470
  try {
560
471
  const configuration = this.configuration;
561
472
  const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
562
- serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName, configuration.redirect_uri);
473
+ serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
563
474
  if (serviceWorker) {
564
475
  const { tokens } = await serviceWorker.initAsync(oidcServerConfiguration, 'tryKeepExistingSessionAsync', configuration);
565
476
  if (tokens) {
@@ -587,7 +498,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
587
498
  message: 'service worker is not supported by this browser',
588
499
  });
589
500
  }
590
- const session = initSession(this.configurationName, configuration.redirect_uri, configuration.storage ?? sessionStorage);
501
+ const session = initSession(this.configurationName, configuration.storage ?? sessionStorage);
591
502
  const { tokens } = await session.initAsync();
592
503
  if (tokens) {
593
504
  // @ts-ignore
@@ -631,6 +542,8 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
631
542
  if (this.loginPromise !== null) {
632
543
  return this.loginPromise;
633
544
  }
545
+ const originExtras = extras;
546
+ extras = { ...extras };
634
547
  const loginLocalAsync = async () => {
635
548
  const location = window.location;
636
549
  const url = callbackPath || location.pathname + (location.search || '') + (location.hash || '');
@@ -640,6 +553,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
640
553
  state = extras.state;
641
554
  delete extras.state;
642
555
  }
556
+
643
557
  if (silentLoginOnly) {
644
558
  try {
645
559
  const extraFinal = extras ?? configuration.extras ?? {};
@@ -660,7 +574,14 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
660
574
  }
661
575
  }
662
576
  this.publishEvent(eventNames.loginAsync_begin, {});
663
-
577
+ console.log('extras', extras);
578
+ if (extras) {
579
+ for (const key of Object.keys(extras)) {
580
+ if (key.endsWith(':authorize_request')) {
581
+ delete extras[key];
582
+ }
583
+ }
584
+ }
664
585
  try {
665
586
  const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
666
587
  if (!scope) {
@@ -672,19 +593,20 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
672
593
  extraFinal.nonce = randomString(12);
673
594
  }
674
595
  const nonce = { nonce: extraFinal.nonce };
675
- const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName, this.configuration.redirect_uri);
596
+ const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
676
597
  const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
677
598
  let storage;
678
599
  if (serviceWorker) {
679
- serviceWorker.setLoginParams(this.configurationName, redirectUri, { callbackPath: url, extras, state });
600
+ serviceWorker.setLoginParams(this.configurationName, { callbackPath: url, extras: originExtras, state });
680
601
  serviceWorker.startKeepAliveServiceWorker();
681
602
  await serviceWorker.initAsync(oidcServerConfiguration, 'loginAsync', configuration);
682
603
  await serviceWorker.setNonceAsync(nonce);
683
604
  storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, {});
684
605
  await storage.setItem('dummy', {});
685
606
  } else {
686
- const session = initSession(this.configurationName, redirectUri);
687
- session.setLoginParams(this.configurationName, redirectUri, { callbackPath: url, extras, state });
607
+ let session = initSession(this.configurationName, configuration.storage ?? sessionStorage);
608
+ session.setLoginParams(this.configurationName, { callbackPath: url, extras: originExtras, state });
609
+ session = initSession(this.configurationName);
688
610
  await session.setNonceAsync(nonce);
689
611
  storage = new MemoryStorageBackend(session.saveItemsAsync, {});
690
612
  }
@@ -778,9 +700,9 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
778
700
  const parsedTokens = response.tokens;
779
701
  // @ts-ignore
780
702
  this.tokens = response.tokens;
781
- const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName, this.configuration.redirect_uri);
703
+ const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName);
782
704
  if (!serviceWorker) {
783
- const session = initSession(this.configurationName, this.configuration.redirect_uri, this.configuration.storage);
705
+ const session = initSession(this.configurationName, this.configuration.storage);
784
706
  session.setTokens(parsedTokens);
785
707
  }
786
708
  this.publishEvent(Oidc.eventNames.token_aquired, parsedTokens);
@@ -805,9 +727,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
805
727
  const oidcServerConfiguration = await this.initAsync(authority, configuration.authority_configuration);
806
728
  const queryParams = getParseQueryStringFromLocation(window.location.href);
807
729
  const sessionState = queryParams.session_state;
808
- const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName, configuration.redirect_uri);
730
+ const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
809
731
  let storage = null;
810
732
  let nonceData = null;
733
+ let getLoginParams = null;
811
734
  if (serviceWorker) {
812
735
  serviceWorker.startKeepAliveServiceWorker();
813
736
  await serviceWorker.initAsync(oidcServerConfiguration, 'loginCallbackAsync', configuration);
@@ -820,12 +743,14 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
820
743
  await storage.removeItem('dummy');
821
744
  await serviceWorker.setSessionStateAsync(sessionState);
822
745
  nonceData = await serviceWorker.getNonceAsync();
746
+ getLoginParams = serviceWorker.getLoginParams(this.configurationName);
823
747
  } else {
824
- const session = initSession(this.configurationName, redirectUri);
748
+ const session = initSession(this.configurationName);
825
749
  session.setSessionState(sessionState);
826
750
  const items = await session.loadItemsAsync();
827
751
  storage = new MemoryStorageBackend(session.saveItemsAsync, items);
828
752
  nonceData = await session.getNonceAsync();
753
+ getLoginParams = session.getLoginParams(this.configurationName);
829
754
  }
830
755
 
831
756
  return new Promise((resolve, reject) => {
@@ -859,6 +784,13 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
859
784
  extras[key] = value;
860
785
  }
861
786
  }
787
+ if (getLoginParams && getLoginParams.extras) {
788
+ for (const [key, value] of Object.entries(getLoginParams.extras)) {
789
+ if (key.endsWith(':authorize_request')) {
790
+ extras[key.replace(':token_request', '')] = value;
791
+ }
792
+ }
793
+ }
862
794
  }
863
795
 
864
796
  const tokenRequest = new TokenRequest({
@@ -884,11 +816,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
884
816
  let formattedTokens = null;
885
817
  if (serviceWorker) {
886
818
  const { tokens } = await serviceWorker.initAsync(oidcServerConfiguration, 'syncTokensAsync', configuration);
887
- loginParams = serviceWorker.getLoginParams(this.configurationName, redirectUri);
819
+ loginParams = serviceWorker.getLoginParams(this.configurationName);
888
820
  formattedTokens = tokens;
889
821
  } else {
890
- const session = initSession(this.configurationName, redirectUri, configuration.storage);
891
- loginParams = session.getLoginParams(this.configurationName, redirectUri);
822
+ const session = initSession(this.configurationName, configuration.storage);
823
+ loginParams = session.getLoginParams(this.configurationName);
892
824
  formattedTokens = setTokens(tokenResponse, null, configuration.token_renew_mode);
893
825
  }
894
826
  if (!isTokensOidcValid(formattedTokens, nonceData.nonce, oidcServerConfiguration)) {
@@ -957,12 +889,12 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
957
889
  const localsilentLoginAsync = async () => {
958
890
  try {
959
891
  let loginParams = null;
960
- const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName, configuration.redirect_uri);
892
+ const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
961
893
  if (serviceWorker) {
962
- loginParams = serviceWorker.getLoginParams(this.configurationName, configuration.redirect_uri);
894
+ loginParams = serviceWorker.getLoginParams(this.configurationName);
963
895
  } else {
964
- const session = initSession(this.configurationName, configuration.redirect_uri, configuration.storage);
965
- loginParams = session.getLoginParams(this.configurationName, configuration.redirect_uri);
896
+ const session = initSession(this.configurationName, configuration.storage);
897
+ loginParams = session.getLoginParams(this.configurationName);
966
898
  }
967
899
  const silent_token_response = await this.silentLoginAsync({
968
900
  ...loginParams.extras,
@@ -1074,7 +1006,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1074
1006
  }
1075
1007
  let nonce = nullNonce;
1076
1008
  const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
1077
- const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, configurationName, configuration.redirect_uri);
1009
+ const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, configurationName);
1078
1010
  if (serviceWorker) {
1079
1011
  const { status, tokens } = await serviceWorker.initAsync(oidcServerConfiguration, 'syncTokensAsync', configuration);
1080
1012
  if (status === 'LOGGED_OUT') {
@@ -1091,7 +1023,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1091
1023
  }
1092
1024
  nonce = await serviceWorker.getNonceAsync();
1093
1025
  } else {
1094
- const session = initSession(configurationName, configuration.redirect_uri, configuration.storage ?? sessionStorage);
1026
+ const session = initSession(configurationName, configuration.storage ?? sessionStorage);
1095
1027
  const { tokens, status } = await session.initAsync();
1096
1028
  if (!tokens) {
1097
1029
  return { tokens: null, status: 'LOGOUT_FROM_ANOTHER_TAB', nonce: nullNonce };
@@ -1153,9 +1085,9 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1153
1085
  if (this.checkSessionIFrame) {
1154
1086
  this.checkSessionIFrame.stop();
1155
1087
  }
1156
- const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName, this.configuration.redirect_uri);
1088
+ const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName);
1157
1089
  if (!serviceWorker) {
1158
- const session = initSession(this.configurationName, this.configuration.redirect_uri, this.configuration.storage);
1090
+ const session = initSession(this.configurationName, this.configuration.storage);
1159
1091
  await session.clearAsync(status);
1160
1092
  } else {
1161
1093
  await serviceWorker.clearAsync(status);
@@ -0,0 +1,90 @@
1
+ import { parseOriginalTokens } from './parseTokens';
2
+
3
+ const internalFetch = async (url, headers, numberRetry = 0, timeoutMs = 10000) => {
4
+ let response;
5
+ try {
6
+ const controller = new AbortController();
7
+ setTimeout(() => controller.abort(), timeoutMs);
8
+ response = await fetch(url, { ...headers, signal: controller.signal });
9
+ } catch (e) {
10
+ if (e.message === 'AbortError' ||
11
+ e.message === 'Network request failed') {
12
+ if (numberRetry <= 1) {
13
+ return await internalFetch(url, headers, numberRetry + 1, timeoutMs);
14
+ } else {
15
+ throw e;
16
+ }
17
+ } else {
18
+ console.error(e.message);
19
+ throw e; // rethrow other unexpected errors
20
+ }
21
+ }
22
+ return response;
23
+ };
24
+
25
+ export const TOKEN_TYPE = {
26
+ refresh_token: 'refresh_token',
27
+ access_token: 'access_token',
28
+ };
29
+
30
+ export const performRevocationRequestAsync = async (url, token, token_type = TOKEN_TYPE.refresh_token, client_id, timeoutMs = 10000) => {
31
+ const details = {
32
+ token,
33
+ token_type_hint: token_type,
34
+ client_id,
35
+ };
36
+
37
+ const formBody = [];
38
+ for (const property in details) {
39
+ const encodedKey = encodeURIComponent(property);
40
+ const encodedValue = encodeURIComponent(details[property]);
41
+ formBody.push(`${encodedKey}=${encodedValue}`);
42
+ }
43
+ const formBodyString = formBody.join('&');
44
+
45
+ const response = await internalFetch(url, {
46
+ method: 'POST',
47
+ headers: {
48
+ 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
49
+ },
50
+ body: formBodyString,
51
+ }, timeoutMs);
52
+ if (response.status !== 200) {
53
+ return { success: false };
54
+ }
55
+ return {
56
+ success: true,
57
+ };
58
+ };
59
+
60
+ export const performTokenRequestAsync = async (url, details, extras, oldTokens, tokenRenewMode: string, timeoutMs = 10000) => {
61
+ for (const [key, value] of Object.entries(extras)) {
62
+ if (details[key] === undefined) {
63
+ details[key] = value;
64
+ }
65
+ }
66
+
67
+ const formBody = [];
68
+ for (const property in details) {
69
+ const encodedKey = encodeURIComponent(property);
70
+ const encodedValue = encodeURIComponent(details[property]);
71
+ formBody.push(`${encodedKey}=${encodedValue}`);
72
+ }
73
+ const formBodyString = formBody.join('&');
74
+
75
+ const response = await internalFetch(url, {
76
+ method: 'POST',
77
+ headers: {
78
+ 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
79
+ },
80
+ body: formBodyString,
81
+ }, timeoutMs);
82
+ if (response.status !== 200) {
83
+ return { success: false, status: response.status };
84
+ }
85
+ const tokens = await response.json();
86
+ return {
87
+ success: true,
88
+ data: parseOriginalTokens(tokens, oldTokens, tokenRenewMode),
89
+ };
90
+ };
@@ -72,7 +72,7 @@ const parseQueryString = (queryString:string) => {
72
72
  // Convert the array of strings into an object
73
73
  for (i = 0, l = queries.length; i < l; i++) {
74
74
  temp = queries[i].split('=');
75
- params[temp[0]] = temp[1];
75
+ params[decodeURIComponent(temp[0])] = temp[1];
76
76
  }
77
77
 
78
78
  return params;