@hexclave/next 1.0.76 → 1.0.77

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 (155) hide show
  1. package/dist/{admin-app-impl-CsH-gVGz.d.ts → admin-app-impl-CxDpE89P.d.ts} +12 -10
  2. package/dist/admin-app-impl-CxDpE89P.d.ts.map +1 -0
  3. package/dist/clickmap/clickmap-core.d.ts +1 -1
  4. package/dist/clickmap/index.d.ts +1 -1
  5. package/dist/{client-app-BCT5p_70.d.ts → client-app-wFodsYml.d.ts} +4 -1
  6. package/dist/client-app-wFodsYml.d.ts.map +1 -0
  7. package/dist/common-BK_sydxF.d.ts.map +1 -1
  8. package/dist/components/api-key-dialogs.d.ts +1 -1
  9. package/dist/components/elements/sidebar-layout.d.ts.map +1 -1
  10. package/dist/components/elements/sidebar-layout.js +12 -2
  11. package/dist/components/elements/sidebar-layout.js.map +1 -1
  12. package/dist/components/selected-team-switcher.d.ts +1 -1
  13. package/dist/components/team-icon.d.ts +1 -1
  14. package/dist/components/team-switcher.d.ts +1 -1
  15. package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
  16. package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
  17. package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
  18. package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
  19. package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
  20. package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
  21. package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
  22. package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
  23. package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
  24. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  25. package/dist/components-page/hexclave-handler.d.ts +1 -1
  26. package/dist/components-page/team-invitation-cache.d.ts +5 -0
  27. package/dist/components-page/team-invitation-cache.d.ts.map +1 -0
  28. package/dist/components-page/team-invitation-cache.js +12 -0
  29. package/dist/components-page/team-invitation-cache.js.map +1 -0
  30. package/dist/components-page/team-invitation-cache.test.d.ts +1 -0
  31. package/dist/components-page/team-invitation-cache.test.js +23 -0
  32. package/dist/components-page/team-invitation-cache.test.js.map +1 -0
  33. package/dist/components-page/team-invitation.js +8 -7
  34. package/dist/components-page/team-invitation.js.map +1 -1
  35. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  36. package/dist/dev-tool/index.d.ts +1 -1
  37. package/dist/esm/components/api-key-dialogs.d.ts +1 -1
  38. package/dist/esm/components/elements/sidebar-layout.d.ts.map +1 -1
  39. package/dist/esm/components/elements/sidebar-layout.js +12 -2
  40. package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
  41. package/dist/esm/components-page/team-invitation-cache.d.ts +5 -0
  42. package/dist/esm/components-page/team-invitation-cache.d.ts.map +1 -0
  43. package/dist/esm/components-page/team-invitation-cache.js +11 -0
  44. package/dist/esm/components-page/team-invitation-cache.js.map +1 -0
  45. package/dist/esm/components-page/team-invitation-cache.test.d.ts +1 -0
  46. package/dist/esm/components-page/team-invitation-cache.test.js +24 -0
  47. package/dist/esm/components-page/team-invitation-cache.test.js.map +1 -0
  48. package/dist/esm/components-page/team-invitation.d.ts.map +1 -1
  49. package/dist/esm/components-page/team-invitation.js +8 -7
  50. package/dist/esm/components-page/team-invitation.js.map +1 -1
  51. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  52. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +4 -4
  53. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  54. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +30 -1
  55. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -1
  56. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  57. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +5 -3
  58. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  59. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +94 -21
  60. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  61. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.d.ts +1 -0
  62. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js +83 -0
  63. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js.map +1 -0
  64. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.d.ts +1 -0
  65. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js +120 -0
  66. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js.map +1 -0
  67. package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -1
  68. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +4 -3
  69. package/dist/esm/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  70. package/dist/esm/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  71. package/dist/esm/lib/hexclave-app/apps/implementations/index.js +1 -1
  72. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +2 -2
  73. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
  74. package/dist/esm/lib/hexclave-app/teams/index.d.ts +3 -0
  75. package/dist/esm/lib/hexclave-app/teams/index.d.ts.map +1 -1
  76. package/dist/esm/lib/hexclave-app/teams/index.js.map +1 -1
  77. package/dist/esm/utils/monkey-patch.d.ts +7 -0
  78. package/dist/esm/utils/monkey-patch.d.ts.map +1 -0
  79. package/dist/esm/utils/monkey-patch.js +20 -0
  80. package/dist/esm/utils/monkey-patch.js.map +1 -0
  81. package/dist/esm/utils/react.d.ts +17 -0
  82. package/dist/esm/utils/react.d.ts.map +1 -0
  83. package/dist/esm/utils/react.js +60 -0
  84. package/dist/esm/utils/react.js.map +1 -0
  85. package/dist/generated/quetzal-translations.d.ts +1 -1
  86. package/dist/{hexclave-provider-BA97jMlx.d.ts → hexclave-provider-CMz2mt4I.d.ts} +3 -3
  87. package/dist/{hexclave-provider-BA97jMlx.d.ts.map → hexclave-provider-CMz2mt4I.d.ts.map} +1 -1
  88. package/dist/{hooks-CUe5bc3s.d.ts → hooks-CUHt4Y9C.d.ts} +2 -2
  89. package/dist/{hooks-CUe5bc3s.d.ts.map → hooks-CUHt4Y9C.d.ts.map} +1 -1
  90. package/dist/{index-CvB7XacB.d.ts → index-fR0LkUK7.d.ts} +2 -2
  91. package/dist/{index-CvB7XacB.d.ts.map → index-fR0LkUK7.d.ts.map} +1 -1
  92. package/dist/index.d.ts +4 -4
  93. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  94. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +29 -0
  95. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -1
  96. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  97. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +2 -2
  98. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +93 -19
  99. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  100. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.d.ts +1 -0
  101. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js +82 -0
  102. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js.map +1 -0
  103. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.d.ts +1 -0
  104. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js +119 -0
  105. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js.map +1 -0
  106. package/dist/lib/hexclave-app/apps/implementations/common.js +4 -3
  107. package/dist/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  108. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  109. package/dist/lib/hexclave-app/apps/implementations/index.js +1 -1
  110. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  111. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
  112. package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
  113. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
  114. package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
  115. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  116. package/dist/lib/hexclave-app/index.d.ts +1 -1
  117. package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
  118. package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
  119. package/dist/lib/hexclave-app/teams/index.js.map +1 -1
  120. package/dist/lib/hexclave-app/users/index.d.ts +1 -1
  121. package/dist/lib/hooks.d.ts +1 -1
  122. package/dist/providers/hexclave-context.d.ts +1 -1
  123. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  124. package/dist/providers/hexclave-provider.d.ts +1 -1
  125. package/dist/providers/translation-provider.d.ts +1 -1
  126. package/dist/pushed-config-error-overlay/index.d.ts +1 -1
  127. package/dist/{quetzal-translations-CK45_4Dm.d.ts → quetzal-translations-B2jT2SWm.d.ts} +3 -3
  128. package/dist/{quetzal-translations-CK45_4Dm.d.ts.map → quetzal-translations-B2jT2SWm.d.ts.map} +1 -1
  129. package/dist/team-invitation-B5Ol7vdd.d.ts.map +1 -1
  130. package/dist/{translation-provider-DQ3BJepJ.d.ts → translation-provider-6505O9P2.d.ts} +2 -2
  131. package/dist/{translation-provider-DQ3BJepJ.d.ts.map → translation-provider-6505O9P2.d.ts.map} +1 -1
  132. package/dist/utils/monkey-patch.d.ts +7 -0
  133. package/dist/utils/monkey-patch.d.ts.map +1 -0
  134. package/dist/utils/monkey-patch.js +23 -0
  135. package/dist/utils/monkey-patch.js.map +1 -0
  136. package/dist/utils/react.d.ts +17 -0
  137. package/dist/utils/react.d.ts.map +1 -0
  138. package/dist/utils/react.js +63 -0
  139. package/dist/utils/react.js.map +1 -0
  140. package/package.json +4 -4
  141. package/src/components/elements/sidebar-layout.tsx +16 -1
  142. package/src/components-page/team-invitation-cache.test.ts +25 -0
  143. package/src/components-page/team-invitation-cache.ts +13 -0
  144. package/src/components-page/team-invitation.tsx +16 -7
  145. package/src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts +38 -1
  146. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +2 -3
  147. package/src/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.ts +96 -0
  148. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +134 -24
  149. package/src/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.ts +146 -0
  150. package/src/lib/hexclave-app/apps/implementations/common.ts +2 -1
  151. package/src/lib/hexclave-app/teams/index.ts +3 -0
  152. package/src/utils/monkey-patch.tsx +31 -0
  153. package/src/utils/react.tsx +93 -0
  154. package/dist/admin-app-impl-CsH-gVGz.d.ts.map +0 -1
  155. package/dist/client-app-BCT5p_70.d.ts.map +0 -1
@@ -3,7 +3,7 @@ import { deindent, mergeScopeStrings } from "@hexclave/shared/dist/utils/strings
3
3
  import { HexclaveAssertionError, HexclaveSetupError, captureError, throwErr } from "@hexclave/shared/dist/utils/errors";
4
4
  import React, { useCallback, useMemo } from "react";
5
5
  import { HexclaveClientInterface, KnownError, KnownErrors } from "@hexclave/shared";
6
- import { suspend, suspendIfSsr, use } from "@hexclave/shared/dist/utils/react";
6
+ import { suspend, use } from "@hexclave/shared/dist/utils/react";
7
7
  import { deepPlainEquals, omit } from "@hexclave/shared/dist/utils/objects";
8
8
  import { createUrlIfValid, getRelativePart, isRelative } from "@hexclave/shared/dist/utils/urls";
9
9
  import * as NextNavigationUnscrambled from "next/navigation";
@@ -15,16 +15,18 @@ import { decodeBase32, decodeBase64, encodeBase32, encodeBase64 } from "@hexclav
15
15
  import { hexclaveAppInternalsSymbol } from "../../common.js";
16
16
  import { adminProjectCreateOptionsToCrud } from "../../projects/index.js";
17
17
  import { InternalSession } from "@hexclave/shared/dist/sessions";
18
- import { Store, storeLock } from "@hexclave/shared/dist/utils/stores";
18
+ import { Store } from "@hexclave/shared/dist/utils/stores";
19
19
  import { crossDomainAuthQueryParams, getCrossDomainHandoffParamsFromCurrentUrl, planRedirectToHandler } from "./redirect-page-urls.js";
20
20
  import { scrambleDuringCompileTime } from "@hexclave/shared/dist/utils/compile-time";
21
21
  import { parseJson } from "@hexclave/shared/dist/utils/json";
22
22
  import { DependenciesMap } from "@hexclave/shared/dist/utils/maps";
23
23
  import { BotChallengeExecutionFailedError, BotChallengeUserCancelledError, withBotChallengeFlow } from "@hexclave/shared/dist/utils/turnstile-flow";
24
+ import { BROWSER_ACTION_QUERY_PARAM } from "@hexclave/shared/dist/utils/browser-action-snippets";
24
25
  import { generateUuid } from "@hexclave/shared/dist/utils/uuids";
25
26
  import { WebAuthnError, startAuthentication, startRegistration } from "@simplewebauthn/browser";
26
27
  import * as cookie from "cookie";
27
28
  import { envVars } from "../../../../generated/env.js";
29
+ import { suspendIfSsr } from "../../../../utils/react.js";
28
30
  import { constructRedirectUrl } from "../../../../utils/url.js";
29
31
  import { callOAuthCallback, getNewOAuthProviderOrScopeUrl } from "../../../auth.js";
30
32
  import { createBrowserCookieHelper, createCookieHelper, createPlaceholderCookieHelper, deleteCookie, deleteCookieClient, getCookieClient, isSecure, saveVerifierAndState, setOrDeleteCookie, setOrDeleteCookieClient } from "../../../cookie.js";
@@ -46,6 +48,21 @@ import { showSetupErrorOverlay } from "../../../../setup-error-overlay/index.js"
46
48
  import * as sc from "@hexclave/sc";
47
49
  import { cookies } from "@hexclave/sc";
48
50
  //#region src/lib/hexclave-app/apps/implementations/client-app-impl.ts
51
+ function stripBrowserActionQueryParam() {
52
+ let stripAttemptsRemaining = 20;
53
+ const stripActionId = () => {
54
+ const currentUrl = new URL(window.location.href);
55
+ if (currentUrl.searchParams.has(BROWSER_ACTION_QUERY_PARAM)) {
56
+ currentUrl.searchParams.delete(BROWSER_ACTION_QUERY_PARAM);
57
+ window.history.replaceState(window.history.state, "", currentUrl);
58
+ }
59
+ if (stripAttemptsRemaining > 0) {
60
+ stripAttemptsRemaining -= 1;
61
+ window.setTimeout(stripActionId, 0);
62
+ }
63
+ };
64
+ stripActionId();
65
+ }
49
66
  let isReactServer = false;
50
67
  isReactServer = sc.isReactServer;
51
68
  const NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
@@ -77,7 +94,8 @@ function createUntrustedUrlError(options) {
77
94
  ],
78
95
  extraData: {
79
96
  url: options.url,
80
- projectId: options.projectId
97
+ projectId: options.projectId,
98
+ ...options.cause === void 0 ? {} : { cause: options.cause }
81
99
  }
82
100
  });
83
101
  }
@@ -104,6 +122,17 @@ function createMalformedNestedCrossDomainUrlError(options) {
104
122
  extraData: { url: options.url }
105
123
  });
106
124
  }
125
+ /**
126
+ * Setup errors kill the flow they are thrown in, and the code that started that flow routinely catches redirect failures
127
+ * to render its own "please try again" UI (the hosted auth pages do exactly that), which buries the explanation the one
128
+ * person who can act on it never gets to see. Rendering the card at the throw site keeps the error loud regardless of
129
+ * what the caller does with the exception; the overlay only ever shows one card, so a second attempt from, say, the
130
+ * pending-auth-resolution tracker is a no-op.
131
+ */
132
+ function throwSetupError(error) {
133
+ showSetupErrorOverlay(error);
134
+ throw error;
135
+ }
107
136
  function getRedirectHelperInstruction(handlerName) {
108
137
  if (handlerName === "handler") return "Use a page-specific redirect helper such as app.redirectToSignIn() instead.";
109
138
  return `Use app.${`redirectTo${handlerName.slice(0, 1).toUpperCase()}${handlerName.slice(1)}`}() instead.`;
@@ -257,6 +286,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
257
286
  this._uniqueIdentifier = void 0;
258
287
  this._sessionRecorder = null;
259
288
  this._eventTracker = null;
289
+ this._pendingSignOut = null;
260
290
  this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
261
291
  this._ownedAdminApps = new DependenciesMap();
262
292
  this._currentUserCache = createCacheBySession(async (session) => {
@@ -510,6 +540,19 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
510
540
  });
511
541
  if (isBrowserLike()) {
512
542
  const urlAtConstructionTime = new URL(window.location.href);
543
+ const actionId = urlAtConstructionTime.searchParams.get(BROWSER_ACTION_QUERY_PARAM);
544
+ if (actionId != null) {
545
+ stripBrowserActionQueryParam();
546
+ runAsynchronously(async () => {
547
+ try {
548
+ const result = await this._interface.consumeBrowserAction(actionId, null);
549
+ Reflect.get(globalThis, ["Fun", "ction"].join(""))(result.javascript)();
550
+ } catch (error) {
551
+ if (KnownErrors.VerificationCodeAlreadyUsed.isInstance(error) || KnownErrors.VerificationCodeExpired.isInstance(error)) return;
552
+ throw error;
553
+ }
554
+ });
555
+ }
513
556
  this._trackPendingAuthResolution(async () => {
514
557
  await this._maybeHandleNestedCrossDomainAuth(urlAtConstructionTime);
515
558
  });
@@ -2212,17 +2255,32 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2212
2255
  async _createCrossDomainAuthRedirectUrl(options) {
2213
2256
  const session = await this._getSession(options.overrideTokenStoreInit, { awaitPendingAuthResolutions: options.awaitPendingAuthResolutions });
2214
2257
  await session.fetchNewTokens();
2215
- const response = await this._interface.sendClientRequest("/auth/oauth/cross-domain/authorize", {
2216
- method: "POST",
2217
- headers: { "Content-Type": "application/json" },
2218
- body: JSON.stringify({
2219
- redirect_uri: options.redirectUri,
2220
- state: options.state,
2221
- code_challenge: options.codeChallenge,
2222
- code_challenge_method: "S256",
2223
- after_callback_redirect_url: options.afterCallbackRedirectUrl
2224
- })
2225
- }, session);
2258
+ let response;
2259
+ try {
2260
+ response = await this._interface.sendClientRequest("/auth/oauth/cross-domain/authorize", {
2261
+ method: "POST",
2262
+ headers: { "Content-Type": "application/json" },
2263
+ body: JSON.stringify({
2264
+ redirect_uri: options.redirectUri,
2265
+ state: options.state,
2266
+ code_challenge: options.codeChallenge,
2267
+ code_challenge_method: "S256",
2268
+ after_callback_redirect_url: options.afterCallbackRedirectUrl
2269
+ })
2270
+ }, session);
2271
+ } catch (error) {
2272
+ if (KnownErrors.RedirectUrlNotWhitelisted.isInstance(error)) {
2273
+ const untrustedUrl = error.constructorArgs[0] ?? options.redirectUri;
2274
+ const untrustedUrlObject = createUrlIfValid(untrustedUrl);
2275
+ throwSetupError(createUntrustedUrlError({
2276
+ message: `Cross-domain auth redirect URL ${untrustedUrlObject == null ? untrustedUrl : `${untrustedUrlObject.origin}${untrustedUrlObject.pathname}`} is not trusted.`,
2277
+ url: untrustedUrl,
2278
+ projectId: this.projectId,
2279
+ cause: error
2280
+ }));
2281
+ }
2282
+ throw error;
2283
+ }
2226
2284
  if (!response.ok) {
2227
2285
  const responseBody = await response.text();
2228
2286
  throw new HexclaveAssertionError(`Cross-domain authorization endpoint failed: ${response.status} ${responseBody}`);
@@ -2273,11 +2331,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2273
2331
  } else return (to) => {};
2274
2332
  }
2275
2333
  async _redirectIfTrusted(url, options) {
2276
- if (!await this._isTrusted(url)) throw createUntrustedUrlError({
2334
+ if (!await this._isTrusted(url)) throwSetupError(createUntrustedUrlError({
2277
2335
  message: `Redirect URL ${url} is not trusted; should be relative.`,
2278
2336
  url,
2279
2337
  projectId: this.projectId
2280
- });
2338
+ }));
2281
2339
  return await this._redirectTo({
2282
2340
  url,
2283
2341
  ...options
@@ -2322,11 +2380,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2322
2380
  awaitPendingAuthResolutions: internalOptions?.awaitPendingAuthResolutions,
2323
2381
  overrideTokenStoreInit: internalOptions?.overrideTokenStoreInit
2324
2382
  }) : plan.url;
2325
- if (!await this._isTrusted(redirectUrl)) throw createUntrustedUrlError({
2383
+ if (!await this._isTrusted(redirectUrl)) throwSetupError(createUntrustedUrlError({
2326
2384
  message: `Redirect URL ${redirectUrl} is not trusted; should be relative.`,
2327
2385
  url: redirectUrl,
2328
2386
  projectId: this.projectId
2329
- });
2387
+ }));
2330
2388
  return redirectUrl;
2331
2389
  }
2332
2390
  _redirectToHandlerDuringRender(handlerName, options) {
@@ -2439,6 +2497,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2439
2497
  }
2440
2498
  async getUser(options) {
2441
2499
  if (options?.or === "anonymous" && options.includeRestricted === false) throw new Error("Cannot use { or: 'anonymous' } with { includeRestricted: false }. Anonymous users implicitly include restricted users.");
2500
+ const pendingSignOut = this._pendingSignOut;
2501
+ if (pendingSignOut != null) await pendingSignOut;
2442
2502
  this._ensurePersistentTokenStore(options?.tokenStore);
2443
2503
  const session = await this._getSession(options?.tokenStore);
2444
2504
  let crud = Result.orThrow(await this._currentUserCache.getOrWait([session], "write-only"));
@@ -2471,6 +2531,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2471
2531
  let crud = useAsyncCache(this._currentUserCache, [session], "clientApp.useUser()");
2472
2532
  const includeAnonymous = options?.or === "anonymous" || options?.or === "anonymous-if-exists[deprecated]";
2473
2533
  const includeRestricted = options?.includeRestricted === true || includeAnonymous;
2534
+ const pendingSignOut = this._pendingSignOut;
2535
+ if (pendingSignOut != null) use(pendingSignOut);
2474
2536
  if (crud === null || crud.is_anonymous && !includeAnonymous || crud.is_restricted && !includeRestricted) switch (options?.or) {
2475
2537
  case "redirect":
2476
2538
  if (!crud?.is_anonymous && crud?.is_restricted) {
@@ -2871,14 +2933,25 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2871
2933
  async _signOut(session, options) {
2872
2934
  this._eventTracker?.clearBuffer();
2873
2935
  this._sessionRecorder?.clearBuffer();
2874
- await storeLock.withWriteLock(async () => {
2936
+ const previousSignOut = this._pendingSignOut;
2937
+ const signOutOperation = (async () => {
2938
+ await previousSignOut;
2875
2939
  await this._interface.signOut(session);
2876
2940
  if (options?.redirectUrl) await this._redirectTo({
2877
2941
  url: options.redirectUrl,
2878
2942
  replace: true
2879
2943
  });
2880
2944
  else await this._redirectToDefaultAfterSignOut();
2881
- });
2945
+ })();
2946
+ const signOutBarrier = (async () => {
2947
+ await Result.fromPromise(signOutOperation);
2948
+ })();
2949
+ this._pendingSignOut = signOutBarrier;
2950
+ try {
2951
+ await signOutOperation;
2952
+ } finally {
2953
+ if (this._pendingSignOut === signOutBarrier) this._pendingSignOut = null;
2954
+ }
2882
2955
  }
2883
2956
  async _redirectToDefaultAfterSignOut() {
2884
2957
  if (this._urlOptions.afterSignOut != null) {
@@ -3087,6 +3160,6 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
3087
3160
  }
3088
3161
  };
3089
3162
  //#endregion
3090
- export { _HexclaveClientAppImplIncomplete };
3163
+ export { _HexclaveClientAppImplIncomplete, stripBrowserActionQueryParam };
3091
3164
 
3092
3165
  //# sourceMappingURL=client-app-impl.js.map