oidc-spa 7.2.5 → 7.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/core/Oidc.d.ts +4 -1
  2. package/core/createOidc.js +65 -18
  3. package/core/createOidc.js.map +1 -1
  4. package/core/oidcClientTsUserToTokens.js +7 -2
  5. package/core/oidcClientTsUserToTokens.js.map +1 -1
  6. package/esm/core/Oidc.d.ts +4 -1
  7. package/esm/core/createOidc.js +65 -18
  8. package/esm/core/createOidc.js.map +1 -1
  9. package/esm/core/oidcClientTsUserToTokens.js +7 -2
  10. package/esm/core/oidcClientTsUserToTokens.js.map +1 -1
  11. package/esm/keycloak/keycloak-js/Keycloak.d.ts +5 -3
  12. package/esm/keycloak/keycloak-js/Keycloak.js +175 -184
  13. package/esm/keycloak/keycloak-js/Keycloak.js.map +1 -1
  14. package/esm/keycloak/keycloak-js/types.d.ts +1 -3
  15. package/esm/mock/oidc.js +2 -1
  16. package/esm/mock/oidc.js.map +1 -1
  17. package/esm/tools/workerTimers.js +2 -5
  18. package/esm/tools/workerTimers.js.map +1 -1
  19. package/esm/vendor/frontend/oidc-client-ts.js +46 -8
  20. package/keycloak/keycloak-js/Keycloak.d.ts +5 -3
  21. package/keycloak/keycloak-js/Keycloak.js +175 -184
  22. package/keycloak/keycloak-js/Keycloak.js.map +1 -1
  23. package/keycloak/keycloak-js/types.d.ts +1 -3
  24. package/mock/oidc.js +2 -1
  25. package/mock/oidc.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/core/Oidc.ts +5 -1
  28. package/src/core/createOidc.ts +81 -16
  29. package/src/core/oidcClientTsUserToTokens.ts +7 -2
  30. package/src/keycloak/keycloak-js/Keycloak.ts +198 -232
  31. package/src/keycloak/keycloak-js/types.ts +1 -4
  32. package/src/mock/oidc.ts +2 -1
  33. package/src/tools/workerTimers.ts +2 -6
  34. package/tools/workerTimers.js +2 -5
  35. package/tools/workerTimers.js.map +1 -1
  36. package/vendor/frontend/oidc-client-ts.js +46 -8
@@ -25,21 +25,6 @@ type ConstructorParams = KeycloakServerConfig & {
25
25
  homeUrl: string;
26
26
  };
27
27
 
28
- type InternalState = {
29
- constructorParams: ConstructorParams;
30
- keycloakUtils: KeycloakUtils;
31
- issuerUri: string;
32
- dInitialized: Deferred<void>;
33
- initOptions: KeycloakInitOptions | undefined;
34
- oidc: Oidc<Record<string, unknown>> | undefined;
35
- tokens: Oidc.Tokens<Record<string, unknown>> | undefined;
36
- profile: KeycloakProfile | undefined;
37
- userInfo: KeycloakUserInfo | undefined;
38
- $onTokenExpired: StatefulEvt<(() => void) | undefined>;
39
- };
40
-
41
- const internalStateByInstance = new WeakMap<Keycloak, InternalState>();
42
-
43
28
  /**
44
29
  * This module provides a drop-in replacement for `keycloak-js`,
45
30
  * designed for teams migrating to `oidc-spa` with minimal changes.
@@ -48,6 +33,19 @@ const internalStateByInstance = new WeakMap<Keycloak, InternalState>();
48
33
  * it is a full alternative implementation aligned with the `keycloak-js` API.
49
34
  */
50
35
  export class Keycloak {
36
+ readonly #state: {
37
+ constructorParams: ConstructorParams;
38
+ keycloakUtils: KeycloakUtils;
39
+ issuerUri: string;
40
+ dInitialized: Deferred<void>;
41
+ initOptions: KeycloakInitOptions | undefined;
42
+ oidc: Oidc<Record<string, unknown>> | undefined;
43
+ tokens: Oidc.Tokens<Record<string, unknown>> | undefined;
44
+ profile: KeycloakProfile | undefined;
45
+ userInfo: KeycloakUserInfo | undefined;
46
+ $onTokenExpired: StatefulEvt<(() => void) | undefined>;
47
+ };
48
+
51
49
  /**
52
50
  * Creates a new Keycloak client instance.
53
51
  * @param config A configuration object or path to a JSON config file.
@@ -59,7 +57,7 @@ export class Keycloak {
59
57
  constructor(params: ConstructorParams) {
60
58
  const issuerUri = `${params.url.replace(/\/$/, "")}/realms/${params.realm}`;
61
59
 
62
- internalStateByInstance.set(this, {
60
+ this.#state = {
63
61
  constructorParams: params,
64
62
  dInitialized: new Deferred(),
65
63
  initOptions: undefined,
@@ -70,7 +68,7 @@ export class Keycloak {
70
68
  profile: undefined,
71
69
  userInfo: undefined,
72
70
  $onTokenExpired: createStatefulEvt(() => undefined)
73
- });
71
+ };
74
72
  }
75
73
 
76
74
  /**
@@ -81,23 +79,19 @@ export class Keycloak {
81
79
  async init(initOptions: KeycloakInitOptions = {}): Promise<boolean> {
82
80
  const { onLoad = "check-sso", redirectUri, enableLogging, scope, locale } = initOptions;
83
81
 
84
- const internalState = internalStateByInstance.get(this);
85
-
86
- assert(internalState !== undefined);
87
-
88
- if (internalState.initOptions !== undefined) {
89
- if (JSON.stringify(internalState.initOptions) !== JSON.stringify(initOptions)) {
82
+ if (this.#state.initOptions !== undefined) {
83
+ if (JSON.stringify(this.#state.initOptions) !== JSON.stringify(initOptions)) {
90
84
  throw new Error("Can't call init() multiple time with different params");
91
85
  }
92
- await internalState.dInitialized.pr;
93
- const { oidc } = internalState;
86
+ await this.#state.dInitialized.pr;
87
+ const { oidc } = this.#state;
94
88
  assert(oidc !== undefined);
95
89
  return oidc.isUserLoggedIn;
96
90
  }
97
91
 
98
- internalState.initOptions = initOptions;
92
+ this.#state.initOptions = initOptions;
99
93
 
100
- const { constructorParams, issuerUri } = internalState;
94
+ const { constructorParams, issuerUri } = this.#state;
101
95
 
102
96
  const autoLogin = onLoad === "login-required";
103
97
 
@@ -106,7 +100,7 @@ export class Keycloak {
106
100
  const oidcOrError = await createOidc({
107
101
  homeUrl: constructorParams.homeUrl,
108
102
  issuerUri,
109
- clientId: internalState.constructorParams.clientId,
103
+ clientId: this.#state.constructorParams.clientId,
110
104
  autoLogin,
111
105
  postLoginRedirectUrl: redirectUri,
112
106
  debugLogs: enableLogging,
@@ -142,101 +136,123 @@ export class Keycloak {
142
136
 
143
137
  const oidc = oidcOrError;
144
138
 
145
- internalState.oidc = oidc;
146
-
147
139
  if (oidc.isUserLoggedIn) {
148
- {
149
- const tokens = await oidc.getTokens();
140
+ const tokens = await oidc.getTokens();
150
141
 
151
- const onNewToken = (tokens_new: Oidc.Tokens<Record<string, unknown>>) => {
152
- internalState.tokens = tokens_new;
153
- this.onAuthRefreshSuccess?.();
154
- };
142
+ const onNewToken = (tokens_new: Oidc.Tokens<Record<string, unknown>>) => {
143
+ this.#state.tokens = tokens_new;
144
+ this.onAuthRefreshSuccess?.();
145
+ };
155
146
 
156
- onNewToken(tokens);
147
+ onNewToken(tokens);
157
148
 
158
- oidc.subscribeToTokensChange(onNewToken);
149
+ oidc.subscribeToTokensChange(onNewToken);
150
+ }
151
+
152
+ this.#state.oidc = oidc;
153
+ this.#state.dInitialized.resolve();
154
+
155
+ this.onReady?.(oidc.isUserLoggedIn);
156
+
157
+ onAuthSuccess_call: {
158
+ if (!oidc.isUserLoggedIn) {
159
+ break onAuthSuccess_call;
159
160
  }
160
161
 
161
- {
162
- const { $onTokenExpired } = internalState;
162
+ this.onAuthSuccess?.();
163
+ }
163
164
 
164
- let clear: (() => void) | undefined = undefined;
165
+ onAuthError_call: {
166
+ if (oidc.isUserLoggedIn) {
167
+ break onAuthError_call;
168
+ }
165
169
 
166
- $onTokenExpired.subscribe(onTokenExpired => {
167
- clear?.();
170
+ if (oidc.initializationError === undefined) {
171
+ break onAuthError_call;
172
+ }
168
173
 
169
- if (onTokenExpired === undefined) {
170
- return;
171
- }
174
+ this.onAuthError?.({
175
+ error: oidc.initializationError.name,
176
+ error_description: oidc.initializationError.message
177
+ });
178
+ }
179
+
180
+ onActionUpdate_call: {
181
+ if (!oidc.isUserLoggedIn) {
182
+ break onActionUpdate_call;
183
+ }
172
184
 
173
- let timer: ReturnType<typeof workerTimers.setTimeout> | undefined = undefined;
185
+ if (this.onActionUpdate === undefined) {
186
+ break onActionUpdate_call;
187
+ }
174
188
 
175
- const onNewToken = () => {
176
- if (timer !== undefined) {
177
- workerTimers.clearTimeout(timer);
178
- }
189
+ const { backFromAuthServer } = oidc;
179
190
 
180
- const { tokens } = internalState;
181
- assert(tokens !== undefined);
191
+ if (backFromAuthServer === undefined) {
192
+ break onActionUpdate_call;
193
+ }
182
194
 
183
- timer = workerTimers.setTimeout(() => {
184
- onTokenExpired.call(this);
185
- }, Math.max(tokens.accessTokenExpirationTime - Date.now() - 3_000, 0));
186
- };
195
+ const status = backFromAuthServer.result.kc_action_status;
187
196
 
188
- onNewToken();
197
+ if (!isAmong(["success", "cancelled", "error"], status)) {
198
+ break onActionUpdate_call;
199
+ }
189
200
 
190
- const { unsubscribe } = oidc.subscribeToTokensChange(onNewToken);
201
+ const action = backFromAuthServer.extraQueryParams.kc_action;
191
202
 
192
- clear = () => {
193
- if (timer !== undefined) {
194
- workerTimers.clearTimeout(timer);
195
- }
196
- unsubscribe();
197
- };
198
- });
203
+ if (action === undefined) {
204
+ break onActionUpdate_call;
199
205
  }
200
206
 
201
- onActionUpdate_call: {
202
- if (this.onActionUpdate === undefined) {
203
- break onActionUpdate_call;
204
- }
207
+ this.onActionUpdate(status, action);
208
+ }
205
209
 
206
- const { backFromAuthServer } = oidc;
210
+ schedule_onTokenExpired_call: {
211
+ if (!oidc.isUserLoggedIn) {
212
+ break schedule_onTokenExpired_call;
213
+ }
207
214
 
208
- if (backFromAuthServer === undefined) {
209
- break onActionUpdate_call;
210
- }
215
+ const { $onTokenExpired } = this.#state;
211
216
 
212
- const status = backFromAuthServer.result.kc_action_status;
217
+ let clear: (() => void) | undefined = undefined;
213
218
 
214
- if (!isAmong(["success", "cancelled", "error"], status)) {
215
- break onActionUpdate_call;
219
+ const next = (onTokenExpired: (() => void) | undefined) => {
220
+ clear?.();
221
+
222
+ if (onTokenExpired === undefined) {
223
+ return;
216
224
  }
217
225
 
218
- const action = backFromAuthServer.extraQueryParams.kc_action;
226
+ let timer: ReturnType<typeof workerTimers.setTimeout> | undefined = undefined;
219
227
 
220
- if (action === undefined) {
221
- break onActionUpdate_call;
222
- }
228
+ const onNewToken = () => {
229
+ if (timer !== undefined) {
230
+ workerTimers.clearTimeout(timer);
231
+ }
223
232
 
224
- this.onActionUpdate(status, action);
225
- }
226
- }
233
+ const { tokens } = this.#state;
234
+ assert(tokens !== undefined);
227
235
 
228
- if (!oidc.isUserLoggedIn && oidc.initializationError !== undefined) {
229
- this.onAuthError?.({
230
- error: oidc.initializationError.name,
231
- error_description: oidc.initializationError.message
232
- });
233
- }
236
+ timer = workerTimers.setTimeout(() => {
237
+ onTokenExpired.call(this);
238
+ }, Math.max(tokens.accessTokenExpirationTime - tokens.getServerDateNow() - 3_000, 0));
239
+ };
234
240
 
235
- internalState.dInitialized.resolve();
241
+ onNewToken();
236
242
 
237
- this.onReady?.(oidc.isUserLoggedIn);
238
- if (oidc.isUserLoggedIn) {
239
- this.onAuthSuccess?.();
243
+ const { unsubscribe } = oidc.subscribeToTokensChange(onNewToken);
244
+
245
+ clear = () => {
246
+ if (timer !== undefined) {
247
+ workerTimers.clearTimeout(timer);
248
+ }
249
+ unsubscribe();
250
+ };
251
+ };
252
+
253
+ next($onTokenExpired.current);
254
+
255
+ $onTokenExpired.subscribe(next);
240
256
  }
241
257
 
242
258
  return oidc.isUserLoggedIn;
@@ -250,11 +266,7 @@ export class Keycloak {
250
266
  return false;
251
267
  }
252
268
 
253
- const internalState = internalStateByInstance.get(this);
254
-
255
- assert(internalState !== undefined);
256
-
257
- const { oidc } = internalState;
269
+ const { oidc } = this.#state;
258
270
 
259
271
  assert(oidc !== undefined);
260
272
 
@@ -269,11 +281,7 @@ export class Keycloak {
269
281
  return undefined;
270
282
  }
271
283
 
272
- const internalState = internalStateByInstance.get(this);
273
-
274
- assert(internalState !== undefined);
275
-
276
- const { oidc, tokens } = internalState;
284
+ const { oidc, tokens } = this.#state;
277
285
 
278
286
  assert(oidc !== undefined);
279
287
 
@@ -320,17 +328,13 @@ export class Keycloak {
320
328
  return undefined;
321
329
  }
322
330
 
323
- const internalState = internalStateByInstance.get(this);
324
-
325
- assert(internalState !== undefined);
326
-
327
- const { oidc, tokens } = internalState;
331
+ const { oidc, tokens } = this.#state;
328
332
 
329
333
  assert(oidc !== undefined);
330
334
 
331
335
  if (!oidc.isUserLoggedIn) {
332
336
  console.warn(
333
- "Trying to read keycloak.realAccess when keycloak.realmAccess is false is a logical error in your application"
337
+ "Trying to read keycloak.realAccess when keycloak.authenticated is false is a logical error in your application"
334
338
  );
335
339
  return undefined;
336
340
  }
@@ -349,11 +353,7 @@ export class Keycloak {
349
353
  return undefined;
350
354
  }
351
355
 
352
- const internalState = internalStateByInstance.get(this);
353
-
354
- assert(internalState !== undefined);
355
-
356
- const { oidc, tokens } = internalState;
356
+ const { oidc, tokens } = this.#state;
357
357
 
358
358
  assert(oidc !== undefined);
359
359
 
@@ -375,21 +375,17 @@ export class Keycloak {
375
375
  * requests to services.
376
376
  */
377
377
  get token(): string | undefined {
378
- const internalState = internalStateByInstance.get(this);
379
-
380
- assert(internalState !== undefined);
381
-
382
378
  if (!this.didInitialize) {
383
- return internalState.initOptions?.token;
379
+ return this.#state.initOptions?.token;
384
380
  }
385
381
 
386
- const { oidc, tokens } = internalState;
382
+ const { oidc, tokens } = this.#state;
387
383
 
388
384
  assert(oidc !== undefined);
389
385
 
390
386
  if (!oidc.isUserLoggedIn) {
391
387
  console.warn(
392
- "Trying to read keycloak.token when keycloak.token is false is a logical error in your application"
388
+ "Trying to read keycloak.token when keycloak.authenticated is false is a logical error in your application"
393
389
  );
394
390
  return undefined;
395
391
  }
@@ -403,12 +399,8 @@ export class Keycloak {
403
399
  * The parsed token as a JavaScript object.
404
400
  */
405
401
  get tokenParsed(): KeycloakTokenParsed | undefined {
406
- const internalState = internalStateByInstance.get(this);
407
-
408
- assert(internalState !== undefined);
409
-
410
402
  if (!this.didInitialize) {
411
- const { token } = internalState.initOptions ?? {};
403
+ const { token } = this.#state.initOptions ?? {};
412
404
 
413
405
  if (token === undefined) {
414
406
  return undefined;
@@ -417,13 +409,13 @@ export class Keycloak {
417
409
  return decodeJwt(token) as KeycloakTokenParsed;
418
410
  }
419
411
 
420
- const { oidc, tokens } = internalState;
412
+ const { oidc, tokens } = this.#state;
421
413
 
422
414
  assert(oidc !== undefined);
423
415
 
424
416
  if (!oidc.isUserLoggedIn) {
425
417
  console.warn(
426
- "Trying to read keycloak.token when keycloak.tokenParsed is false is a logical error in your application"
418
+ "Trying to read keycloak.tokenParsed when keycloak.authenticated is false is a logical error in your application"
427
419
  );
428
420
  return undefined;
429
421
  }
@@ -437,21 +429,17 @@ export class Keycloak {
437
429
  * The base64 encoded refresh token that can be used to retrieve a new token.
438
430
  */
439
431
  get refreshToken(): string | undefined {
440
- const internalState = internalStateByInstance.get(this);
441
-
442
- assert(internalState !== undefined);
443
-
444
432
  if (!this.didInitialize) {
445
- return internalState.initOptions?.refreshToken;
433
+ return this.#state.initOptions?.refreshToken;
446
434
  }
447
435
 
448
- const { oidc, tokens } = internalState;
436
+ const { oidc, tokens } = this.#state;
449
437
 
450
438
  assert(oidc !== undefined);
451
439
 
452
440
  if (!oidc.isUserLoggedIn) {
453
441
  console.warn(
454
- "Trying to read keycloak.token when keycloak.refreshToken is false is a logical error in your application"
442
+ "Trying to read keycloak.refreshToken when keycloak.authenticated is false is a logical error in your application"
455
443
  );
456
444
  return undefined;
457
445
  }
@@ -465,12 +453,8 @@ export class Keycloak {
465
453
  * The parsed refresh token as a JavaScript object.
466
454
  */
467
455
  get refreshTokenParsed(): KeycloakTokenParsed | undefined {
468
- const internalState = internalStateByInstance.get(this);
469
-
470
- assert(internalState !== undefined);
471
-
472
456
  if (!this.didInitialize) {
473
- const { refreshToken } = internalState.initOptions ?? {};
457
+ const { refreshToken } = this.#state.initOptions ?? {};
474
458
 
475
459
  if (refreshToken === undefined) {
476
460
  return undefined;
@@ -479,13 +463,13 @@ export class Keycloak {
479
463
  return decodeJwt(refreshToken) as KeycloakTokenParsed;
480
464
  }
481
465
 
482
- const { oidc, tokens } = internalState;
466
+ const { oidc, tokens } = this.#state;
483
467
 
484
468
  assert(oidc !== undefined);
485
469
 
486
470
  if (!oidc.isUserLoggedIn) {
487
471
  console.warn(
488
- "Trying to read keycloak.token when keycloak.refreshTokenParsed is false is a logical error in your application"
472
+ "Trying to read keycloak.refreshTokenParsed when keycloak.authenticated is false is a logical error in your application"
489
473
  );
490
474
  return undefined;
491
475
  }
@@ -503,21 +487,17 @@ export class Keycloak {
503
487
  * The base64 encoded ID token.
504
488
  */
505
489
  get idToken(): string | undefined {
506
- const internalState = internalStateByInstance.get(this);
507
-
508
- assert(internalState !== undefined);
509
-
510
490
  if (!this.didInitialize) {
511
- return internalState.initOptions?.idToken;
491
+ return this.#state.initOptions?.idToken;
512
492
  }
513
493
 
514
- const { oidc, tokens } = internalState;
494
+ const { oidc, tokens } = this.#state;
515
495
 
516
496
  assert(oidc !== undefined);
517
497
 
518
498
  if (!oidc.isUserLoggedIn) {
519
499
  console.warn(
520
- "Trying to read keycloak.token when keycloak.token is false is a logical error in your application"
500
+ "Trying to read keycloak.idToken when keycloak.authenticated is false is a logical error in your application"
521
501
  );
522
502
  return undefined;
523
503
  }
@@ -531,12 +511,8 @@ export class Keycloak {
531
511
  * The parsed id token as a JavaScript object.
532
512
  */
533
513
  get idTokenParsed(): KeycloakTokenParsed | undefined {
534
- const internalState = internalStateByInstance.get(this);
535
-
536
- assert(internalState !== undefined);
537
-
538
514
  if (!this.didInitialize) {
539
- const { idToken } = internalState.initOptions ?? {};
515
+ const { idToken } = this.#state.initOptions ?? {};
540
516
 
541
517
  if (idToken === undefined) {
542
518
  return undefined;
@@ -545,13 +521,13 @@ export class Keycloak {
545
521
  return decodeJwt(idToken) as KeycloakTokenParsed;
546
522
  }
547
523
 
548
- const { oidc, tokens } = internalState;
524
+ const { oidc, tokens } = this.#state;
549
525
 
550
526
  assert(oidc !== undefined);
551
527
 
552
528
  if (!oidc.isUserLoggedIn) {
553
529
  console.warn(
554
- "Trying to read keycloak.token when keycloak.refreshTokenParsed is false is a logical error in your application"
530
+ "Trying to read keycloak.idTokenParsed when keycloak.authenticated is false is a logical error in your application"
555
531
  );
556
532
  return undefined;
557
533
  }
@@ -566,28 +542,46 @@ export class Keycloak {
566
542
  * The estimated time difference between the browser time and the Keycloak
567
543
  * server in seconds. This value is just an estimation, but is accurate
568
544
  * enough when determining if a token is expired or not.
569
- *
570
- * NOTE oidc-spa: Not supported.
571
545
  */
572
- timeSkew = null;
546
+ get timeSkew(): number | null {
547
+ if (!this.didInitialize) {
548
+ const { timeSkew } = this.#state.initOptions ?? {};
549
+
550
+ if (timeSkew === undefined) {
551
+ return null;
552
+ }
553
+
554
+ return timeSkew;
555
+ }
556
+
557
+ const { oidc, tokens } = this.#state;
558
+
559
+ assert(oidc !== undefined);
560
+
561
+ if (!oidc.isUserLoggedIn) {
562
+ console.warn(
563
+ "Trying to read keycloak.timeSkew when keycloak.authenticated is false is a logical error in your application"
564
+ );
565
+ return null;
566
+ }
567
+
568
+ assert(tokens !== undefined);
569
+
570
+ return Math.ceil((tokens.getServerDateNow() - Date.now()) / 1000);
571
+ }
573
572
 
574
573
  /**
575
574
  * Whether the instance has been initialized by calling `.init()`.
576
575
  */
577
576
  get didInitialize(): boolean {
578
- const internalState = internalStateByInstance.get(this);
579
- assert(internalState !== undefined);
580
- return internalState.oidc !== undefined;
577
+ return this.#state.oidc !== undefined;
581
578
  }
582
579
 
583
580
  /**
584
581
  * @private Undocumented.
585
582
  */
586
583
  get loginRequired(): boolean {
587
- const internalState = internalStateByInstance.get(this);
588
- assert(internalState !== undefined);
589
-
590
- const { initOptions } = internalState;
584
+ const { initOptions } = this.#state;
591
585
 
592
586
  if (initOptions === undefined) {
593
587
  return false;
@@ -600,11 +594,9 @@ export class Keycloak {
600
594
  * @private Undocumented.
601
595
  */
602
596
  get authServerUrl(): string {
603
- const internalState = internalStateByInstance.get(this);
604
- assert(internalState !== undefined);
605
597
  const {
606
598
  keycloakUtils: { issuerUriParsed }
607
- } = internalState;
599
+ } = this.#state;
608
600
 
609
601
  return `${issuerUriParsed.origin}${issuerUriParsed.kcHttpRelativePath}`;
610
602
  }
@@ -613,11 +605,9 @@ export class Keycloak {
613
605
  * @private Undocumented.
614
606
  */
615
607
  get realm(): string {
616
- const internalState = internalStateByInstance.get(this);
617
- assert(internalState !== undefined);
618
608
  const {
619
609
  keycloakUtils: { issuerUriParsed }
620
- } = internalState;
610
+ } = this.#state;
621
611
 
622
612
  return issuerUriParsed.realm;
623
613
  }
@@ -626,9 +616,7 @@ export class Keycloak {
626
616
  * @private Undocumented.
627
617
  */
628
618
  get clientId(): string {
629
- const internalState = internalStateByInstance.get(this);
630
- assert(internalState !== undefined);
631
- const { constructorParams } = internalState;
619
+ const { constructorParams } = this.#state;
632
620
  return constructorParams.clientId;
633
621
  }
634
622
 
@@ -636,9 +624,7 @@ export class Keycloak {
636
624
  * @private Undocumented.
637
625
  */
638
626
  get redirectUri(): string | undefined {
639
- const internalState = internalStateByInstance.get(this);
640
- assert(internalState !== undefined);
641
- const { initOptions } = internalState;
627
+ const { initOptions } = this.#state;
642
628
  if (initOptions === undefined) {
643
629
  return undefined;
644
630
  }
@@ -653,9 +639,7 @@ export class Keycloak {
653
639
  return undefined;
654
640
  }
655
641
 
656
- const internalState = internalStateByInstance.get(this);
657
- assert(internalState !== undefined);
658
- const { oidc, tokens } = internalState;
642
+ const { oidc, tokens } = this.#state;
659
643
 
660
644
  assert(oidc !== undefined);
661
645
 
@@ -679,9 +663,7 @@ export class Keycloak {
679
663
  * @private Undocumented.
680
664
  */
681
665
  get profile(): KeycloakProfile | undefined {
682
- const internalState = internalStateByInstance.get(this);
683
- assert(internalState !== undefined);
684
- const { profile } = internalState;
666
+ const { profile } = this.#state;
685
667
  return profile;
686
668
  }
687
669
 
@@ -689,9 +671,7 @@ export class Keycloak {
689
671
  * @private Undocumented.
690
672
  */
691
673
  get userInfo(): KeycloakUserInfo | undefined {
692
- const internalState = internalStateByInstance.get(this);
693
- assert(internalState !== undefined);
694
- const { userInfo } = internalState;
674
+ const { userInfo } = this.#state;
695
675
  return userInfo;
696
676
  }
697
677
 
@@ -737,15 +717,11 @@ export class Keycloak {
737
717
  * obtain a new access token.
738
718
  */
739
719
  set onTokenExpired(value: (() => void) | undefined) {
740
- const internalState = internalStateByInstance.get(this);
741
- assert(internalState !== undefined);
742
- const { $onTokenExpired } = internalState;
720
+ const { $onTokenExpired } = this.#state;
743
721
  $onTokenExpired.current = value;
744
722
  }
745
723
  get onTokenExpired() {
746
- const internalState = internalStateByInstance.get(this);
747
- assert(internalState !== undefined);
748
- const { $onTokenExpired } = internalState;
724
+ const { $onTokenExpired } = this.#state;
749
725
  return $onTokenExpired.current;
750
726
  }
751
727
 
@@ -774,14 +750,11 @@ export class Keycloak {
774
750
  doesCurrentHrefRequiresAuth
775
751
  } = options ?? {};
776
752
 
777
- const internalState = internalStateByInstance.get(this);
778
- assert(internalState !== undefined);
779
-
780
753
  if (!this.didInitialize) {
781
- await internalState.dInitialized.pr;
754
+ await this.#state.dInitialized.pr;
782
755
  }
783
756
 
784
- const { oidc, keycloakUtils } = internalState;
757
+ const { oidc, keycloakUtils } = this.#state;
785
758
 
786
759
  assert(oidc !== undefined);
787
760
 
@@ -836,15 +809,11 @@ export class Keycloak {
836
809
  * @param options Logout options.
837
810
  */
838
811
  async logout(options?: KeycloakLogoutOptions): Promise<never> {
839
- const internalState = internalStateByInstance.get(this);
840
-
841
- assert(internalState !== undefined);
842
-
843
812
  if (!this.didInitialize) {
844
- await internalState.dInitialized.pr;
813
+ await this.#state.dInitialized.pr;
845
814
  }
846
815
 
847
- const { oidc, initOptions } = internalState;
816
+ const { oidc, initOptions } = this.#state;
848
817
 
849
818
  assert(oidc !== undefined);
850
819
  assert(initOptions !== undefined);
@@ -922,11 +891,7 @@ export class Keycloak {
922
891
  createAccountUrl(options?: KeycloakAccountOptions & { locale?: string }): string {
923
892
  const { locale, redirectUri } = options ?? {};
924
893
 
925
- const internalState = internalStateByInstance.get(this);
926
-
927
- assert(internalState !== undefined);
928
-
929
- const { keycloakUtils } = internalState;
894
+ const { keycloakUtils } = this.#state;
930
895
 
931
896
  return keycloakUtils.getAccountUrl({
932
897
  clientId: this.clientId,
@@ -941,9 +906,6 @@ export class Keycloak {
941
906
  * @param minValidity If not specified, `0` is used.
942
907
  */
943
908
  isTokenExpired(minValidity: number = 0): boolean {
944
- const internalState = internalStateByInstance.get(this);
945
- assert(internalState !== undefined);
946
-
947
909
  let accessTokenExpirationTime: number;
948
910
 
949
911
  if (!this.didInitialize) {
@@ -958,7 +920,7 @@ export class Keycloak {
958
920
 
959
921
  accessTokenExpirationTime = time;
960
922
  } else {
961
- const { tokens } = internalState;
923
+ const { tokens } = this.#state;
962
924
  assert(tokens !== undefined);
963
925
 
964
926
  accessTokenExpirationTime = tokens.accessTokenExpirationTime;
@@ -991,15 +953,11 @@ export class Keycloak {
991
953
  * });
992
954
  */
993
955
  async updateToken(minValidity: number = 5): Promise<boolean> {
994
- const internalState = internalStateByInstance.get(this);
995
-
996
- assert(internalState !== undefined);
997
-
998
956
  if (!this.didInitialize) {
999
- await internalState.dInitialized.pr;
957
+ await this.#state.dInitialized.pr;
1000
958
  }
1001
959
 
1002
- const { oidc } = internalState;
960
+ const { oidc } = this.#state;
1003
961
 
1004
962
  assert(oidc !== undefined);
1005
963
 
@@ -1055,14 +1013,11 @@ export class Keycloak {
1055
1013
  * @returns A promise to set functions to be invoked on success or error.
1056
1014
  */
1057
1015
  async loadUserProfile(): Promise<KeycloakProfile> {
1058
- const internalState = internalStateByInstance.get(this);
1059
- assert(internalState !== undefined);
1060
-
1061
1016
  if (!this.didInitialize) {
1062
- await internalState.dInitialized.pr;
1017
+ await this.#state.dInitialized.pr;
1063
1018
  }
1064
1019
 
1065
- const { oidc, keycloakUtils } = internalState;
1020
+ const { oidc, keycloakUtils } = this.#state;
1066
1021
 
1067
1022
  assert(oidc !== undefined);
1068
1023
 
@@ -1070,21 +1025,18 @@ export class Keycloak {
1070
1025
 
1071
1026
  const { accessToken } = await oidc.getTokens();
1072
1027
 
1073
- return (internalState.profile = await keycloakUtils.fetchUserProfile({ accessToken }));
1028
+ return (this.#state.profile = await keycloakUtils.fetchUserProfile({ accessToken }));
1074
1029
  }
1075
1030
 
1076
1031
  /**
1077
1032
  * @private Undocumented.
1078
1033
  */
1079
1034
  async loadUserInfo(): Promise<KeycloakUserInfo> {
1080
- const internalState = internalStateByInstance.get(this);
1081
- assert(internalState !== undefined);
1082
-
1083
1035
  if (!this.didInitialize) {
1084
- await internalState.dInitialized.pr;
1036
+ await this.#state.dInitialized.pr;
1085
1037
  }
1086
1038
 
1087
- const { oidc, keycloakUtils } = internalState;
1039
+ const { oidc, keycloakUtils } = this.#state;
1088
1040
 
1089
1041
  assert(oidc !== undefined);
1090
1042
 
@@ -1092,6 +1044,20 @@ export class Keycloak {
1092
1044
 
1093
1045
  const { accessToken } = await oidc.getTokens();
1094
1046
 
1095
- return (internalState.userInfo = await keycloakUtils.fetchUserInfo({ accessToken }));
1047
+ return (this.#state.userInfo = await keycloakUtils.fetchUserInfo({ accessToken }));
1048
+ }
1049
+
1050
+ /** Get the underlying oidc-spa instance */
1051
+ get oidc(): Oidc<Record<string, unknown>> {
1052
+ assert(
1053
+ this.didInitialize,
1054
+ "Cannot get keycloak.oidc before the init() method was called and have resolved."
1055
+ );
1056
+
1057
+ const { oidc } = this.#state;
1058
+
1059
+ assert(oidc !== undefined);
1060
+
1061
+ return oidc;
1096
1062
  }
1097
1063
  }