@axa-fr/react-oidc 6.0.0-beta9 → 6.0.2

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 (54) hide show
  1. package/README.md +13 -12
  2. package/dist/FetchToken.d.ts.map +1 -1
  3. package/dist/FetchToken.js +10 -6
  4. package/dist/FetchToken.js.map +1 -1
  5. package/dist/OidcProvider.d.ts +1 -0
  6. package/dist/OidcProvider.d.ts.map +1 -1
  7. package/dist/OidcProvider.js +11 -4
  8. package/dist/OidcProvider.js.map +1 -1
  9. package/dist/OidcSecure.js +2 -2
  10. package/dist/OidcSecure.js.map +1 -1
  11. package/dist/OidcServiceWorker.js +62 -32
  12. package/dist/OidcTrustedDomains.js +7 -2
  13. package/dist/ReactOidc.d.ts.map +1 -1
  14. package/dist/ReactOidc.js +4 -3
  15. package/dist/ReactOidc.js.map +1 -1
  16. package/dist/core/default-component/SilentLogin.component.js +1 -1
  17. package/dist/core/default-component/SilentLogin.component.js.map +1 -1
  18. package/dist/core/routes/OidcRoutes.d.ts.map +1 -1
  19. package/dist/core/routes/OidcRoutes.js +1 -4
  20. package/dist/core/routes/OidcRoutes.js.map +1 -1
  21. package/dist/vanilla/initSession.d.ts +2 -1
  22. package/dist/vanilla/initSession.d.ts.map +1 -1
  23. package/dist/vanilla/initSession.js +7 -7
  24. package/dist/vanilla/initSession.js.map +1 -1
  25. package/dist/vanilla/initWorker.d.ts +2 -3
  26. package/dist/vanilla/initWorker.d.ts.map +1 -1
  27. package/dist/vanilla/initWorker.js +6 -21
  28. package/dist/vanilla/initWorker.js.map +1 -1
  29. package/dist/vanilla/oidc.d.ts +10 -5
  30. package/dist/vanilla/oidc.d.ts.map +1 -1
  31. package/dist/vanilla/oidc.js +463 -492
  32. package/dist/vanilla/oidc.js.map +1 -1
  33. package/dist/vanilla/parseTokens.d.ts +5 -0
  34. package/dist/vanilla/parseTokens.d.ts.map +1 -0
  35. package/dist/vanilla/parseTokens.js +107 -0
  36. package/dist/vanilla/parseTokens.js.map +1 -0
  37. package/package.json +3 -3
  38. package/src/oidc/FetchToken.tsx +7 -4
  39. package/src/oidc/OidcProvider.tsx +9 -0
  40. package/src/oidc/OidcSecure.tsx +2 -2
  41. package/src/oidc/ReactOidc.tsx +4 -3
  42. package/src/oidc/core/default-component/SilentLogin.component.tsx +1 -1
  43. package/src/oidc/core/routes/OidcRoutes.tsx +0 -4
  44. package/src/oidc/vanilla/OidcServiceWorker.js +62 -32
  45. package/src/oidc/vanilla/OidcTrustedDomains.js +7 -2
  46. package/src/oidc/vanilla/initSession.ts +6 -7
  47. package/src/oidc/vanilla/initWorker.ts +6 -15
  48. package/src/oidc/vanilla/oidc.ts +220 -277
  49. package/src/oidc/vanilla/parseTokens.ts +107 -0
  50. package/dist/core/default-component/ServiceWorkerInstall.component.d.ts +0 -4
  51. package/dist/core/default-component/ServiceWorkerInstall.component.d.ts.map +0 -1
  52. package/dist/core/default-component/ServiceWorkerInstall.component.js +0 -131
  53. package/dist/core/default-component/ServiceWorkerInstall.component.js.map +0 -1
  54. package/src/oidc/core/default-component/ServiceWorkerInstall.component.tsx +0 -60
@@ -18,7 +18,7 @@ let database = {
18
18
  default: {
19
19
  configurationName: "default",
20
20
  tokens: null,
21
- isLogin:null,
21
+ status:null,
22
22
  items:[],
23
23
  oidcServerConfiguration: null
24
24
  }
@@ -28,7 +28,7 @@ const countLetter = (str, find)=> {
28
28
  return (str.split(find)).length - 1;
29
29
  }
30
30
 
31
- function extractAccessTokenPayload(accessToken) {
31
+ const extractTokenPayload=(accessToken)=> {
32
32
  try{
33
33
  if (!accessToken) {
34
34
  return null;
@@ -44,6 +44,18 @@ function extractAccessTokenPayload(accessToken) {
44
44
  return null;
45
45
  }
46
46
 
47
+ const computeTimeLeft = (refreshTimeBeforeTokensExpirationInSecond, expiresAt)=>{
48
+ const currentTimeUnixSecond = new Date().getTime() /1000;
49
+ return Math.round(((expiresAt - refreshTimeBeforeTokensExpirationInSecond) - currentTimeUnixSecond));
50
+ }
51
+
52
+ const isTokensValid= (tokens) =>{
53
+ if(!tokens){
54
+ return false;
55
+ }
56
+ return computeTimeLeft(0, tokens.expiresAt) > 0;
57
+ }
58
+
47
59
  function hideTokens(currentDatabaseElement) {
48
60
  const configurationName = currentDatabaseElement.configurationName;
49
61
  return (response) => {
@@ -52,17 +64,33 @@ function hideTokens(currentDatabaseElement) {
52
64
  const currentTimeUnixSecond = new Date().getTime() /1000;
53
65
  tokens.issued_at = currentTimeUnixSecond;
54
66
  }
55
- currentDatabaseElement.tokens = tokens;
56
- currentDatabaseElement.isLogin = true;
67
+
68
+ const accessTokenPayload = extractTokenPayload(tokens.access_token);
57
69
  const secureTokens = {
58
70
  ...tokens,
59
71
  access_token: ACCESS_TOKEN +"_" + configurationName,
72
+ accessTokenPayload : accessTokenPayload
60
73
  };
74
+ tokens.accessTokenPayload = accessTokenPayload;
75
+
76
+ let _idTokenPayload = null;
77
+ if(tokens.id_token) {
78
+ _idTokenPayload = extractTokenPayload(tokens.id_token);
79
+ secureTokens.idTokenPayload = _idTokenPayload;
80
+ tokens.idTokenPayload = _idTokenPayload;
81
+ }
61
82
  if(tokens.refresh_token){
62
83
  secureTokens.refresh_token = REFRESH_TOKEN + "_" + configurationName;
63
84
  }
64
-
65
- const body = JSON.stringify(secureTokens)
85
+
86
+ const idTokenExpiresAt =(_idTokenPayload && _idTokenPayload.exp) ? _idTokenPayload.exp: Number.MAX_VALUE;
87
+ const accessTokenExpiresAt = (accessTokenPayload && accessTokenPayload.exp)? accessTokenPayload.exp : tokens.issuedAt + tokens.expiresIn;
88
+ const expiresAt = idTokenExpiresAt < accessTokenExpiresAt ? idTokenExpiresAt : accessTokenExpiresAt;
89
+ secureTokens.expiresAt = expiresAt;
90
+ const body = JSON.stringify(secureTokens);
91
+ tokens.expiresAt = expiresAt;
92
+ currentDatabaseElement.tokens = tokens;
93
+ currentDatabaseElement.status = "LOGGED_IN";
66
94
  return new Response(body, response);
67
95
  });
68
96
  };
@@ -157,6 +185,10 @@ const handleFetch = async (event) => {
157
185
 
158
186
  const currentDatabaseForRequestAccessToken = getCurrentDatabaseDomain(database, originalRequest.url);
159
187
  if(currentDatabaseForRequestAccessToken && currentDatabaseForRequestAccessToken.tokens) {
188
+
189
+ while (currentDatabaseForRequestAccessToken.tokens && !isTokensValid(currentDatabaseForRequestAccessToken.tokens)){
190
+ await sleep(200);
191
+ }
160
192
  const newRequest = new Request(originalRequest, {
161
193
  headers: {
162
194
  ...serializeHeaders(originalRequest.headers),
@@ -175,7 +207,8 @@ const handleFetch = async (event) => {
175
207
  const numberDatabase = currentDatabases.length;
176
208
  if(numberDatabase > 0) {
177
209
  const maPromesse = new Promise((resolve, reject) => {
178
- const response = originalRequest.clone().text().then(actualBody => {
210
+ const clonedRequest = originalRequest.clone();
211
+ const response = clonedRequest.text().then(actualBody => {
179
212
  if(actualBody.includes(REFRESH_TOKEN)) {
180
213
  let newBody = actualBody;
181
214
  for(let i= 0;i<numberDatabase;i++){
@@ -188,34 +221,34 @@ const handleFetch = async (event) => {
188
221
  }
189
222
  }
190
223
 
191
- return fetch(originalRequest, {
224
+ return fetch(clonedRequest, {
192
225
  body: newBody,
193
- method: originalRequest.method,
226
+ method: clonedRequest.method,
194
227
  headers: {
195
228
  ...serializeHeaders(originalRequest.headers),
196
229
  },
197
- mode: originalRequest.mode,
198
- cache: originalRequest.cache,
199
- redirect: originalRequest.redirect,
200
- referrer: originalRequest.referrer,
201
- credentials: originalRequest.credentials,
202
- integrity: originalRequest.integrity
230
+ mode: clonedRequest.mode,
231
+ cache: clonedRequest.cache,
232
+ redirect: clonedRequest.redirect,
233
+ referrer: clonedRequest.referrer,
234
+ credentials: clonedRequest.credentials,
235
+ integrity: clonedRequest.integrity
203
236
  }).then(hideTokens(currentDatabase));
204
237
  } else if(actualBody.includes("code_verifier=") && currentLoginCallbackConfigurationName){
205
238
  currentDatabase = database[currentLoginCallbackConfigurationName];
206
239
  currentLoginCallbackConfigurationName=null;
207
- return fetch(originalRequest,{
240
+ return fetch(clonedRequest,{
208
241
  body: actualBody,
209
- method: originalRequest.method,
242
+ method: clonedRequest.method,
210
243
  headers: {
211
244
  ...serializeHeaders(originalRequest.headers),
212
245
  },
213
- mode: originalRequest.mode,
214
- cache: originalRequest.cache,
215
- redirect: originalRequest.redirect,
216
- referrer: originalRequest.referrer,
217
- credentials: originalRequest.credentials,
218
- integrity: originalRequest.integrity
246
+ mode: clonedRequest.mode,
247
+ cache: clonedRequest.cache,
248
+ redirect: clonedRequest.redirect,
249
+ referrer: clonedRequest.referrer,
250
+ credentials: clonedRequest.credentials,
251
+ integrity: clonedRequest.integrity
219
252
  }).then(hideTokens(currentDatabase));
220
253
  }
221
254
  });
@@ -267,7 +300,7 @@ addEventListener('message', event => {
267
300
  tokens: null,
268
301
  items:[],
269
302
  oidcServerConfiguration: null,
270
- isLogin:null,
303
+ status:null,
271
304
  configurationName: configurationName,
272
305
  };
273
306
  currentDatabase = database[configurationName];
@@ -282,7 +315,7 @@ addEventListener('message', event => {
282
315
  case "clear":
283
316
  currentDatabase.tokens = null;
284
317
  currentDatabase.items = null;
285
- currentDatabase.isLogin = false;
318
+ currentDatabase.status = data.data.status;
286
319
  port.postMessage({configurationName});
287
320
  return;
288
321
  case "init":
@@ -299,10 +332,11 @@ addEventListener('message', event => {
299
332
  } else{
300
333
  currentLoginCallbackConfigurationName = null;
301
334
  }
335
+
302
336
  if(!currentDatabase.tokens){
303
337
  port.postMessage({
304
338
  tokens:null,
305
- isLogin: currentDatabase.isLogin,
339
+ status: currentDatabase.status,
306
340
  configurationName});
307
341
  } else {
308
342
  const tokens = {
@@ -314,16 +348,12 @@ addEventListener('message', event => {
314
348
  }
315
349
  port.postMessage({
316
350
  tokens,
317
- isLogin: currentDatabase.isLogin,
351
+ status: currentDatabase.status,
318
352
  configurationName
319
353
  });
320
354
  }
321
355
  return;
322
-
323
- case "getAccessTokenPayload":
324
- const accessTokenPayload = extractAccessTokenPayload(currentDatabase.tokens.access_token);
325
- port.postMessage({configurationName, accessTokenPayload});
326
- return;
356
+
327
357
  case "setSessionState":
328
358
  currentDatabase.sessionState = data.data.sessionState;
329
359
  port.postMessage({configurationName});
@@ -1,9 +1,14 @@
1
1
  
2
- // Add here trusted domains, access tokens will be send to
2
+ // Add bellow trusted domains, access tokens will automatically injected to be send to
3
+ // trusted domain can also be a path like https://www.myapi.com/users,
4
+ // then all subroute like https://www.myapi.com/useers/1 will be authorized to send access_token to.
5
+
6
+ // Domains used by OIDC server must be also declared here
3
7
  const trustedDomains = {
4
- default:["http://localhost:4200", "https://demo.duendesoftware.com"],
8
+ default:["https://demo.duendesoftware.com"],
5
9
  config_classic: ["https://demo.duendesoftware.com"] ,
6
10
  config_without_refresh_token: ["https://demo.duendesoftware.com"],
7
11
  config_google: ["https://oauth2.googleapis.com", "https://openidconnect.googleapis.com"],
8
12
  config_with_hash: ["https://demo.duendesoftware.com"]
9
13
  };
14
+
@@ -9,22 +9,21 @@
9
9
  return Promise.resolve(JSON.parse(storage[`oidc_items.${configurationName}:${redirectUri}`]));
10
10
  }
11
11
 
12
- const clearAsync=() =>{
13
- storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({tokens:null});
12
+ const clearAsync=(status) =>{
13
+ storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({tokens:null, status});
14
14
  return Promise.resolve();
15
15
  }
16
16
 
17
17
  const initAsync=async () => {
18
18
  if(!storage[`oidc.${configurationName}:${redirectUri}`]){
19
- storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({tokens:null});
20
- return {tokens:null};
19
+ storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({tokens:null, status:null});
20
+ return {tokens:null, status:null};
21
21
  }
22
- return Promise.resolve({ tokens : JSON.parse(storage[`oidc.${configurationName}:${redirectUri}`]).tokens });
22
+ const data = JSON.parse(storage[`oidc.${configurationName}:${redirectUri}`]);
23
+ return Promise.resolve({ tokens : data.tokens, status: data.status });
23
24
  }
24
25
 
25
26
  const setTokens = (tokens) => {
26
- //console.log("setTokens");
27
- //console.log(tokens);
28
27
  storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({tokens});
29
28
  }
30
29
 
@@ -1,4 +1,5 @@
1
1
  import timer from "./timer"
2
+ import {parseOriginalTokens} from "./parseTokens";
2
3
 
3
4
  function get_browser() {
4
5
  let ua = navigator.userAgent, tem,
@@ -106,19 +107,9 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
106
107
  const unregisterAsync = async () => {
107
108
  return await registration.unregister();
108
109
  }
109
-
110
- const getAccessTokenPayloadAsync=async () => {
111
- const result = await sendMessageAsync(registration)({
112
- type: "getAccessTokenPayload",
113
- data: null,
114
- configurationName
115
- });
116
- // @ts-ignore
117
- return result.accessTokenPayload;
118
- }
119
-
120
- const clearAsync=() =>{
121
- return sendMessageAsync(registration)({type: "clear", data: null, configurationName});
110
+
111
+ const clearAsync=(status) =>{
112
+ return sendMessageAsync(registration)({type: "clear", data: {status}, configurationName});
122
113
  }
123
114
  const initAsync= async (oidcServerConfiguration, where) => {
124
115
  const result = await sendMessageAsync(registration)({
@@ -127,7 +118,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
127
118
  configurationName
128
119
  });
129
120
  // @ts-ignore
130
- return { tokens : result.tokens, isLogin: result.isLogin};
121
+ return { tokens : parseOriginalTokens(result.tokens), status: result.status};
131
122
  }
132
123
 
133
124
  const startKeepAliveServiceWorker = () => {
@@ -152,7 +143,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
152
143
  loadItemsAsync,
153
144
  clearAsync,
154
145
  initAsync,
155
- getAccessTokenPayloadAsync,
146
+ // getAccessTokenPayloadAsync,
156
147
  startKeepAliveServiceWorker,
157
148
  isServiceWorkerProxyActiveAsync,
158
149
  setSessionStateAsync,