@axa-fr/oidc-client 7.22.18 → 7.22.19

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 (73) hide show
  1. package/README.md +31 -39
  2. package/bin/copy-service-worker-files.mjs +24 -17
  3. package/dist/OidcTrustedDomains.js +14 -12
  4. package/dist/cache.d.ts.map +1 -1
  5. package/dist/checkSession.d.ts +1 -1
  6. package/dist/checkSession.d.ts.map +1 -1
  7. package/dist/checkSessionIFrame.d.ts.map +1 -1
  8. package/dist/crypto.d.ts.map +1 -1
  9. package/dist/fetch.d.ts +2 -1
  10. package/dist/fetch.d.ts.map +1 -1
  11. package/dist/index.d.ts +5 -5
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +935 -601
  14. package/dist/index.umd.cjs +2 -2
  15. package/dist/initSession.d.ts +1 -1
  16. package/dist/initSession.d.ts.map +1 -1
  17. package/dist/initWorker.d.ts +2 -2
  18. package/dist/initWorker.d.ts.map +1 -1
  19. package/dist/initWorkerOption.d.ts.map +1 -1
  20. package/dist/jwt.d.ts +2 -2
  21. package/dist/jwt.d.ts.map +1 -1
  22. package/dist/keepSession.d.ts.map +1 -1
  23. package/dist/location.d.ts.map +1 -1
  24. package/dist/login.d.ts +1 -1
  25. package/dist/login.d.ts.map +1 -1
  26. package/dist/logout.d.ts +1 -1
  27. package/dist/logout.d.ts.map +1 -1
  28. package/dist/oidc.d.ts +1 -1
  29. package/dist/oidc.d.ts.map +1 -1
  30. package/dist/oidcClient.d.ts +2 -2
  31. package/dist/oidcClient.d.ts.map +1 -1
  32. package/dist/parseTokens.d.ts.map +1 -1
  33. package/dist/renewTokens.d.ts.map +1 -1
  34. package/dist/requests.d.ts +1 -1
  35. package/dist/requests.d.ts.map +1 -1
  36. package/dist/silentLogin.d.ts.map +1 -1
  37. package/dist/timer.d.ts.map +1 -1
  38. package/dist/types.d.ts +1 -1
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/user.d.ts.map +1 -1
  41. package/dist/version.d.ts +1 -1
  42. package/package.json +2 -2
  43. package/src/cache.ts +21 -18
  44. package/src/checkSession.ts +89 -54
  45. package/src/checkSessionIFrame.ts +70 -69
  46. package/src/crypto.ts +27 -25
  47. package/src/events.ts +28 -28
  48. package/src/fetch.ts +40 -21
  49. package/src/index.ts +6 -17
  50. package/src/iniWorker.spec.ts +26 -16
  51. package/src/initSession.ts +115 -113
  52. package/src/initWorker.ts +299 -212
  53. package/src/initWorkerOption.ts +121 -114
  54. package/src/jwt.ts +150 -136
  55. package/src/keepSession.ts +100 -81
  56. package/src/location.ts +24 -26
  57. package/src/login.ts +246 -189
  58. package/src/logout.spec.ts +131 -76
  59. package/src/logout.ts +130 -115
  60. package/src/oidc.ts +426 -337
  61. package/src/oidcClient.ts +129 -105
  62. package/src/parseTokens.spec.ts +198 -179
  63. package/src/parseTokens.ts +221 -186
  64. package/src/renewTokens.ts +397 -284
  65. package/src/requests.spec.ts +5 -7
  66. package/src/requests.ts +142 -114
  67. package/src/route-utils.spec.ts +17 -19
  68. package/src/route-utils.ts +29 -26
  69. package/src/silentLogin.ts +145 -127
  70. package/src/timer.ts +10 -11
  71. package/src/types.ts +56 -46
  72. package/src/user.ts +17 -12
  73. package/src/version.ts +1 -1
package/src/oidc.ts CHANGED
@@ -1,401 +1,490 @@
1
- import {startCheckSessionAsync as defaultStartCheckSessionAsync} from './checkSession.js';
2
- import {CheckSessionIFrame} from './checkSessionIFrame.js';
3
- import {eventNames} from './events.js';
4
- import {initSession} from './initSession.js';
5
- import {defaultServiceWorkerUpdateRequireCallback, initWorkerAsync, sleepAsync} from './initWorker.js';
6
- import {defaultLoginAsync, loginCallbackAsync} from './login.js';
7
- import {destroyAsync, logoutAsync} from './logout.js';
8
- import {TokenRenewMode, Tokens,} from './parseTokens.js';
1
+ import { startCheckSessionAsync as defaultStartCheckSessionAsync } from './checkSession.js';
2
+ import { CheckSessionIFrame } from './checkSessionIFrame.js';
3
+ import { base64urlOfHashOfASCIIEncodingAsync } from './crypto';
4
+ import { eventNames } from './events.js';
5
+ import { initSession } from './initSession.js';
6
+ import { defaultServiceWorkerUpdateRequireCallback, initWorkerAsync } from './initWorker.js';
7
+ import { activateServiceWorker } from './initWorkerOption';
9
8
  import {
10
- autoRenewTokens,
11
- renewTokensAndStartTimerAsync
12
- } from './renewTokens.js';
13
- import {fetchFromIssuer} from './requests.js';
14
- import {getParseQueryStringFromLocation} from './route-utils.js';
9
+ defaultDemonstratingProofOfPossessionConfiguration,
10
+ generateJwtDemonstratingProofOfPossessionAsync,
11
+ } from './jwt';
12
+ import { tryKeepSessionAsync } from './keepSession';
13
+ import { ILOidcLocation, OidcLocation } from './location';
14
+ import { defaultLoginAsync, loginCallbackAsync } from './login.js';
15
+ import { destroyAsync, logoutAsync } from './logout.js';
16
+ import { TokenRenewMode, Tokens } from './parseTokens.js';
17
+ import { autoRenewTokens, renewTokensAndStartTimerAsync } from './renewTokens.js';
18
+ import { fetchFromIssuer } from './requests.js';
19
+ import { getParseQueryStringFromLocation } from './route-utils.js';
15
20
  import defaultSilentLoginAsync from './silentLogin.js';
16
21
  import timer from './timer.js';
17
- import {AuthorityConfiguration, Fetch, OidcConfiguration, StringMap, TokenAutomaticRenewMode} from './types.js';
18
- import {userInfoAsync} from './user.js';
19
- import {base64urlOfHashOfASCIIEncodingAsync} from "./crypto";
20
22
  import {
21
- defaultDemonstratingProofOfPossessionConfiguration,
22
- generateJwtDemonstratingProofOfPossessionAsync
23
- } from "./jwt";
24
- import {ILOidcLocation, OidcLocation} from "./location";
25
- import {activateServiceWorker} from "./initWorkerOption";
26
- import {tryKeepSessionAsync} from "./keepSession";
27
-
28
-
23
+ AuthorityConfiguration,
24
+ Fetch,
25
+ OidcConfiguration,
26
+ StringMap,
27
+ TokenAutomaticRenewMode,
28
+ } from './types.js';
29
+ import { userInfoAsync } from './user.js';
29
30
 
30
31
  export const getFetchDefault = () => {
31
- return fetch;
32
+ return fetch;
32
33
  };
33
34
 
34
35
  export interface OidcAuthorizationServiceConfigurationJson {
35
- check_session_iframe?: string;
36
- issuer:string;
36
+ check_session_iframe?: string;
37
+ issuer: string;
37
38
  }
38
39
 
39
-
40
-
41
40
  export class OidcAuthorizationServiceConfiguration {
42
- private checkSessionIframe: string;
43
- private issuer: string;
44
- private authorizationEndpoint: string;
45
- private tokenEndpoint: string;
46
- private revocationEndpoint: string;
47
- private userInfoEndpoint: string;
48
- private endSessionEndpoint: string;
49
-
50
- constructor(request: any) {
51
- this.authorizationEndpoint = request.authorization_endpoint;
52
- this.tokenEndpoint = request.token_endpoint;
53
- this.revocationEndpoint = request.revocation_endpoint;
54
- this.userInfoEndpoint = request.userinfo_endpoint;
55
- this.checkSessionIframe = request.check_session_iframe;
56
- this.issuer = request.issuer;
57
- this.endSessionEndpoint = request.end_session_endpoint;
58
- }
41
+ private checkSessionIframe: string;
42
+ private issuer: string;
43
+ private authorizationEndpoint: string;
44
+ private tokenEndpoint: string;
45
+ private revocationEndpoint: string;
46
+ private userInfoEndpoint: string;
47
+ private endSessionEndpoint: string;
48
+
49
+ constructor(request: any) {
50
+ this.authorizationEndpoint = request.authorization_endpoint;
51
+ this.tokenEndpoint = request.token_endpoint;
52
+ this.revocationEndpoint = request.revocation_endpoint;
53
+ this.userInfoEndpoint = request.userinfo_endpoint;
54
+ this.checkSessionIframe = request.check_session_iframe;
55
+ this.issuer = request.issuer;
56
+ this.endSessionEndpoint = request.end_session_endpoint;
57
+ }
59
58
  }
60
59
 
61
60
  const oidcDatabase = {};
62
- const oidcFactory = (getFetch : () => Fetch, location: ILOidcLocation = new OidcLocation()) => (configuration: OidcConfiguration, name = 'default') => {
61
+ const oidcFactory =
62
+ (getFetch: () => Fetch, location: ILOidcLocation = new OidcLocation()) =>
63
+ (configuration: OidcConfiguration, name = 'default') => {
63
64
  if (oidcDatabase[name]) {
64
- return oidcDatabase[name];
65
+ return oidcDatabase[name];
65
66
  }
66
67
  oidcDatabase[name] = new Oidc(configuration, name, getFetch, location);
67
68
  return oidcDatabase[name];
68
- };
69
+ };
69
70
  export type LoginCallback = {
70
- callbackPath:string;
71
- }
71
+ callbackPath: string;
72
+ };
72
73
 
73
74
  export type InternalLoginCallback = {
74
- callbackPath:string;
75
- parsedTokens:Tokens;
76
- }
75
+ callbackPath: string;
76
+ parsedTokens: Tokens;
77
+ };
77
78
 
78
- const loginCallbackWithAutoTokensRenewAsync = async (oidc) : Promise<LoginCallback> => {
79
- const { parsedTokens, callbackPath } = await oidc.loginCallbackAsync();
80
- oidc.timeoutId = autoRenewTokens(oidc, parsedTokens.expiresAt);
81
- return { callbackPath };
79
+ const loginCallbackWithAutoTokensRenewAsync = async (oidc): Promise<LoginCallback> => {
80
+ const { parsedTokens, callbackPath } = await oidc.loginCallbackAsync();
81
+ oidc.timeoutId = autoRenewTokens(oidc, parsedTokens.expiresAt);
82
+ return { callbackPath };
82
83
  };
83
84
 
84
- const getRandomInt = (max) => {
85
- return Math.floor(Math.random() * max);
85
+ const getRandomInt = max => {
86
+ return Math.floor(Math.random() * max);
86
87
  };
87
88
 
88
89
  export class Oidc {
89
- public configuration: OidcConfiguration;
90
- public userInfo: null;
91
- public tokens?: Tokens;
92
- public events: Array<any>;
93
- public timeoutId: NodeJS.Timeout | number;
94
- public configurationName: string;
95
- public checkSessionIFrame: CheckSessionIFrame;
96
- public getFetch: () => Fetch;
97
- public location: ILOidcLocation;
98
- constructor(configuration:OidcConfiguration, configurationName = 'default', getFetch : () => Fetch, location: ILOidcLocation = new OidcLocation()) {
99
- let silent_login_uri = configuration.silent_login_uri;
100
- if (configuration.silent_redirect_uri && !configuration.silent_login_uri) {
101
- silent_login_uri = `${configuration.silent_redirect_uri.replace('-callback', '').replace('callback', '')}-login`;
102
- }
103
- let refresh_time_before_tokens_expiration_in_second = configuration.refresh_time_before_tokens_expiration_in_second ?? 120;
104
- if (refresh_time_before_tokens_expiration_in_second > 60) {
105
- refresh_time_before_tokens_expiration_in_second = refresh_time_before_tokens_expiration_in_second - Math.floor(Math.random() * 40);
106
- }
107
- this.location = location ?? new OidcLocation();
108
- const service_worker_update_require_callback = configuration.service_worker_update_require_callback ?? defaultServiceWorkerUpdateRequireCallback(this.location);
109
-
110
- this.configuration = {
111
- ...configuration,
112
- silent_login_uri,
113
- token_automatic_renew_mode: configuration.token_automatic_renew_mode ?? TokenAutomaticRenewMode.AutomaticBeforeTokenExpiration,
114
- monitor_session: configuration.monitor_session ?? false,
115
- refresh_time_before_tokens_expiration_in_second,
116
- silent_login_timeout: configuration.silent_login_timeout ?? 12000,
117
- token_renew_mode: configuration.token_renew_mode ?? TokenRenewMode.access_token_or_id_token_invalid,
118
- demonstrating_proof_of_possession: configuration.demonstrating_proof_of_possession ?? false,
119
- authority_timeout_wellknowurl_in_millisecond: configuration.authority_timeout_wellknowurl_in_millisecond ?? 10000,
120
- logout_tokens_to_invalidate: configuration.logout_tokens_to_invalidate ?? ['access_token', 'refresh_token'],
121
- service_worker_update_require_callback,
122
- service_worker_activate: configuration.service_worker_activate ?? activateServiceWorker,
123
- demonstrating_proof_of_possession_configuration: configuration.demonstrating_proof_of_possession_configuration ?? defaultDemonstratingProofOfPossessionConfiguration,
124
- preload_user_info: configuration.preload_user_info ?? false,
125
- };
126
-
127
- this.getFetch = getFetch ?? getFetchDefault;
128
- this.configurationName = configurationName;
129
- this.tokens = null;
130
- this.userInfo = null;
131
- this.events = [];
132
- this.timeoutId = null;
133
- this.loginCallbackWithAutoTokensRenewAsync.bind(this);
134
- this.initAsync.bind(this);
135
- this.loginCallbackAsync.bind(this);
136
- this.subscribeEvents.bind(this);
137
- this.removeEventSubscription.bind(this);
138
- this.publishEvent.bind(this);
139
- this.destroyAsync.bind(this);
140
- this.logoutAsync.bind(this);
141
- this.renewTokensAsync.bind(this);
142
- this.initAsync(this.configuration.authority, this.configuration.authority_configuration);
90
+ public configuration: OidcConfiguration;
91
+ public userInfo: null;
92
+ public tokens?: Tokens;
93
+ public events: Array<any>;
94
+ public timeoutId: NodeJS.Timeout | number;
95
+ public configurationName: string;
96
+ public checkSessionIFrame: CheckSessionIFrame;
97
+ public getFetch: () => Fetch;
98
+ public location: ILOidcLocation;
99
+ constructor(
100
+ configuration: OidcConfiguration,
101
+ configurationName = 'default',
102
+ getFetch: () => Fetch,
103
+ location: ILOidcLocation = new OidcLocation(),
104
+ ) {
105
+ let silent_login_uri = configuration.silent_login_uri;
106
+ if (configuration.silent_redirect_uri && !configuration.silent_login_uri) {
107
+ silent_login_uri = `${configuration.silent_redirect_uri.replace('-callback', '').replace('callback', '')}-login`;
108
+ }
109
+ let refresh_time_before_tokens_expiration_in_second =
110
+ configuration.refresh_time_before_tokens_expiration_in_second ?? 120;
111
+ if (refresh_time_before_tokens_expiration_in_second > 60) {
112
+ refresh_time_before_tokens_expiration_in_second =
113
+ refresh_time_before_tokens_expiration_in_second - Math.floor(Math.random() * 40);
114
+ }
115
+ this.location = location ?? new OidcLocation();
116
+ const service_worker_update_require_callback =
117
+ configuration.service_worker_update_require_callback ??
118
+ defaultServiceWorkerUpdateRequireCallback(this.location);
119
+
120
+ this.configuration = {
121
+ ...configuration,
122
+ silent_login_uri,
123
+ token_automatic_renew_mode:
124
+ configuration.token_automatic_renew_mode ??
125
+ TokenAutomaticRenewMode.AutomaticBeforeTokenExpiration,
126
+ monitor_session: configuration.monitor_session ?? false,
127
+ refresh_time_before_tokens_expiration_in_second,
128
+ silent_login_timeout: configuration.silent_login_timeout ?? 12000,
129
+ token_renew_mode:
130
+ configuration.token_renew_mode ?? TokenRenewMode.access_token_or_id_token_invalid,
131
+ demonstrating_proof_of_possession: configuration.demonstrating_proof_of_possession ?? false,
132
+ authority_timeout_wellknowurl_in_millisecond:
133
+ configuration.authority_timeout_wellknowurl_in_millisecond ?? 10000,
134
+ logout_tokens_to_invalidate: configuration.logout_tokens_to_invalidate ?? [
135
+ 'access_token',
136
+ 'refresh_token',
137
+ ],
138
+ service_worker_update_require_callback,
139
+ service_worker_activate: configuration.service_worker_activate ?? activateServiceWorker,
140
+ demonstrating_proof_of_possession_configuration:
141
+ configuration.demonstrating_proof_of_possession_configuration ??
142
+ defaultDemonstratingProofOfPossessionConfiguration,
143
+ preload_user_info: configuration.preload_user_info ?? false,
144
+ };
145
+
146
+ this.getFetch = getFetch ?? getFetchDefault;
147
+ this.configurationName = configurationName;
148
+ this.tokens = null;
149
+ this.userInfo = null;
150
+ this.events = [];
151
+ this.timeoutId = null;
152
+ this.loginCallbackWithAutoTokensRenewAsync.bind(this);
153
+ this.initAsync.bind(this);
154
+ this.loginCallbackAsync.bind(this);
155
+ this.subscribeEvents.bind(this);
156
+ this.removeEventSubscription.bind(this);
157
+ this.publishEvent.bind(this);
158
+ this.destroyAsync.bind(this);
159
+ this.logoutAsync.bind(this);
160
+ this.renewTokensAsync.bind(this);
161
+ this.initAsync(this.configuration.authority, this.configuration.authority_configuration);
162
+ }
163
+
164
+ subscribeEvents(func): string {
165
+ const id = getRandomInt(9999999999999).toString();
166
+ this.events.push({ id, func });
167
+ return id;
168
+ }
169
+
170
+ removeEventSubscription(id): void {
171
+ const newEvents = this.events.filter(e => e.id !== id);
172
+ this.events = newEvents;
173
+ }
174
+
175
+ publishEvent(eventName, data) {
176
+ this.events.forEach(event => {
177
+ event.func(eventName, data);
178
+ });
179
+ }
180
+
181
+ static getOrCreate =
182
+ (getFetch: () => Fetch, location: ILOidcLocation) =>
183
+ (configuration, name = 'default') => {
184
+ return oidcFactory(getFetch, location)(configuration, name);
185
+ };
186
+
187
+ static get(name = 'default') {
188
+ const isInsideBrowser = typeof process === 'undefined';
189
+ if (!Object.prototype.hasOwnProperty.call(oidcDatabase, name) && isInsideBrowser) {
190
+ throw Error(`OIDC library does seem initialized.
191
+ Please checkout that you are using OIDC hook inside a <OidcProvider configurationName="${name}"></OidcProvider> component.`);
143
192
  }
193
+ return oidcDatabase[name];
194
+ }
144
195
 
145
- subscribeEvents(func):string {
146
- const id = getRandomInt(9999999999999).toString();
147
- this.events.push({ id, func });
148
- return id;
196
+ static eventNames = eventNames;
197
+
198
+ _silentLoginCallbackFromIFrame() {
199
+ if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
200
+ const location = this.location;
201
+ const queryParams = getParseQueryStringFromLocation(location.getCurrentHref());
202
+ window.parent.postMessage(
203
+ `${this.configurationName}_oidc_tokens:${JSON.stringify({ tokens: this.tokens, sessionState: queryParams.session_state })}`,
204
+ location.getOrigin(),
205
+ );
149
206
  }
207
+ }
150
208
 
151
- removeEventSubscription(id) :void {
152
- const newEvents = this.events.filter(e => e.id !== id);
153
- this.events = newEvents;
209
+ _silentLoginErrorCallbackFromIFrame(exception = null) {
210
+ if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
211
+ const location = this.location;
212
+ const queryParams = getParseQueryStringFromLocation(location.getCurrentHref());
213
+ if (queryParams.error) {
214
+ window.parent.postMessage(
215
+ `${this.configurationName}_oidc_error:${JSON.stringify({ error: queryParams.error })}`,
216
+ location.getOrigin(),
217
+ );
218
+ } else {
219
+ window.parent.postMessage(
220
+ `${this.configurationName}_oidc_exception:${JSON.stringify({ error: exception == null ? '' : exception.toString() })}`,
221
+ location.getOrigin(),
222
+ );
223
+ }
154
224
  }
225
+ }
155
226
 
156
- publishEvent(eventName, data) {
157
- this.events.forEach(event => {
158
- event.func(eventName, data);
159
- });
227
+ async silentLoginCallbackAsync() {
228
+ try {
229
+ await this.loginCallbackAsync(true);
230
+ this._silentLoginCallbackFromIFrame();
231
+ } catch (exception) {
232
+ console.error(exception);
233
+ this._silentLoginErrorCallbackFromIFrame(exception);
234
+ }
235
+ }
236
+
237
+ initPromise = null;
238
+ async initAsync(authority: string, authorityConfiguration: AuthorityConfiguration) {
239
+ if (this.initPromise !== null) {
240
+ return this.initPromise;
160
241
  }
242
+ const localFuncAsync = async () => {
243
+ if (authorityConfiguration != null) {
244
+ return new OidcAuthorizationServiceConfiguration({
245
+ authorization_endpoint: authorityConfiguration.authorization_endpoint,
246
+ end_session_endpoint: authorityConfiguration.end_session_endpoint,
247
+ revocation_endpoint: authorityConfiguration.revocation_endpoint,
248
+ token_endpoint: authorityConfiguration.token_endpoint,
249
+ userinfo_endpoint: authorityConfiguration.userinfo_endpoint,
250
+ check_session_iframe: authorityConfiguration.check_session_iframe,
251
+ issuer: authorityConfiguration.issuer,
252
+ });
253
+ }
161
254
 
162
- static getOrCreate = (getFetch : () => Fetch, location:ILOidcLocation) => (configuration, name = 'default') => {
163
- return oidcFactory(getFetch, location)(configuration, name);
255
+ const serviceWorker = await initWorkerAsync(this.configuration, this.configurationName);
256
+ const storage = serviceWorker ? window.localStorage : null;
257
+ return await fetchFromIssuer(this.getFetch())(
258
+ authority,
259
+ this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60,
260
+ storage,
261
+ this.configuration.authority_timeout_wellknowurl_in_millisecond,
262
+ );
164
263
  };
264
+ this.initPromise = localFuncAsync();
265
+ return this.initPromise.finally(() => {
266
+ // in case if anything went wrong with the promise, we should reset the initPromise to null too
267
+ // otherwise client can't re-init the OIDC client
268
+ // as the promise is already fulfilled with rejected state, so could not ever reach this point again,
269
+ // so that leads to infinite loop of calls, when client tries to re-init the OIDC client after error
270
+ this.initPromise = null;
271
+ });
272
+ }
165
273
 
166
- static get(name = 'default') {
167
- const isInsideBrowser = (typeof process === 'undefined');
168
- if (!Object.prototype.hasOwnProperty.call(oidcDatabase, name) && isInsideBrowser) {
169
- throw Error(`OIDC library does seem initialized.
170
- Please checkout that you are using OIDC hook inside a <OidcProvider configurationName="${name}"></OidcProvider> component.`);
171
- }
172
- return oidcDatabase[name];
274
+ tryKeepExistingSessionPromise = null;
275
+ async tryKeepExistingSessionAsync(): Promise<boolean> {
276
+ if (this.tryKeepExistingSessionPromise !== null) {
277
+ return this.tryKeepExistingSessionPromise;
173
278
  }
279
+ this.tryKeepExistingSessionPromise = tryKeepSessionAsync(this);
280
+ return this.tryKeepExistingSessionPromise.finally(() => {
281
+ this.tryKeepExistingSessionPromise = null;
282
+ });
283
+ }
174
284
 
175
- static eventNames = eventNames;
285
+ async startCheckSessionAsync(
286
+ checkSessionIFrameUri,
287
+ clientId,
288
+ sessionState,
289
+ isSilentSignin = false,
290
+ ) {
291
+ await defaultStartCheckSessionAsync(this, oidcDatabase, this.configuration)(
292
+ checkSessionIFrameUri,
293
+ clientId,
294
+ sessionState,
295
+ isSilentSignin,
296
+ );
297
+ }
176
298
 
177
- _silentLoginCallbackFromIFrame() {
178
- if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
179
- const location = this.location;
180
- const queryParams = getParseQueryStringFromLocation(location.getCurrentHref());
181
- window.parent.postMessage(`${this.configurationName}_oidc_tokens:${JSON.stringify({ tokens: this.tokens, sessionState: queryParams.session_state })}`, location.getOrigin());
182
- }
299
+ loginPromise: Promise<void> = null;
300
+ async loginAsync(
301
+ callbackPath: string = undefined,
302
+ extras: StringMap = null,
303
+ isSilentSignin = false,
304
+ scope: string = undefined,
305
+ silentLoginOnly = false,
306
+ ) {
307
+ if (this.logoutPromise) {
308
+ await this.logoutPromise;
183
309
  }
184
310
 
185
- _silentLoginErrorCallbackFromIFrame(exception=null) {
186
- if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
187
- const location = this.location;
188
- const queryParams = getParseQueryStringFromLocation(location.getCurrentHref());
189
- if(queryParams.error) {
190
- window.parent.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error: queryParams.error})}`, location.getOrigin());
191
- } else {
192
- window.parent.postMessage(`${this.configurationName}_oidc_exception:${JSON.stringify({ error: exception == null ? "" : exception.toString() })}`, location.getOrigin());
193
- }
194
-
195
- }
311
+ if (this.loginPromise !== null) {
312
+ return this.loginPromise;
313
+ }
314
+ if (silentLoginOnly) {
315
+ return defaultSilentLoginAsync(
316
+ window,
317
+ this.configurationName,
318
+ this.configuration,
319
+ this.publishEvent.bind(this),
320
+ this,
321
+ )(extras, scope);
196
322
  }
323
+ this.loginPromise = defaultLoginAsync(
324
+ this.configurationName,
325
+ this.configuration,
326
+ this.publishEvent.bind(this),
327
+ this.initAsync.bind(this),
328
+ this.location,
329
+ )(callbackPath, extras, isSilentSignin, scope);
330
+ return this.loginPromise.finally(() => {
331
+ this.loginPromise = null;
332
+ });
333
+ }
197
334
 
198
- async silentLoginCallbackAsync() {
199
- try {
200
- await this.loginCallbackAsync(true);
201
- this._silentLoginCallbackFromIFrame();
202
- } catch (exception) {
203
- console.error(exception);
204
- this._silentLoginErrorCallbackFromIFrame(exception);
205
- }
335
+ loginCallbackPromise: Promise<any> = null;
336
+ async loginCallbackAsync(isSilenSignin = false) {
337
+ if (this.loginCallbackPromise !== null) {
338
+ return this.loginCallbackPromise;
206
339
  }
207
340
 
208
- initPromise = null;
209
- async initAsync(authority:string, authorityConfiguration:AuthorityConfiguration) {
210
- if (this.initPromise !== null) {
211
- return this.initPromise;
212
- }
213
- const localFuncAsync = async () => {
214
- if (authorityConfiguration != null) {
215
- return new OidcAuthorizationServiceConfiguration({
216
- authorization_endpoint: authorityConfiguration.authorization_endpoint,
217
- end_session_endpoint: authorityConfiguration.end_session_endpoint,
218
- revocation_endpoint: authorityConfiguration.revocation_endpoint,
219
- token_endpoint: authorityConfiguration.token_endpoint,
220
- userinfo_endpoint: authorityConfiguration.userinfo_endpoint,
221
- check_session_iframe: authorityConfiguration.check_session_iframe,
222
- issuer: authorityConfiguration.issuer,
223
- });
224
- }
225
-
226
- const serviceWorker = await initWorkerAsync(this.configuration, this.configurationName);
227
- const storage = serviceWorker ? window.localStorage : null;
228
- return await fetchFromIssuer(this.getFetch())(authority, this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60, storage, this.configuration.authority_timeout_wellknowurl_in_millisecond);
229
- };
230
- this.initPromise = localFuncAsync();
231
- return this.initPromise.finally(() => {
232
- // in case if anything went wrong with the promise, we should reset the initPromise to null too
233
- // otherwise client can't re-init the OIDC client
234
- // as the promise is already fulfilled with rejected state, so could not ever reach this point again,
235
- // so that leads to infinite loop of calls, when client tries to re-init the OIDC client after error
236
- this.initPromise = null;
237
- });
341
+ const loginCallbackLocalAsync = async (): Promise<InternalLoginCallback> => {
342
+ const response = await loginCallbackAsync(this)(isSilenSignin);
343
+ // @ts-ignore
344
+ const parsedTokens = response.tokens;
345
+ // @ts-ignore
346
+ this.tokens = parsedTokens;
347
+ const serviceWorker = await initWorkerAsync(this.configuration, this.configurationName);
348
+ if (!serviceWorker) {
349
+ const session = initSession(this.configurationName, this.configuration.storage);
350
+ session.setTokens(parsedTokens);
351
+ }
352
+ this.publishEvent(Oidc.eventNames.token_aquired, parsedTokens);
353
+ if (this.configuration.preload_user_info) {
354
+ await this.userInfoAsync();
355
+ }
356
+ // @ts-ignore
357
+ return { parsedTokens, state: response.state, callbackPath: response.callbackPath };
358
+ };
359
+ this.loginCallbackPromise = loginCallbackLocalAsync();
360
+ return this.loginCallbackPromise.finally(() => {
361
+ this.loginCallbackPromise = null;
362
+ });
363
+ }
364
+
365
+ async generateDemonstrationOfProofOfPossessionAsync(
366
+ accessToken: string,
367
+ url: string,
368
+ method: string,
369
+ extras: StringMap = {},
370
+ ): Promise<string> {
371
+ const configuration = this.configuration;
372
+ const claimsExtras = {
373
+ ath: await base64urlOfHashOfASCIIEncodingAsync(accessToken),
374
+ ...extras,
375
+ };
376
+
377
+ const serviceWorker = await initWorkerAsync(configuration, this.configurationName);
378
+
379
+ if (serviceWorker) {
380
+ return `DPOP_SECURED_BY_OIDC_SERVICE_WORKER_${this.configurationName}`;
238
381
  }
239
382
 
240
- tryKeepExistingSessionPromise = null;
241
- async tryKeepExistingSessionAsync() :Promise<boolean> {
242
- if (this.tryKeepExistingSessionPromise !== null) {
243
- return this.tryKeepExistingSessionPromise;
244
- }
245
- this.tryKeepExistingSessionPromise = tryKeepSessionAsync(this);
246
- return this.tryKeepExistingSessionPromise.finally(() => {
247
- this.tryKeepExistingSessionPromise = null;
248
- });
383
+ const session = initSession(this.configurationName, configuration.storage);
384
+ const jwk = await session.getDemonstratingProofOfPossessionJwkAsync();
385
+ const demonstratingProofOfPossessionNonce = session.getDemonstratingProofOfPossessionNonce();
386
+
387
+ if (demonstratingProofOfPossessionNonce) {
388
+ claimsExtras['nonce'] = demonstratingProofOfPossessionNonce;
249
389
  }
250
390
 
251
- async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin = false) {
252
- await defaultStartCheckSessionAsync(this, oidcDatabase, this.configuration)(checkSessionIFrameUri, clientId, sessionState, isSilentSignin);
391
+ return await generateJwtDemonstratingProofOfPossessionAsync(window)(
392
+ configuration.demonstrating_proof_of_possession_configuration,
393
+ )(jwk, method, url, claimsExtras);
394
+ }
395
+
396
+ loginCallbackWithAutoTokensRenewPromise: Promise<LoginCallback> = null;
397
+ loginCallbackWithAutoTokensRenewAsync(): Promise<LoginCallback> {
398
+ if (this.loginCallbackWithAutoTokensRenewPromise !== null) {
399
+ return this.loginCallbackWithAutoTokensRenewPromise;
253
400
  }
401
+ this.loginCallbackWithAutoTokensRenewPromise = loginCallbackWithAutoTokensRenewAsync(this);
402
+ return this.loginCallbackWithAutoTokensRenewPromise.finally(() => {
403
+ this.loginCallbackWithAutoTokensRenewPromise = null;
404
+ });
405
+ }
254
406
 
255
- loginPromise: Promise<void> = null;
256
- async loginAsync(callbackPath:string = undefined, extras:StringMap = null, isSilentSignin = false, scope:string = undefined, silentLoginOnly = false) {
257
- if (this.logoutPromise) {
258
- await this.logoutPromise;
259
- }
260
-
261
- if (this.loginPromise !== null) {
262
- return this.loginPromise;
263
- }
264
- if (silentLoginOnly) {
265
- return defaultSilentLoginAsync(window, this.configurationName, this.configuration, this.publishEvent.bind(this), this)(extras, scope);
266
- }
267
- this.loginPromise = defaultLoginAsync(this.configurationName, this.configuration, this.publishEvent.bind(this), this.initAsync.bind(this), this.location)(callbackPath, extras, isSilentSignin, scope);
268
- return this.loginPromise.finally(() => {
269
- this.loginPromise = null;
270
- });
407
+ userInfoPromise: Promise<any> = null;
408
+ userInfoAsync(noCache = false, demonstrating_proof_of_possession = false) {
409
+ if (this.userInfoPromise !== null) {
410
+ return this.userInfoPromise;
271
411
  }
412
+ this.userInfoPromise = userInfoAsync(this)(noCache, demonstrating_proof_of_possession);
413
+ return this.userInfoPromise.finally(() => {
414
+ this.userInfoPromise = null;
415
+ });
416
+ }
272
417
 
273
- loginCallbackPromise : Promise<any> = null;
274
- async loginCallbackAsync(isSilenSignin = false) {
275
- if (this.loginCallbackPromise !== null) {
276
- return this.loginCallbackPromise;
277
- }
278
-
279
- const loginCallbackLocalAsync = async():Promise<InternalLoginCallback> => {
280
- const response = await loginCallbackAsync(this)(isSilenSignin);
281
- // @ts-ignore
282
- const parsedTokens = response.tokens;
283
- // @ts-ignore
284
- this.tokens = parsedTokens;
285
- const serviceWorker = await initWorkerAsync(this.configuration, this.configurationName);
286
- if (!serviceWorker) {
287
- const session = initSession(this.configurationName, this.configuration.storage);
288
- session.setTokens(parsedTokens);
289
- }
290
- this.publishEvent(Oidc.eventNames.token_aquired, parsedTokens);
291
- if(this.configuration.preload_user_info){
292
- await this.userInfoAsync();
293
- }
294
- // @ts-ignore
295
- return { parsedTokens, state: response.state, callbackPath: response.callbackPath };
296
- };
297
- this.loginCallbackPromise = loginCallbackLocalAsync();
298
- return this.loginCallbackPromise.finally(() => {
299
- this.loginCallbackPromise = null;
300
- });
418
+ renewTokensPromise: Promise<any> = null;
419
+
420
+ async renewTokensAsync(extras: StringMap = null) {
421
+ if (this.renewTokensPromise !== null) {
422
+ return this.renewTokensPromise;
423
+ }
424
+ if (!this.timeoutId) {
425
+ return;
301
426
  }
427
+ timer.clearTimeout(this.timeoutId);
428
+ // @ts-ignore
429
+ this.renewTokensPromise = renewTokensAndStartTimerAsync(this, true, extras);
430
+ return this.renewTokensPromise.finally(() => {
431
+ this.renewTokensPromise = null;
432
+ });
433
+ }
434
+
435
+ async destroyAsync(status) {
436
+ return await destroyAsync(this)(status);
437
+ }
302
438
 
303
- async generateDemonstrationOfProofOfPossessionAsync(accessToken:string, url:string, method:string, extras:StringMap= {}): Promise<string> {
304
-
305
- const configuration = this.configuration;
306
- const claimsExtras = {
307
- ath: await base64urlOfHashOfASCIIEncodingAsync(accessToken),
308
- ...extras
309
- };
310
-
311
- const serviceWorker = await initWorkerAsync(configuration, this.configurationName);
312
- let demonstratingProofOfPossessionNonce:string;
313
-
314
- if (serviceWorker) {
315
- return `DPOP_SECURED_BY_OIDC_SERVICE_WORKER_${this.configurationName}`;
316
- }
317
-
318
- const session = initSession(this.configurationName, configuration.storage);
319
- let jwk = await session.getDemonstratingProofOfPossessionJwkAsync();
320
- demonstratingProofOfPossessionNonce = await session.getDemonstratingProofOfPossessionNonce();
321
-
322
-
323
- if (demonstratingProofOfPossessionNonce) {
324
- claimsExtras['nonce'] = demonstratingProofOfPossessionNonce;
325
- }
326
-
327
- return await generateJwtDemonstratingProofOfPossessionAsync(window)(configuration.demonstrating_proof_of_possession_configuration)(jwk, method, url, claimsExtras);
439
+ async logoutSameTabAsync(clientId: string, sub: any) {
440
+ // @ts-ignore
441
+ if (
442
+ this.configuration.monitor_session &&
443
+ this.configuration.client_id === clientId &&
444
+ sub &&
445
+ this.tokens &&
446
+ this.tokens.idTokenPayload &&
447
+ this.tokens.idTokenPayload.sub === sub
448
+ ) {
449
+ await this.destroyAsync('LOGGED_OUT');
450
+ this.publishEvent(eventNames.logout_from_same_tab, { mmessage: 'SessionMonitor', sub });
328
451
  }
452
+ }
329
453
 
330
- loginCallbackWithAutoTokensRenewPromise:Promise<LoginCallback> = null;
331
- loginCallbackWithAutoTokensRenewAsync():Promise<LoginCallback> {
332
- if (this.loginCallbackWithAutoTokensRenewPromise !== null) {
333
- return this.loginCallbackWithAutoTokensRenewPromise;
334
- }
335
- this.loginCallbackWithAutoTokensRenewPromise = loginCallbackWithAutoTokensRenewAsync(this);
336
- return this.loginCallbackWithAutoTokensRenewPromise.finally(() => {
337
- this.loginCallbackWithAutoTokensRenewPromise = null;
338
- });
339
- }
340
-
341
- userInfoPromise:Promise<any> = null;
342
- userInfoAsync(noCache = false, demonstrating_proof_of_possession=false) {
343
- if (this.userInfoPromise !== null) {
344
- return this.userInfoPromise;
345
- }
346
- this.userInfoPromise = userInfoAsync(this)(noCache, demonstrating_proof_of_possession);
347
- return this.userInfoPromise.finally(() => {
348
- this.userInfoPromise = null;
349
- });
350
- }
351
-
352
- renewTokensPromise:Promise<any> = null;
353
-
354
- async renewTokensAsync (extras:StringMap = null) {
355
- if (this.renewTokensPromise !== null) {
356
- return this.renewTokensPromise;
357
- }
358
- if (!this.timeoutId) {
359
- return;
360
- }
361
- timer.clearTimeout(this.timeoutId);
362
- // @ts-ignore
363
- this.renewTokensPromise = renewTokensAndStartTimerAsync(this, true, extras);
364
- return this.renewTokensPromise.finally(() => {
365
- this.renewTokensPromise = null;
366
- });
367
- }
368
-
369
- async destroyAsync(status) {
370
- return await destroyAsync(this)(status);
371
- }
372
-
373
- async logoutSameTabAsync(clientId: string, sub: any) {
374
- // @ts-ignore
375
- if (this.configuration.monitor_session && this.configuration.client_id === clientId && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
376
- await this.destroyAsync('LOGGED_OUT');
377
- this.publishEvent(eventNames.logout_from_same_tab, { mmessage: 'SessionMonitor', sub });
378
- }
379
- }
380
-
381
- async logoutOtherTabAsync(clientId: string, sub: any) {
382
- // @ts-ignore
383
- if (this.configuration.monitor_session && this.configuration.client_id === clientId && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
384
- await this.destroyAsync('LOGGED_OUT');
385
- this.publishEvent(eventNames.logout_from_another_tab, { message: 'SessionMonitor', sub });
386
- }
454
+ async logoutOtherTabAsync(clientId: string, sub: any) {
455
+ // @ts-ignore
456
+ if (
457
+ this.configuration.monitor_session &&
458
+ this.configuration.client_id === clientId &&
459
+ sub &&
460
+ this.tokens &&
461
+ this.tokens.idTokenPayload &&
462
+ this.tokens.idTokenPayload.sub === sub
463
+ ) {
464
+ await this.destroyAsync('LOGGED_OUT');
465
+ this.publishEvent(eventNames.logout_from_another_tab, { message: 'SessionMonitor', sub });
387
466
  }
467
+ }
388
468
 
389
- logoutPromise:Promise<void> = null;
390
- async logoutAsync(callbackPathOrUrl: string | null | undefined = undefined, extras: StringMap = null) {
391
- if (this.logoutPromise) {
392
- return this.logoutPromise;
393
- }
394
- this.logoutPromise = logoutAsync(this, oidcDatabase, this.getFetch(), console, this.location)(callbackPathOrUrl, extras);
395
- return this.logoutPromise.finally(() => {
396
- this.logoutPromise = null;
397
- });
469
+ logoutPromise: Promise<void> = null;
470
+ async logoutAsync(
471
+ callbackPathOrUrl: string | null | undefined = undefined,
472
+ extras: StringMap = null,
473
+ ) {
474
+ if (this.logoutPromise) {
475
+ return this.logoutPromise;
398
476
  }
477
+ this.logoutPromise = logoutAsync(
478
+ this,
479
+ oidcDatabase,
480
+ this.getFetch(),
481
+ console,
482
+ this.location,
483
+ )(callbackPathOrUrl, extras);
484
+ return this.logoutPromise.finally(() => {
485
+ this.logoutPromise = null;
486
+ });
399
487
  }
488
+ }
400
489
 
401
- export default Oidc;
490
+ export default Oidc;