oidc-spa 8.1.15 → 8.2.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 (151) hide show
  1. package/core/BASE_URL.d.ts +4 -0
  2. package/core/BASE_URL.js +12 -0
  3. package/core/BASE_URL.js.map +1 -0
  4. package/core/OidcMetadata.d.ts +5 -0
  5. package/core/OidcMetadata.js +56 -0
  6. package/core/OidcMetadata.js.map +1 -1
  7. package/core/createOidc.d.ts +15 -8
  8. package/core/createOidc.js +207 -104
  9. package/core/createOidc.js.map +1 -1
  10. package/core/diagnostic.d.ts +0 -1
  11. package/core/diagnostic.js +18 -5
  12. package/core/diagnostic.js.map +1 -1
  13. package/core/earlyInit.d.ts +1 -0
  14. package/core/earlyInit.js +8 -8
  15. package/core/earlyInit.js.map +1 -1
  16. package/core/loginOrGoToAuthServer.d.ts +0 -1
  17. package/core/loginOrGoToAuthServer.js +1 -16
  18. package/core/loginOrGoToAuthServer.js.map +1 -1
  19. package/core/loginSilent.d.ts +1 -2
  20. package/core/loginSilent.js +3 -21
  21. package/core/loginSilent.js.map +1 -1
  22. package/core/prShouldLoadApp.d.ts +4 -0
  23. package/core/prShouldLoadApp.js +13 -0
  24. package/core/prShouldLoadApp.js.map +1 -0
  25. package/esm/core/BASE_URL.d.ts +4 -0
  26. package/esm/core/BASE_URL.js +8 -0
  27. package/esm/core/BASE_URL.js.map +1 -0
  28. package/esm/core/OidcMetadata.d.ts +5 -0
  29. package/esm/core/OidcMetadata.js +54 -0
  30. package/esm/core/OidcMetadata.js.map +1 -1
  31. package/esm/core/createOidc.d.ts +15 -8
  32. package/esm/core/createOidc.js +207 -104
  33. package/esm/core/createOidc.js.map +1 -1
  34. package/esm/core/diagnostic.d.ts +0 -1
  35. package/esm/core/diagnostic.js +15 -1
  36. package/esm/core/diagnostic.js.map +1 -1
  37. package/esm/core/earlyInit.d.ts +1 -0
  38. package/esm/core/earlyInit.js +8 -8
  39. package/esm/core/earlyInit.js.map +1 -1
  40. package/esm/core/loginOrGoToAuthServer.d.ts +0 -1
  41. package/esm/core/loginOrGoToAuthServer.js +1 -16
  42. package/esm/core/loginOrGoToAuthServer.js.map +1 -1
  43. package/esm/core/loginSilent.d.ts +1 -2
  44. package/esm/core/loginSilent.js +3 -21
  45. package/esm/core/loginSilent.js.map +1 -1
  46. package/esm/core/prShouldLoadApp.d.ts +4 -0
  47. package/esm/core/prShouldLoadApp.js +9 -0
  48. package/esm/core/prShouldLoadApp.js.map +1 -0
  49. package/esm/keycloak/keycloak-js/Keycloak.d.ts +1 -1
  50. package/esm/keycloak/keycloak-js/Keycloak.js +1 -1
  51. package/esm/keycloak/keycloak-js/Keycloak.js.map +1 -1
  52. package/esm/keycloak/keycloakIssuerUriParsed.js +8 -1
  53. package/esm/keycloak/keycloakIssuerUriParsed.js.map +1 -1
  54. package/esm/mock/oidc.d.ts +3 -1
  55. package/esm/mock/oidc.js +4 -2
  56. package/esm/mock/oidc.js.map +1 -1
  57. package/esm/react-spa/apiBuilder.d.ts +12 -0
  58. package/esm/react-spa/apiBuilder.js +26 -0
  59. package/esm/react-spa/apiBuilder.js.map +1 -0
  60. package/esm/react-spa/createOidcSpaApi.d.ts +8 -0
  61. package/esm/react-spa/createOidcSpaApi.js +387 -0
  62. package/esm/react-spa/createOidcSpaApi.js.map +1 -0
  63. package/esm/react-spa/index.d.ts +2 -0
  64. package/esm/react-spa/index.js +3 -0
  65. package/esm/react-spa/index.js.map +1 -0
  66. package/esm/react-spa/types.d.ts +279 -0
  67. package/esm/react-spa/types.js +2 -0
  68. package/esm/react-spa/types.js.map +1 -0
  69. package/esm/tanstack-start/react/apiBuilder.js.map +1 -1
  70. package/esm/tanstack-start/react/createOidcSpaApi.js +13 -9
  71. package/esm/tanstack-start/react/createOidcSpaApi.js.map +1 -1
  72. package/esm/tanstack-start/react/types.d.ts +5 -4
  73. package/esm/tools/isLikelyDevServer.d.ts +1 -0
  74. package/esm/tools/isLikelyDevServer.js +14 -0
  75. package/esm/tools/isLikelyDevServer.js.map +1 -0
  76. package/keycloak/keycloak-js/Keycloak.d.ts +1 -1
  77. package/keycloak/keycloak-js/Keycloak.js +1 -1
  78. package/keycloak/keycloak-js/Keycloak.js.map +1 -1
  79. package/keycloak/keycloakIssuerUriParsed.js +8 -1
  80. package/keycloak/keycloakIssuerUriParsed.js.map +1 -1
  81. package/mock/oidc.d.ts +3 -1
  82. package/mock/oidc.js +4 -2
  83. package/mock/oidc.js.map +1 -1
  84. package/package.json +5 -1
  85. package/react-spa/apiBuilder.d.ts +12 -0
  86. package/react-spa/apiBuilder.js +29 -0
  87. package/react-spa/apiBuilder.js.map +1 -0
  88. package/react-spa/createOidcSpaApi.d.ts +8 -0
  89. package/react-spa/createOidcSpaApi.js +423 -0
  90. package/react-spa/createOidcSpaApi.js.map +1 -0
  91. package/react-spa/index.d.ts +2 -0
  92. package/react-spa/index.js +6 -0
  93. package/react-spa/index.js.map +1 -0
  94. package/react-spa/types.d.ts +279 -0
  95. package/react-spa/types.js +3 -0
  96. package/react-spa/types.js.map +1 -0
  97. package/src/angular.ts +1 -1
  98. package/src/core/BASE_URL.ts +9 -0
  99. package/src/core/OidcMetadata.ts +75 -0
  100. package/src/core/createOidc.ts +273 -147
  101. package/src/core/diagnostic.ts +21 -2
  102. package/src/core/earlyInit.ts +14 -11
  103. package/src/core/loginOrGoToAuthServer.ts +0 -22
  104. package/src/core/loginSilent.ts +4 -27
  105. package/src/core/prShouldLoadApp.ts +11 -0
  106. package/src/keycloak/keycloak-js/Keycloak.ts +2 -2
  107. package/src/keycloak/keycloakIssuerUriParsed.ts +10 -1
  108. package/src/mock/oidc.ts +9 -3
  109. package/src/react-spa/apiBuilder.ts +70 -0
  110. package/src/react-spa/createOidcSpaApi.tsx +527 -0
  111. package/src/react-spa/index.ts +4 -0
  112. package/src/react-spa/types.tsx +308 -0
  113. package/src/tanstack-start/react/apiBuilder.ts +0 -1
  114. package/src/tanstack-start/react/createOidcSpaApi.tsx +24 -20
  115. package/src/tanstack-start/react/types.tsx +3 -4
  116. package/src/tools/isLikelyDevServer.ts +17 -0
  117. package/src/vite-plugin/handleClientEntrypoint.ts +5 -5
  118. package/src/vite-plugin/manageOptimizedDeps.ts +64 -0
  119. package/src/vite-plugin/projectType.ts +18 -0
  120. package/src/vite-plugin/vite-plugin.ts +40 -10
  121. package/tools/isLikelyDevServer.d.ts +1 -0
  122. package/tools/isLikelyDevServer.js +17 -0
  123. package/tools/isLikelyDevServer.js.map +1 -0
  124. package/vite-plugin/handleClientEntrypoint.d.ts +2 -0
  125. package/vite-plugin/handleClientEntrypoint.js +3 -4
  126. package/vite-plugin/handleClientEntrypoint.js.map +1 -1
  127. package/vite-plugin/manageOptimizedDeps.d.ts +6 -0
  128. package/vite-plugin/{excludeModuleExportFromOptimizedDeps.js → manageOptimizedDeps.js} +42 -7
  129. package/vite-plugin/manageOptimizedDeps.js.map +1 -0
  130. package/vite-plugin/projectType.d.ts +4 -0
  131. package/vite-plugin/projectType.js +15 -0
  132. package/vite-plugin/projectType.js.map +1 -0
  133. package/vite-plugin/{transformCreateFileRoute.js → transformTanstackRouterCreateFileRoute.js} +1 -1
  134. package/vite-plugin/transformTanstackRouterCreateFileRoute.js.map +1 -0
  135. package/vite-plugin/vite-plugin.d.ts +1 -1
  136. package/vite-plugin/vite-plugin.js +28 -8
  137. package/vite-plugin/vite-plugin.js.map +1 -1
  138. package/esm/tools/infer_import_meta_env_BASE_URL.d.ts +0 -1
  139. package/esm/tools/infer_import_meta_env_BASE_URL.js +0 -15
  140. package/esm/tools/infer_import_meta_env_BASE_URL.js.map +0 -1
  141. package/src/tools/infer_import_meta_env_BASE_URL.ts +0 -19
  142. package/src/vite-plugin/detectProjectType.ts +0 -20
  143. package/src/vite-plugin/excludeModuleExportFromOptimizedDeps.ts +0 -20
  144. package/vite-plugin/detectProjectType.d.ts +0 -10
  145. package/vite-plugin/detectProjectType.js +0 -15
  146. package/vite-plugin/detectProjectType.js.map +0 -1
  147. package/vite-plugin/excludeModuleExportFromOptimizedDeps.d.ts +0 -4
  148. package/vite-plugin/excludeModuleExportFromOptimizedDeps.js.map +0 -1
  149. package/vite-plugin/transformCreateFileRoute.js.map +0 -1
  150. /package/src/vite-plugin/{transformCreateFileRoute.ts → transformTanstackRouterCreateFileRoute.ts} +0 -0
  151. /package/vite-plugin/{transformCreateFileRoute.d.ts → transformTanstackRouterCreateFileRoute.d.ts} +0 -0
@@ -20,7 +20,6 @@ namespace Params {
20
20
  redirectUrl: string;
21
21
  extraQueryParams_local: Record<string, string | undefined> | undefined;
22
22
  transformUrlBeforeRedirect_local: ((url: string) => string) | undefined;
23
- onCantFetchWellKnownEndpointError: () => void;
24
23
  };
25
24
 
26
25
  export type Login = Common & {
@@ -90,10 +89,8 @@ export function createLoginOrGoToAuthServer(params: {
90
89
  redirectUrl: redirectUrl_params,
91
90
  extraQueryParams_local,
92
91
  transformUrlBeforeRedirect_local,
93
- onCantFetchWellKnownEndpointError: onCantFetchWellKnownEndpointError_params,
94
92
  ...rest
95
93
  } = params;
96
- let onCantFetchWellKnownEndpointError = onCantFetchWellKnownEndpointError_params;
97
94
 
98
95
  log?.(`Calling loginOrGoToAuthServer ${JSON.stringify(params, null, 2)}`);
99
96
 
@@ -147,12 +144,6 @@ export function createLoginOrGoToAuthServer(params: {
147
144
  };
148
145
 
149
146
  window.addEventListener("pageshow", callback);
150
-
151
- onCantFetchWellKnownEndpointError = () => {
152
- window.removeEventListener("pageshow", callback);
153
- onCantFetchWellKnownEndpointError_params();
154
- };
155
-
156
147
  break bf_cache_handling;
157
148
  }
158
149
 
@@ -183,12 +174,6 @@ export function createLoginOrGoToAuthServer(params: {
183
174
  };
184
175
 
185
176
  window.addEventListener("pageshow", callback);
186
-
187
- onCantFetchWellKnownEndpointError = () => {
188
- window.removeEventListener("pageshow", callback);
189
- globalContext.evtHasLoginBeenCalled.current = false;
190
- onCantFetchWellKnownEndpointError_params();
191
- };
192
177
  }
193
178
  }
194
179
 
@@ -348,13 +333,6 @@ export function createLoginOrGoToAuthServer(params: {
348
333
  .then(
349
334
  () => new Promise<never>(() => {}),
350
335
  (error: Error) => {
351
- if (error.message === "Failed to fetch") {
352
- // NOTE: See ./loginSilent for explanation.
353
- onCantFetchWellKnownEndpointError();
354
-
355
- return new Promise<never>(() => {});
356
- }
357
-
358
336
  if (error.message.includes("Crypto.subtle is available only in secure contexts")) {
359
337
  throw new Error(
360
338
  [
@@ -20,8 +20,7 @@ type ResultOfLoginSilent =
20
20
  authResponse: AuthResponse;
21
21
  }
22
22
  | {
23
- outcome: "failure";
24
- cause: "timeout" | "can't reach well-known oidc endpoint";
23
+ outcome: "timeout";
25
24
  }
26
25
  | {
27
26
  outcome: "token refreshed using refresh token";
@@ -106,8 +105,7 @@ export async function loginSilent(params: {
106
105
  const timeouts = [
107
106
  setTimeout(() => {
108
107
  dResult.resolve({
109
- outcome: "failure",
110
- cause: "timeout"
108
+ outcome: "timeout"
111
109
  });
112
110
  }, timeoutDelayMs),
113
111
  setTimeout(() => {
@@ -259,28 +257,7 @@ export async function loginSilent(params: {
259
257
  oidcClientTsUser
260
258
  });
261
259
  },
262
- (error: Error) => {
263
- if (error.message === "Failed to fetch") {
264
- // NOTE: If we got an error here it means that the fetch to the
265
- // well-known oidc endpoint failed.
266
- // This usually means that the server is down or that the issuerUri
267
- // is not pointing to a valid oidc server.
268
- // It could be a CORS error on the well-known endpoint but it's unlikely.
269
-
270
- // NOTE: This error should happen well before we displayed
271
- // the warning notifying that something is probably misconfigured.
272
- // wasSuccess shouldn't really be a required parameter but we do it
273
- // for peace of mind.
274
- clearTimeouts({ wasSuccess: false });
275
-
276
- dResult.resolve({
277
- outcome: "failure",
278
- cause: "can't reach well-known oidc endpoint"
279
- });
280
-
281
- return;
282
- }
283
-
260
+ () => {
284
261
  // NOTE: Here, except error on our understanding there can't be any other
285
262
  // error than timeout so we fail silently and let the timeout expire.
286
263
  }
@@ -289,7 +266,7 @@ export async function loginSilent(params: {
289
266
  dResult.pr.then(result => {
290
267
  clearSessionStoragePublicKey();
291
268
 
292
- if (result.outcome === "failure") {
269
+ if (result.outcome === "timeout") {
293
270
  clearStateStore({ stateUrlParamValue: stateUrlParamValue_instance });
294
271
  }
295
272
  });
@@ -0,0 +1,11 @@
1
+ import { assert } from "../tools/tsafe/assert";
2
+
3
+ let prShouldLoadApp_resolve: (shouldLoadApp: boolean) => void | undefined;
4
+
5
+ export const prShouldLoadApp = new Promise<boolean>(resolve => (prShouldLoadApp_resolve = resolve));
6
+
7
+ export function resolvePrShouldLoadApp(params: { shouldLoadApp: boolean }) {
8
+ const { shouldLoadApp } = params;
9
+ assert(prShouldLoadApp_resolve !== undefined);
10
+ prShouldLoadApp_resolve(shouldLoadApp);
11
+ }
@@ -23,7 +23,7 @@ import { type StatefulEvt, createStatefulEvt } from "../../tools/StatefulEvt";
23
23
  import { readExpirationTimeInJwt } from "../../tools/readExpirationTimeInJwt";
24
24
 
25
25
  type ConstructorParams = KeycloakServerConfig & {
26
- homeUrl: string;
26
+ BASE_URL?: string;
27
27
  };
28
28
 
29
29
  /**
@@ -99,7 +99,7 @@ export class Keycloak {
99
99
  let hasCreateResolved = false;
100
100
 
101
101
  const oidcOrError = await createOidc({
102
- homeUrl: constructorParams.homeUrl,
102
+ homeUrl: constructorParams.BASE_URL,
103
103
  issuerUri,
104
104
  clientId: this.#state.constructorParams.clientId,
105
105
  autoLogin,
@@ -11,7 +11,16 @@ export type KeycloakIssuerUriParsed = {
11
11
  export function parseKeycloakIssuerUri(params: { issuerUri: string }): KeycloakIssuerUriParsed {
12
12
  const { issuerUri } = params;
13
13
 
14
- assert(isKeycloak({ issuerUri }));
14
+ if (!isKeycloak({ issuerUri })) {
15
+ throw new Error(
16
+ [
17
+ `oidc-spa: The issuer uri provided ${issuerUri}`,
18
+ "if you are in an environnement that should support multiple",
19
+ "auth provider, you should first test `isKeycloakUrl({ issuerUri })`",
20
+ "before calling parseKeycloakIssuerUri({ issuerUri })"
21
+ ].join(" ")
22
+ );
23
+ }
15
24
 
16
25
  const url = new URL(issuerUri.replace(/\/$/, ""));
17
26
 
package/src/mock/oidc.ts CHANGED
@@ -5,6 +5,7 @@ import { toFullyQualifiedUrl } from "../tools/toFullyQualifiedUrl";
5
5
  import { getSearchParam, addOrUpdateSearchParam } from "../tools/urlSearchParams";
6
6
  import { getRootRelativeOriginalLocationHref } from "../core/earlyInit";
7
7
  import { INFINITY_TIME } from "../tools/INFINITY_TIME";
8
+ import { getBASE_URL } from "../core/BASE_URL";
8
9
 
9
10
  export type ParamsOfCreateMockOidc<
10
11
  DecodedIdToken extends Record<string, unknown> = Record<string, unknown>,
@@ -18,7 +19,11 @@ export type ParamsOfCreateMockOidc<
18
19
  * In the majority of cases it should be `homeUrl: "/"` but it could aso be something like `homeUrl: "/dashboard"`
19
20
  * if your web app isn't hosted at the root of the domain.
20
21
  */
21
- homeUrl: string;
22
+ BASE_URL?: string;
23
+
24
+ /** @deprecated: Use BASE_URL (same thing, just renamed). */
25
+ homeUrl?: string;
26
+
22
27
  autoLogin?: AutoLogin;
23
28
  postLoginRedirectUrl?: string;
24
29
  } & (AutoLogin extends true
@@ -41,11 +46,12 @@ export async function createMockOidc<
41
46
  isUserInitiallyLoggedIn = true,
42
47
  mockedParams = {},
43
48
  mockedTokens = {},
44
- homeUrl: homeUrl_params,
45
49
  autoLogin = false,
46
50
  postLoginRedirectUrl
47
51
  } = params;
48
52
 
53
+ const BASE_URL_params = params.BASE_URL ?? params.homeUrl;
54
+
49
55
  const isUserLoggedIn = (() => {
50
56
  const { wasPresent, value } = getSearchParam({
51
57
  url: toFullyQualifiedUrl({
@@ -82,7 +88,7 @@ export async function createMockOidc<
82
88
  })();
83
89
 
84
90
  const homeUrl = toFullyQualifiedUrl({
85
- urlish: homeUrl_params,
91
+ urlish: BASE_URL_params ?? getBASE_URL() ?? "/",
86
92
  doAssertNoQueryParams: true,
87
93
  doOutputWithTrailingSlash: true
88
94
  });
@@ -0,0 +1,70 @@
1
+ import type { OidcSpaApi } from "./types";
2
+ import type { Oidc as Oidc_core } from "../core";
3
+ import type { ZodSchemaLike } from "../tools/ZodSchemaLike";
4
+ import { createOidcSpaApi } from "./createOidcSpaApi";
5
+
6
+ export type OidcSpaApiBuilder<
7
+ AutoLogin extends boolean = false,
8
+ DecodedIdToken extends Record<string, unknown> = Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec,
9
+ ExcludedMethod extends
10
+ | "withAutoLogin"
11
+ | "withExpectedDecodedIdTokenShape"
12
+ | "withAccessTokenValidation"
13
+ | "finalize" = never
14
+ > = Omit<
15
+ {
16
+ withAutoLogin: () => OidcSpaApiBuilder<true, DecodedIdToken, ExcludedMethod | "withAutoLogin">;
17
+ withExpectedDecodedIdTokenShape: <DecodedIdToken extends Record<string, unknown>>(params: {
18
+ decodedIdTokenSchema: ZodSchemaLike<
19
+ Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec,
20
+ DecodedIdToken
21
+ >;
22
+ decodedIdToken_mock?: NoInfer<DecodedIdToken>;
23
+ }) => OidcSpaApiBuilder<
24
+ AutoLogin,
25
+ DecodedIdToken,
26
+ ExcludedMethod | "withExpectedDecodedIdTokenShape"
27
+ >;
28
+
29
+ finalize: () => OidcSpaApi<AutoLogin, DecodedIdToken>;
30
+ },
31
+ ExcludedMethod
32
+ >;
33
+
34
+ function createOidcSpaApiBuilder<
35
+ AutoLogin extends boolean = false,
36
+ DecodedIdToken extends Record<string, unknown> = Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec
37
+ >(params: {
38
+ autoLogin: AutoLogin;
39
+ decodedIdTokenSchema:
40
+ | ZodSchemaLike<Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec, DecodedIdToken>
41
+ | undefined;
42
+ decodedIdToken_mock: DecodedIdToken | undefined;
43
+ }): OidcSpaApiBuilder<AutoLogin, DecodedIdToken> {
44
+ return {
45
+ withAutoLogin: () =>
46
+ createOidcSpaApiBuilder({
47
+ autoLogin: true,
48
+ decodedIdTokenSchema: params.decodedIdTokenSchema,
49
+ decodedIdToken_mock: params.decodedIdToken_mock
50
+ }),
51
+ withExpectedDecodedIdTokenShape: ({ decodedIdTokenSchema, decodedIdToken_mock }) =>
52
+ createOidcSpaApiBuilder({
53
+ autoLogin: params.autoLogin,
54
+ decodedIdTokenSchema,
55
+ decodedIdToken_mock: decodedIdToken_mock
56
+ }),
57
+ finalize: () =>
58
+ createOidcSpaApi<AutoLogin, DecodedIdToken>({
59
+ autoLogin: params.autoLogin,
60
+ decodedIdTokenSchema: params.decodedIdTokenSchema,
61
+ decodedIdToken_mock: params.decodedIdToken_mock
62
+ })
63
+ };
64
+ }
65
+
66
+ export const oidcSpaApiBuilder = createOidcSpaApiBuilder({
67
+ autoLogin: false,
68
+ decodedIdToken_mock: undefined,
69
+ decodedIdTokenSchema: undefined
70
+ });