@axa-fr/react-oidc 6.5.0-beta0 → 6.5.1

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.
@@ -21,7 +21,7 @@ import {getParseQueryStringFromLocation} from "./route-utils";
21
21
  import {AuthorizationServiceConfigurationJson} from "@openid/appauth/src/authorization_service_configuration";
22
22
  import {computeTimeLeft, isTokensOidcValid, isTokensValid, parseOriginalTokens, setTokens} from "./parseTokens";
23
23
 
24
- const performTokenRequestAsync= async (url, details, extras) => {
24
+ const performTokenRequestAsync= async (url, details, extras, oldTokens) => {
25
25
 
26
26
  for (let [key, value] of Object.entries(extras)) {
27
27
  if (details[key] === undefined) {
@@ -42,7 +42,6 @@ const performTokenRequestAsync= async (url, details, extras) => {
42
42
  headers: {
43
43
  'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
44
44
  },
45
- //mode: 'cors',
46
45
  body: formBodyString,
47
46
  });
48
47
  if(response.status !== 200){
@@ -51,7 +50,7 @@ const performTokenRequestAsync= async (url, details, extras) => {
51
50
  const tokens = await response.json();
52
51
  return {
53
52
  success : true,
54
- data: parseOriginalTokens(tokens)
53
+ data: parseOriginalTokens(tokens, oldTokens)
55
54
  };
56
55
  }
57
56
 
@@ -154,12 +153,12 @@ const loginCallbackWithAutoTokensRenewAsync = async (oidc) => {
154
153
  return { state, callbackPath };
155
154
  }
156
155
 
157
- async function renewTokensAndStartTimerAsync(oidc, refreshToken, forceRefresh =false) {
158
- const {tokens, status} = await oidc.synchroniseTokensAsync(refreshToken, 0, forceRefresh);
156
+ async function renewTokensAndStartTimerAsync(oidc, refreshToken, forceRefresh =false, extras:StringMap=null) {
157
+ const {tokens, status} = await oidc.synchroniseTokensAsync(refreshToken, 0, forceRefresh, extras);
159
158
  oidc.tokens = tokens;
160
159
  const serviceWorker = await initWorkerAsync(oidc.configuration.service_worker_relative_url, oidc.configurationName);
161
160
  if (!serviceWorker) {
162
- const session = initSession(this.configurationName, oidc.configuration.redirect_uri, oidc.configuration.storage);
161
+ const session = initSession(oidc.configurationName, oidc.configuration.redirect_uri, oidc.configuration.storage);
163
162
  await session.setTokens(oidc.tokens);
164
163
  }
165
164
 
@@ -169,17 +168,17 @@ async function renewTokensAndStartTimerAsync(oidc, refreshToken, forceRefresh =f
169
168
  }
170
169
 
171
170
  if (oidc.timeoutId) {
172
- oidc.timeoutId = autoRenewTokens(oidc, tokens.refreshToken, oidc.tokens.expiresAt);
171
+ oidc.timeoutId = autoRenewTokens(oidc, tokens.refreshToken, oidc.tokens.expiresAt, extras);
173
172
  }
174
173
  }
175
174
 
176
- const autoRenewTokens = (oidc, refreshToken, expiresAt) => {
175
+ const autoRenewTokens = (oidc, refreshToken, expiresAt, extras:StringMap=null) => {
177
176
  const refreshTimeBeforeTokensExpirationInSecond = oidc.configuration.refresh_time_before_tokens_expiration_in_second;
178
177
  return timer.setTimeout(async () => {
179
178
  const timeLeft = computeTimeLeft(refreshTimeBeforeTokensExpirationInSecond, expiresAt);
180
179
  const timeInfo = { timeLeft };
181
180
  oidc.publishEvent(Oidc.eventNames.token_timer, timeInfo);
182
- await renewTokensAndStartTimerAsync(oidc, refreshToken);
181
+ await renewTokensAndStartTimerAsync(oidc, refreshToken, false, extras);
183
182
  }, 1000);
184
183
  }
185
184
 
@@ -224,7 +223,6 @@ const userInfoAsync = async (oidc) => {
224
223
  const res = await fetch(url, {
225
224
  headers: {
226
225
  authorization: `Bearer ${accessToken}`,
227
- // credentials: 'include'
228
226
  }
229
227
  });
230
228
 
@@ -328,9 +326,7 @@ export class Oidc {
328
326
  public tokens: null;
329
327
  public events: Array<any>;
330
328
  private timeoutId: NodeJS.Timeout;
331
- //private serviceWorker?: any;
332
329
  private configurationName: string;
333
- //private session?: any;
334
330
  private checkSessionIFrame: CheckSessionIFrame;
335
331
  constructor(configuration:OidcConfiguration, configurationName="default") {
336
332
  let silent_login_uri = configuration.silent_login_uri;
@@ -349,8 +345,6 @@ export class Oidc {
349
345
  this.userInfo = null;
350
346
  this.events = [];
351
347
  this.timeoutId = null;
352
- //this.serviceWorker = null;
353
- //this.session = null;
354
348
  this.synchroniseTokensAsync.bind(this);
355
349
  this.loginCallbackWithAutoTokensRenewAsync.bind(this);
356
350
  this.initAsync.bind(this);
@@ -563,7 +557,6 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
563
557
  serviceWorker.startKeepAliveServiceWorker();
564
558
  // @ts-ignore
565
559
  this.tokens = tokens;
566
- //this.serviceWorker = serviceWorker;
567
560
  // @ts-ignore
568
561
  this.timeoutId = autoRenewTokens(this, this.tokens.refreshToken, this.tokens.expiresAt);
569
562
  const sessionState = await serviceWorker.getSessionStateAsync();
@@ -590,8 +583,6 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
590
583
  if (tokens) {
591
584
  // @ts-ignore
592
585
  this.tokens = setTokens(tokens);
593
- //session.setTokens(this.tokens);
594
- //this.session = session;
595
586
  // @ts-ignore
596
587
  this.timeoutId = autoRenewTokens(this, tokens.refreshToken, this.tokens.expiresAt);
597
588
  const sessionState = session.getSessionState();
@@ -627,7 +618,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
627
618
  }
628
619
 
629
620
  loginPromise: Promise<any>=null;
630
- async loginAsync(callbackPath:string=undefined, extras:StringMap=null, state:string=undefined, isSilentSignin:boolean=false, scope:string=undefined, silentLoginOnly = false) {
621
+ async loginAsync(callbackPath:string=undefined, extras:StringMap=null, isSilentSignin:boolean=false, scope:string=undefined, silentLoginOnly = false) {
631
622
  if(this.loginPromise !== null){
632
623
  return this.loginPromise;
633
624
  }
@@ -638,6 +629,12 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
638
629
  const url = callbackPath || location.pathname + (location.search || '') + (location.hash || '');
639
630
 
640
631
  const configuration = this.configuration;
632
+ let state = undefined;
633
+ if(extras && "state" in extras){
634
+ state = extras["state"];
635
+ delete extras["state"];
636
+ }
637
+
641
638
 
642
639
  if(silentLoginOnly){
643
640
  try {
@@ -651,7 +648,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
651
648
  this.tokens = silentResult.tokens;
652
649
  this.publishEvent(eventNames.token_aquired, {});
653
650
  // @ts-ignore
654
- this.timeoutId = autoRenewTokens(this, this.tokens.refreshToken, this.tokens.expiresAt);
651
+ this.timeoutId = autoRenewTokens(this, this.tokens.refreshToken, this.tokens.expiresAt, extras);
655
652
  return {};
656
653
  }
657
654
  }catch (e) {
@@ -825,7 +822,6 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
825
822
  let nonceData = null;
826
823
  if(serviceWorker){
827
824
  serviceWorker.startKeepAliveServiceWorker();
828
- //const serviceWorker = serviceWorker;
829
825
  await serviceWorker.initAsync(oidcServerConfiguration, "loginCallbackAsync");
830
826
  const items = await serviceWorker.loadItemsAsync();
831
827
  storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, items);
@@ -837,7 +833,6 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
837
833
  await serviceWorker.setSessionStateAsync(sessionState);
838
834
  nonceData = await serviceWorker.getNonceAsync();
839
835
  }else{
840
- //this.session = initSession(this.configurationName, redirectUri, configuration.storage ?? sessionStorage);
841
836
  const session = initSession(this.configurationName, redirectUri);
842
837
  session.setSessionState(sessionState);
843
838
  const items = await session.loadItemsAsync();
@@ -946,7 +941,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
946
941
  }
947
942
  }
948
943
 
949
- async synchroniseTokensAsync(refreshToken, index=0, forceRefresh =false) {
944
+ async synchroniseTokensAsync(refreshToken, index=0, forceRefresh =false, extras:StringMap=null) {
950
945
 
951
946
  if (document.hidden) {
952
947
  await sleepAsync(1000);
@@ -959,13 +954,17 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
959
954
  numberTryOnline--;
960
955
  this.publishEvent(eventNames.refreshTokensAsync, {message: `wait because navigator is offline try ${numberTryOnline}` });
961
956
  }
962
-
957
+ if(!extras){
958
+ extras = {}
959
+ }
963
960
  const configuration = this.configuration;
964
961
  const localsilentLoginAsync= async () => {
965
962
  try {
966
963
  const loginParams = getLoginParams(this.configurationName, configuration.redirect_uri);
964
+
967
965
  const silent_token_response = await this.silentLoginAsync({
968
966
  ...loginParams.extras,
967
+ ...extras,
969
968
  prompt: "none"
970
969
  }, loginParams.state);
971
970
  if (silent_token_response) {
@@ -988,7 +987,6 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
988
987
 
989
988
  if (index <=4) {
990
989
  try {
991
-
992
990
  const { status, tokens } = await this.syncTokensInfoAsync(configuration, this.configurationName, this.tokens, forceRefresh);
993
991
  switch (status) {
994
992
  case "SESSION_LOST":
@@ -1017,12 +1015,9 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1017
1015
  const clientId = configuration.client_id;
1018
1016
  const redirectUri = configuration.redirect_uri;
1019
1017
  const authority = configuration.authority;
1020
- let extras = {};
1021
- if(configuration.token_request_extras) {
1022
- for (let [key, value] of Object.entries(configuration.token_request_extras)) {
1023
- extras[key] = value;
1024
- }
1025
- }
1018
+ const tokenExtras = configuration.token_request_extras ? configuration.token_request_extras : {};
1019
+ let finalExtras = {...tokenExtras, ...extras};
1020
+
1026
1021
  const details = {
1027
1022
  client_id: clientId,
1028
1023
  redirect_uri: redirectUri,
@@ -1030,7 +1025,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1030
1025
  refresh_token: tokens.refreshToken,
1031
1026
  };
1032
1027
  const oidcServerConfiguration = await this.initAsync(authority, configuration.authority_configuration);
1033
- const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint, details, extras)
1028
+ const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint, details, finalExtras, tokens);
1034
1029
  if (tokenResponse.success) {
1035
1030
  if(!isTokensOidcValid(tokenResponse.data, null, oidcServerConfiguration)){
1036
1031
  this.publishEvent(eventNames.refreshTokensAsync_error, {message: `refresh token return not valid tokens` });
@@ -1127,13 +1122,13 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1127
1122
  })
1128
1123
  }
1129
1124
 
1130
- async renewTokensAsync (){
1125
+ async renewTokensAsync (extras:StringMap=null){
1131
1126
  if(!this.timeoutId){
1132
1127
  return;
1133
1128
  }
1134
1129
  timer.clearTimeout(this.timeoutId);
1135
1130
  // @ts-ignore
1136
- await renewTokensAndStartTimerAsync(this, this.tokens.refreshToken, true);
1131
+ await renewTokensAndStartTimerAsync(this, this.tokens.refreshToken, true, extras);
1137
1132
  }
1138
1133
 
1139
1134
  async destroyAsync(status) {
@@ -33,7 +33,7 @@ const extractAccessTokenPayload = tokens => {
33
33
  };
34
34
 
35
35
 
36
- export const setTokens = (tokens) =>{
36
+ export const setTokens = (tokens, oldTokens=null) =>{
37
37
 
38
38
  if(!tokens){
39
39
  return null;
@@ -57,12 +57,19 @@ export const setTokens = (tokens) =>{
57
57
  const accessTokenExpiresAt = (accessTokenPayload && accessTokenPayload.exp)? accessTokenPayload.exp : tokens.issuedAt + tokens.expiresIn;
58
58
  const expiresAt = idTokenExipreAt < accessTokenExpiresAt ? idTokenExipreAt : accessTokenExpiresAt;
59
59
 
60
- return {...tokens, idTokenPayload: _idTokenPayload, accessTokenPayload, expiresAt};
60
+ const newTokens = {...tokens, idTokenPayload: _idTokenPayload, accessTokenPayload, expiresAt};
61
+ // When refresh_token is not rotated we reuse ald refresh_token
62
+ if(oldTokens != null && "refreshToken" in oldTokens && !("refreshToken" in tokens)){
63
+ const refreshToken = oldTokens.refreshToken
64
+ return {...newTokens, refreshToken};
65
+ }
66
+
67
+ return newTokens;
61
68
  }
62
69
 
63
70
 
64
71
 
65
- export const parseOriginalTokens= (tokens) =>{
72
+ export const parseOriginalTokens= (tokens, oldTokens) =>{
66
73
  if(!tokens){
67
74
  return null;
68
75
  }
@@ -75,12 +82,16 @@ export const parseOriginalTokens= (tokens) =>{
75
82
  accessToken: tokens.access_token,
76
83
  expiresIn: tokens.expires_in,
77
84
  idToken: tokens.id_token,
78
- refreshToken: tokens.refresh_token,
79
85
  scope: tokens.scope,
80
86
  tokenType: tokens.token_type,
81
87
  issuedAt: tokens.issued_at
82
88
  };
83
89
 
90
+ if("refresh_token" in tokens) {
91
+ // @ts-ignore
92
+ data.refreshToken= tokens.refresh_token;
93
+ }
94
+
84
95
 
85
96
  if(tokens.accessTokenPayload !== undefined){
86
97
  // @ts-ignore
@@ -92,7 +103,7 @@ export const parseOriginalTokens= (tokens) =>{
92
103
  data.idTokenPayload = tokens.idTokenPayload;
93
104
  }
94
105
 
95
- return setTokens(data);
106
+ return setTokens(data, oldTokens);
96
107
  }
97
108
 
98
109
  export const computeTimeLeft = (refreshTimeBeforeTokensExpirationInSecond, expiresAt)=>{