oidc-spa 8.0.3 → 8.0.5

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 (61) hide show
  1. package/angular/angular.d.ts +72 -0
  2. package/angular/angular.js +254 -0
  3. package/angular/angular.js.map +1 -0
  4. package/angular/index.d.ts +1 -0
  5. package/angular/index.js +6 -0
  6. package/angular/index.js.map +1 -0
  7. package/core/createOidc.js +14 -1
  8. package/core/createOidc.js.map +1 -1
  9. package/core/oidcClientTsUserToTokens.js +7 -0
  10. package/core/oidcClientTsUserToTokens.js.map +1 -1
  11. package/esm/angular/angular.d.ts +72 -0
  12. package/esm/angular/angular.js +250 -0
  13. package/esm/angular/angular.js.map +1 -0
  14. package/esm/angular/index.d.ts +1 -0
  15. package/esm/angular/index.js +2 -0
  16. package/esm/angular/index.js.map +1 -0
  17. package/esm/core/createOidc.js +14 -1
  18. package/esm/core/createOidc.js.map +1 -1
  19. package/esm/core/oidcClientTsUserToTokens.js +7 -0
  20. package/esm/core/oidcClientTsUserToTokens.js.map +1 -1
  21. package/esm/mock/angular.d.ts +41 -0
  22. package/esm/mock/angular.js +7 -0
  23. package/esm/mock/angular.js.map +1 -0
  24. package/esm/mock/oidc.js +2 -1
  25. package/esm/mock/oidc.js.map +1 -1
  26. package/esm/mock/react.js +2 -2
  27. package/esm/mock/react.js.map +1 -1
  28. package/esm/react/react.d.ts +1 -1
  29. package/esm/react/react.js +5 -5
  30. package/esm/react/react.js.map +1 -1
  31. package/esm/tools/INFINITY_TIME.d.ts +1 -0
  32. package/esm/tools/INFINITY_TIME.js +3 -0
  33. package/esm/tools/INFINITY_TIME.js.map +1 -0
  34. package/esm/tools/readExpirationTimeInJwt.js +4 -0
  35. package/esm/tools/readExpirationTimeInJwt.js.map +1 -1
  36. package/mock/angular.d.ts +41 -0
  37. package/mock/angular.js +10 -0
  38. package/mock/angular.js.map +1 -0
  39. package/mock/oidc.js +2 -1
  40. package/mock/oidc.js.map +1 -1
  41. package/mock/react.js +1 -1
  42. package/mock/react.js.map +1 -1
  43. package/package.json +24 -3
  44. package/react/react.d.ts +1 -1
  45. package/react/react.js +6 -6
  46. package/react/react.js.map +1 -1
  47. package/src/angular/angular.ts +429 -0
  48. package/src/angular/index.ts +1 -0
  49. package/src/core/createOidc.ts +18 -0
  50. package/src/core/oidcClientTsUserToTokens.ts +9 -0
  51. package/src/mock/angular.ts +11 -0
  52. package/src/mock/oidc.ts +2 -1
  53. package/src/mock/react.tsx +2 -2
  54. package/src/react/react.tsx +6 -6
  55. package/src/tools/INFINITY_TIME.ts +2 -0
  56. package/src/tools/readExpirationTimeInJwt.ts +5 -0
  57. package/tools/INFINITY_TIME.d.ts +1 -0
  58. package/tools/INFINITY_TIME.js +6 -0
  59. package/tools/INFINITY_TIME.js.map +1 -0
  60. package/tools/readExpirationTimeInJwt.js +4 -0
  61. package/tools/readExpirationTimeInJwt.js.map +1 -1
@@ -0,0 +1,429 @@
1
+ import { type Oidc, createOidc, type ParamsOfCreateOidc, OidcInitializationError } from "../core";
2
+ import { assert, type Equals } from "../vendor/frontend/tsafe";
3
+ import { id } from "../vendor/frontend/tsafe";
4
+ import type { ValueOrAsyncGetter } from "../tools/ValueOrAsyncGetter";
5
+ import { Deferred } from "../tools/Deferred";
6
+ import { type Signal, type EnvironmentProviders, provideAppInitializer, inject } from "@angular/core";
7
+ import { type CanActivateFn, Router } from "@angular/router";
8
+ import { toSignal } from "@angular/core/rxjs-interop";
9
+ import { BehaviorSubject } from "rxjs";
10
+ import { createObjectThatThrowsIfAccessed } from "../tools/createObjectThatThrowsIfAccessed";
11
+
12
+ export type OidcAngular = OidcAngular.NotLoggedIn | OidcAngular.LoggedIn;
13
+
14
+ export namespace OidcAngular {
15
+ export type Common = Oidc.Common;
16
+
17
+ export type NotLoggedIn = Common & {
18
+ isUserLoggedIn: false;
19
+ login: (params?: {
20
+ extraQueryParams?: Record<string, string | undefined>;
21
+ transformUrlBeforeRedirect?: (url: string) => string;
22
+ }) => Promise<never>;
23
+ };
24
+
25
+ export type LoggedIn = Common & {
26
+ isUserLoggedIn: true;
27
+ logout: Oidc.LoggedIn["logout"];
28
+ renewTokens: Oidc.LoggedIn["renewTokens"];
29
+ goToAuthServer: Oidc.LoggedIn["goToAuthServer"];
30
+ backFromAuthServer:
31
+ | {
32
+ extraQueryParams: Record<string, string>;
33
+ result: Record<string, string>;
34
+ }
35
+ | undefined;
36
+ isNewBrowserSession: boolean;
37
+ };
38
+ }
39
+
40
+ type OidcAngularApi<DecodedIdToken extends Record<string, unknown>, AutoLogin extends boolean> = {
41
+ getOidc: AutoLogin extends true
42
+ ? {
43
+ (params?: { assert: "user logged in" }): OidcAngular.LoggedIn;
44
+ }
45
+ : {
46
+ (params?: { assert?: undefined }): OidcAngular;
47
+ (params: { assert: "user logged in" }): OidcAngular.LoggedIn;
48
+ (params: { assert: "user not logged in" }): OidcAngular.NotLoggedIn;
49
+ };
50
+
51
+ getOidcInitializationError: () => OidcInitializationError | undefined;
52
+
53
+ get$decodedIdToken: () => Signal<DecodedIdToken>;
54
+
55
+ get$secondsLeftBeforeAutoLogout: (params: {
56
+ warningDurationSeconds: number;
57
+ }) => Signal<number | undefined>;
58
+
59
+ getTokens: () => Promise<
60
+ | { isUserLoggedIn: false; prTokens?: never }
61
+ | { isUserLoggedIn: true; prTokens: Promise<Oidc.Tokens<DecodedIdToken>> }
62
+ >;
63
+
64
+ provideOidcInitAwaiter: EnvironmentProviders;
65
+ } & (AutoLogin extends true
66
+ ? {}
67
+ : {
68
+ enforceLoginGuard: CanActivateFn;
69
+ });
70
+
71
+ export function createAngularOidc_dependencyInjection<
72
+ DecodedIdToken extends Record<string, unknown>,
73
+ ParamsOfCreateOidc extends {
74
+ autoLogin?: boolean;
75
+ } & (
76
+ | {
77
+ decodedIdTokenSchema: { parse: (data: unknown) => DecodedIdToken } | undefined;
78
+ }
79
+ | {}
80
+ )
81
+ >(
82
+ paramsOrGetParams: ValueOrAsyncGetter<ParamsOfCreateOidc>,
83
+ createOidc: (params: ParamsOfCreateOidc) => Promise<Oidc<DecodedIdToken>>
84
+ ): OidcAngularApi<
85
+ DecodedIdToken,
86
+ ParamsOfCreateOidc extends { autoLogin?: true | undefined } ? true : false
87
+ > {
88
+ const dReadyToCreate = new Deferred<void>();
89
+
90
+ // NOTE: It can be InitializationError only if autoLogin is true
91
+ const prOidcOrAutoLoginInitializationError = (async () => {
92
+ const params = await (async () => {
93
+ await dReadyToCreate.pr;
94
+
95
+ if (typeof paramsOrGetParams === "function") {
96
+ const getParams = paramsOrGetParams;
97
+
98
+ const params = await getParams();
99
+
100
+ return params;
101
+ }
102
+
103
+ const params = paramsOrGetParams;
104
+
105
+ return params;
106
+ })();
107
+
108
+ let oidc: Oidc<DecodedIdToken>;
109
+
110
+ try {
111
+ oidc = await createOidc(params);
112
+ } catch (error) {
113
+ if (!(error instanceof OidcInitializationError)) {
114
+ throw error;
115
+ }
116
+
117
+ return error;
118
+ }
119
+
120
+ return oidc;
121
+ })();
122
+
123
+ let oidcOrAutoLoginInitializationError: Oidc<DecodedIdToken> | OidcInitializationError | undefined =
124
+ undefined;
125
+
126
+ prOidcOrAutoLoginInitializationError.then(value => {
127
+ oidcOrAutoLoginInitializationError = value;
128
+ });
129
+
130
+ function getOidc(params?: { assert?: "user logged in" | "user not logged in" }): OidcAngular {
131
+ const { assert: assert_params } = params ?? {};
132
+
133
+ if (oidcOrAutoLoginInitializationError === undefined) {
134
+ throw new Error("oidc-spa: calling getOidc() before provideOidcInitAwaiter has resolved");
135
+ }
136
+
137
+ if (oidcOrAutoLoginInitializationError instanceof OidcInitializationError) {
138
+ throw new Error(
139
+ "oidc-spa: calling getOidc() while getOidcInitializationError() is not `undefined` in autoLogin: true mode"
140
+ );
141
+ }
142
+
143
+ const oidc = oidcOrAutoLoginInitializationError;
144
+
145
+ check_assertion: {
146
+ if (assert_params === undefined) {
147
+ break check_assertion;
148
+ }
149
+
150
+ const getMessage = (v: string) =>
151
+ [
152
+ "There is a logic error in the application.",
153
+ `If this component is mounted the user is supposed ${v}.`,
154
+ "An explicit assertion was made in this sense."
155
+ ].join(" ");
156
+
157
+ switch (assert_params) {
158
+ case "user logged in":
159
+ if (!oidc.isUserLoggedIn) {
160
+ throw new Error(getMessage("to be logged in but currently they arn't"));
161
+ }
162
+ break;
163
+ case "user not logged in":
164
+ if (oidc.isUserLoggedIn) {
165
+ throw new Error(getMessage("not to be logged in but currently they are"));
166
+ }
167
+ break;
168
+ default:
169
+ assert<Equals<typeof assert_params, never>>(false);
170
+ }
171
+ }
172
+
173
+ const common: OidcAngular.Common = {
174
+ params: oidc.params
175
+ };
176
+
177
+ return oidc.isUserLoggedIn
178
+ ? id<OidcAngular.LoggedIn>({
179
+ ...common,
180
+ isUserLoggedIn: true,
181
+ logout: oidc.logout,
182
+ renewTokens: oidc.renewTokens,
183
+ goToAuthServer: oidc.goToAuthServer,
184
+ backFromAuthServer: oidc.backFromAuthServer,
185
+ isNewBrowserSession: oidc.isNewBrowserSession
186
+ })
187
+ : id<OidcAngular.NotLoggedIn>({
188
+ ...common,
189
+ isUserLoggedIn: false,
190
+ login: params =>
191
+ oidc.login({
192
+ ...params,
193
+ doesCurrentHrefRequiresAuth: false
194
+ })
195
+ });
196
+ }
197
+
198
+ function getOidcInitializationError(): OidcInitializationError | undefined {
199
+ if (oidcOrAutoLoginInitializationError === undefined) {
200
+ throw new Error(
201
+ "oidc-spa: calling getOidcInitializationError() before provideOidcInitAwaiter has resolved"
202
+ );
203
+ }
204
+
205
+ if (oidcOrAutoLoginInitializationError instanceof OidcInitializationError) {
206
+ return oidcOrAutoLoginInitializationError;
207
+ }
208
+
209
+ const oidc = oidcOrAutoLoginInitializationError;
210
+
211
+ if (!oidc.isUserLoggedIn && oidc.initializationError !== undefined) {
212
+ return oidc.initializationError;
213
+ }
214
+
215
+ return undefined;
216
+ }
217
+
218
+ const { get$decodedIdToken } = (() => {
219
+ function createDecodedIdToken$() {
220
+ if (oidcOrAutoLoginInitializationError === undefined) {
221
+ throw new Error(
222
+ "oidc-spa: calling get$decodedIdToken() before provideOidcInitAwaiter has resolved"
223
+ );
224
+ }
225
+
226
+ if (oidcOrAutoLoginInitializationError instanceof OidcInitializationError) {
227
+ throw new Error(
228
+ "oidc-spa: calling getOidc() while getOidcInitializationError() is not `undefined` in autoLogin: true mode"
229
+ );
230
+ }
231
+
232
+ const oidc = oidcOrAutoLoginInitializationError;
233
+
234
+ let initialValue: DecodedIdToken;
235
+
236
+ if (!oidc.isUserLoggedIn) {
237
+ initialValue = createObjectThatThrowsIfAccessed({
238
+ debugMessage: [
239
+ "You are trying to read the decodedIdToken but the user",
240
+ "isn't logged in"
241
+ ].join(" ")
242
+ });
243
+ } else {
244
+ initialValue = oidc.getDecodedIdToken();
245
+ }
246
+
247
+ const decodedIdToken$ = new BehaviorSubject<DecodedIdToken>(initialValue);
248
+
249
+ if (oidc.isUserLoggedIn) {
250
+ oidc.subscribeToTokensChange(() => {
251
+ const decodedIdToken = oidc.getDecodedIdToken();
252
+
253
+ if (decodedIdToken$.getValue() === decodedIdToken) {
254
+ return;
255
+ }
256
+
257
+ decodedIdToken$.next(decodedIdToken);
258
+ });
259
+ }
260
+
261
+ return decodedIdToken$;
262
+ }
263
+
264
+ let decodedIdToken$: BehaviorSubject<DecodedIdToken> | undefined = undefined;
265
+
266
+ function get$decodedIdToken(): Signal<DecodedIdToken> {
267
+ return toSignal((decodedIdToken$ ??= createDecodedIdToken$()), {
268
+ requireSync: true
269
+ });
270
+ }
271
+
272
+ return { get$decodedIdToken };
273
+ })();
274
+
275
+ const { get$secondsLeftBeforeAutoLogout } = (() => {
276
+ function createSecondsLeftBeforeAutoLogout$() {
277
+ if (oidcOrAutoLoginInitializationError === undefined) {
278
+ throw new Error(
279
+ "oidc-spa: calling get$decodedIdToken() before provideOidcInitAwaiter has resolved"
280
+ );
281
+ }
282
+
283
+ if (oidcOrAutoLoginInitializationError instanceof OidcInitializationError) {
284
+ throw new Error(
285
+ "oidc-spa: calling getOidc() while getOidcInitializationError() is not `undefined` in autoLogin: true mode"
286
+ );
287
+ }
288
+
289
+ const oidc = oidcOrAutoLoginInitializationError;
290
+
291
+ const secondsLeftBeforeAutoLogout$ = new BehaviorSubject<number | undefined>(undefined);
292
+
293
+ if (oidc.isUserLoggedIn) {
294
+ oidc.subscribeToAutoLogoutCountdown(({ secondsLeft }) =>
295
+ secondsLeftBeforeAutoLogout$.next(secondsLeft)
296
+ );
297
+ }
298
+
299
+ return secondsLeftBeforeAutoLogout$;
300
+ }
301
+
302
+ let secondsLeftBeforeAutoLogout$: BehaviorSubject<number | undefined> | undefined = undefined;
303
+
304
+ function get$secondsLeftBeforeAutoLogout(params: {
305
+ warningDurationSeconds: number;
306
+ }): Signal<number | undefined> {
307
+ const { warningDurationSeconds } = params;
308
+
309
+ secondsLeftBeforeAutoLogout$ ??= createSecondsLeftBeforeAutoLogout$();
310
+
311
+ const secondsLeftBeforeAutoLogout$_cropped = new BehaviorSubject<number | undefined>(
312
+ secondsLeftBeforeAutoLogout$.getValue()
313
+ );
314
+
315
+ secondsLeftBeforeAutoLogout$.subscribe(secondsLeftBeforeAutoLogout => {
316
+ if (
317
+ secondsLeftBeforeAutoLogout === undefined ||
318
+ secondsLeftBeforeAutoLogout > warningDurationSeconds
319
+ ) {
320
+ if (secondsLeftBeforeAutoLogout$_cropped.getValue() !== undefined) {
321
+ secondsLeftBeforeAutoLogout$_cropped.next(undefined);
322
+ }
323
+ return;
324
+ }
325
+
326
+ secondsLeftBeforeAutoLogout$_cropped.next(secondsLeftBeforeAutoLogout);
327
+ });
328
+
329
+ const signal = toSignal(secondsLeftBeforeAutoLogout$_cropped, {
330
+ requireSync: true
331
+ });
332
+
333
+ return signal;
334
+ }
335
+
336
+ return { get$secondsLeftBeforeAutoLogout };
337
+ })();
338
+
339
+ async function getTokens(): Promise<
340
+ | { isUserLoggedIn: false; prTokens?: never }
341
+ | { isUserLoggedIn: true; prTokens: Promise<Oidc.Tokens<DecodedIdToken>> }
342
+ > {
343
+ const oidcOrAutoLoginInitializationError = await prOidcOrAutoLoginInitializationError;
344
+
345
+ if (oidcOrAutoLoginInitializationError instanceof OidcInitializationError) {
346
+ return new Promise<never>(() => {});
347
+ }
348
+
349
+ const oidc = oidcOrAutoLoginInitializationError;
350
+
351
+ return oidc.isUserLoggedIn
352
+ ? { isUserLoggedIn: true, prTokens: oidc.getTokens() }
353
+ : {
354
+ isUserLoggedIn: false
355
+ };
356
+ }
357
+
358
+ const provideOidcInitAwaiter: EnvironmentProviders = provideAppInitializer(async () => {
359
+ dReadyToCreate.resolve();
360
+ await prOidcOrAutoLoginInitializationError;
361
+ });
362
+
363
+ const enforceLoginGuard: CanActivateFn = async route => {
364
+ const router = inject(Router);
365
+
366
+ const oidcOrAutoLoginInitializationError = await prOidcOrAutoLoginInitializationError;
367
+
368
+ if (oidcOrAutoLoginInitializationError instanceof OidcInitializationError) {
369
+ // TODO: Not the correct behavior here.
370
+ return new Promise<never>(() => {});
371
+ }
372
+
373
+ const oidc = oidcOrAutoLoginInitializationError;
374
+
375
+ if (!oidc.isUserLoggedIn) {
376
+ const redirectUrl = (() => {
377
+ const tree = router.createUrlTree(
378
+ route.url.map(u => u.path),
379
+ {
380
+ queryParams: route.queryParams
381
+ }
382
+ );
383
+ return router.serializeUrl(tree);
384
+ })();
385
+
386
+ const doesCurrentHrefRequiresAuth =
387
+ location.href.replace(/\/$/, "") === redirectUrl.replace(/\/$/, "");
388
+
389
+ await oidc.login({
390
+ doesCurrentHrefRequiresAuth,
391
+ redirectUrl
392
+ });
393
+ }
394
+
395
+ return true;
396
+ };
397
+
398
+ const oidcAngularApi = id<OidcAngularApi<DecodedIdToken, false>>({
399
+ getOidc: getOidc as any,
400
+ getOidcInitializationError,
401
+ get$decodedIdToken,
402
+ get$secondsLeftBeforeAutoLogout,
403
+ getTokens,
404
+ provideOidcInitAwaiter,
405
+ enforceLoginGuard
406
+ });
407
+
408
+ // @ts-expect-error: We know what we are doing
409
+ return oidcAngularApi;
410
+ }
411
+
412
+ /** @see: https://docs.oidc-spa.dev/v/v8/usage#angular-api */
413
+ export function createAngularOidc<
414
+ DecodedIdToken extends Record<string, unknown> = Oidc.Tokens.DecodedIdToken_base,
415
+ AutoLogin extends boolean = false
416
+ >(params: ValueOrAsyncGetter<Omit<ParamsOfCreateOidc<DecodedIdToken, AutoLogin>, "homeUrl">>) {
417
+ return createAngularOidc_dependencyInjection(params, params =>
418
+ createOidc({
419
+ ...params,
420
+ homeUrl: (() => {
421
+ const baseEl = document.querySelector<HTMLBaseElement>("base[href]");
422
+ if (!baseEl) {
423
+ throw new Error('No <base href="..."> element found in the DOM');
424
+ }
425
+ return baseEl.getAttribute("href") ?? "/";
426
+ })()
427
+ })
428
+ );
429
+ }
@@ -0,0 +1 @@
1
+ export { type OidcAngular, createAngularOidc } from "./angular";
@@ -47,6 +47,7 @@ import {
47
47
  import { createGetIsNewBrowserSession } from "./isNewBrowserSession";
48
48
  import { getIsOnline } from "../tools/getIsOnline";
49
49
  import { isKeycloak } from "../keycloak/isKeycloak";
50
+ import { INFINITY_TIME } from "../tools/INFINITY_TIME";
50
51
 
51
52
  // NOTE: Replaced at build time
52
53
  const VERSION = "{{OIDC_SPA_VERSION}}";
@@ -1502,6 +1503,14 @@ export async function createOidc_nonMemoized<
1502
1503
  return;
1503
1504
  }
1504
1505
 
1506
+ if (
1507
+ currentTokens.refreshTokenExpirationTime !== undefined &&
1508
+ currentTokens.refreshTokenExpirationTime >= INFINITY_TIME
1509
+ ) {
1510
+ log?.("The refresh_token never expires, disabling auto-renewal mechanism");
1511
+ return;
1512
+ }
1513
+
1505
1514
  const msBeforeExpiration =
1506
1515
  (currentTokens.refreshTokenExpirationTime ?? currentTokens.accessTokenExpirationTime) -
1507
1516
  currentTokens.getServerDateNow();
@@ -1612,9 +1621,18 @@ export async function createOidc_nonMemoized<
1612
1621
  return undefined;
1613
1622
  }
1614
1623
 
1624
+ if (currentTokens.refreshTokenExpirationTime >= INFINITY_TIME) {
1625
+ return 0;
1626
+ }
1627
+
1615
1628
  return (currentTokens.refreshTokenExpirationTime - currentTokens.issuedAtTime) / 1000;
1616
1629
  };
1617
1630
 
1631
+ if (getCurrentRefreshTokenTtlInSeconds() === 0) {
1632
+ log?.("The refresh_token never expires, disabling auto logout mechanism");
1633
+ break auto_logout;
1634
+ }
1635
+
1618
1636
  if (getCurrentRefreshTokenTtlInSeconds() === undefined) {
1619
1637
  log?.(
1620
1638
  `${
@@ -3,6 +3,7 @@ import { assert, id } from "../vendor/frontend/tsafe";
3
3
  import { readExpirationTimeInJwt } from "../tools/readExpirationTimeInJwt";
4
4
  import { decodeJwt } from "../tools/decodeJwt";
5
5
  import type { Oidc } from "./Oidc";
6
+ import { INFINITY_TIME } from "../tools/INFINITY_TIME";
6
7
 
7
8
  export function oidcClientTsUserToTokens<DecodedIdToken extends Record<string, unknown>>(params: {
8
9
  oidcClientTsUser: OidcClientTsUser;
@@ -187,6 +188,10 @@ export function oidcClientTsUserToTokens<DecodedIdToken extends Record<string, u
187
188
 
188
189
  assert(typeof refresh_expires_at === "number", "2033392");
189
190
 
191
+ if (refresh_expires_at === 0) {
192
+ return INFINITY_TIME;
193
+ }
194
+
190
195
  return refresh_expires_at * 1000;
191
196
  }
192
197
 
@@ -199,6 +204,10 @@ export function oidcClientTsUserToTokens<DecodedIdToken extends Record<string, u
199
204
 
200
205
  assert(typeof refresh_expires_in === "number", "2033425330");
201
206
 
207
+ if (refresh_expires_in === 0) {
208
+ return INFINITY_TIME;
209
+ }
210
+
202
211
  return issuedAtTime + refresh_expires_in * 1000;
203
212
  }
204
213
 
@@ -0,0 +1,11 @@
1
+ import { createAngularOidc_dependencyInjection } from "../angular/angular";
2
+ import { createMockOidc, type ParamsOfCreateMockOidc } from "./oidc";
3
+ import type { ValueOrAsyncGetter } from "../tools/ValueOrAsyncGetter";
4
+
5
+ /** @see: https://docs.oidc-spa.dev/v/v8/mock */
6
+ export function createMockAngularOidc<
7
+ DecodedIdToken extends Record<string, unknown> = Record<string, unknown>,
8
+ AutoLogin extends boolean = false
9
+ >(params: ValueOrAsyncGetter<ParamsOfCreateMockOidc<DecodedIdToken, AutoLogin>>) {
10
+ return createAngularOidc_dependencyInjection(params, createMockOidc);
11
+ }
package/src/mock/oidc.ts CHANGED
@@ -4,6 +4,7 @@ import { id } from "../vendor/frontend/tsafe";
4
4
  import { toFullyQualifiedUrl } from "../tools/toFullyQualifiedUrl";
5
5
  import { getSearchParam, addOrUpdateSearchParam } from "../tools/urlSearchParams";
6
6
  import { getRootRelativeOriginalLocationHref } from "../core/earlyInit";
7
+ import { INFINITY_TIME } from "../tools/INFINITY_TIME";
7
8
 
8
9
  export type ParamsOfCreateMockOidc<
9
10
  DecodedIdToken extends Record<string, unknown> = Record<string, unknown>,
@@ -144,7 +145,7 @@ export async function createMockOidc<
144
145
  ...(() => {
145
146
  const tokens_common: Oidc.Tokens.Common<DecodedIdToken> = {
146
147
  accessToken: mockedTokens.accessToken ?? "mocked-access-token",
147
- accessTokenExpirationTime: mockedTokens.accessTokenExpirationTime ?? Infinity,
148
+ accessTokenExpirationTime: mockedTokens.accessTokenExpirationTime ?? INFINITY_TIME,
148
149
  idToken: mockedTokens.idToken ?? "mocked-id-token",
149
150
  decodedIdToken:
150
151
  mockedTokens.decodedIdToken ??
@@ -1,4 +1,4 @@
1
- import { createOidcReactApi_dependencyInjection } from "../react/react";
1
+ import { createReactOidc_dependencyInjection } from "../react/react";
2
2
  import { createMockOidc, type ParamsOfCreateMockOidc } from "./oidc";
3
3
  import type { ValueOrAsyncGetter } from "../tools/ValueOrAsyncGetter";
4
4
 
@@ -7,5 +7,5 @@ export function createMockReactOidc<
7
7
  DecodedIdToken extends Record<string, unknown> = Record<string, unknown>,
8
8
  AutoLogin extends boolean = false
9
9
  >(params: ValueOrAsyncGetter<ParamsOfCreateMockOidc<DecodedIdToken, AutoLogin>>) {
10
- return createOidcReactApi_dependencyInjection(params, createMockOidc);
10
+ return createReactOidc_dependencyInjection(params, createMockOidc);
11
11
  }
@@ -114,7 +114,7 @@ type OidcReactApi<DecodedIdToken extends Record<string, unknown>, AutoLogin exte
114
114
  }) => Promise<void | never>;
115
115
  });
116
116
 
117
- export function createOidcReactApi_dependencyInjection<
117
+ export function createReactOidc_dependencyInjection<
118
118
  DecodedIdToken extends Record<string, unknown>,
119
119
  ParamsOfCreateOidc extends {
120
120
  autoLogin?: boolean;
@@ -140,11 +140,11 @@ export function createOidcReactApi_dependencyInjection<
140
140
  // NOTE: It can be InitializationError only if autoLogin is true
141
141
  const prOidcOrInitializationError = (async () => {
142
142
  const params = await (async () => {
143
+ await dReadyToCreate.pr;
144
+
143
145
  if (typeof paramsOrGetParams === "function") {
144
146
  const getParams = paramsOrGetParams;
145
147
 
146
- await dReadyToCreate.pr;
147
-
148
148
  const params = await getParams();
149
149
 
150
150
  return params;
@@ -439,7 +439,7 @@ export function createOidcReactApi_dependencyInjection<
439
439
  return oidc;
440
440
  }
441
441
 
442
- const oidcReact: OidcReactApi<DecodedIdToken, false> = {
442
+ const oidcReactApi: OidcReactApi<DecodedIdToken, false> = {
443
443
  OidcProvider,
444
444
  useOidc: useOidc as any,
445
445
  getOidc,
@@ -448,7 +448,7 @@ export function createOidcReactApi_dependencyInjection<
448
448
  };
449
449
 
450
450
  // @ts-expect-error: We know what we are doing
451
- return oidcReact;
451
+ return oidcReactApi;
452
452
  }
453
453
 
454
454
  /** @see: https://docs.oidc-spa.dev/v/v8/usage#react-api */
@@ -456,5 +456,5 @@ export function createReactOidc<
456
456
  DecodedIdToken extends Record<string, unknown> = Oidc.Tokens.DecodedIdToken_base,
457
457
  AutoLogin extends boolean = false
458
458
  >(params: ValueOrAsyncGetter<ParamsOfCreateOidc<DecodedIdToken, AutoLogin>>) {
459
- return createOidcReactApi_dependencyInjection(params, createOidc);
459
+ return createReactOidc_dependencyInjection(params, createOidc);
460
460
  }
@@ -0,0 +1,2 @@
1
+ // We do not use Infinity because it's not serializable.
2
+ export const INFINITY_TIME = new Date("9999-12-31T23:59:59.999Z").getTime();
@@ -1,5 +1,6 @@
1
1
  import { decodeJwt } from "./decodeJwt";
2
2
  import { assert } from "../vendor/frontend/tsafe";
3
+ import { INFINITY_TIME } from "./INFINITY_TIME";
3
4
 
4
5
  // Return undefined if token provided wasn't a JWT or if it hasn't an exp claim number
5
6
  export function readExpirationTimeInJwt(token: string): number | undefined {
@@ -12,5 +13,9 @@ export function readExpirationTimeInJwt(token: string): number | undefined {
12
13
  return undefined;
13
14
  }
14
15
 
16
+ if (exp === 0) {
17
+ return INFINITY_TIME;
18
+ }
19
+
15
20
  return exp * 1000;
16
21
  }
@@ -0,0 +1 @@
1
+ export declare const INFINITY_TIME: number;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INFINITY_TIME = void 0;
4
+ // We do not use Infinity because it's not serializable.
5
+ exports.INFINITY_TIME = new Date("9999-12-31T23:59:59.999Z").getTime();
6
+ //# sourceMappingURL=INFINITY_TIME.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"INFINITY_TIME.js","sourceRoot":"","sources":["../src/tools/INFINITY_TIME.ts"],"names":[],"mappings":";;;AAAA,wDAAwD;AAC3C,QAAA,aAAa,GAAG,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC,OAAO,EAAE,CAAC"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.readExpirationTimeInJwt = readExpirationTimeInJwt;
4
4
  const decodeJwt_1 = require("./decodeJwt");
5
5
  const tsafe_1 = require("../vendor/frontend/tsafe");
6
+ const INFINITY_TIME_1 = require("./INFINITY_TIME");
6
7
  // Return undefined if token provided wasn't a JWT or if it hasn't an exp claim number
7
8
  function readExpirationTimeInJwt(token) {
8
9
  let exp;
@@ -13,6 +14,9 @@ function readExpirationTimeInJwt(token) {
13
14
  catch {
14
15
  return undefined;
15
16
  }
17
+ if (exp === 0) {
18
+ return INFINITY_TIME_1.INFINITY_TIME;
19
+ }
16
20
  return exp * 1000;
17
21
  }
18
22
  //# sourceMappingURL=readExpirationTimeInJwt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"readExpirationTimeInJwt.js","sourceRoot":"","sources":["../src/tools/readExpirationTimeInJwt.ts"],"names":[],"mappings":";;AAIA,0DAWC;AAfD,2CAAwC;AACxC,oDAAkD;AAElD,sFAAsF;AACtF,SAAgB,uBAAuB,CAAC,KAAa;IACjD,IAAI,GAAW,CAAC;IAEhB,IAAI,CAAC;QACD,GAAG,GAAG,IAAA,qBAAS,EAAkB,KAAK,CAAC,CAAC,GAAG,CAAC;QAC5C,IAAA,cAAM,EAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,OAAO,GAAG,GAAG,IAAI,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"readExpirationTimeInJwt.js","sourceRoot":"","sources":["../src/tools/readExpirationTimeInJwt.ts"],"names":[],"mappings":";;AAKA,0DAeC;AApBD,2CAAwC;AACxC,oDAAkD;AAClD,mDAAgD;AAEhD,sFAAsF;AACtF,SAAgB,uBAAuB,CAAC,KAAa;IACjD,IAAI,GAAW,CAAC;IAEhB,IAAI,CAAC;QACD,GAAG,GAAG,IAAA,qBAAS,EAAkB,KAAK,CAAC,CAAC,GAAG,CAAC;QAC5C,IAAA,cAAM,EAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACZ,OAAO,6BAAa,CAAC;IACzB,CAAC;IAED,OAAO,GAAG,GAAG,IAAI,CAAC;AACtB,CAAC"}