@axa-fr/react-oidc 6.12.0 → 6.13.0

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 (78) hide show
  1. package/bin/copy.js +12 -9
  2. package/dist/OidcProvider.d.ts +1 -1
  3. package/dist/OidcProvider.d.ts.map +1 -1
  4. package/dist/OidcSecure.d.ts +1 -1
  5. package/dist/OidcSecure.d.ts.map +1 -1
  6. package/dist/ReactOidc.d.ts +1 -1
  7. package/dist/ReactOidc.d.ts.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/vanilla/checkSession.d.ts +5 -0
  12. package/dist/vanilla/checkSession.d.ts.map +1 -0
  13. package/dist/vanilla/checkSession.js +68 -0
  14. package/dist/vanilla/checkSession.js.map +1 -0
  15. package/dist/vanilla/events.d.ts +29 -0
  16. package/dist/vanilla/events.d.ts.map +1 -0
  17. package/dist/vanilla/events.js +32 -0
  18. package/dist/vanilla/events.js.map +1 -0
  19. package/dist/vanilla/initSession.d.ts +3 -3
  20. package/dist/vanilla/initSession.d.ts.map +1 -1
  21. package/dist/vanilla/initSession.js +19 -23
  22. package/dist/vanilla/initSession.js.map +1 -1
  23. package/dist/vanilla/initWorker.d.ts +4 -4
  24. package/dist/vanilla/initWorker.d.ts.map +1 -1
  25. package/dist/vanilla/initWorker.js +11 -15
  26. package/dist/vanilla/initWorker.js.map +1 -1
  27. package/dist/vanilla/login.d.ts +4 -0
  28. package/dist/vanilla/login.d.ts.map +1 -0
  29. package/dist/vanilla/login.js +244 -0
  30. package/dist/vanilla/login.js.map +1 -0
  31. package/dist/vanilla/oidc.d.ts +4 -37
  32. package/dist/vanilla/oidc.d.ts.map +1 -1
  33. package/dist/vanilla/oidc.js +99 -519
  34. package/dist/vanilla/oidc.js.map +1 -1
  35. package/dist/vanilla/renewTokens.d.ts +4 -0
  36. package/dist/vanilla/renewTokens.d.ts.map +1 -0
  37. package/dist/vanilla/renewTokens.js +50 -0
  38. package/dist/vanilla/renewTokens.js.map +1 -0
  39. package/dist/vanilla/requests.d.ts +2 -0
  40. package/dist/vanilla/requests.d.ts.map +1 -1
  41. package/dist/vanilla/requests.js +20 -1
  42. package/dist/vanilla/requests.js.map +1 -1
  43. package/dist/vanilla/route-utils.js +1 -1
  44. package/dist/vanilla/route-utils.js.map +1 -1
  45. package/dist/vanilla/silentLogin.d.ts +9 -0
  46. package/dist/vanilla/silentLogin.d.ts.map +1 -0
  47. package/dist/vanilla/silentLogin.js +145 -0
  48. package/dist/vanilla/silentLogin.js.map +1 -0
  49. package/dist/vanilla/types.d.ts +33 -0
  50. package/dist/vanilla/types.d.ts.map +1 -0
  51. package/dist/vanilla/types.js +3 -0
  52. package/dist/vanilla/types.js.map +1 -0
  53. package/dist/vanilla/user.d.ts +2 -0
  54. package/dist/vanilla/user.d.ts.map +1 -0
  55. package/dist/vanilla/user.js +48 -0
  56. package/dist/vanilla/user.js.map +1 -0
  57. package/dist/vanilla/vanillaOidc.d.ts +2 -1
  58. package/dist/vanilla/vanillaOidc.d.ts.map +1 -1
  59. package/dist/vanilla/vanillaOidc.js.map +1 -1
  60. package/package.json +1 -1
  61. package/src/oidc/OidcProvider.tsx +1 -1
  62. package/src/oidc/OidcSecure.tsx +1 -1
  63. package/src/oidc/ReactOidc.tsx +1 -1
  64. package/src/oidc/index.ts +1 -1
  65. package/src/oidc/vanilla/checkSession.ts +55 -0
  66. package/src/oidc/vanilla/events.ts +29 -0
  67. package/src/oidc/vanilla/index.ts +1 -1
  68. package/src/oidc/vanilla/initSession.ts +19 -25
  69. package/src/oidc/vanilla/initWorker.ts +12 -18
  70. package/src/oidc/vanilla/login.ts +242 -0
  71. package/src/oidc/vanilla/oidc.ts +53 -554
  72. package/src/oidc/vanilla/renewTokens.ts +36 -0
  73. package/src/oidc/vanilla/requests.ts +24 -0
  74. package/src/oidc/vanilla/route-utils.ts +1 -1
  75. package/src/oidc/vanilla/silentLogin.ts +143 -0
  76. package/src/oidc/vanilla/types.ts +35 -0
  77. package/src/oidc/vanilla/user.ts +39 -0
  78. package/src/oidc/vanilla/vanillaOidc.ts +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"vanillaOidc.js","sourceRoot":"","sources":["../../src/oidc/vanilla/vanillaOidc.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iCAA2E;AAC3E,+CAAuE;AAMvE,MAAa,WAAW;IAEpB,YAAY,IAAU;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,eAAe,CAAC,IAAoB;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,uBAAuB,CAAC,EAAS;QAC7B,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,YAAY,CAAC,SAAgB,EAAE,IAAQ;QACnC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,aAA+B,EAAE,IAAI,GAAG,SAAS;QAChE,OAAO,IAAI,WAAW,CAAC,WAAI,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,SAAS;QACvB,OAAO,IAAI,WAAW,CAAC,WAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC;IAGD,2BAA2B;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC;IACpD,CAAC;IAED,UAAU,CAAC,eAAsB,SAAS,EAAE,SAAmB,IAAI,EAAE,cAAc,GAAG,KAAK,EAAE,QAAe,SAAS,EAAE,eAAe,GAAG,KAAK;QAC1I,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAC/F,CAAC;IAED,WAAW,CAAC,oBAA+C,SAAS,EAAE,SAAoB,IAAI;QAC1F,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,wBAAwB;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,wBAAwB,EAAE,CAAC;IACjD,CAAC;IAED,gBAAgB,CAAC,SAAmB,IAAI;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,kBAAkB;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,qCAAqC,EAAE,CAAC;IAC9D,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,IAAI,aAAa;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IACpC,CAAC;IAEK,kBAAkB,CAAC,MAAM,GAAG,GAAG,EAAE,UAAU,GAAG,EAAE;;YAClD,OAAO,IAAA,gCAAkB,EAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC9D,CAAC;KAAA;IAEK,aAAa;;YACf,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QACtC,CAAC;KAAA;;AAjEL,kCAkEC;AAxCU,sBAAU,GAAG,WAAI,CAAC,UAAU,CAAC"}
1
+ {"version":3,"file":"vanillaOidc.js","sourceRoot":"","sources":["../../src/oidc/vanilla/vanillaOidc.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iCAA6C;AAC7C,+CAAuE;AAOvE,MAAa,WAAW;IAEpB,YAAY,IAAU;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,eAAe,CAAC,IAAoB;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,uBAAuB,CAAC,EAAS;QAC7B,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,YAAY,CAAC,SAAgB,EAAE,IAAQ;QACnC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,aAA+B,EAAE,IAAI,GAAG,SAAS;QAChE,OAAO,IAAI,WAAW,CAAC,WAAI,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,SAAS;QACvB,OAAO,IAAI,WAAW,CAAC,WAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC;IAGD,2BAA2B;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC;IACpD,CAAC;IAED,UAAU,CAAC,eAAsB,SAAS,EAAE,SAAmB,IAAI,EAAE,cAAc,GAAG,KAAK,EAAE,QAAe,SAAS,EAAE,eAAe,GAAG,KAAK;QAC1I,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAC/F,CAAC;IAED,WAAW,CAAC,oBAA+C,SAAS,EAAE,SAAoB,IAAI;QAC1F,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,wBAAwB;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,wBAAwB,EAAE,CAAC;IACjD,CAAC;IAED,gBAAgB,CAAC,SAAmB,IAAI;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,kBAAkB;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,qCAAqC,EAAE,CAAC;IAC9D,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,IAAI,aAAa;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IACpC,CAAC;IAEK,kBAAkB,CAAC,MAAM,GAAG,GAAG,EAAE,UAAU,GAAG,EAAE;;YAClD,OAAO,IAAA,gCAAkB,EAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC9D,CAAC;KAAA;IAEK,aAAa;;YACf,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QACtC,CAAC;KAAA;;AAjEL,kCAkEC;AAxCU,sBAAU,GAAG,WAAI,CAAC,UAAU,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axa-fr/react-oidc",
3
- "version": "6.12.0",
3
+ "version": "6.13.0",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "jsnext:main": "dist/index.js",
@@ -5,7 +5,7 @@ import { Authenticating, CallBackSuccess, Loading, SessionLost } from './core/de
5
5
  import ServiceWorkerNotSupported from './core/default-component/ServiceWorkerNotSupported.component';
6
6
  import OidcRoutes from './core/routes/OidcRoutes';
7
7
  import { CustomHistory } from './core/routes/withRouter';
8
- import { OidcConfiguration } from './vanilla/oidc';
8
+ import { OidcConfiguration } from './vanilla/types';
9
9
  import { VanillaOidc } from './vanilla/vanillaOidc';
10
10
 
11
11
  export type oidcContext = {
@@ -1,6 +1,6 @@
1
1
  import { FC, PropsWithChildren, useEffect } from 'react';
2
2
 
3
- import { StringMap } from './vanilla/oidc';
3
+ import { StringMap } from './vanilla/types';
4
4
  import { VanillaOidc } from './vanilla/vanillaOidc';
5
5
 
6
6
  export type OidcSecureProps = {
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
2
 
3
- import { StringMap } from './vanilla/oidc';
3
+ import { StringMap } from './vanilla/types';
4
4
  import { VanillaOidc } from './vanilla/vanillaOidc';
5
5
 
6
6
  const defaultConfigurationName = 'default';
package/src/oidc/index.ts CHANGED
@@ -3,5 +3,5 @@ export { OidcProvider } from './OidcProvider';
3
3
  export { OidcSecure, withOidcSecure } from './OidcSecure';
4
4
  export { useOidc, useOidcAccessToken, useOidcIdToken } from './ReactOidc';
5
5
  export { OidcUserStatus, useOidcUser } from './User';
6
- export type { OidcConfiguration } from './vanilla/oidc';
7
6
  export { TokenRenewMode } from './vanilla/parseTokens';
7
+ export type { AuthorityConfiguration, OidcConfiguration, StringMap } from './vanilla/types';
@@ -0,0 +1,55 @@
1
+ import { CheckSessionIFrame } from './checkSessionIFrame';
2
+ import { Tokens } from './parseTokens';
3
+ import { OidcConfiguration } from './types';
4
+
5
+ // eslint-disable-next-line @typescript-eslint/ban-types
6
+ export const startCheckSessionAsync = (oidcDatabase:any, configuration :OidcConfiguration, checkSessionIFrame: CheckSessionIFrame, silentLoginAsync:Function, getCurrentTokens: () => Tokens) => (checkSessionIFrameUri, clientId, sessionState, isSilentSignin = false) => {
7
+ return new Promise<CheckSessionIFrame>((resolve, reject): void => {
8
+ if (configuration.silent_login_uri && configuration.silent_redirect_uri && configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
9
+ const checkSessionCallback = () => {
10
+ checkSessionIFrame.stop();
11
+ const tokens = getCurrentTokens();
12
+ if (tokens === null) {
13
+ return;
14
+ }
15
+ const idToken = tokens.idToken;
16
+ const idTokenPayload = tokens.idTokenPayload;
17
+ silentLoginAsync({
18
+ prompt: 'none',
19
+ id_token_hint: idToken,
20
+ scope: 'openid',
21
+ }).then((silentSigninResponse) => {
22
+ const iFrameIdTokenPayload = silentSigninResponse.tokens.idTokenPayload;
23
+ if (idTokenPayload.sub === iFrameIdTokenPayload.sub) {
24
+ const sessionState = silentSigninResponse.sessionState;
25
+ checkSessionIFrame.start(silentSigninResponse.sessionState);
26
+ if (idTokenPayload.sid === iFrameIdTokenPayload.sid) {
27
+ console.debug('SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:', sessionState);
28
+ } else {
29
+ console.debug('SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:', sessionState);
30
+ }
31
+ } else {
32
+ console.debug('SessionMonitor._callback: Different subject signed into OP:', iFrameIdTokenPayload.sub);
33
+ }
34
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
35
+ }).catch(async (e) => {
36
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
37
+ for (const [key, oidc] of Object.entries(oidcDatabase)) {
38
+ // @ts-ignore
39
+ await oidc.logoutOtherTabAsync(this.configuration.client_id, idTokenPayload.sub);
40
+ }
41
+ });
42
+ };
43
+
44
+ checkSessionIFrame = new CheckSessionIFrame(checkSessionCallback, clientId, checkSessionIFrameUri);
45
+ checkSessionIFrame.load().then(() => {
46
+ checkSessionIFrame.start(sessionState);
47
+ resolve(checkSessionIFrame);
48
+ }).catch((e) => {
49
+ reject(e);
50
+ });
51
+ } else {
52
+ resolve(null);
53
+ }
54
+ });
55
+ };
@@ -0,0 +1,29 @@
1
+
2
+ export const eventNames = {
3
+ service_worker_not_supported_by_browser: 'service_worker_not_supported_by_browser',
4
+ token_aquired: 'token_aquired',
5
+ logout_from_another_tab: 'logout_from_another_tab',
6
+ logout_from_same_tab: 'logout_from_same_tab',
7
+ token_renewed: 'token_renewed',
8
+ token_timer: 'token_timer',
9
+ loginAsync_begin: 'loginAsync_begin',
10
+ loginAsync_error: 'loginAsync_error',
11
+ loginCallbackAsync_begin: 'loginCallbackAsync_begin',
12
+ loginCallbackAsync_end: 'loginCallbackAsync_end',
13
+ loginCallbackAsync_error: 'loginCallbackAsync_error',
14
+ refreshTokensAsync_begin: 'refreshTokensAsync_begin',
15
+ refreshTokensAsync: 'refreshTokensAsync',
16
+ refreshTokensAsync_end: 'refreshTokensAsync_end',
17
+ refreshTokensAsync_error: 'refreshTokensAsync_error',
18
+ refreshTokensAsync_silent_error: 'refreshTokensAsync_silent_error',
19
+ tryKeepExistingSessionAsync_begin: 'tryKeepExistingSessionAsync_begin',
20
+ tryKeepExistingSessionAsync_end: 'tryKeepExistingSessionAsync_end',
21
+ tryKeepExistingSessionAsync_error: 'tryKeepExistingSessionAsync_error',
22
+ silentLoginAsync_begin: 'silentLoginAsync_begin',
23
+ silentLoginAsync: 'silentLoginAsync',
24
+ silentLoginAsync_end: 'silentLoginAsync_end',
25
+ silentLoginAsync_error: 'silentLoginAsync_error',
26
+ syncTokensAsync_begin: 'syncTokensAsync_begin',
27
+ syncTokensAsync_end: 'syncTokensAsync_end',
28
+ syncTokensAsync_error: 'syncTokensAsync_error',
29
+ };
@@ -1,2 +1,2 @@
1
- export { OidcConfiguration } from './oidc';
1
+ export { AuthorityConfiguration, OidcConfiguration, StringMap } from './types';
2
2
  export { VanillaOidc } from './vanillaOidc';
@@ -1,68 +1,62 @@
1
- export const initSession = (configurationName, redirectUri, storage = sessionStorage) => {
1
+ export const initSession = (configurationName, storage = sessionStorage) => {
2
2
  const saveItemsAsync = (items) => {
3
- storage[`oidc_items.${configurationName}:${redirectUri}`] = JSON.stringify(items);
3
+ storage[`oidc.items.${configurationName}`] = JSON.stringify(items);
4
4
  return Promise.resolve();
5
5
  };
6
6
 
7
7
  const loadItemsAsync = () => {
8
- return Promise.resolve(JSON.parse(storage[`oidc_items.${configurationName}:${redirectUri}`]));
8
+ return Promise.resolve(JSON.parse(storage[`oidc.items.${configurationName}`]));
9
9
  };
10
10
 
11
11
  const clearAsync = (status) => {
12
- storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({ tokens: null, status });
12
+ storage[`oidc.${configurationName}`] = JSON.stringify({ tokens: null, status });
13
13
  return Promise.resolve();
14
14
  };
15
15
 
16
16
  const initAsync = async () => {
17
- if (!storage[`oidc.${configurationName}:${redirectUri}`]) {
18
- storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({ tokens: null, status: null });
17
+ if (!storage[`oidc.${configurationName}`]) {
18
+ storage[`oidc.${configurationName}`] = JSON.stringify({ tokens: null, status: null });
19
19
  return { tokens: null, status: null };
20
20
  }
21
- const data = JSON.parse(storage[`oidc.${configurationName}:${redirectUri}`]);
21
+ const data = JSON.parse(storage[`oidc.${configurationName}`]);
22
22
  return Promise.resolve({ tokens: data.tokens, status: data.status });
23
23
  };
24
24
 
25
25
  const setTokens = (tokens) => {
26
- storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({ tokens });
26
+ storage[`oidc.${configurationName}`] = JSON.stringify({ tokens });
27
27
  };
28
28
 
29
29
  const setSessionState = (sessionState) => {
30
- storage[`oidc.session_state.${configurationName}:${redirectUri}`] = sessionState;
30
+ storage[`oidc.session_state.${configurationName}`] = sessionState;
31
31
  };
32
32
 
33
33
  const getSessionState = () => {
34
- return storage[`oidc.session_state.${configurationName}:${redirectUri}`];
34
+ return storage[`oidc.session_state.${configurationName}`];
35
35
  };
36
36
 
37
37
  const setNonceAsync = (nonce) => {
38
- localStorage[`oidc.nonce.${configurationName}:${redirectUri}`] = nonce.nonce;
38
+ localStorage[`oidc.nonce.${configurationName}`] = nonce.nonce;
39
39
  };
40
40
 
41
41
  const getNonceAsync = async () => {
42
42
  // @ts-ignore
43
- return { nonce: localStorage[`oidc.nonce.${configurationName}:${redirectUri}`] };
43
+ return { nonce: localStorage[`oidc.nonce.${configurationName}`] };
44
44
  };
45
45
 
46
46
  const getTokens = () => {
47
- if (!storage[`oidc.${configurationName}:${redirectUri}`]) {
47
+ if (!storage[`oidc.${configurationName}`]) {
48
48
  return null;
49
49
  }
50
- return JSON.stringify({ tokens: JSON.parse(storage[`oidc.${configurationName}:${redirectUri}`]).tokens });
50
+ return JSON.stringify({ tokens: JSON.parse(storage[`oidc.${configurationName}`]).tokens });
51
51
  };
52
52
 
53
- const getLoginSessionKey = (configurationName:string, redirectUri:string) => {
54
- return `oidc_login.${configurationName}:${redirectUri}`;
55
- };
56
-
57
- const setLoginParams = (configurationName:string, redirectUri:string, data) => {
58
- const sessionKey = getLoginSessionKey(configurationName, redirectUri);
53
+ let getLoginParamsCache = null;
54
+ const setLoginParams = (configurationName:string, data) => {
59
55
  getLoginParamsCache = data;
60
- storage[sessionKey] = JSON.stringify(data);
56
+ storage[`oidc.login.${configurationName}`] = JSON.stringify(data);
61
57
  };
62
-
63
- let getLoginParamsCache = null;
64
- const getLoginParams = (configurationName, redirectUri) => {
65
- const dataString = storage[getLoginSessionKey(configurationName, redirectUri)];
58
+ const getLoginParams = (configurationName) => {
59
+ const dataString = storage[`oidc.login.${configurationName}`];
66
60
  if (!getLoginParamsCache) {
67
61
  getLoginParamsCache = JSON.parse(dataString);
68
62
  }
@@ -1,7 +1,7 @@
1
1
  import { initSession } from './initSession';
2
- import { OidcConfiguration } from './oidc';
3
2
  import { parseOriginalTokens } from './parseTokens';
4
3
  import timer from './timer';
4
+ import { OidcConfiguration } from './types';
5
5
 
6
6
  export const getOperatingSystem = () => {
7
7
  const nVer = navigator.appVersion;
@@ -140,7 +140,7 @@ const sendMessageAsync = (registration) => (data) => {
140
140
  });
141
141
  };
142
142
 
143
- export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName, redirectUri) => {
143
+ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName) => {
144
144
  if (typeof window === 'undefined' || typeof navigator === 'undefined' || !navigator.serviceWorker || !serviceWorkerRelativeUrl) {
145
145
  return null;
146
146
  }
@@ -192,7 +192,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
192
192
  const saveItemsAsync = (items) => {
193
193
  // iOS kill Service Worker when domain we leave domain
194
194
  if (operatingSystem.os === 'iOS') {
195
- const session = initSession(configurationName, redirectUri);
195
+ const session = initSession(configurationName);
196
196
  return session.saveItemsAsync(items);
197
197
  }
198
198
  return sendMessageAsync(registration)({ type: 'saveItems', data: items, configurationName });
@@ -200,7 +200,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
200
200
  const loadItemsAsync = () => {
201
201
  // iOS kill Service Worker when domain we leave domain
202
202
  if (operatingSystem.os === 'iOS') {
203
- const session = initSession(configurationName, redirectUri);
203
+ const session = initSession(configurationName);
204
204
  return session.loadItemsAsync();
205
205
  }
206
206
  return sendMessageAsync(registration)({ type: 'loadItems', data: null, configurationName });
@@ -208,7 +208,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
208
208
  const clearAsync = async (status) => {
209
209
  // iOS kill Service Worker when domain we leave domain
210
210
  if (operatingSystem.os === 'iOS') {
211
- const session = initSession(configurationName, redirectUri);
211
+ const session = initSession(configurationName);
212
212
  await session.clearAsync(status);
213
213
  }
214
214
  return sendMessageAsync(registration)({ type: 'clear', data: { status }, configurationName });
@@ -243,7 +243,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
243
243
  const setNonceAsync = (nonce) => {
244
244
  // iOS kill Service Worker when domain we leave domain
245
245
  if (operatingSystem.os === 'iOS') {
246
- const session = initSession(configurationName, redirectUri);
246
+ const session = initSession(configurationName);
247
247
  return session.setNonceAsync(nonce);
248
248
  }
249
249
  return sendMessageAsync(registration)({ type: 'setNonce', data: { nonce }, configurationName });
@@ -253,7 +253,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
253
253
  const getNonceAsync = async () => {
254
254
  // iOS kill Service Worker when domain we leave domain
255
255
  if (operatingSystem.os === 'iOS') {
256
- const session = initSession(configurationName, redirectUri);
256
+ const session = initSession(configurationName);
257
257
  return session.getNonceAsync();
258
258
  }
259
259
  // @ts-ignore
@@ -261,19 +261,13 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
261
261
  return { nonce: keyNonce };
262
262
  };
263
263
 
264
- const getLoginSessionKey = (configurationName:string, redirectUri:string) => {
265
- return `oidc_login.${configurationName}:${redirectUri}`;
266
- };
267
-
268
- const setLoginParams = (configurationName:string, redirectUri:string, data) => {
269
- const sessionKey = getLoginSessionKey(configurationName, redirectUri);
264
+ let getLoginParamsCache = null;
265
+ const setLoginParams = (configurationName:string, data) => {
270
266
  getLoginParamsCache = data;
271
- sessionStorage[sessionKey] = JSON.stringify(data);
267
+ localStorage[`oidc.login.${configurationName}`] = JSON.stringify(data);
272
268
  };
273
-
274
- let getLoginParamsCache = null;
275
- const getLoginParams = (configurationName, redirectUri) => {
276
- const dataString = sessionStorage[getLoginSessionKey(configurationName, redirectUri)];
269
+ const getLoginParams = (configurationName) => {
270
+ const dataString = localStorage[`oidc.login.${configurationName}`];
277
271
  if (!getLoginParamsCache) {
278
272
  getLoginParamsCache = JSON.parse(dataString);
279
273
  }
@@ -0,0 +1,242 @@
1
+ import {
2
+ AuthorizationNotifier,
3
+ AuthorizationRequest, BaseTokenRequestHandler,
4
+ DefaultCrypto, FetchRequestor, GRANT_TYPE_AUTHORIZATION_CODE,
5
+ RedirectRequestHandler,
6
+ TokenRequest,
7
+ } from '@openid/appauth';
8
+
9
+ import { eventNames } from './events';
10
+ import { initSession } from './initSession';
11
+ import { initWorkerAsync } from './initWorker';
12
+ import { MemoryStorageBackend } from './memoryStorageBackend';
13
+ import { HashQueryStringUtils, NoHashQueryStringUtils } from './noHashQueryStringUtils';
14
+ import { isTokensOidcValid, setTokens } from './parseTokens';
15
+ import { getParseQueryStringFromLocation } from './route-utils';
16
+ import { OidcConfiguration, StringMap } from './types';
17
+
18
+ const randomString = function(length) {
19
+ let text = '';
20
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
21
+ for (let i = 0; i < length; i++) {
22
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
23
+ }
24
+ return text;
25
+ };
26
+
27
+ // eslint-disable-next-line @typescript-eslint/ban-types
28
+ export const defaultLoginAsync = (window, configurationName, configuration:OidcConfiguration, publishEvent :(string, any)=>void, initAsync:Function) => (callbackPath:string = undefined, extras:StringMap = null, isSilentSignin = false, scope:string = undefined) => {
29
+ const originExtras = extras;
30
+ extras = { ...extras };
31
+ const loginLocalAsync = async () => {
32
+ const location = window.location;
33
+ const url = callbackPath || location.pathname + (location.search || '') + (location.hash || '');
34
+ let state;
35
+ if (extras && 'state' in extras) {
36
+ state = extras.state;
37
+ delete extras.state;
38
+ }
39
+
40
+ publishEvent(eventNames.loginAsync_begin, {});
41
+ if (extras) {
42
+ for (const key of Object.keys(extras)) {
43
+ if (key.endsWith(':token_request')) {
44
+ delete extras[key];
45
+ }
46
+ }
47
+ }
48
+ try {
49
+ const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
50
+ if (!scope) {
51
+ scope = configuration.scope;
52
+ }
53
+
54
+ const extraFinal = extras ?? configuration.extras ?? {};
55
+ if (!extraFinal.nonce) {
56
+ extraFinal.nonce = randomString(12);
57
+ }
58
+ const nonce = { nonce: extraFinal.nonce };
59
+ const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, configurationName);
60
+ const oidcServerConfiguration = await initAsync(configuration.authority, configuration.authority_configuration);
61
+ let storage;
62
+ if (serviceWorker) {
63
+ serviceWorker.setLoginParams(configurationName, { callbackPath: url, extras: originExtras, state });
64
+ serviceWorker.startKeepAliveServiceWorker();
65
+ await serviceWorker.initAsync(oidcServerConfiguration, 'loginAsync', configuration);
66
+ await serviceWorker.setNonceAsync(nonce);
67
+ storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, {});
68
+ await storage.setItem('dummy', {});
69
+ } else {
70
+ let session = initSession(configurationName, configuration.storage ?? sessionStorage);
71
+ session.setLoginParams(configurationName, { callbackPath: url, extras: originExtras, state });
72
+ session = initSession(configurationName);
73
+ await session.setNonceAsync(nonce);
74
+ storage = new MemoryStorageBackend(session.saveItemsAsync, {});
75
+ }
76
+
77
+ // @ts-ignore
78
+ const queryStringUtil = redirectUri.includes('#') ? new HashQueryStringUtils() : new NoHashQueryStringUtils();
79
+ const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
80
+ const authRequest = new AuthorizationRequest({
81
+ client_id: configuration.client_id,
82
+ redirect_uri: redirectUri,
83
+ scope,
84
+ response_type: AuthorizationRequest.RESPONSE_TYPE_CODE,
85
+ state,
86
+ extras: extraFinal,
87
+ });
88
+ authorizationHandler.performAuthorizationRequest(oidcServerConfiguration, authRequest);
89
+ } catch (exception) {
90
+ publishEvent(eventNames.loginAsync_error, exception);
91
+ throw exception;
92
+ }
93
+ };
94
+ return loginLocalAsync();
95
+ };
96
+
97
+ export const loginCallbackAsync = (oidc) => async (isSilentSignin = false) => {
98
+ try {
99
+ oidc.publishEvent(eventNames.loginCallbackAsync_begin, {});
100
+ const configuration = oidc.configuration;
101
+ const clientId = configuration.client_id;
102
+ const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
103
+ const authority = configuration.authority;
104
+ const tokenRequestTimeout = configuration.token_request_timeout;
105
+ const oidcServerConfiguration = await oidc.initAsync(authority, configuration.authority_configuration);
106
+ const queryParams = getParseQueryStringFromLocation(window.location.href);
107
+ const sessionState = queryParams.session_state;
108
+ const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, oidc.configurationName);
109
+ let storage = null;
110
+ let nonceData = null;
111
+ let getLoginParams = null;
112
+ if (serviceWorker) {
113
+ serviceWorker.startKeepAliveServiceWorker();
114
+ await serviceWorker.initAsync(oidcServerConfiguration, 'loginCallbackAsync', configuration);
115
+ const items = await serviceWorker.loadItemsAsync();
116
+ storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, items);
117
+ const dummy = await storage.getItem('dummy');
118
+ if (!dummy) {
119
+ throw new Error('Service Worker storage disapear');
120
+ }
121
+ await storage.removeItem('dummy');
122
+ await serviceWorker.setSessionStateAsync(sessionState);
123
+ nonceData = await serviceWorker.getNonceAsync();
124
+ getLoginParams = serviceWorker.getLoginParams(oidc.configurationName);
125
+ } else {
126
+ const session = initSession(oidc.configurationName);
127
+ session.setSessionState(sessionState);
128
+ const items = await session.loadItemsAsync();
129
+ storage = new MemoryStorageBackend(session.saveItemsAsync, items);
130
+ nonceData = await session.getNonceAsync();
131
+ getLoginParams = session.getLoginParams(oidc.configurationName);
132
+ }
133
+
134
+ return new Promise((resolve, reject) => {
135
+ let queryStringUtil = new NoHashQueryStringUtils();
136
+ if (redirectUri.includes('#')) {
137
+ const splithash = window.location.href.split('#');
138
+ if (splithash.length === 2 && splithash[1].includes('?')) {
139
+ queryStringUtil = new HashQueryStringUtils();
140
+ }
141
+ }
142
+ const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
143
+ const notifier = new AuthorizationNotifier();
144
+ authorizationHandler.setAuthorizationNotifier(notifier);
145
+
146
+ notifier.setAuthorizationListener((request, response, error) => {
147
+ if (error) {
148
+ reject(error);
149
+ return;
150
+ }
151
+ if (!response) {
152
+ reject(new Error('no response'));
153
+ return;
154
+ }
155
+
156
+ const extras = {};
157
+ if (request && request.internal) {
158
+ // @ts-ignore
159
+ extras.code_verifier = request.internal.code_verifier;
160
+ if (configuration.token_request_extras) {
161
+ for (const [key, value] of Object.entries(configuration.token_request_extras)) {
162
+ extras[key] = value;
163
+ }
164
+ }
165
+ if (getLoginParams && getLoginParams.extras) {
166
+ for (const [key, value] of Object.entries(getLoginParams.extras)) {
167
+ if (key.endsWith(':token_request')) {
168
+ extras[key.replace(':token_request', '')] = value;
169
+ }
170
+ }
171
+ }
172
+ }
173
+
174
+ const tokenRequest = new TokenRequest({
175
+ client_id: clientId,
176
+ redirect_uri: redirectUri, // @ts-ignore
177
+ grant_type: GRANT_TYPE_AUTHORIZATION_CODE,
178
+ code: response.code,
179
+ refresh_token: undefined,
180
+ extras,
181
+ });
182
+
183
+ let timeoutId = setTimeout(() => {
184
+ reject(new Error('performTokenRequest timeout'));
185
+ timeoutId = null;
186
+ }, tokenRequestTimeout ?? 12000);
187
+ try {
188
+ const tokenHandler = new BaseTokenRequestHandler(new FetchRequestor());
189
+ tokenHandler.performTokenRequest(oidcServerConfiguration, tokenRequest).then(async (tokenResponse) => {
190
+ if (timeoutId) {
191
+ clearTimeout(timeoutId);
192
+ oidc.timeoutId = null;
193
+ let loginParams = null;
194
+ let formattedTokens = null;
195
+ if (serviceWorker) {
196
+ const { tokens } = await serviceWorker.initAsync(oidcServerConfiguration, 'syncTokensAsync', configuration);
197
+ loginParams = serviceWorker.getLoginParams(oidc.configurationName);
198
+ formattedTokens = tokens;
199
+ } else {
200
+ const session = initSession(oidc.configurationName, configuration.storage);
201
+ loginParams = session.getLoginParams(oidc.configurationName);
202
+ formattedTokens = setTokens(tokenResponse, null, configuration.token_renew_mode);
203
+ }
204
+ if (!isTokensOidcValid(formattedTokens, nonceData.nonce, oidcServerConfiguration)) {
205
+ const exception = new Error('Tokens are not OpenID valid');
206
+ if (timeoutId) {
207
+ clearTimeout(timeoutId);
208
+ oidc.timeoutId = null;
209
+ oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
210
+ console.error(exception);
211
+ reject(exception);
212
+ }
213
+ }
214
+
215
+ oidc.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, clientId, sessionState, isSilentSignin).then(() => {
216
+ oidc.publishEvent(eventNames.loginCallbackAsync_end, {});
217
+ resolve({
218
+ tokens: formattedTokens,
219
+ state: request.state,
220
+ callbackPath: loginParams.callbackPath,
221
+ });
222
+ });
223
+ }
224
+ });
225
+ } catch (exception) {
226
+ if (timeoutId) {
227
+ clearTimeout(timeoutId);
228
+ oidc.timeoutId = null;
229
+ oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
230
+ console.error(exception);
231
+ reject(exception);
232
+ }
233
+ }
234
+ });
235
+ authorizationHandler.completeAuthorizationRequestIfPossible();
236
+ });
237
+ } catch (exception) {
238
+ console.error(exception);
239
+ oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
240
+ throw exception;
241
+ }
242
+ };