oidc-spa 8.2.3 → 8.2.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 (66) hide show
  1. package/core/Oidc.d.ts +1 -0
  2. package/core/createOidc.js +6 -26
  3. package/core/createOidc.js.map +1 -1
  4. package/core/homeAndRedirectUri.d.ts +5 -0
  5. package/core/homeAndRedirectUri.js +32 -0
  6. package/core/homeAndRedirectUri.js.map +1 -0
  7. package/esm/angular.d.ts +1 -0
  8. package/esm/angular.js +3 -0
  9. package/esm/angular.js.map +1 -1
  10. package/esm/core/Oidc.d.ts +1 -0
  11. package/esm/core/createOidc.js +6 -26
  12. package/esm/core/createOidc.js.map +1 -1
  13. package/esm/core/homeAndRedirectUri.d.ts +5 -0
  14. package/esm/core/homeAndRedirectUri.js +29 -0
  15. package/esm/core/homeAndRedirectUri.js.map +1 -0
  16. package/esm/keycloak/keycloak-js/Keycloak.js +11 -2
  17. package/esm/keycloak/keycloak-js/Keycloak.js.map +1 -1
  18. package/esm/keycloak/keycloakUtils.d.ts +3 -1
  19. package/esm/keycloak/keycloakUtils.js +26 -5
  20. package/esm/keycloak/keycloakUtils.js.map +1 -1
  21. package/esm/mock/oidc.js +2 -1
  22. package/esm/mock/oidc.js.map +1 -1
  23. package/esm/react-spa/apiBuilder.d.ts +2 -2
  24. package/esm/react-spa/apiBuilder.js +1 -1
  25. package/esm/react-spa/apiBuilder.js.map +1 -1
  26. package/esm/react-spa/createOidcSpaApi.js +3 -1
  27. package/esm/react-spa/createOidcSpaApi.js.map +1 -1
  28. package/esm/react-spa/types.d.ts +1 -0
  29. package/esm/tanstack-start/react/apiBuilder.d.ts +2 -2
  30. package/esm/tanstack-start/react/apiBuilder.js +1 -1
  31. package/esm/tanstack-start/react/apiBuilder.js.map +1 -1
  32. package/esm/tanstack-start/react/createOidcSpaApi.js +3 -1
  33. package/esm/tanstack-start/react/createOidcSpaApi.js.map +1 -1
  34. package/esm/tanstack-start/react/types.d.ts +1 -0
  35. package/esm/tools/parseKeycloakIssuerUri.js +5 -1
  36. package/esm/tools/parseKeycloakIssuerUri.js.map +1 -1
  37. package/keycloak/keycloak-js/Keycloak.js +11 -2
  38. package/keycloak/keycloak-js/Keycloak.js.map +1 -1
  39. package/keycloak/keycloakUtils.d.ts +3 -1
  40. package/keycloak/keycloakUtils.js +26 -5
  41. package/keycloak/keycloakUtils.js.map +1 -1
  42. package/mock/oidc.js +2 -1
  43. package/mock/oidc.js.map +1 -1
  44. package/package.json +1 -1
  45. package/react-spa/apiBuilder.d.ts +2 -2
  46. package/react-spa/apiBuilder.js +1 -1
  47. package/react-spa/apiBuilder.js.map +1 -1
  48. package/react-spa/createOidcSpaApi.js +3 -1
  49. package/react-spa/createOidcSpaApi.js.map +1 -1
  50. package/react-spa/types.d.ts +1 -0
  51. package/src/angular.ts +4 -0
  52. package/src/core/Oidc.ts +1 -0
  53. package/src/core/createOidc.ts +5 -30
  54. package/src/core/homeAndRedirectUri.ts +36 -0
  55. package/src/keycloak/keycloak-js/Keycloak.ts +13 -2
  56. package/src/keycloak/keycloakUtils.ts +38 -6
  57. package/src/mock/oidc.ts +2 -1
  58. package/src/react-spa/apiBuilder.ts +3 -3
  59. package/src/react-spa/createOidcSpaApi.tsx +3 -1
  60. package/src/react-spa/types.tsx +1 -0
  61. package/src/tanstack-start/react/apiBuilder.ts +3 -3
  62. package/src/tanstack-start/react/createOidcSpaApi.tsx +3 -1
  63. package/src/tanstack-start/react/types.tsx +1 -0
  64. package/src/tools/parseKeycloakIssuerUri.ts +6 -1
  65. package/tools/parseKeycloakIssuerUri.js +5 -1
  66. package/tools/parseKeycloakIssuerUri.js.map +1 -1
@@ -45,7 +45,6 @@ import { getIsOnline } from "../tools/getIsOnline";
45
45
  import { isKeycloak } from "../keycloak/isKeycloak";
46
46
  import { INFINITY_TIME } from "../tools/INFINITY_TIME";
47
47
  import { prShouldLoadApp } from "./prShouldLoadApp";
48
- import { getBASE_URL } from "./BASE_URL";
49
48
  import { getIsLikelyDevServer } from "../tools/isLikelyDevServer";
50
49
  import { createObjectThatThrowsIfAccessed } from "../tools/createObjectThatThrowsIfAccessed";
51
50
  import {
@@ -53,6 +52,7 @@ import {
53
52
  notifyNewInstanceThatCantUseIframes
54
53
  } from "./instancesThatCantUseIframes";
55
54
  import { getDesiredPostLoginRedirectUrl } from "./desiredPostLoginRedirectUrl";
55
+ import { getHomeAndRedirectUri } from "./homeAndRedirectUri";
56
56
 
57
57
  // NOTE: Replaced at build time
58
58
  const VERSION = "{{OIDC_SPA_VERSION}}";
@@ -405,33 +405,7 @@ export async function createOidc_nonMemoized<
405
405
  return extraTokenParamsOrGetter;
406
406
  })();
407
407
 
408
- const homeUrlAndRedirectUri = toFullyQualifiedUrl({
409
- urlish: (() => {
410
- if (BASE_URL_params !== undefined) {
411
- return BASE_URL_params;
412
- }
413
-
414
- const BASE_URL = getBASE_URL();
415
-
416
- if (BASE_URL === undefined) {
417
- throw new Error(
418
- [
419
- "oidc-spa: If you do not use the oidc-spa Vite plugin",
420
- "you must provide the BASE_URL to the earlyInit() examples:",
421
- "oidcSpaEarlyInit({ BASE_URL: import.meta.env.BASE_URL })",
422
- "oidcSpaEarlyInit({ BASE_URL: '/' })",
423
- "",
424
- "You can also pass this parameter to createOidc({ BASE_URL: '...' })",
425
- "or bootstrapOidc({ BASE_URL: '...' })"
426
- ].join("\n")
427
- );
428
- }
429
-
430
- return BASE_URL;
431
- })(),
432
- doAssertNoQueryParams: true,
433
- doOutputWithTrailingSlash: true
434
- });
408
+ const { homeUrlAndRedirectUri } = getHomeAndRedirectUri({ BASE_URL_params });
435
409
 
436
410
  log?.(
437
411
  `Calling createOidc v${VERSION} ${JSON.stringify(
@@ -439,7 +413,7 @@ export async function createOidc_nonMemoized<
439
413
  issuerUri,
440
414
  clientId,
441
415
  scopes,
442
- oidcRedirectUri: homeUrlAndRedirectUri
416
+ validRedirectUri: homeUrlAndRedirectUri
443
417
  },
444
418
  null,
445
419
  2
@@ -1066,7 +1040,8 @@ export async function createOidc_nonMemoized<
1066
1040
  const oidc_common: Oidc.Common = {
1067
1041
  params: {
1068
1042
  issuerUri,
1069
- clientId
1043
+ clientId,
1044
+ validRedirectUri: homeUrlAndRedirectUri
1070
1045
  }
1071
1046
  };
1072
1047
 
@@ -0,0 +1,36 @@
1
+ import { toFullyQualifiedUrl } from "../tools/toFullyQualifiedUrl";
2
+ import { getBASE_URL } from "./BASE_URL";
3
+
4
+ export function getHomeAndRedirectUri(params: { BASE_URL_params: string | undefined }) {
5
+ const { BASE_URL_params } = params;
6
+
7
+ const homeUrlAndRedirectUri = toFullyQualifiedUrl({
8
+ urlish: (() => {
9
+ if (BASE_URL_params !== undefined) {
10
+ return BASE_URL_params;
11
+ }
12
+
13
+ const BASE_URL = getBASE_URL();
14
+
15
+ if (BASE_URL === undefined) {
16
+ throw new Error(
17
+ [
18
+ "oidc-spa: If you do not use the oidc-spa Vite plugin",
19
+ "you must provide the BASE_URL to the earlyInit() examples:",
20
+ "oidcSpaEarlyInit({ BASE_URL: import.meta.env.BASE_URL })",
21
+ "oidcSpaEarlyInit({ BASE_URL: '/' })",
22
+ "",
23
+ "You can also pass this parameter to createOidc({ BASE_URL: '...' })",
24
+ "or bootstrapOidc({ BASE_URL: '...' })"
25
+ ].join("\n")
26
+ );
27
+ }
28
+
29
+ return BASE_URL;
30
+ })(),
31
+ doAssertNoQueryParams: true,
32
+ doOutputWithTrailingSlash: true
33
+ });
34
+
35
+ return { homeUrlAndRedirectUri };
36
+ }
@@ -21,6 +21,7 @@ import { type KeycloakUtils, createKeycloakUtils } from "../keycloakUtils";
21
21
  import { workerTimers } from "../../vendor/frontend/worker-timers";
22
22
  import { type StatefulEvt, createStatefulEvt } from "../../tools/StatefulEvt";
23
23
  import { readExpirationTimeInJwt } from "../../tools/readExpirationTimeInJwt";
24
+ import { getHomeAndRedirectUri } from "../../core/homeAndRedirectUri";
24
25
 
25
26
  type ConstructorParams = KeycloakServerConfig & {
26
27
  /**
@@ -934,11 +935,21 @@ export class Keycloak {
934
935
  createAccountUrl(options?: KeycloakAccountOptions & { locale?: string }): string {
935
936
  const { locale, redirectUri } = options ?? {};
936
937
 
937
- const { keycloakUtils } = this.#state;
938
+ const { keycloakUtils, constructorParams } = this.#state;
938
939
 
939
940
  return keycloakUtils.getAccountUrl({
940
941
  clientId: this.clientId,
941
- backToAppFromAccountUrl: redirectUri ?? location.href,
942
+ validRedirectUri: (() => {
943
+ if (redirectUri !== undefined) {
944
+ return redirectUri;
945
+ }
946
+
947
+ const { homeUrlAndRedirectUri } = getHomeAndRedirectUri({
948
+ BASE_URL_params: constructorParams.BASE_URL
949
+ });
950
+
951
+ return homeUrlAndRedirectUri;
952
+ })(),
942
953
  locale
943
954
  });
944
955
  }
@@ -1,5 +1,6 @@
1
1
  import { toFullyQualifiedUrl } from "../tools/toFullyQualifiedUrl";
2
2
  import { type KeycloakIssuerUriParsed, parseKeycloakIssuerUri } from "./keycloakIssuerUriParsed";
3
+ import { assert } from "../tools/tsafe/assert";
3
4
 
4
5
  export type KeycloakUtils = {
5
6
  issuerUriParsed: KeycloakIssuerUriParsed;
@@ -7,7 +8,9 @@ export type KeycloakUtils = {
7
8
  adminConsoleUrl_master: string;
8
9
  getAccountUrl: (params: {
9
10
  clientId: string;
10
- backToAppFromAccountUrl: string;
11
+ validRedirectUri?: string;
12
+ /** @deprecated: Use validRedirectUri */
13
+ backToAppFromAccountUrl?: string;
11
14
  locale?: string;
12
15
  }) => string;
13
16
  fetchUserProfile: (params: { accessToken: string }) => Promise<KeycloakProfile>;
@@ -49,17 +52,46 @@ export function createKeycloakUtils(params: { issuerUri: string }): KeycloakUtil
49
52
  issuerUriParsed,
50
53
  adminConsoleUrl: getAdminConsoleUrl(issuerUriParsed.realm),
51
54
  adminConsoleUrl_master: getAdminConsoleUrl("master"),
52
- getAccountUrl: ({ clientId, backToAppFromAccountUrl, locale }) => {
55
+ getAccountUrl: ({ clientId, locale, ...rest }) => {
56
+ const validRedirectUri = (() => {
57
+ const { validRedirectUri, backToAppFromAccountUrl } = rest;
58
+
59
+ if (validRedirectUri !== undefined) {
60
+ assert(
61
+ backToAppFromAccountUrl === undefined,
62
+ "getAccountUrl: backToAppFromAccountUrl is deprecated"
63
+ );
64
+ return validRedirectUri;
65
+ }
66
+
67
+ assert(
68
+ backToAppFromAccountUrl !== undefined,
69
+ "getAccountUrl: Must provide validRedirectUri"
70
+ );
71
+
72
+ return backToAppFromAccountUrl;
73
+ })();
74
+
53
75
  const accountUrlObj = new URL(
54
76
  `${keycloakServerUrl}/realms/${issuerUriParsed.realm}/account`
55
77
  );
56
78
  accountUrlObj.searchParams.set("referrer", clientId);
57
79
  accountUrlObj.searchParams.set(
58
80
  "referrer_uri",
59
- toFullyQualifiedUrl({
60
- urlish: backToAppFromAccountUrl,
61
- doAssertNoQueryParams: false
62
- })
81
+ (() => {
82
+ try {
83
+ return toFullyQualifiedUrl({
84
+ urlish: validRedirectUri,
85
+ doAssertNoQueryParams: true,
86
+ doOutputWithTrailingSlash: true
87
+ });
88
+ } catch {
89
+ return toFullyQualifiedUrl({
90
+ urlish: validRedirectUri,
91
+ doAssertNoQueryParams: false
92
+ });
93
+ }
94
+ })()
63
95
  );
64
96
  if (locale !== undefined) {
65
97
  accountUrlObj.searchParams.set("kc_locale", locale);
package/src/mock/oidc.ts CHANGED
@@ -96,7 +96,8 @@ export async function createMockOidc<
96
96
  const common: Oidc.Common = {
97
97
  params: {
98
98
  clientId: mockedParams.clientId ?? "mymockclient",
99
- issuerUri: mockedParams.issuerUri ?? "https://my-mock-oidc-server.net/realms/mymockrealm"
99
+ issuerUri: mockedParams.issuerUri ?? "https://my-mock-oidc-server.net/realms/mymockrealm",
100
+ validRedirectUri: homeUrl
100
101
  }
101
102
  };
102
103
 
@@ -10,7 +10,7 @@ export type OidcSpaApiBuilder<
10
10
  | "withAutoLogin"
11
11
  | "withExpectedDecodedIdTokenShape"
12
12
  | "withAccessTokenValidation"
13
- | "finalize" = never
13
+ | "createUtils" = never
14
14
  > = Omit<
15
15
  {
16
16
  withAutoLogin: () => OidcSpaApiBuilder<true, DecodedIdToken, ExcludedMethod | "withAutoLogin">;
@@ -26,7 +26,7 @@ export type OidcSpaApiBuilder<
26
26
  ExcludedMethod | "withExpectedDecodedIdTokenShape"
27
27
  >;
28
28
 
29
- finalize: () => OidcSpaApi<AutoLogin, DecodedIdToken>;
29
+ createUtils: () => OidcSpaApi<AutoLogin, DecodedIdToken>;
30
30
  },
31
31
  ExcludedMethod
32
32
  >;
@@ -54,7 +54,7 @@ function createOidcSpaApiBuilder<
54
54
  decodedIdTokenSchema,
55
55
  decodedIdToken_mock: decodedIdToken_mock
56
56
  }),
57
- finalize: () =>
57
+ createUtils: () =>
58
58
  createOidcSpaApi<AutoLogin, DecodedIdToken>({
59
59
  autoLogin: params.autoLogin,
60
60
  decodedIdTokenSchema: params.decodedIdTokenSchema,
@@ -226,6 +226,7 @@ export function createOidcSpaApi<
226
226
  initializationError: oidcCore.initializationError,
227
227
  issuerUri: oidcCore.params.issuerUri,
228
228
  clientId: oidcCore.params.clientId,
229
+ validRedirectUri: oidcCore.params.validRedirectUri,
229
230
  autoLogoutState: { shouldDisplayWarning: false },
230
231
  login: params =>
231
232
  oidcCore.login({
@@ -251,7 +252,8 @@ export function createOidcSpaApi<
251
252
  return evtAutoLogoutState.current;
252
253
  },
253
254
  issuerUri: oidcCore.params.issuerUri,
254
- clientId: oidcCore.params.clientId
255
+ clientId: oidcCore.params.clientId,
256
+ validRedirectUri: oidcCore.params.validRedirectUri
255
257
  });
256
258
  }
257
259
 
@@ -31,6 +31,7 @@ export namespace UseOidc {
31
31
  type Common = {
32
32
  issuerUri: string;
33
33
  clientId: string;
34
+ validRedirectUri: string;
34
35
  };
35
36
 
36
37
  export type NotLoggedIn = Common & {
@@ -14,7 +14,7 @@ export type OidcSpaApiBuilder<
14
14
  | "withAutoLogin"
15
15
  | "withExpectedDecodedIdTokenShape"
16
16
  | "withAccessTokenValidation"
17
- | "finalize" = never
17
+ | "createUtils" = never
18
18
  > = Omit<
19
19
  {
20
20
  withAutoLogin: () => OidcSpaApiBuilder<
@@ -61,7 +61,7 @@ export type OidcSpaApiBuilder<
61
61
  ExcludedMethod | "withAccessTokenValidation"
62
62
  >;
63
63
  };
64
- finalize: () => OidcSpaApi<AutoLogin, DecodedIdToken, AccessTokenClaims>;
64
+ createUtils: () => OidcSpaApi<AutoLogin, DecodedIdToken, AccessTokenClaims>;
65
65
  },
66
66
  ExcludedMethod
67
67
  >;
@@ -127,7 +127,7 @@ function createOidcSpaApiBuilder<
127
127
  }
128
128
  })()
129
129
  }),
130
- finalize: () =>
130
+ createUtils: () =>
131
131
  createOidcSpaApi<AutoLogin, DecodedIdToken, AccessTokenClaims>({
132
132
  autoLogin: params.autoLogin,
133
133
  decodedIdTokenSchema: params.decodedIdTokenSchema,
@@ -216,6 +216,7 @@ export function createOidcSpaApi<
216
216
  initializationError: oidcCore.initializationError,
217
217
  issuerUri: oidcCore.params.issuerUri,
218
218
  clientId: oidcCore.params.clientId,
219
+ validRedirectUri: oidcCore.params.validRedirectUri,
219
220
  autoLogoutState: { shouldDisplayWarning: false },
220
221
  login: params =>
221
222
  oidcCore.login({
@@ -241,7 +242,8 @@ export function createOidcSpaApi<
241
242
  return evtAutoLogoutState.current;
242
243
  },
243
244
  issuerUri: oidcCore.params.issuerUri,
244
- clientId: oidcCore.params.clientId
245
+ clientId: oidcCore.params.clientId,
246
+ validRedirectUri: oidcCore.params.validRedirectUri
245
247
  });
246
248
  }
247
249
 
@@ -45,6 +45,7 @@ export namespace CreateOidcComponent {
45
45
  type Common = {
46
46
  issuerUri: string;
47
47
  clientId: string;
48
+ validRedirectUri: string;
48
49
  };
49
50
 
50
51
  export type NotLoggedIn = Common & {
@@ -44,6 +44,11 @@ export function parseKeycloakIssuerUri(issuerUri: string):
44
44
  kcHttpRelativePath: keycloakUtils.issuerUriParsed.kcHttpRelativePath,
45
45
  adminConsoleUrl: keycloakUtils.adminConsoleUrl,
46
46
  adminConsoleUrl_master: keycloakUtils.adminConsoleUrl_master,
47
- getAccountUrl: keycloakUtils.getAccountUrl
47
+ getAccountUrl: ({ clientId, backToAppFromAccountUrl, locale }) =>
48
+ keycloakUtils.getAccountUrl({
49
+ clientId,
50
+ validRedirectUri: backToAppFromAccountUrl,
51
+ locale
52
+ })
48
53
  };
49
54
  }
@@ -30,7 +30,11 @@ function parseKeycloakIssuerUri(issuerUri) {
30
30
  kcHttpRelativePath: keycloakUtils.issuerUriParsed.kcHttpRelativePath,
31
31
  adminConsoleUrl: keycloakUtils.adminConsoleUrl,
32
32
  adminConsoleUrl_master: keycloakUtils.adminConsoleUrl_master,
33
- getAccountUrl: keycloakUtils.getAccountUrl
33
+ getAccountUrl: ({ clientId, backToAppFromAccountUrl, locale }) => keycloakUtils.getAccountUrl({
34
+ clientId,
35
+ validRedirectUri: backToAppFromAccountUrl,
36
+ locale
37
+ })
34
38
  };
35
39
  }
36
40
  //# sourceMappingURL=parseKeycloakIssuerUri.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parseKeycloakIssuerUri.js","sourceRoot":"","sources":["../src/tools/parseKeycloakIssuerUri.ts"],"names":[],"mappings":";;AAmBA,wDA6BC;AAhDD,0CAA8D;AAE9D;;;;;;;;;;;;;;;;KAgBK;AACL,SAAgB,sBAAsB,CAAC,SAAiB;IAepD,IAAI,CAAC,IAAA,qBAAU,EAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,aAAa,GAAG,IAAA,8BAAmB,EAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAEzD,OAAO;QACH,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,MAAM;QAC5C,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,KAAK;QAC1C,kBAAkB,EAAE,aAAa,CAAC,eAAe,CAAC,kBAAkB;QACpE,eAAe,EAAE,aAAa,CAAC,eAAe;QAC9C,sBAAsB,EAAE,aAAa,CAAC,sBAAsB;QAC5D,aAAa,EAAE,aAAa,CAAC,aAAa;KAC7C,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"parseKeycloakIssuerUri.js","sourceRoot":"","sources":["../src/tools/parseKeycloakIssuerUri.ts"],"names":[],"mappings":";;AAmBA,wDAkCC;AArDD,0CAA8D;AAE9D;;;;;;;;;;;;;;;;KAgBK;AACL,SAAgB,sBAAsB,CAAC,SAAiB;IAepD,IAAI,CAAC,IAAA,qBAAU,EAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,aAAa,GAAG,IAAA,8BAAmB,EAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAEzD,OAAO;QACH,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,MAAM;QAC5C,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,KAAK;QAC1C,kBAAkB,EAAE,aAAa,CAAC,eAAe,CAAC,kBAAkB;QACpE,eAAe,EAAE,aAAa,CAAC,eAAe;QAC9C,sBAAsB,EAAE,aAAa,CAAC,sBAAsB;QAC5D,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,EAAE,EAAE,EAAE,CAC7D,aAAa,CAAC,aAAa,CAAC;YACxB,QAAQ;YACR,gBAAgB,EAAE,uBAAuB;YACzC,MAAM;SACT,CAAC;KACT,CAAC;AACN,CAAC"}