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

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 (64) hide show
  1. package/dist/OidcProvider.d.ts +1 -1
  2. package/dist/OidcProvider.d.ts.map +1 -1
  3. package/dist/OidcSecure.d.ts +1 -1
  4. package/dist/OidcSecure.d.ts.map +1 -1
  5. package/dist/ReactOidc.d.ts +1 -1
  6. package/dist/ReactOidc.d.ts.map +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/vanilla/checkSession.d.ts +5 -0
  11. package/dist/vanilla/checkSession.d.ts.map +1 -0
  12. package/dist/vanilla/checkSession.js +68 -0
  13. package/dist/vanilla/checkSession.js.map +1 -0
  14. package/dist/vanilla/events.d.ts +29 -0
  15. package/dist/vanilla/events.d.ts.map +1 -0
  16. package/dist/vanilla/events.js +32 -0
  17. package/dist/vanilla/events.js.map +1 -0
  18. package/dist/vanilla/initWorker.d.ts +1 -1
  19. package/dist/vanilla/initWorker.d.ts.map +1 -1
  20. package/dist/vanilla/initWorker.js +2 -2
  21. package/dist/vanilla/initWorker.js.map +1 -1
  22. package/dist/vanilla/login.d.ts +4 -0
  23. package/dist/vanilla/login.d.ts.map +1 -0
  24. package/dist/vanilla/login.js +125 -0
  25. package/dist/vanilla/login.js.map +1 -0
  26. package/dist/vanilla/oidc.d.ts +7 -36
  27. package/dist/vanilla/oidc.d.ts.map +1 -1
  28. package/dist/vanilla/oidc.js +53 -349
  29. package/dist/vanilla/oidc.js.map +1 -1
  30. package/dist/vanilla/requests.d.ts +2 -0
  31. package/dist/vanilla/requests.d.ts.map +1 -1
  32. package/dist/vanilla/requests.js +20 -1
  33. package/dist/vanilla/requests.js.map +1 -1
  34. package/dist/vanilla/silentLogin.d.ts +8 -0
  35. package/dist/vanilla/silentLogin.d.ts.map +1 -0
  36. package/dist/vanilla/silentLogin.js +95 -0
  37. package/dist/vanilla/silentLogin.js.map +1 -0
  38. package/dist/vanilla/types.d.ts +33 -0
  39. package/dist/vanilla/types.d.ts.map +1 -0
  40. package/dist/vanilla/types.js +3 -0
  41. package/dist/vanilla/types.js.map +1 -0
  42. package/dist/vanilla/user.d.ts +2 -0
  43. package/dist/vanilla/user.d.ts.map +1 -0
  44. package/dist/vanilla/user.js +48 -0
  45. package/dist/vanilla/user.js.map +1 -0
  46. package/dist/vanilla/vanillaOidc.d.ts +2 -1
  47. package/dist/vanilla/vanillaOidc.d.ts.map +1 -1
  48. package/dist/vanilla/vanillaOidc.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/oidc/OidcProvider.tsx +1 -1
  51. package/src/oidc/OidcSecure.tsx +1 -1
  52. package/src/oidc/ReactOidc.tsx +1 -1
  53. package/src/oidc/index.ts +1 -1
  54. package/src/oidc/vanilla/checkSession.ts +55 -0
  55. package/src/oidc/vanilla/events.ts +29 -0
  56. package/src/oidc/vanilla/index.ts +1 -1
  57. package/src/oidc/vanilla/initWorker.ts +3 -3
  58. package/src/oidc/vanilla/login.ts +118 -0
  59. package/src/oidc/vanilla/oidc.ts +23 -372
  60. package/src/oidc/vanilla/requests.ts +24 -0
  61. package/src/oidc/vanilla/silentLogin.ts +102 -0
  62. package/src/oidc/vanilla/types.ts +35 -0
  63. package/src/oidc/vanilla/user.ts +39 -0
  64. package/src/oidc/vanilla/vanillaOidc.ts +2 -1
@@ -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,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;
@@ -268,12 +268,12 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
268
268
  const setLoginParams = (configurationName:string, data) => {
269
269
  const sessionKey = getLoginSessionKey(configurationName);
270
270
  getLoginParamsCache = data;
271
- sessionStorage[sessionKey] = JSON.stringify(data);
271
+ localStorage[sessionKey] = JSON.stringify(data);
272
272
  };
273
273
 
274
274
  let getLoginParamsCache = null;
275
275
  const getLoginParams = (configurationName) => {
276
- const dataString = sessionStorage[getLoginSessionKey(configurationName)];
276
+ const dataString = localStorage[getLoginSessionKey(configurationName)];
277
277
  if (!getLoginParamsCache) {
278
278
  getLoginParamsCache = JSON.parse(dataString);
279
279
  }
@@ -0,0 +1,118 @@
1
+ import { AuthorizationRequest, DefaultCrypto, RedirectRequestHandler } from '@openid/appauth';
2
+
3
+ import { eventNames } from './events';
4
+ import { initSession } from './initSession';
5
+ import { initWorkerAsync } from './initWorker';
6
+ import { MemoryStorageBackend } from './memoryStorageBackend';
7
+ import { HashQueryStringUtils, NoHashQueryStringUtils } from './noHashQueryStringUtils';
8
+ import { OidcConfiguration, StringMap } from './types';
9
+
10
+ const randomString = function(length) {
11
+ let text = '';
12
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
13
+ for (let i = 0; i < length; i++) {
14
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
15
+ }
16
+ return text;
17
+ };
18
+
19
+ // eslint-disable-next-line @typescript-eslint/ban-types
20
+ export const defaultLoginAsync = (window, configurationName, configuration:OidcConfiguration, silentLoginAsync:Function, publishEvent :(string, any)=>void, initAsync:Function) => (callbackPath:string = undefined, extras:StringMap = null, isSilentSignin = false, scope:string = undefined) => {
21
+ const originExtras = extras;
22
+ extras = { ...extras };
23
+ const loginLocalAsync = async () => {
24
+ const location = window.location;
25
+ const url = callbackPath || location.pathname + (location.search || '') + (location.hash || '');
26
+ let state;
27
+ if (extras && 'state' in extras) {
28
+ state = extras.state;
29
+ delete extras.state;
30
+ }
31
+
32
+ publishEvent(eventNames.loginAsync_begin, {});
33
+ if (extras) {
34
+ for (const key of Object.keys(extras)) {
35
+ if (key.endsWith(':token_request')) {
36
+ delete extras[key];
37
+ }
38
+ }
39
+ }
40
+ try {
41
+ const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
42
+ if (!scope) {
43
+ scope = configuration.scope;
44
+ }
45
+
46
+ const extraFinal = extras ?? configuration.extras ?? {};
47
+ if (!extraFinal.nonce) {
48
+ extraFinal.nonce = randomString(12);
49
+ }
50
+ const nonce = { nonce: extraFinal.nonce };
51
+ const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, configurationName);
52
+ const oidcServerConfiguration = await initAsync(configuration.authority, configuration.authority_configuration);
53
+ let storage;
54
+ if (serviceWorker) {
55
+ serviceWorker.setLoginParams(configurationName, { callbackPath: url, extras: originExtras, state });
56
+ serviceWorker.startKeepAliveServiceWorker();
57
+ await serviceWorker.initAsync(oidcServerConfiguration, 'loginAsync', configuration);
58
+ await serviceWorker.setNonceAsync(nonce);
59
+ storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, {});
60
+ await storage.setItem('dummy', {});
61
+ } else {
62
+ let session = initSession(configurationName, configuration.storage ?? sessionStorage);
63
+ session.setLoginParams(configurationName, { callbackPath: url, extras: originExtras, state });
64
+ session = initSession(configurationName);
65
+ await session.setNonceAsync(nonce);
66
+ storage = new MemoryStorageBackend(session.saveItemsAsync, {});
67
+ }
68
+
69
+ // @ts-ignore
70
+ const queryStringUtil = redirectUri.includes('#') ? new HashQueryStringUtils() : new NoHashQueryStringUtils();
71
+ const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
72
+ const authRequest = new AuthorizationRequest({
73
+ client_id: configuration.client_id,
74
+ redirect_uri: redirectUri,
75
+ scope,
76
+ response_type: AuthorizationRequest.RESPONSE_TYPE_CODE,
77
+ state,
78
+ extras: extraFinal,
79
+ });
80
+ authorizationHandler.performAuthorizationRequest(oidcServerConfiguration, authRequest);
81
+ } catch (exception) {
82
+ publishEvent(eventNames.loginAsync_error, exception);
83
+ throw exception;
84
+ }
85
+ };
86
+ return loginLocalAsync();
87
+ };
88
+
89
+ // eslint-disable-next-line @typescript-eslint/ban-types
90
+ export const defaultSilentLoginAsync2 = (window, configurationName, configuration:OidcConfiguration, publishEvent :(string, any)=>void, oidc:any) => (extras:StringMap = null, scope:string = undefined) => {
91
+ extras = { ...extras };
92
+ const loginLocalAsync = async () => {
93
+ let state;
94
+ if (extras && 'state' in extras) {
95
+ state = extras.state;
96
+ delete extras.state;
97
+ }
98
+
99
+ try {
100
+ const extraFinal = extras ?? configuration.extras ?? {};
101
+ const silentResult = await oidc.silentLoginAsync({
102
+ ...extraFinal,
103
+ prompt: 'none',
104
+ }, state, scope);
105
+
106
+ if (silentResult) {
107
+ oidc.tokens = silentResult.tokens;
108
+ publishEvent(eventNames.token_aquired, {});
109
+ // @ts-ignore
110
+ this.timeoutId = autoRenewTokens(this, this.tokens.refreshToken, this.tokens.expiresAt, extras);
111
+ return {};
112
+ }
113
+ } catch (e) {
114
+ return e;
115
+ }
116
+ };
117
+ return loginLocalAsync();
118
+ };
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  AuthorizationNotifier,
3
- AuthorizationRequest,
4
3
  AuthorizationServiceConfiguration,
5
4
  BaseTokenRequestHandler,
6
5
  DefaultCrypto,
@@ -12,31 +11,26 @@ import {
12
11
  } from '@openid/appauth';
13
12
  import { AuthorizationServiceConfigurationJson } from '@openid/appauth/src/authorization_service_configuration';
14
13
 
15
- import { getFromCache, setCache } from './cache';
14
+ import { startCheckSessionAsync as defaultStartCheckSessionAsync } from './checkSession';
16
15
  import { CheckSessionIFrame } from './checkSessionIFrame';
16
+ import { eventNames } from './events';
17
17
  import { initSession } from './initSession';
18
18
  import { initWorkerAsync, sleepAsync } from './initWorker';
19
+ import { defaultLoginAsync, defaultSilentLoginAsync2 } from './login';
19
20
  import { MemoryStorageBackend } from './memoryStorageBackend';
20
21
  import { HashQueryStringUtils, NoHashQueryStringUtils } from './noHashQueryStringUtils';
21
22
  import {
22
23
  computeTimeLeft,
23
24
  isTokensOidcValid,
24
- isTokensValid,
25
25
  setTokens, TokenRenewMode,
26
26
  Tokens,
27
27
  } from './parseTokens';
28
- import { performRevocationRequestAsync, performTokenRequestAsync, TOKEN_TYPE } from './requests';
28
+ import { fetchFromIssuer, performRevocationRequestAsync, performTokenRequestAsync, TOKEN_TYPE } from './requests';
29
29
  import { getParseQueryStringFromLocation } from './route-utils';
30
+ import defaultSilentLoginAsync from './silentLogin';
30
31
  import timer from './timer';
31
-
32
- const randomString = function(length) {
33
- let text = '';
34
- const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
35
- for (let i = 0; i < length; i++) {
36
- text += possible.charAt(Math.floor(Math.random() * possible.length));
37
- }
38
- return text;
39
- };
32
+ import { AuthorityConfiguration, OidcConfiguration, StringMap } from './types';
33
+ import { userInfoAsync } from './user';
40
34
 
41
35
  export interface OidcAuthorizationServiceConfigurationJson extends AuthorizationServiceConfigurationJson{
42
36
  check_session_iframe?: string;
@@ -58,41 +52,6 @@ export class OidcAuthorizationServiceConfiguration extends AuthorizationServiceC
58
52
  }
59
53
  }
60
54
 
61
- export interface StringMap {
62
- [key: string]: string;
63
- }
64
-
65
- export interface AuthorityConfiguration {
66
- authorization_endpoint: string;
67
- token_endpoint: string;
68
- revocation_endpoint: string;
69
- end_session_endpoint?: string;
70
- userinfo_endpoint?: string;
71
- check_session_iframe?:string;
72
- issuer:string;
73
- }
74
-
75
- export type OidcConfiguration = {
76
- client_id: string;
77
- redirect_uri: string;
78
- silent_redirect_uri?:string;
79
- silent_login_uri?:string;
80
- silent_login_timeout?:number;
81
- scope: string;
82
- authority: string;
83
- authority_time_cache_wellknowurl_in_second?: number;
84
- authority_configuration?: AuthorityConfiguration;
85
- refresh_time_before_tokens_expiration_in_second?: number;
86
- token_request_timeout?: number;
87
- service_worker_relative_url?:string;
88
- service_worker_only?:boolean;
89
- extras?:StringMap;
90
- token_request_extras?:StringMap;
91
- storage?: Storage;
92
- monitor_session?: boolean;
93
- token_renew_mode?: string;
94
- };
95
-
96
55
  const oidcDatabase = {};
97
56
  const oidcFactory = (configuration: OidcConfiguration, name = 'default') => {
98
57
  if (oidcDatabase[name]) {
@@ -146,105 +105,17 @@ const autoRenewTokens = (oidc, refreshToken, expiresAt, extras:StringMap = null)
146
105
  }, 1000);
147
106
  };
148
107
 
149
- const userInfoAsync = async (oidc) => {
150
- if (oidc.userInfo != null) {
151
- return oidc.userInfo;
152
- }
153
- if (!oidc.tokens) {
154
- return null;
155
- }
156
- const accessToken = oidc.tokens.accessToken;
157
- if (!accessToken) {
158
- return null;
159
- }
160
-
161
- // We wait the synchronisation before making a request
162
- while (oidc.tokens && !isTokensValid(oidc.tokens)) {
163
- await sleepAsync(200);
164
- }
165
-
166
- const oidcServerConfiguration = await oidc.initAsync(oidc.configuration.authority, oidc.configuration.authority_configuration);
167
- const url = oidcServerConfiguration.userInfoEndpoint;
168
- const fetchUserInfo = async (accessToken) => {
169
- const res = await fetch(url, {
170
- headers: {
171
- authorization: `Bearer ${accessToken}`,
172
- },
173
- });
174
-
175
- if (res.status !== 200) {
176
- return null;
177
- }
178
-
179
- return res.json();
180
- };
181
- const userInfo = await fetchUserInfo(accessToken);
182
- oidc.userInfo = userInfo;
183
- return userInfo;
184
- };
185
-
186
- const eventNames = {
187
- service_worker_not_supported_by_browser: 'service_worker_not_supported_by_browser',
188
- token_aquired: 'token_aquired',
189
- logout_from_another_tab: 'logout_from_another_tab',
190
- logout_from_same_tab: 'logout_from_same_tab',
191
- token_renewed: 'token_renewed',
192
- token_timer: 'token_timer',
193
- loginAsync_begin: 'loginAsync_begin',
194
- loginAsync_error: 'loginAsync_error',
195
- loginCallbackAsync_begin: 'loginCallbackAsync_begin',
196
- loginCallbackAsync_end: 'loginCallbackAsync_end',
197
- loginCallbackAsync_error: 'loginCallbackAsync_error',
198
- refreshTokensAsync_begin: 'refreshTokensAsync_begin',
199
- refreshTokensAsync: 'refreshTokensAsync',
200
- refreshTokensAsync_end: 'refreshTokensAsync_end',
201
- refreshTokensAsync_error: 'refreshTokensAsync_error',
202
- refreshTokensAsync_silent_error: 'refreshTokensAsync_silent_error',
203
- tryKeepExistingSessionAsync_begin: 'tryKeepExistingSessionAsync_begin',
204
- tryKeepExistingSessionAsync_end: 'tryKeepExistingSessionAsync_end',
205
- tryKeepExistingSessionAsync_error: 'tryKeepExistingSessionAsync_error',
206
- silentLoginAsync_begin: 'silentLoginAsync_begin',
207
- silentLoginAsync: 'silentLoginAsync',
208
- silentLoginAsync_end: 'silentLoginAsync_end',
209
- silentLoginAsync_error: 'silentLoginAsync_error',
210
- syncTokensAsync_begin: 'syncTokensAsync_begin',
211
- syncTokensAsync_end: 'syncTokensAsync_end',
212
- syncTokensAsync_error: 'syncTokensAsync_error',
213
- };
214
-
215
108
  const getRandomInt = (max) => {
216
109
  return Math.floor(Math.random() * max);
217
110
  };
218
111
 
219
- const oneHourSecond = 60 * 60;
220
- const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond, storage = window.sessionStorage):
221
- Promise<OidcAuthorizationServiceConfiguration> => {
222
- const fullUrl = `${openIdIssuerUrl}/.well-known/openid-configuration`;
223
-
224
- const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
225
- const data = getFromCache(localStorageKey, storage, timeCacheSecond);
226
- if (data) {
227
- return new OidcAuthorizationServiceConfiguration(data);
228
- }
229
- const response = await fetch(fullUrl);
230
-
231
- if (response.status !== 200) {
232
- return null;
233
- }
234
-
235
- const result = await response.json();
236
-
237
- setCache(localStorageKey, result, storage);
238
- return new OidcAuthorizationServiceConfiguration(result);
239
- };
240
-
241
112
  export class Oidc {
242
113
  public configuration: OidcConfiguration;
243
114
  public userInfo: null;
244
115
  public tokens?: Tokens;
245
116
  public events: Array<any>;
246
117
  private timeoutId: NodeJS.Timeout;
247
- private configurationName: string;
118
+ public configurationName: string;
248
119
  private checkSessionIFrame: CheckSessionIFrame;
249
120
  constructor(configuration:OidcConfiguration, configurationName = 'default') {
250
121
  let silent_login_uri = configuration.silent_login_uri;
@@ -335,96 +206,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
335
206
  }
336
207
 
337
208
  async silentLoginAsync(extras:StringMap = null, state:string = null, scope:string = null) {
338
- if (!this.configuration.silent_redirect_uri || !this.configuration.silent_login_uri) {
339
- return Promise.resolve(null);
340
- }
341
-
342
- try {
343
- this.publishEvent(eventNames.silentLoginAsync_begin, {});
344
- const configuration = this.configuration;
345
- let queries = '';
346
-
347
- if (state) {
348
- if (extras == null) {
349
- extras = {};
350
- }
351
- extras.state = state;
352
- }
353
-
354
- if (scope) {
355
- if (extras == null) {
356
- extras = {};
357
- }
358
- extras.scope = scope;
359
- }
360
-
361
- if (extras != null) {
362
- for (const [key, value] of Object.entries(extras)) {
363
- if (queries === '') {
364
- queries = `?${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
365
- } else {
366
- queries += `&${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
367
- }
368
- }
369
- }
370
- const link = configuration.silent_login_uri + queries;
371
- const idx = link.indexOf('/', link.indexOf('//') + 2);
372
- const iFrameOrigin = link.substr(0, idx);
373
- const iframe = document.createElement('iframe');
374
- iframe.width = '0px';
375
- iframe.height = '0px';
376
-
377
- iframe.id = `${this.configurationName}_oidc_iframe`;
378
- iframe.setAttribute('src', link);
379
- document.body.appendChild(iframe);
380
- return new Promise((resolve, reject) => {
381
- try {
382
- let isResolved = false;
383
- window.onmessage = (e: MessageEvent<any>) => {
384
- if (e.origin === iFrameOrigin &&
385
- e.source === iframe.contentWindow
386
- ) {
387
- const key = `${this.configurationName}_oidc_tokens:`;
388
- const key_error = `${this.configurationName}_oidc_error:`;
389
- const data = e.data;
390
- if (data && typeof (data) === 'string') {
391
- if (!isResolved) {
392
- if (data.startsWith(key)) {
393
- const result = JSON.parse(e.data.replace(key, ''));
394
- this.publishEvent(eventNames.silentLoginAsync_end, {});
395
- iframe.remove();
396
- isResolved = true;
397
- resolve(result);
398
- } else if (data.startsWith(key_error)) {
399
- const result = JSON.parse(e.data.replace(key_error, ''));
400
- this.publishEvent(eventNames.silentLoginAsync_error, result);
401
- iframe.remove();
402
- isResolved = true;
403
- reject(new Error('oidc_' + result.error));
404
- }
405
- }
406
- }
407
- }
408
- };
409
- const silentSigninTimeout = configuration.silent_login_timeout;
410
- setTimeout(() => {
411
- if (!isResolved) {
412
- this.publishEvent(eventNames.silentLoginAsync_error, { reason: 'timeout' });
413
- iframe.remove();
414
- isResolved = true;
415
- reject(new Error('timeout'));
416
- }
417
- }, silentSigninTimeout);
418
- } catch (e) {
419
- iframe.remove();
420
- this.publishEvent(eventNames.silentLoginAsync_error, e);
421
- reject(e);
422
- }
423
- });
424
- } catch (e) {
425
- this.publishEvent(eventNames.silentLoginAsync_error, e);
426
- throw e;
427
- }
209
+ return defaultSilentLoginAsync(this.configurationName, this.configuration, this.publishEvent.bind(this))(extras, state, scope);
428
210
  }
429
211
 
430
212
  initPromise = null;
@@ -537,157 +319,26 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
537
319
  });
538
320
  }
539
321
 
322
+ async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin = false) {
323
+ const getCurrentTokens = () => this.tokens;
324
+ this.checkSessionIFrame = await defaultStartCheckSessionAsync(oidcDatabase, this.configuration, this.checkSessionIFrame, this.silentLoginAsync.bind(this), getCurrentTokens)(checkSessionIFrameUri, clientId, sessionState, isSilentSignin);
325
+ }
326
+
540
327
  loginPromise: Promise<void> = null;
541
328
  async loginAsync(callbackPath:string = undefined, extras:StringMap = null, isSilentSignin = false, scope:string = undefined, silentLoginOnly = false) {
542
329
  if (this.loginPromise !== null) {
543
330
  return this.loginPromise;
544
331
  }
545
- const originExtras = extras;
546
- extras = { ...extras };
547
- const loginLocalAsync = async () => {
548
- const location = window.location;
549
- const url = callbackPath || location.pathname + (location.search || '') + (location.hash || '');
550
- const configuration = this.configuration;
551
- let state;
552
- if (extras && 'state' in extras) {
553
- state = extras.state;
554
- delete extras.state;
555
- }
556
-
557
- if (silentLoginOnly) {
558
- try {
559
- const extraFinal = extras ?? configuration.extras ?? {};
560
- const silentResult = await this.silentLoginAsync({
561
- ...extraFinal,
562
- prompt: 'none',
563
- }, state, scope);
564
-
565
- if (silentResult) {
566
- this.tokens = silentResult.tokens;
567
- this.publishEvent(eventNames.token_aquired, {});
568
- // @ts-ignore
569
- this.timeoutId = autoRenewTokens(this, this.tokens.refreshToken, this.tokens.expiresAt, extras);
570
- return {};
571
- }
572
- } catch (e) {
573
- return e;
574
- }
575
- }
576
- this.publishEvent(eventNames.loginAsync_begin, {});
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
- }
585
- try {
586
- const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
587
- if (!scope) {
588
- scope = configuration.scope;
589
- }
590
-
591
- const extraFinal = extras ?? configuration.extras ?? {};
592
- if (!extraFinal.nonce) {
593
- extraFinal.nonce = randomString(12);
594
- }
595
- const nonce = { nonce: extraFinal.nonce };
596
- const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
597
- const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
598
- let storage;
599
- if (serviceWorker) {
600
- serviceWorker.setLoginParams(this.configurationName, { callbackPath: url, extras: originExtras, state });
601
- serviceWorker.startKeepAliveServiceWorker();
602
- await serviceWorker.initAsync(oidcServerConfiguration, 'loginAsync', configuration);
603
- await serviceWorker.setNonceAsync(nonce);
604
- storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, {});
605
- await storage.setItem('dummy', {});
606
- } else {
607
- let session = initSession(this.configurationName, configuration.storage ?? sessionStorage);
608
- session.setLoginParams(this.configurationName, { callbackPath: url, extras: originExtras, state });
609
- session = initSession(this.configurationName);
610
- await session.setNonceAsync(nonce);
611
- storage = new MemoryStorageBackend(session.saveItemsAsync, {});
612
- }
613
-
614
- // @ts-ignore
615
- const queryStringUtil = redirectUri.includes('#') ? new HashQueryStringUtils() : new NoHashQueryStringUtils();
616
- const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
617
- const authRequest = new AuthorizationRequest({
618
- client_id: configuration.client_id,
619
- redirect_uri: redirectUri,
620
- scope,
621
- response_type: AuthorizationRequest.RESPONSE_TYPE_CODE,
622
- state,
623
- extras: extraFinal,
624
- });
625
- authorizationHandler.performAuthorizationRequest(oidcServerConfiguration, authRequest);
626
- } catch (exception) {
627
- this.publishEvent(eventNames.loginAsync_error, exception);
628
- throw exception;
629
- }
630
- };
631
- this.loginPromise = loginLocalAsync();
332
+ if (silentLoginOnly) {
333
+ return defaultSilentLoginAsync2(window, this.configurationName, this.configuration, this.publishEvent.bind(this), this)(extras, scope);
334
+ }
335
+ this.loginPromise = defaultLoginAsync(window, this.configurationName, this.configuration, this.silentLoginAsync.bind(this), this.publishEvent.bind(this), this.initAsync.bind(this))(callbackPath, extras, isSilentSignin, scope);
632
336
  return this.loginPromise.then(result => {
633
337
  this.loginPromise = null;
634
338
  return result;
635
339
  });
636
340
  }
637
341
 
638
- async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin = false) {
639
- return new Promise<void>((resolve, reject): void => {
640
- if (this.configuration.silent_login_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
641
- const checkSessionCallback = () => {
642
- this.checkSessionIFrame.stop();
643
-
644
- if (this.tokens === null) {
645
- return;
646
- }
647
- // @ts-ignore
648
- const idToken = this.tokens.idToken;
649
- // @ts-ignore
650
- const idTokenPayload = this.tokens.idTokenPayload;
651
- this.silentLoginAsync({
652
- prompt: 'none',
653
- id_token_hint: idToken,
654
- scope: 'openid',
655
- }).then((silentSigninResponse) => {
656
- const iFrameIdTokenPayload = silentSigninResponse.tokens.idTokenPayload;
657
- if (idTokenPayload.sub === iFrameIdTokenPayload.sub) {
658
- const sessionState = silentSigninResponse.sessionState;
659
- this.checkSessionIFrame.start(silentSigninResponse.sessionState);
660
- if (idTokenPayload.sid === iFrameIdTokenPayload.sid) {
661
- console.debug('SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:', sessionState);
662
- } else {
663
- console.debug('SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:', sessionState);
664
- }
665
- } else {
666
- console.debug('SessionMonitor._callback: Different subject signed into OP:', iFrameIdTokenPayload.sub);
667
- }
668
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
669
- }).catch(async (e) => {
670
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
671
- for (const [key, oidc] of Object.entries(oidcDatabase)) {
672
- // @ts-ignore
673
- await oidc.logoutOtherTabAsync(this.configuration.client_id, idTokenPayload.sub);
674
- }
675
- });
676
- };
677
-
678
- this.checkSessionIFrame = new CheckSessionIFrame(checkSessionCallback, clientId, checkSessionIFrameUri);
679
- this.checkSessionIFrame.load().then(() => {
680
- this.checkSessionIFrame.start(sessionState);
681
- resolve();
682
- }).catch((e) => {
683
- reject(e);
684
- });
685
- } else {
686
- resolve();
687
- }
688
- });
689
- }
690
-
691
342
  loginCallbackPromise : Promise<any> = null;
692
343
  async loginCallbackAsync(isSilenSignin = false) {
693
344
  if (this.loginCallbackPromise !== null) {
@@ -775,9 +426,9 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
775
426
  return;
776
427
  }
777
428
 
778
- let extras = null;
429
+ const extras = {};
779
430
  if (request && request.internal) {
780
- extras = {};
431
+ // @ts-ignore
781
432
  extras.code_verifier = request.internal.code_verifier;
782
433
  if (configuration.token_request_extras) {
783
434
  for (const [key, value] of Object.entries(configuration.token_request_extras)) {
@@ -786,7 +437,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
786
437
  }
787
438
  if (getLoginParams && getLoginParams.extras) {
788
439
  for (const [key, value] of Object.entries(getLoginParams.extras)) {
789
- if (key.endsWith(':authorize_request')) {
440
+ if (key.endsWith(':token_request')) {
790
441
  extras[key.replace(':token_request', '')] = value;
791
442
  }
792
443
  }
@@ -795,8 +446,8 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
795
446
 
796
447
  const tokenRequest = new TokenRequest({
797
448
  client_id: clientId,
798
- redirect_uri: redirectUri,
799
- grant_type: GRANT_TYPE_AUTHORIZATION_CODE,
449
+ redirect_uri: redirectUri, // @ts-ignore
450
+ grant_type: extras.grant_type ?? GRANT_TYPE_AUTHORIZATION_CODE,
800
451
  code: response.code,
801
452
  refresh_token: undefined,
802
453
  extras,