@hexclave/next 1.0.5 → 1.0.6

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 (89) hide show
  1. package/dist/components-page/account-settings/payments/payments-panel.js +3 -3
  2. package/dist/components-page/account-settings/payments/payments-panel.js.map +1 -1
  3. package/dist/components-page/hexclave-handler-client.d.ts +13 -1
  4. package/dist/components-page/hexclave-handler-client.d.ts.map +1 -1
  5. package/dist/components-page/hexclave-handler-client.js +44 -9
  6. package/dist/components-page/hexclave-handler-client.js.map +1 -1
  7. package/dist/components-page/hexclave-handler-client.test.d.ts +1 -0
  8. package/dist/components-page/hexclave-handler-client.test.js +51 -0
  9. package/dist/components-page/hexclave-handler-client.test.js.map +1 -0
  10. package/dist/dev-tool/dev-tool-core.js +2 -2
  11. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  12. package/dist/esm/components-page/account-settings/payments/payments-panel.js +2 -2
  13. package/dist/esm/components-page/account-settings/payments/payments-panel.js.map +1 -1
  14. package/dist/esm/components-page/hexclave-handler-client.d.ts +12 -1
  15. package/dist/esm/components-page/hexclave-handler-client.d.ts.map +1 -1
  16. package/dist/esm/components-page/hexclave-handler-client.js +46 -12
  17. package/dist/esm/components-page/hexclave-handler-client.js.map +1 -1
  18. package/dist/esm/components-page/hexclave-handler-client.test.d.ts +1 -0
  19. package/dist/esm/components-page/hexclave-handler-client.test.js +51 -0
  20. package/dist/esm/components-page/hexclave-handler-client.test.js.map +1 -0
  21. package/dist/esm/dev-tool/dev-tool-core.js +2 -2
  22. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  23. package/dist/esm/generated/env.d.ts +26 -0
  24. package/dist/esm/{lib → generated}/env.d.ts.map +1 -1
  25. package/dist/esm/generated/env.js +67 -0
  26. package/dist/esm/generated/env.js.map +1 -0
  27. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  28. package/dist/esm/global.d.ts +8 -1
  29. package/dist/esm/global.d.ts.map +1 -0
  30. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  31. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +263 -3
  32. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  33. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +3 -1
  34. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  35. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +53 -26
  36. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  37. package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts +8 -8
  38. package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -1
  39. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +28 -14
  40. package/dist/esm/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  41. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
  42. package/dist/esm/lib/hexclave-app/url-targets.d.ts.map +1 -1
  43. package/dist/esm/lib/hexclave-app/url-targets.js +25 -11
  44. package/dist/esm/lib/hexclave-app/url-targets.js.map +1 -1
  45. package/dist/esm/lib/hexclave-app/url-targets.test.js +12 -0
  46. package/dist/esm/lib/hexclave-app/url-targets.test.js.map +1 -1
  47. package/dist/generated/env.d.ts +26 -0
  48. package/dist/{lib → generated}/env.d.ts.map +1 -1
  49. package/dist/generated/env.js +69 -0
  50. package/dist/generated/env.js.map +1 -0
  51. package/dist/generated/quetzal-translations.d.ts +2 -2
  52. package/dist/global.d.ts +8 -1
  53. package/dist/global.d.ts.map +1 -0
  54. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  55. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +263 -3
  56. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  57. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +3 -1
  58. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  59. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +52 -25
  60. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  61. package/dist/lib/hexclave-app/apps/implementations/common.d.ts +8 -8
  62. package/dist/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -1
  63. package/dist/lib/hexclave-app/apps/implementations/common.js +28 -14
  64. package/dist/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  65. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
  66. package/dist/lib/hexclave-app/url-targets.d.ts.map +1 -1
  67. package/dist/lib/hexclave-app/url-targets.js +25 -11
  68. package/dist/lib/hexclave-app/url-targets.js.map +1 -1
  69. package/dist/lib/hexclave-app/url-targets.test.js +12 -0
  70. package/dist/lib/hexclave-app/url-targets.test.js.map +1 -1
  71. package/package.json +9 -7
  72. package/src/components-page/account-settings/payments/payments-panel.tsx +2 -2
  73. package/src/components-page/hexclave-handler-client.test.tsx +64 -0
  74. package/src/components-page/hexclave-handler-client.tsx +50 -11
  75. package/src/dev-tool/dev-tool-core.ts +2 -2
  76. package/src/generated/.gitignore +1 -1
  77. package/src/global.d.ts +8 -1
  78. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +316 -3
  79. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +69 -25
  80. package/src/lib/hexclave-app/apps/implementations/common.ts +34 -14
  81. package/src/lib/hexclave-app/url-targets.test.ts +17 -0
  82. package/src/lib/hexclave-app/url-targets.ts +25 -7
  83. package/dist/esm/lib/env.d.ts +0 -42
  84. package/dist/esm/lib/env.js +0 -93
  85. package/dist/esm/lib/env.js.map +0 -1
  86. package/dist/lib/env.d.ts +0 -42
  87. package/dist/lib/env.js +0 -95
  88. package/dist/lib/env.js.map +0 -1
  89. package/src/lib/env.ts +0 -93
@@ -4,7 +4,7 @@ import React, { useCallback, useMemo } from "react";
4
4
  import { HexclaveClientInterface, KnownErrors } from "@hexclave/shared";
5
5
  import { suspend, suspendIfSsr, use } from "@hexclave/shared/dist/utils/react";
6
6
  import { deepPlainEquals, omit } from "@hexclave/shared/dist/utils/objects";
7
- import { createUrlIfValid, isRelative } from "@hexclave/shared/dist/utils/urls";
7
+ import { createUrlIfValid, getRelativePart, isRelative } from "@hexclave/shared/dist/utils/urls";
8
8
  import * as NextNavigationUnscrambled from "next/navigation";
9
9
  import { Result } from "@hexclave/shared/dist/utils/results";
10
10
  import { deindent, mergeScopeStrings } from "@hexclave/shared/dist/utils/strings";
@@ -14,19 +14,19 @@ import { getTrustedParentDomain, validateRedirectUrl } from "@hexclave/shared/di
14
14
  import { decodeBase32, decodeBase64, encodeBase32, encodeBase64 } from "@hexclave/shared/dist/utils/bytes";
15
15
  import { hexclaveAppInternalsSymbol } from "../../common.js";
16
16
  import { adminProjectCreateOptionsToCrud } from "../../projects/index.js";
17
- import { WebAuthnError, startAuthentication, startRegistration } from "@simplewebauthn/browser";
18
17
  import { InternalSession } from "@hexclave/shared/dist/sessions";
18
+ import { Store, storeLock } from "@hexclave/shared/dist/utils/stores";
19
+ import { WebAuthnError, startAuthentication, startRegistration } from "@simplewebauthn/browser";
19
20
  import { scrambleDuringCompileTime } from "@hexclave/shared/dist/utils/compile-time";
20
21
  import { parseJson } from "@hexclave/shared/dist/utils/json";
21
22
  import { DependenciesMap } from "@hexclave/shared/dist/utils/maps";
22
- import { Store, storeLock } from "@hexclave/shared/dist/utils/stores";
23
23
  import { BotChallengeExecutionFailedError, BotChallengeUserCancelledError, withBotChallengeFlow } from "@hexclave/shared/dist/utils/turnstile-flow";
24
24
  import { generateUuid } from "@hexclave/shared/dist/utils/uuids";
25
25
  import * as cookie from "cookie";
26
26
  import { constructRedirectUrl } from "../../../../utils/url.js";
27
27
  import { callOAuthCallback, getNewOAuthProviderOrScopeUrl } from "../../../auth.js";
28
28
  import { createBrowserCookieHelper, createCookieHelper, createPlaceholderCookieHelper, deleteCookie, deleteCookieClient, getCookieClient, isSecure, saveVerifierAndState, setOrDeleteCookie, setOrDeleteCookieClient } from "../../../cookie.js";
29
- import { envVars } from "../../../env.js";
29
+ import { envVars } from "../../../../generated/env.js";
30
30
  import { apiKeyCreationOptionsToCrud } from "../../api-keys/index.js";
31
31
  import { contactChannelCreateOptionsToCrud, contactChannelUpdateOptionsToCrud } from "../../contact-channels/index.js";
32
32
  import { teamCreateOptionsToCrud, teamUpdateOptionsToCrud } from "../../teams/index.js";
@@ -505,15 +505,15 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
505
505
  for (const param of oauthCallbackResponseQueryParams) currentUrl.searchParams.delete(param);
506
506
  return currentUrl.toString();
507
507
  }
508
- async _getCurrentRefreshTokenIdIfSignedIn(options) {
509
- const tokens = await (await this._getSession(options?.overrideTokenStoreInit, options)).getOrFetchLikelyValidTokens(0, null);
508
+ async _fetchCurrentRefreshTokenIdIfSignedIn(options) {
509
+ const tokens = await (await this._getSession(options?.overrideTokenStoreInit, options)).fetchNewTokens();
510
510
  if (tokens?.refreshToken == null) return null;
511
511
  return tokens.accessToken.payload.refresh_token_id;
512
512
  }
513
513
  async _addNestedCrossDomainAuthParamsToRedirectUrl(options) {
514
514
  const targetUrl = new URL(options.url, options.currentUrl);
515
515
  if (targetUrl.origin === options.currentUrl.origin) return options.url;
516
- const refreshTokenId = await this._getCurrentRefreshTokenIdIfSignedIn({
516
+ const refreshTokenId = await this._fetchCurrentRefreshTokenIdIfSignedIn({
517
517
  awaitPendingAuthResolutions: options.awaitPendingAuthResolutions,
518
518
  overrideTokenStoreInit: options.overrideTokenStoreInit
519
519
  });
@@ -544,7 +544,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
544
544
  const afterCallbackRedirectUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.afterCallbackRedirectUrl);
545
545
  const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl : new URL(afterCallbackRedirectUrlString, redirectUriUrl);
546
546
  if (!await this._isTrusted(afterCallbackRedirectUrl.toString())) throw new Error(`Nested cross-domain auth after-callback redirect URL ${afterCallbackRedirectUrlString} is not trusted.`);
547
- if (await this._getCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) !== refreshTokenId) throw new Error("Nested cross-domain auth source session does not match the requested refresh token ID.");
547
+ if (await this._fetchCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) !== refreshTokenId) throw new Error("Nested cross-domain auth source session does not match the requested refresh token ID.");
548
548
  await this._redirectTo({
549
549
  url: await this._createCrossDomainAuthRedirectUrl({
550
550
  redirectUri: redirectUriUrl.toString(),
@@ -557,7 +557,9 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
557
557
  });
558
558
  return true;
559
559
  }
560
- if (await this._getCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) === refreshTokenId) return false;
560
+ const currentRefreshTokenId = await this._fetchCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false });
561
+ if (currentRefreshTokenId === refreshTokenId) return false;
562
+ if (currentRefreshTokenId != null) (await this._getSession(void 0, { awaitPendingAuthResolutions: false })).markInvalid();
561
563
  const callbackUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.callbackUrl);
562
564
  if (callbackUrlString == null) throw new HexclaveAssertionError("Nested cross-domain auth URL is missing callback URL");
563
565
  if (isRelative(callbackUrlString)) throw new Error("Nested cross-domain auth callback URL must be absolute.");
@@ -710,6 +712,13 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
710
712
  accessToken
711
713
  };
712
714
  }
715
+ _getCurrentBrowserCookieTokenStoreValue(old) {
716
+ const tokens = this._getTokensFromCookies(this._getAllBrowserCookies());
717
+ return {
718
+ refreshToken: tokens.refreshToken,
719
+ accessToken: tokens.accessToken ?? (old?.refreshToken === tokens.refreshToken ? old.accessToken : null)
720
+ };
721
+ }
713
722
  get _accessTokenCookieName() {
714
723
  return `hexclave-access`;
715
724
  }
@@ -814,19 +823,12 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
814
823
  _getBrowserCookieTokenStore() {
815
824
  if (!isBrowserLike()) throw new Error("Cannot use cookie token store on the server!");
816
825
  if (this._storedBrowserCookieTokenStore === null) {
817
- const getCurrentValue = (old) => {
818
- const tokens = this._getTokensFromCookies(this._getAllBrowserCookies());
819
- return {
820
- refreshToken: tokens.refreshToken,
821
- accessToken: tokens.accessToken ?? (old?.refreshToken === tokens.refreshToken ? old.accessToken : null)
822
- };
823
- };
824
- this._storedBrowserCookieTokenStore = new Store(getCurrentValue(null));
826
+ this._storedBrowserCookieTokenStore = new Store(this._getCurrentBrowserCookieTokenStoreValue(null));
825
827
  let hasSucceededInWriting = true;
826
828
  setInterval(() => {
827
829
  if (hasSucceededInWriting) {
828
830
  const oldValue = this._storedBrowserCookieTokenStore.get();
829
- const currentValue = getCurrentValue(oldValue);
831
+ const currentValue = this._getCurrentBrowserCookieTokenStoreValue(oldValue);
830
832
  if (!deepPlainEquals(currentValue, oldValue)) this._storedBrowserCookieTokenStore.set(currentValue);
831
833
  }
832
834
  }, 100);
@@ -852,6 +854,10 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
852
854
  else throw e;
853
855
  }
854
856
  });
857
+ } else {
858
+ const oldValue = this._storedBrowserCookieTokenStore.get();
859
+ const currentValue = this._getCurrentBrowserCookieTokenStoreValue(oldValue);
860
+ if (!deepPlainEquals(currentValue, oldValue)) this._storedBrowserCookieTokenStore.set(currentValue);
855
861
  }
856
862
  return this._storedBrowserCookieTokenStore;
857
863
  }
@@ -946,17 +952,17 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
946
952
  accessToken: tokenObj.accessToken
947
953
  });
948
954
  session.onAccessTokenChange((newAccessToken) => {
949
- tokenStore.update((old) => ({
955
+ tokenStore.update((old) => InternalSession.calculateSessionKey(old) === sessionKey ? {
950
956
  ...old,
951
957
  accessToken: newAccessToken?.token ?? null
952
- }));
958
+ } : old);
953
959
  });
954
960
  session.onInvalidate(() => {
955
- tokenStore.update((old) => ({
961
+ tokenStore.update((old) => InternalSession.calculateSessionKey(old) === sessionKey ? {
956
962
  ...old,
957
963
  accessToken: null,
958
964
  refreshToken: null
959
- }));
965
+ } : old);
960
966
  });
961
967
  let sessionsBySessionKey = this._sessionsByTokenStoreAndSessionKey.get(tokenStore) ?? /* @__PURE__ */ new Map();
962
968
  this._sessionsByTokenStoreAndSessionKey.set(tokenStore, sessionsBySessionKey);
@@ -1905,17 +1911,17 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
1905
1911
  }
1906
1912
  _getBotChallengeSiteKeys() {
1907
1913
  if (!isBrowserLike()) return null;
1908
- const visibleSiteKey = envVars.NEXT_PUBLIC_STACK_BOT_CHALLENGE_SITE_KEY;
1914
+ const visibleSiteKey = envVars.HEXCLAVE_BOT_CHALLENGE_SITE_KEY;
1909
1915
  if (!visibleSiteKey) {
1910
1916
  if (!this._botChallengeSiteKeysWarned) {
1911
1917
  this._botChallengeSiteKeysWarned = true;
1912
- console.warn("[stack-auth] NEXT_PUBLIC_STACK_BOT_CHALLENGE_SITE_KEY is not set — bot challenge fraud protection is disabled. Set the env variable to enable it.");
1918
+ console.warn("[stack-auth] HEXCLAVE_BOT_CHALLENGE_SITE_KEY is not set — bot challenge fraud protection is disabled. Set the env variable to enable it.");
1913
1919
  }
1914
1920
  return null;
1915
1921
  }
1916
1922
  return {
1917
1923
  visibleSiteKey,
1918
- invisibleSiteKey: envVars.NEXT_PUBLIC_STACK_BOT_CHALLENGE_INVISIBLE_SITE_KEY ?? visibleSiteKey
1924
+ invisibleSiteKey: envVars.HEXCLAVE_BOT_CHALLENGE_INVISIBLE_SITE_KEY ?? visibleSiteKey
1919
1925
  };
1920
1926
  }
1921
1927
  _getBotChallengeFlowFailure(error) {
@@ -2037,6 +2043,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2037
2043
  }
2038
2044
  async _createCrossDomainAuthRedirectUrl(options) {
2039
2045
  const session = await this._getSession(options.overrideTokenStoreInit, { awaitPendingAuthResolutions: options.awaitPendingAuthResolutions });
2046
+ await session.fetchNewTokens();
2040
2047
  const response = await this._interface.sendClientRequest("/auth/oauth/cross-domain/authorize", {
2041
2048
  method: "POST",
2042
2049
  headers: { "Content-Type": "application/json" },
@@ -2137,6 +2144,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2137
2144
  return await this._redirectToHandler("signUp", options);
2138
2145
  }
2139
2146
  async redirectToSignOut(options) {
2147
+ const configuredSignOutTarget = this._urlOptions.signOut ?? this._urlOptions.default;
2148
+ if (typeof configuredSignOutTarget !== "string" && configuredSignOutTarget?.type === "hosted") return await this.signOut();
2140
2149
  return await this._redirectToHandler("signOut", options);
2141
2150
  }
2142
2151
  async redirectToEmailVerification(options) {
@@ -2674,9 +2683,27 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2674
2683
  url: options.redirectUrl,
2675
2684
  replace: true
2676
2685
  });
2677
- else await this.redirectToAfterSignOut();
2686
+ else await this._redirectToDefaultAfterSignOut();
2678
2687
  });
2679
2688
  }
2689
+ async _redirectToDefaultAfterSignOut() {
2690
+ if (this._urlOptions.afterSignOut != null) {
2691
+ await this.redirectToAfterSignOut({ replace: true });
2692
+ return;
2693
+ }
2694
+ if (this._urlOptions.home != null) {
2695
+ await this.redirectToHome({ replace: true });
2696
+ return;
2697
+ }
2698
+ if (this._urlOptions.default?.type === "hosted" && typeof window !== "undefined") {
2699
+ await this._redirectTo({
2700
+ url: getRelativePart(new URL(window.location.href)),
2701
+ replace: true
2702
+ });
2703
+ return;
2704
+ }
2705
+ await this.redirectToAfterSignOut({ replace: true });
2706
+ }
2680
2707
  async signOut(options) {
2681
2708
  const user = await this.getUser({ tokenStore: options?.tokenStore ?? void 0 });
2682
2709
  if (user) await user.signOut({ redirectUrl: options?.redirectUrl });