oidc-spa 8.6.18 → 8.7.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.
Files changed (153) hide show
  1. package/README.md +2 -2
  2. package/backend.d.ts +3 -20
  3. package/backend.js +50 -242
  4. package/backend.js.map +1 -1
  5. package/core/OidcMetadata.d.ts +2 -2
  6. package/core/OidcMetadata.js.map +1 -1
  7. package/core/createOidc.d.ts +2 -4
  8. package/core/createOidc.js +46 -6
  9. package/core/createOidc.js.map +1 -1
  10. package/core/dpop.d.ts +20 -0
  11. package/core/dpop.js +389 -0
  12. package/core/dpop.js.map +1 -0
  13. package/core/earlyInit.js +2 -0
  14. package/core/earlyInit.js.map +1 -1
  15. package/core/evtIsUserActive.d.ts +8 -1
  16. package/core/evtIsUserActive.js +4 -2
  17. package/core/evtIsUserActive.js.map +1 -1
  18. package/core/oidcClientTsUserToTokens.d.ts +1 -0
  19. package/core/oidcClientTsUserToTokens.js +15 -5
  20. package/core/oidcClientTsUserToTokens.js.map +1 -1
  21. package/core/tokenExfiltrationDefense.js +49 -6
  22. package/core/tokenExfiltrationDefense.js.map +1 -1
  23. package/esm/angular.d.ts +2 -0
  24. package/esm/angular.mjs.map +1 -1
  25. package/esm/backend.d.ts +3 -20
  26. package/esm/backend.mjs +50 -242
  27. package/esm/backend.mjs.map +1 -1
  28. package/esm/core/OidcMetadata.d.ts +2 -2
  29. package/esm/core/OidcMetadata.mjs.map +1 -1
  30. package/esm/core/createOidc.d.ts +2 -4
  31. package/esm/core/createOidc.mjs +46 -6
  32. package/esm/core/createOidc.mjs.map +1 -1
  33. package/esm/core/dpop.d.ts +20 -0
  34. package/esm/core/dpop.mjs +384 -0
  35. package/esm/core/dpop.mjs.map +1 -0
  36. package/esm/core/earlyInit.mjs +2 -0
  37. package/esm/core/earlyInit.mjs.map +1 -1
  38. package/esm/core/evtIsUserActive.d.ts +8 -1
  39. package/esm/core/evtIsUserActive.mjs +4 -2
  40. package/esm/core/evtIsUserActive.mjs.map +1 -1
  41. package/esm/core/oidcClientTsUserToTokens.d.ts +1 -0
  42. package/esm/core/oidcClientTsUserToTokens.mjs +15 -5
  43. package/esm/core/oidcClientTsUserToTokens.mjs.map +1 -1
  44. package/esm/core/tokenExfiltrationDefense.mjs +49 -6
  45. package/esm/core/tokenExfiltrationDefense.mjs.map +1 -1
  46. package/esm/react-spa/createOidcSpaApi.mjs +2 -1
  47. package/esm/react-spa/createOidcSpaApi.mjs.map +1 -1
  48. package/esm/react-spa/types.d.ts +2 -0
  49. package/esm/server/createOidcSpaUtils.d.ts +5 -0
  50. package/esm/server/createOidcSpaUtils.mjs +639 -0
  51. package/esm/server/createOidcSpaUtils.mjs.map +1 -0
  52. package/esm/server/index.d.ts +2 -0
  53. package/esm/server/index.mjs +3 -0
  54. package/esm/server/index.mjs.map +1 -0
  55. package/esm/server/types.d.ts +79 -0
  56. package/esm/server/types.mjs +2 -0
  57. package/esm/server/types.mjs.map +1 -0
  58. package/esm/server/utilsBuilder.d.ts +10 -0
  59. package/esm/server/utilsBuilder.mjs +13 -0
  60. package/esm/server/utilsBuilder.mjs.map +1 -0
  61. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.d.ts +1 -1
  62. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.mjs +102 -94
  63. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.mjs.map +1 -1
  64. package/esm/tanstack-start/react/createOidcSpaApi.d.ts +2 -2
  65. package/esm/tanstack-start/react/createOidcSpaApi.mjs +60 -51
  66. package/esm/tanstack-start/react/createOidcSpaApi.mjs.map +1 -1
  67. package/esm/tanstack-start/react/index.d.ts +1 -1
  68. package/esm/tanstack-start/react/index.mjs +2 -2
  69. package/esm/tanstack-start/react/index.mjs.map +1 -1
  70. package/esm/tanstack-start/react/types.d.ts +36 -11
  71. package/esm/tanstack-start/react/{apiBuilder.d.ts → utilsBuilder.d.ts} +9 -9
  72. package/esm/tanstack-start/react/{apiBuilder.mjs → utilsBuilder.mjs} +6 -6
  73. package/esm/tanstack-start/react/utilsBuilder.mjs.map +1 -0
  74. package/esm/tools/generateES256DPoPProof.d.ts +8 -0
  75. package/esm/tools/generateES256DPoPProof.mjs +48 -0
  76. package/esm/tools/generateES256DPoPProof.mjs.map +1 -0
  77. package/esm/tools/getServerDateNow.d.ts +5 -0
  78. package/esm/tools/getServerDateNow.mjs +7 -0
  79. package/esm/tools/getServerDateNow.mjs.map +1 -0
  80. package/esm/tools/startCountdown.mjs +9 -3
  81. package/esm/tools/startCountdown.mjs.map +1 -1
  82. package/esm/vendor/{backend → server}/evt.mjs +84 -140
  83. package/esm/vendor/{backend → server}/jose.mjs +5 -27
  84. package/esm/vendor/{backend → server}/tsafe.d.ts +1 -0
  85. package/esm/vendor/{backend → server}/tsafe.mjs +6 -0
  86. package/esm/vendor/{backend → server}/zod.mjs +196 -50
  87. package/package.json +6 -1
  88. package/react-spa/createOidcSpaApi.js +2 -1
  89. package/react-spa/createOidcSpaApi.js.map +1 -1
  90. package/react-spa/types.d.ts +2 -0
  91. package/server/createOidcSpaUtils.d.ts +5 -0
  92. package/server/createOidcSpaUtils.js +642 -0
  93. package/server/createOidcSpaUtils.js.map +1 -0
  94. package/server/index.d.ts +2 -0
  95. package/server/index.js +6 -0
  96. package/server/index.js.map +1 -0
  97. package/server/types.d.ts +79 -0
  98. package/server/types.js +3 -0
  99. package/server/types.js.map +1 -0
  100. package/server/utilsBuilder.d.ts +10 -0
  101. package/server/utilsBuilder.js +16 -0
  102. package/server/utilsBuilder.js.map +1 -0
  103. package/src/angular.ts +3 -0
  104. package/src/backend.ts +63 -364
  105. package/src/core/OidcMetadata.ts +4 -2
  106. package/src/core/createOidc.ts +61 -9
  107. package/src/core/dpop.ts +583 -0
  108. package/src/core/earlyInit.ts +3 -0
  109. package/src/core/evtIsUserActive.ts +11 -5
  110. package/src/core/oidcClientTsUserToTokens.ts +18 -4
  111. package/src/core/tokenExfiltrationDefense.ts +60 -5
  112. package/src/react-spa/createOidcSpaApi.ts +2 -1
  113. package/src/react-spa/types.tsx +3 -0
  114. package/src/server/createOidcSpaUtils.ts +848 -0
  115. package/src/server/index.ts +4 -0
  116. package/src/server/types.tsx +99 -0
  117. package/src/server/utilsBuilder.ts +41 -0
  118. package/src/tanstack-start/react/accessTokenValidation_rfc9068.ts +134 -124
  119. package/src/tanstack-start/react/createOidcSpaApi.ts +73 -69
  120. package/src/tanstack-start/react/index.ts +2 -2
  121. package/src/tanstack-start/react/types.tsx +44 -12
  122. package/src/tanstack-start/react/{apiBuilder.ts → utilsBuilder.ts} +14 -14
  123. package/src/tools/generateES256DPoPProof.ts +74 -0
  124. package/src/tools/getServerDateNow.ts +11 -0
  125. package/src/tools/startCountdown.ts +10 -3
  126. package/src/vendor/{backend → server}/tsafe.ts +1 -0
  127. package/tools/generateES256DPoPProof.d.ts +8 -0
  128. package/tools/generateES256DPoPProof.js +51 -0
  129. package/tools/generateES256DPoPProof.js.map +1 -0
  130. package/tools/getServerDateNow.d.ts +5 -0
  131. package/tools/getServerDateNow.js +10 -0
  132. package/tools/getServerDateNow.js.map +1 -0
  133. package/tools/startCountdown.js +9 -3
  134. package/tools/startCountdown.js.map +1 -1
  135. package/vendor/server/evt.js +3 -0
  136. package/vendor/server/jose.js +3 -0
  137. package/vendor/{backend → server}/tsafe.d.ts +1 -0
  138. package/vendor/server/tsafe.js +2 -0
  139. package/vendor/server/zod.js +3 -0
  140. package/esm/tanstack-start/react/apiBuilder.mjs.map +0 -1
  141. package/vendor/backend/evt.js +0 -3
  142. package/vendor/backend/jose.js +0 -3
  143. package/vendor/backend/tsafe.js +0 -2
  144. package/vendor/backend/zod.js +0 -3
  145. /package/esm/vendor/{backend → server}/evt.d.ts +0 -0
  146. /package/esm/vendor/{backend → server}/jose.d.ts +0 -0
  147. /package/esm/vendor/{backend → server}/zod.d.ts +0 -0
  148. /package/src/vendor/{backend → server}/evt.ts +0 -0
  149. /package/src/vendor/{backend → server}/jose.ts +0 -0
  150. /package/src/vendor/{backend → server}/zod.ts +0 -0
  151. /package/vendor/{backend → server}/evt.d.ts +0 -0
  152. /package/vendor/{backend → server}/jose.d.ts +0 -0
  153. /package/vendor/{backend → server}/zod.d.ts +0 -0
@@ -59,6 +59,7 @@ import {
59
59
  getIsStateDataCookieEnabled
60
60
  } from "./StateDataCookie";
61
61
  import { getIsTokenSubstitutionEnabled } from "./tokenPlaceholderSubstitution";
62
+ import { createInMemoryDPoPStore } from "./dpop";
62
63
  import { loadWebcryptoLinerShim } from "../tools/loadWebcryptoLinerShim";
63
64
 
64
65
  // NOTE: Replaced at build time
@@ -133,10 +134,6 @@ export type ParamsOfCreateOidc<
133
134
  idleSessionLifetimeInSeconds?: number;
134
135
 
135
136
  /**
136
- * Usage discouraged, this parameter exists because we don't want to assume
137
- * too much about your usecase but I can't think of a scenario where you would
138
- * want anything other than the current page.
139
- *
140
137
  * Default: { redirectTo: "current page" }
141
138
  */
142
139
  autoLogoutParams?: Parameters<Oidc.LoggedIn<any>["logout"]>[0];
@@ -247,6 +244,9 @@ export type ParamsOfCreateOidc<
247
244
  * API and no iframe capabilities.
248
245
  */
249
246
  postLoginRedirectUrl?: string;
247
+
248
+ /** Default: false */
249
+ dpop?: boolean;
250
250
  };
251
251
 
252
252
  const globalContext = {
@@ -380,7 +380,8 @@ export async function createOidc_nonMemoized<
380
380
  __unsafe_clientSecret,
381
381
  __unsafe_useIdTokenAsAccessToken = false,
382
382
  __metadata,
383
- sessionRestorationMethod = params.autoLogin === true ? "full page redirect" : "auto"
383
+ sessionRestorationMethod = params.autoLogin === true ? "full page redirect" : "auto",
384
+ dpop
384
385
  } = params;
385
386
 
386
387
  const scopes = Array.from(new Set(["openid", ...(params.scopes ?? ["profile"])]));
@@ -454,6 +455,45 @@ export async function createOidc_nonMemoized<
454
455
 
455
456
  const oidcMetadata = __metadata ?? (await fetchOidcMetadata({ issuerUri }));
456
457
 
458
+ const isDPoPEnabled = (() => {
459
+ if (dpop === undefined) {
460
+ log?.(
461
+ "DPoP disabled because it wasn't explicitly enabled when calling createOidc/bootstrapOidc"
462
+ );
463
+ }
464
+
465
+ if (!dpop) {
466
+ log?.("DPoP explicitly disabled in createOidc/bootstrapOidc params");
467
+ return false;
468
+ }
469
+
470
+ if (oidcMetadata === undefined) {
471
+ return false;
472
+ }
473
+
474
+ if (__unsafe_useIdTokenAsAccessToken) {
475
+ return false;
476
+ }
477
+
478
+ const isSupported = (() => {
479
+ const { dpop_signing_alg_values_supported } = oidcMetadata;
480
+
481
+ if (dpop_signing_alg_values_supported === undefined) {
482
+ return false;
483
+ }
484
+
485
+ return dpop_signing_alg_values_supported.includes("ES256");
486
+ })();
487
+
488
+ if (!isSupported) {
489
+ log?.("DPoP disabled because it's not supported by your IdP");
490
+ } else {
491
+ log?.("DPoP enabled");
492
+ }
493
+
494
+ return isSupported;
495
+ })();
496
+
457
497
  const canUseIframe = (() => {
458
498
  switch (sessionRestorationMethod) {
459
499
  case "auto":
@@ -666,7 +706,13 @@ export async function createOidc_nonMemoized<
666
706
  prefix: STATE_STORE_KEY_PREFIX
667
707
  }),
668
708
  client_secret: __unsafe_clientSecret,
669
- metadata: oidcMetadata
709
+ metadata: oidcMetadata,
710
+ dpop: !isDPoPEnabled
711
+ ? undefined
712
+ : {
713
+ bind_authorization_code: false,
714
+ store: createInMemoryDPoPStore({ configId })
715
+ }
670
716
  });
671
717
 
672
718
  const evtInitializationOutcomeUserNotLoggedIn = createEvt<void>();
@@ -1245,6 +1291,7 @@ export async function createOidc_nonMemoized<
1245
1291
  decodedIdTokenSchema,
1246
1292
  __unsafe_useIdTokenAsAccessToken,
1247
1293
  decodedIdToken_previous: undefined,
1294
+ isDPoPEnabled,
1248
1295
  log
1249
1296
  });
1250
1297
 
@@ -1572,6 +1619,7 @@ export async function createOidc_nonMemoized<
1572
1619
  decodedIdTokenSchema,
1573
1620
  __unsafe_useIdTokenAsAccessToken,
1574
1621
  decodedIdToken_previous: currentTokens.decodedIdToken,
1622
+ isDPoPEnabled,
1575
1623
  log
1576
1624
  });
1577
1625
 
@@ -2059,8 +2107,8 @@ export async function createOidc_nonMemoized<
2059
2107
  sessionId
2060
2108
  });
2061
2109
 
2062
- const { unsubscribe: unsubscribeFromIsUserActive } = evtIsUserActive.subscribe(isUserActive => {
2063
- if (isUserActive) {
2110
+ const { unsubscribe: unsubscribeFromIsUserActive } = evtIsUserActive.subscribe(eventData => {
2111
+ if (eventData.isUserActive) {
2064
2112
  if (stopCountdown !== undefined) {
2065
2113
  stopCountdown();
2066
2114
  stopCountdown = undefined;
@@ -2073,7 +2121,11 @@ export async function createOidc_nonMemoized<
2073
2121
  assert(currentRefreshTokenTtlInSeconds !== undefined, "902992326");
2074
2122
 
2075
2123
  stopCountdown = startCountdown({
2076
- countDownFromSeconds: currentRefreshTokenTtlInSeconds
2124
+ countDownFromSeconds: Math.floor(
2125
+ (currentRefreshTokenTtlInSeconds * 1_000 -
2126
+ eventData.hasBeenInactiveForHowLongMs) /
2127
+ 1_000
2128
+ )
2077
2129
  }).stopCountdown;
2078
2130
  }
2079
2131
  });