oidc-spa 6.6.1 → 6.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -57,11 +57,22 @@ export type ParamsOfCreateOidc<
57
57
  **/
58
58
  scopes?: string[];
59
59
  /**
60
- * Transform the url before redirecting to the login pages.
60
+ * Transform the url of the authorization endpoint before redirecting to the login pages.
61
61
  */
62
62
  transformUrlBeforeRedirect?: (url: string) => string;
63
+
64
+ /**
65
+ * NOTE: Will replace transformUrlBeforeRedirect in the next major version.
66
+ *
67
+ * Transform the url (authorization endpoint) before redirecting to the login pages.
68
+ *
69
+ * The isSilent parameter is true when the redirect is initiated in the background iframe for silent signin.
70
+ * This can be used to omit ui related query parameters (like `ui_locales`).
71
+ */
72
+ transformUrlBeforeRedirect_next?: (params: { isSilent: boolean; url: string }) => string;
73
+
63
74
  /**
64
- * Extra query params to be added on the login url.
75
+ * Extra query params to be added to the authorization endpoint url before redirecting or silent signing in.
65
76
  * You can provide a function that returns those extra query params, it will be called
66
77
  * when login() is called.
67
78
  *
@@ -69,7 +80,9 @@ export type ParamsOfCreateOidc<
69
80
  *
70
81
  * This parameter can also be passed to login() directly.
71
82
  */
72
- extraQueryParams?: Record<string, string> | (() => Record<string, string>);
83
+ extraQueryParams?:
84
+ | Record<string, string | undefined>
85
+ | ((params: { isSilent: boolean; url: string }) => Record<string, string | undefined>);
73
86
  /**
74
87
  * Extra body params to be added to the /token POST request.
75
88
  *
@@ -81,7 +94,7 @@ export type ParamsOfCreateOidc<
81
94
  * Example: extraTokenParams: ()=> ({ selectedCustomer: "xxx" })
82
95
  * extraTokenParams: { selectedCustomer: "xxx" }
83
96
  */
84
- extraTokenParams?: Record<string, string> | (() => Record<string, string>);
97
+ extraTokenParams?: Record<string, string | undefined> | (() => Record<string, string | undefined>);
85
98
  /**
86
99
  * Where to redirect after successful login.
87
100
  * Default: window.location.href (here)
@@ -246,6 +259,7 @@ export async function createOidc_nonMemoized<
246
259
  }
247
260
  ): Promise<AutoLogin extends true ? Oidc.LoggedIn<DecodedIdToken> : Oidc<DecodedIdToken>> {
248
261
  const {
262
+ transformUrlBeforeRedirect_next,
249
263
  transformUrlBeforeRedirect,
250
264
  extraQueryParams: extraQueryParamsOrGetter,
251
265
  extraTokenParams: extraTokenParamsOrGetter,
@@ -261,19 +275,29 @@ export async function createOidc_nonMemoized<
261
275
 
262
276
  const { issuerUri, clientId, scopes, configId, log } = preProcessedParams;
263
277
 
264
- const [getExtraQueryParams, getExtraTokenParams] = (
265
- [extraQueryParamsOrGetter, extraTokenParamsOrGetter] as const
266
- ).map(valueOrGetter => {
267
- if (typeof valueOrGetter === "function") {
268
- return valueOrGetter;
278
+ const getExtraQueryParams = (() => {
279
+ if (extraQueryParamsOrGetter === undefined) {
280
+ return undefined;
269
281
  }
270
282
 
271
- if (valueOrGetter !== undefined) {
272
- return () => valueOrGetter;
283
+ if (typeof extraQueryParamsOrGetter !== "function") {
284
+ return () => extraQueryParamsOrGetter;
273
285
  }
274
286
 
275
- return undefined;
276
- });
287
+ return extraQueryParamsOrGetter;
288
+ })();
289
+
290
+ const getExtraTokenParams = (() => {
291
+ if (extraTokenParamsOrGetter === undefined) {
292
+ return undefined;
293
+ }
294
+
295
+ if (typeof extraTokenParamsOrGetter !== "function") {
296
+ return () => extraTokenParamsOrGetter;
297
+ }
298
+
299
+ return extraTokenParamsOrGetter;
300
+ })();
277
301
 
278
302
  const homeAndCallbackUrl = toFullyQualifiedUrl({
279
303
  urlish: homeUrl_params,
@@ -369,8 +393,10 @@ export async function createOidc_nonMemoized<
369
393
  const { loginOrGoToAuthServer } = createLoginOrGoToAuthServer({
370
394
  configId,
371
395
  oidcClientTsUserManager,
372
- getExtraQueryParams,
373
396
  transformUrlBeforeRedirect,
397
+ transformUrlBeforeRedirect_next,
398
+ getExtraQueryParams,
399
+ getExtraTokenParams,
374
400
  homeAndCallbackUrl,
375
401
  evtIsUserLoggedIn,
376
402
  log
@@ -400,7 +426,13 @@ export async function createOidc_nonMemoized<
400
426
  switch (stateData.action) {
401
427
  case "login":
402
428
  {
403
- log?.("Handling login redirect auth response", authResponse);
429
+ log?.(
430
+ `Handling login redirect auth response ${JSON.stringify(
431
+ authResponse,
432
+ null,
433
+ 2
434
+ )}`
435
+ );
404
436
 
405
437
  const authResponseUrl = authResponseToUrl(authResponse);
406
438
 
@@ -540,6 +572,8 @@ export async function createOidc_nonMemoized<
540
572
  oidcClientTsUserManager,
541
573
  stateQueryParamValue_instance,
542
574
  configId,
575
+ transformUrlBeforeRedirect_next,
576
+ getExtraQueryParams,
543
577
  getExtraTokenParams
544
578
  });
545
579
 
@@ -886,7 +920,9 @@ export async function createOidc_nonMemoized<
886
920
  return new Promise<never>(() => {});
887
921
  },
888
922
  renewTokens: (() => {
889
- async function renewTokens_nonMutexed(params: { extraTokenParams: Record<string, string> }) {
923
+ async function renewTokens_nonMutexed(params: {
924
+ extraTokenParams: Record<string, string | undefined>;
925
+ }) {
890
926
  const { extraTokenParams } = params;
891
927
 
892
928
  log?.("Renewing tokens");
@@ -897,6 +933,8 @@ export async function createOidc_nonMemoized<
897
933
  oidcClientTsUserManager,
898
934
  stateQueryParamValue_instance,
899
935
  configId,
936
+ transformUrlBeforeRedirect_next,
937
+ getExtraQueryParams,
900
938
  getExtraTokenParams: () => extraTokenParams
901
939
  });
902
940
 
@@ -999,7 +1037,7 @@ export async function createOidc_nonMemoized<
999
1037
  let ongoingCall:
1000
1038
  | {
1001
1039
  pr: Promise<void>;
1002
- extraTokenParams: Record<string, string>;
1040
+ extraTokenParams: Record<string, string | undefined>;
1003
1041
  }
1004
1042
  | undefined = undefined;
1005
1043
 
@@ -1,7 +1,7 @@
1
1
  import type { UserManager as OidcClientTsUserManager } from "../vendor/frontend/oidc-client-ts-and-jwt-decode";
2
2
  import { toFullyQualifiedUrl } from "../tools/toFullyQualifiedUrl";
3
- import { id, assert, type Equals } from "../vendor/frontend/tsafe";
4
- import type { StateData } from "./StateData";
3
+ import { assert, type Equals, noUndefined } from "../vendor/frontend/tsafe";
4
+ import { StateData } from "./StateData";
5
5
  import type { NonPostableEvt } from "../tools/Evt";
6
6
  import { type StatefulEvt, createStatefulEvt } from "../tools/StatefulEvt";
7
7
  import { Deferred } from "../tools/Deferred";
@@ -27,7 +27,7 @@ type Params = Params.Login | Params.GoToAuthServer;
27
27
  namespace Params {
28
28
  type Common = {
29
29
  redirectUrl: string;
30
- extraQueryParams_local: Record<string, string> | undefined;
30
+ extraQueryParams_local: Record<string, string | undefined> | undefined;
31
31
  transformUrlBeforeRedirect_local: ((url: string) => string) | undefined;
32
32
  };
33
33
 
@@ -59,8 +59,15 @@ export function getPrSafelyRestoredFromBfCacheAfterLoginBackNavigation() {
59
59
  export function createLoginOrGoToAuthServer(params: {
60
60
  configId: string;
61
61
  oidcClientTsUserManager: OidcClientTsUserManager;
62
- getExtraQueryParams: (() => Record<string, string>) | undefined;
63
62
  transformUrlBeforeRedirect: ((url: string) => string) | undefined;
63
+ transformUrlBeforeRedirect_next: ((params: { isSilent: false; url: string }) => string) | undefined;
64
+
65
+ getExtraQueryParams:
66
+ | ((params: { isSilent: false; url: string }) => Record<string, string | undefined>)
67
+ | undefined;
68
+
69
+ getExtraTokenParams: (() => Record<string, string | undefined>) | undefined;
70
+
64
71
  homeAndCallbackUrl: string;
65
72
  evtIsUserLoggedIn: NonPostableEvt<boolean>;
66
73
  log: typeof console.log | undefined;
@@ -68,8 +75,13 @@ export function createLoginOrGoToAuthServer(params: {
68
75
  const {
69
76
  configId,
70
77
  oidcClientTsUserManager,
71
- getExtraQueryParams,
78
+
72
79
  transformUrlBeforeRedirect,
80
+ transformUrlBeforeRedirect_next,
81
+ getExtraQueryParams,
82
+
83
+ getExtraTokenParams,
84
+
73
85
  homeAndCallbackUrl,
74
86
  evtIsUserLoggedIn,
75
87
  log
@@ -83,7 +95,7 @@ export function createLoginOrGoToAuthServer(params: {
83
95
  const {
84
96
  redirectUrl: redirectUrl_params,
85
97
  extraQueryParams_local,
86
- transformUrlBeforeRedirect_local,
98
+ transformUrlBeforeRedirect_local: transformUrl,
87
99
  ...rest
88
100
  } = params;
89
101
 
@@ -152,33 +164,82 @@ export function createLoginOrGoToAuthServer(params: {
152
164
 
153
165
  log?.(`redirectUrl: ${redirectUrl}`);
154
166
 
167
+ const stateData: StateData = {
168
+ context: "redirect",
169
+ redirectUrl,
170
+ extraQueryParams: {},
171
+ hasBeenProcessedByCallback: false,
172
+ configId,
173
+ action: "login",
174
+ redirectUrl_consentRequiredCase: (() => {
175
+ switch (rest.action) {
176
+ case "login":
177
+ return lastPublicUrl ?? homeAndCallbackUrl;
178
+ case "go to auth server":
179
+ return redirectUrl;
180
+ }
181
+ })()
182
+ };
183
+
155
184
  const transformUrl_oidcClientTs = (url: string) => {
156
185
  (
157
186
  [
158
- [getExtraQueryParams?.(), transformUrlBeforeRedirect],
159
- [extraQueryParams_local, transformUrlBeforeRedirect_local]
187
+ [
188
+ undefined,
189
+ transformUrlBeforeRedirect_next === undefined
190
+ ? undefined
191
+ : (url: string) => transformUrlBeforeRedirect_next({ url, isSilent: false })
192
+ ],
193
+ [getExtraQueryParams, transformUrlBeforeRedirect],
194
+ [extraQueryParams_local, transformUrl]
160
195
  ] as const
161
- ).forEach(([extraQueryParams, transformUrlBeforeRedirect]) => {
196
+ ).forEach(([extraQueryParamsMaybeGetter, transformUrlBeforeRedirect], i) => {
197
+ const urlObj_before = i !== 2 ? undefined : new URL(url);
198
+
162
199
  add_extra_query_params: {
163
- if (extraQueryParams === undefined) {
200
+ if (extraQueryParamsMaybeGetter === undefined) {
164
201
  break add_extra_query_params;
165
202
  }
166
203
 
204
+ const extraQueryParams =
205
+ typeof extraQueryParamsMaybeGetter === "function"
206
+ ? extraQueryParamsMaybeGetter({ isSilent: false, url })
207
+ : extraQueryParamsMaybeGetter;
208
+
167
209
  const url_obj = new URL(url);
168
210
 
169
211
  for (const [name, value] of Object.entries(extraQueryParams)) {
212
+ if (value === undefined) {
213
+ continue;
214
+ }
170
215
  url_obj.searchParams.set(name, value);
171
216
  }
172
217
 
173
218
  url = url_obj.href;
174
219
  }
175
220
 
176
- apply_transform_before_redirect: {
221
+ apply_transform_url: {
177
222
  if (transformUrlBeforeRedirect === undefined) {
178
- break apply_transform_before_redirect;
223
+ break apply_transform_url;
179
224
  }
180
225
  url = transformUrlBeforeRedirect(url);
181
226
  }
227
+
228
+ update_state: {
229
+ if (urlObj_before === undefined) {
230
+ break update_state;
231
+ }
232
+
233
+ for (const [name, value] of new URL(url).searchParams.entries()) {
234
+ const value_before = urlObj_before.searchParams.get(name);
235
+
236
+ if (value_before === value) {
237
+ continue;
238
+ }
239
+
240
+ stateData.extraQueryParams[name] = value;
241
+ }
242
+ }
182
243
  });
183
244
 
184
245
  return url;
@@ -197,48 +258,9 @@ export function createLoginOrGoToAuthServer(params: {
197
258
 
198
259
  log?.(`redirectMethod: ${redirectMethod}`);
199
260
 
200
- const { extraQueryParams } = (() => {
201
- const extraQueryParams: Record<string, string> = extraQueryParams_local ?? {};
202
-
203
- read_query_params_added_by_transform_before_redirect: {
204
- if (transformUrlBeforeRedirect_local === undefined) {
205
- break read_query_params_added_by_transform_before_redirect;
206
- }
207
-
208
- let url_afterTransform;
209
-
210
- try {
211
- url_afterTransform = transformUrlBeforeRedirect_local("https://dummy.com");
212
- } catch {
213
- break read_query_params_added_by_transform_before_redirect;
214
- }
215
-
216
- for (const [name, value] of new URL(url_afterTransform).searchParams) {
217
- extraQueryParams[name] = value;
218
- }
219
- }
220
-
221
- return { extraQueryParams };
222
- })();
223
-
224
261
  return oidcClientTsUserManager
225
262
  .signinRedirect({
226
- state: id<StateData>({
227
- context: "redirect",
228
- redirectUrl,
229
- extraQueryParams,
230
- hasBeenProcessedByCallback: false,
231
- configId,
232
- action: "login",
233
- redirectUrl_consentRequiredCase: (() => {
234
- switch (rest.action) {
235
- case "login":
236
- return lastPublicUrl ?? homeAndCallbackUrl;
237
- case "go to auth server":
238
- return redirectUrl;
239
- }
240
- })()
241
- }),
263
+ state: stateData,
242
264
  redirectMethod,
243
265
  prompt: (() => {
244
266
  switch (rest.action) {
@@ -249,7 +271,9 @@ export function createLoginOrGoToAuthServer(params: {
249
271
  }
250
272
  assert<Equals<typeof rest, never>>;
251
273
  })(),
252
- transformUrl: transformUrl_oidcClientTs
274
+ transformUrl: transformUrl_oidcClientTs,
275
+ extraTokenParams:
276
+ getExtraTokenParams === undefined ? undefined : noUndefined(getExtraTokenParams())
253
277
  })
254
278
  .then(() => new Promise<never>(() => {}));
255
279
  }
@@ -1,6 +1,6 @@
1
1
  import type { UserManager as OidcClientTsUserManager } from "../vendor/frontend/oidc-client-ts-and-jwt-decode";
2
2
  import { Deferred } from "../tools/Deferred";
3
- import { id, assert } from "../vendor/frontend/tsafe";
3
+ import { id, assert, noUndefined } from "../vendor/frontend/tsafe";
4
4
  import { getStateData, clearStateStore, type StateData } from "./StateData";
5
5
  import { getDownlinkAndRtt } from "../tools/getDownlinkAndRtt";
6
6
  import { getIsDev } from "../tools/isDev";
@@ -25,10 +25,23 @@ export async function loginSilent(params: {
25
25
  oidcClientTsUserManager: OidcClientTsUserManager;
26
26
  stateQueryParamValue_instance: string;
27
27
  configId: string;
28
- getExtraTokenParams: (() => Record<string, string>) | undefined;
28
+
29
+ transformUrlBeforeRedirect_next: ((params: { isSilent: true; url: string }) => string) | undefined;
30
+
31
+ getExtraQueryParams:
32
+ | ((params: { isSilent: true; url: string }) => Record<string, string | undefined>)
33
+ | undefined;
34
+
35
+ getExtraTokenParams: (() => Record<string, string | undefined>) | undefined;
29
36
  }): Promise<ResultOfLoginSilent> {
30
- const { oidcClientTsUserManager, stateQueryParamValue_instance, configId, getExtraTokenParams } =
31
- params;
37
+ const {
38
+ oidcClientTsUserManager,
39
+ stateQueryParamValue_instance,
40
+ configId,
41
+ transformUrlBeforeRedirect_next,
42
+ getExtraQueryParams,
43
+ getExtraTokenParams
44
+ } = params;
32
45
 
33
46
  const dResult = new Deferred<ResultOfLoginSilent>();
34
47
 
@@ -88,6 +101,36 @@ export async function loginSilent(params: {
88
101
 
89
102
  window.addEventListener("message", listener, false);
90
103
 
104
+ const transformUrl_oidcClientTs = (url: string) => {
105
+ add_extra_query_params: {
106
+ if (getExtraQueryParams === undefined) {
107
+ break add_extra_query_params;
108
+ }
109
+
110
+ const extraQueryParams = getExtraQueryParams({ isSilent: true, url });
111
+
112
+ const url_obj = new URL(url);
113
+
114
+ for (const [name, value] of Object.entries(extraQueryParams)) {
115
+ if (value === undefined) {
116
+ continue;
117
+ }
118
+ url_obj.searchParams.set(name, value);
119
+ }
120
+
121
+ url = url_obj.href;
122
+ }
123
+
124
+ apply_transform_url: {
125
+ if (transformUrlBeforeRedirect_next === undefined) {
126
+ break apply_transform_url;
127
+ }
128
+ url = transformUrlBeforeRedirect_next({ url, isSilent: true });
129
+ }
130
+
131
+ return url;
132
+ };
133
+
91
134
  oidcClientTsUserManager
92
135
  .signinSilent({
93
136
  state: id<StateData.IFrame>({
@@ -95,7 +138,9 @@ export async function loginSilent(params: {
95
138
  configId
96
139
  }),
97
140
  silentRequestTimeoutInSeconds: timeoutDelayMs / 1000,
98
- extraTokenParams: getExtraTokenParams?.()
141
+ extraTokenParams:
142
+ getExtraTokenParams === undefined ? undefined : noUndefined(getExtraTokenParams()),
143
+ transformUrl: transformUrl_oidcClientTs
99
144
  })
100
145
  .then(
101
146
  oidcClientTsUser => {
@@ -5,11 +5,13 @@ import {
5
5
  useContext,
6
6
  useReducer,
7
7
  useRef,
8
- type ReactNode
8
+ type ReactNode,
9
+ type ComponentType,
10
+ type FC,
11
+ JSX
9
12
  } from "react";
10
- import type { JSX } from "../tools/JSX";
11
13
  import { type Oidc, createOidc, type ParamsOfCreateOidc, OidcInitializationError } from "../oidc";
12
- import { assert, type Equals } from "../vendor/frontend/tsafe";
14
+ import { assert, type Equals, type Param0 } from "../vendor/frontend/tsafe";
13
15
  import { id } from "../vendor/frontend/tsafe";
14
16
  import type { ValueOrAsyncGetter } from "../tools/ValueOrAsyncGetter";
15
17
  import { Deferred } from "../tools/Deferred";
@@ -23,7 +25,12 @@ export namespace OidcReact {
23
25
 
24
26
  export type NotLoggedIn = Common & {
25
27
  isUserLoggedIn: false;
26
- login: Oidc.NotLoggedIn["login"];
28
+ login: (params?: {
29
+ extraQueryParams?: Record<string, string | undefined>;
30
+ redirectUrl?: string;
31
+ transformUrlBeforeRedirect?: (url: string) => string;
32
+ doesCurrentHrefRequiresAuth?: boolean;
33
+ }) => Promise<never>;
27
34
  initializationError: OidcInitializationError | undefined;
28
35
 
29
36
  /** @deprecated: Use `const { decodedIdToken, tokens} = useOidc();` */
@@ -67,6 +74,14 @@ export namespace OidcReact {
67
74
  isNewBrowserSession: boolean;
68
75
  };
69
76
  }
77
+ {
78
+ type Actual = Param0<OidcReact.NotLoggedIn["login"]>;
79
+ type Expected = Omit<Param0<Oidc.NotLoggedIn["login"]>, "doesCurrentHrefRequiresAuth"> & {
80
+ doesCurrentHrefRequiresAuth?: boolean;
81
+ };
82
+
83
+ assert<Equals<Actual, Expected>>();
84
+ }
70
85
 
71
86
  type OidcReactApi<DecodedIdToken extends Record<string, unknown>, AutoLogin extends boolean> = {
72
87
  OidcProvider: AutoLogin extends true
@@ -88,6 +103,12 @@ type OidcReactApi<DecodedIdToken extends Record<string, unknown>, AutoLogin exte
88
103
  getOidc: () => Promise<
89
104
  AutoLogin extends true ? Oidc.LoggedIn<DecodedIdToken> : Oidc<DecodedIdToken>
90
105
  >;
106
+ withAuthenticationRequired: <Props extends Record<string, unknown>>(
107
+ Component: ComponentType<Props>,
108
+ params?: {
109
+ onRedirecting: () => JSX.Element | null;
110
+ }
111
+ ) => FC<Props>;
91
112
  };
92
113
 
93
114
  export function createOidcReactApi_dependencyInjection<
@@ -109,7 +130,9 @@ export function createOidcReactApi_dependencyInjection<
109
130
  > {
110
131
  const dReadyToCreate = new Deferred<void>();
111
132
 
112
- const oidcContext = createContext<Oidc<DecodedIdToken> | undefined>(undefined);
133
+ const oidcContext = createContext<{ oidc: Oidc<DecodedIdToken>; fallback: ReactNode } | undefined>(
134
+ undefined
135
+ );
113
136
 
114
137
  // NOTE: It can be InitializationError only if autoLogin is true
115
138
  const prOidcOrInitializationError = (async () => {
@@ -183,7 +206,11 @@ export function createOidcReactApi_dependencyInjection<
183
206
 
184
207
  const oidc = oidcOrInitializationError;
185
208
 
186
- return <oidcContext.Provider value={oidc}>{children}</oidcContext.Provider>;
209
+ return (
210
+ <oidcContext.Provider value={{ oidc, fallback: fallback ?? null }}>
211
+ {children}
212
+ </oidcContext.Provider>
213
+ );
187
214
  }
188
215
 
189
216
  function useOidc(params?: {
@@ -191,9 +218,11 @@ export function createOidcReactApi_dependencyInjection<
191
218
  }): OidcReact<DecodedIdToken> {
192
219
  const { assert: assert_params } = params ?? {};
193
220
 
194
- const oidc = useContext(oidcContext);
221
+ const contextValue = useContext(oidcContext);
195
222
 
196
- assert(oidc !== undefined, "You must use useOidc inside the corresponding OidcProvider");
223
+ assert(contextValue !== undefined, "You must use useOidc inside the corresponding OidcProvider");
224
+
225
+ const { oidc } = contextValue;
197
226
 
198
227
  check_assertion: {
199
228
  if (assert_params === undefined) {
@@ -289,7 +318,8 @@ export function createOidcReactApi_dependencyInjection<
289
318
  return id<OidcReact.NotLoggedIn>({
290
319
  ...common,
291
320
  isUserLoggedIn: false,
292
- login: oidc.login,
321
+ login: ({ doesCurrentHrefRequiresAuth = false, ...rest } = {}) =>
322
+ oidc.login({ doesCurrentHrefRequiresAuth, ...rest }),
293
323
  initializationError: oidc.initializationError
294
324
  });
295
325
  }
@@ -315,6 +345,39 @@ export function createOidcReactApi_dependencyInjection<
315
345
  return oidcReact;
316
346
  }
317
347
 
348
+ function withAuthenticationRequired<Props extends Record<string, unknown>>(
349
+ Component: ComponentType<Props>,
350
+ params?: {
351
+ onRedirecting?: () => JSX.Element | null;
352
+ }
353
+ ): FC<Props> {
354
+ const { onRedirecting } = params ?? {};
355
+
356
+ function ComponentWithAuthenticationRequired(props: Props) {
357
+ const contextValue = useContext(oidcContext);
358
+
359
+ assert(contextValue !== undefined);
360
+
361
+ const { oidc, fallback } = contextValue;
362
+
363
+ useEffect(() => {
364
+ if (oidc.isUserLoggedIn) {
365
+ return;
366
+ }
367
+
368
+ oidc.login({ doesCurrentHrefRequiresAuth: true });
369
+ }, []);
370
+
371
+ if (!oidc.isUserLoggedIn) {
372
+ return onRedirecting === undefined ? fallback : onRedirecting();
373
+ }
374
+
375
+ return <Component {...props} />;
376
+ }
377
+
378
+ return ComponentWithAuthenticationRequired;
379
+ }
380
+
318
381
  const prOidc = prOidcOrInitializationError.then(oidcOrInitializationError => {
319
382
  if (oidcOrInitializationError instanceof OidcInitializationError) {
320
383
  return new Promise<never>(() => {});
@@ -341,7 +404,8 @@ export function createOidcReactApi_dependencyInjection<
341
404
  }
342
405
 
343
406
  return oidc;
344
- }
407
+ },
408
+ withAuthenticationRequired
345
409
  };
346
410
  }
347
411
 
@@ -2,4 +2,5 @@ export { id } from "tsafe/id";
2
2
  export { assert, is, type Equals } from "tsafe/assert";
3
3
  export { typeGuard } from "tsafe/typeGuard";
4
4
  export { overwriteReadonlyProp } from "tsafe/lab/overwriteReadonlyProp";
5
+ export { noUndefined } from "tsafe/noUndefined";
5
6
  export type { Param0 } from "tsafe";