@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.
- package/dist/{admin-app-impl-CsH-gVGz.d.ts → admin-app-impl-CxDpE89P.d.ts} +12 -10
- package/dist/admin-app-impl-CxDpE89P.d.ts.map +1 -0
- package/dist/clickmap/clickmap-core.d.ts +1 -1
- package/dist/clickmap/index.d.ts +1 -1
- package/dist/{client-app-BCT5p_70.d.ts → client-app-wFodsYml.d.ts} +4 -1
- package/dist/client-app-wFodsYml.d.ts.map +1 -0
- package/dist/common-BK_sydxF.d.ts.map +1 -1
- package/dist/components/api-key-dialogs.d.ts +1 -1
- package/dist/components/elements/sidebar-layout.d.ts.map +1 -1
- package/dist/components/elements/sidebar-layout.js +12 -2
- package/dist/components/elements/sidebar-layout.js.map +1 -1
- package/dist/components/selected-team-switcher.d.ts +1 -1
- package/dist/components/team-icon.d.ts +1 -1
- package/dist/components/team-switcher.d.ts +1 -1
- package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
- package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
- package/dist/components-page/hexclave-handler-client.d.ts +1 -1
- package/dist/components-page/hexclave-handler.d.ts +1 -1
- package/dist/components-page/team-invitation-cache.d.ts +5 -0
- package/dist/components-page/team-invitation-cache.d.ts.map +1 -0
- package/dist/components-page/team-invitation-cache.js +12 -0
- package/dist/components-page/team-invitation-cache.js.map +1 -0
- package/dist/components-page/team-invitation-cache.test.d.ts +1 -0
- package/dist/components-page/team-invitation-cache.test.js +23 -0
- package/dist/components-page/team-invitation-cache.test.js.map +1 -0
- package/dist/components-page/team-invitation.js +8 -7
- package/dist/components-page/team-invitation.js.map +1 -1
- package/dist/dev-tool/dev-tool-core.d.ts +1 -1
- package/dist/dev-tool/index.d.ts +1 -1
- package/dist/esm/components/api-key-dialogs.d.ts +1 -1
- package/dist/esm/components/elements/sidebar-layout.d.ts.map +1 -1
- package/dist/esm/components/elements/sidebar-layout.js +12 -2
- package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
- package/dist/esm/components-page/team-invitation-cache.d.ts +5 -0
- package/dist/esm/components-page/team-invitation-cache.d.ts.map +1 -0
- package/dist/esm/components-page/team-invitation-cache.js +11 -0
- package/dist/esm/components-page/team-invitation-cache.js.map +1 -0
- package/dist/esm/components-page/team-invitation-cache.test.d.ts +1 -0
- package/dist/esm/components-page/team-invitation-cache.test.js +24 -0
- package/dist/esm/components-page/team-invitation-cache.test.js.map +1 -0
- package/dist/esm/components-page/team-invitation.d.ts.map +1 -1
- package/dist/esm/components-page/team-invitation.js +8 -7
- package/dist/esm/components-page/team-invitation.js.map +1 -1
- package/dist/esm/generated/quetzal-translations.d.ts +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +4 -4
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +30 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +5 -3
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +94 -21
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js +83 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js +120 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js +4 -3
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/index.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
- package/dist/esm/lib/hexclave-app/teams/index.d.ts +3 -0
- package/dist/esm/lib/hexclave-app/teams/index.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/teams/index.js.map +1 -1
- package/dist/esm/utils/monkey-patch.d.ts +7 -0
- package/dist/esm/utils/monkey-patch.d.ts.map +1 -0
- package/dist/esm/utils/monkey-patch.js +20 -0
- package/dist/esm/utils/monkey-patch.js.map +1 -0
- package/dist/esm/utils/react.d.ts +17 -0
- package/dist/esm/utils/react.d.ts.map +1 -0
- package/dist/esm/utils/react.js +60 -0
- package/dist/esm/utils/react.js.map +1 -0
- package/dist/generated/quetzal-translations.d.ts +1 -1
- package/dist/{hexclave-provider-BA97jMlx.d.ts → hexclave-provider-CMz2mt4I.d.ts} +3 -3
- package/dist/{hexclave-provider-BA97jMlx.d.ts.map → hexclave-provider-CMz2mt4I.d.ts.map} +1 -1
- package/dist/{hooks-CUe5bc3s.d.ts → hooks-CUHt4Y9C.d.ts} +2 -2
- package/dist/{hooks-CUe5bc3s.d.ts.map → hooks-CUHt4Y9C.d.ts.map} +1 -1
- package/dist/{index-CvB7XacB.d.ts → index-fR0LkUK7.d.ts} +2 -2
- package/dist/{index-CvB7XacB.d.ts.map → index-fR0LkUK7.d.ts.map} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +29 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +2 -2
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +93 -19
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js +82 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js +119 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/common.js +4 -3
- package/dist/lib/hexclave-app/apps/implementations/common.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/index.js +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
- package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
- package/dist/lib/hexclave-app/index.d.ts +1 -1
- package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
- package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
- package/dist/lib/hexclave-app/teams/index.js.map +1 -1
- package/dist/lib/hexclave-app/users/index.d.ts +1 -1
- package/dist/lib/hooks.d.ts +1 -1
- package/dist/providers/hexclave-context.d.ts +1 -1
- package/dist/providers/hexclave-provider-client.d.ts +1 -1
- package/dist/providers/hexclave-provider.d.ts +1 -1
- package/dist/providers/translation-provider.d.ts +1 -1
- package/dist/pushed-config-error-overlay/index.d.ts +1 -1
- package/dist/{quetzal-translations-CK45_4Dm.d.ts → quetzal-translations-B2jT2SWm.d.ts} +3 -3
- package/dist/{quetzal-translations-CK45_4Dm.d.ts.map → quetzal-translations-B2jT2SWm.d.ts.map} +1 -1
- package/dist/team-invitation-B5Ol7vdd.d.ts.map +1 -1
- package/dist/{translation-provider-DQ3BJepJ.d.ts → translation-provider-6505O9P2.d.ts} +2 -2
- package/dist/{translation-provider-DQ3BJepJ.d.ts.map → translation-provider-6505O9P2.d.ts.map} +1 -1
- package/dist/utils/monkey-patch.d.ts +7 -0
- package/dist/utils/monkey-patch.d.ts.map +1 -0
- package/dist/utils/monkey-patch.js +23 -0
- package/dist/utils/monkey-patch.js.map +1 -0
- package/dist/utils/react.d.ts +17 -0
- package/dist/utils/react.d.ts.map +1 -0
- package/dist/utils/react.js +63 -0
- package/dist/utils/react.js.map +1 -0
- package/package.json +4 -4
- package/src/components/elements/sidebar-layout.tsx +16 -1
- package/src/components-page/team-invitation-cache.test.ts +25 -0
- package/src/components-page/team-invitation-cache.ts +13 -0
- package/src/components-page/team-invitation.tsx +16 -7
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts +38 -1
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +2 -3
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.ts +96 -0
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +134 -24
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.ts +146 -0
- package/src/lib/hexclave-app/apps/implementations/common.ts +2 -1
- package/src/lib/hexclave-app/teams/index.ts +3 -0
- package/src/utils/monkey-patch.tsx +31 -0
- package/src/utils/react.tsx +93 -0
- package/dist/admin-app-impl-CsH-gVGz.d.ts.map +0 -1
- package/dist/client-app-BCT5p_70.d.ts.map +0 -1
|
@@ -31,14 +31,15 @@ import { DependenciesMap } from "@hexclave/shared/dist/utils/maps";
|
|
|
31
31
|
import { ProviderType } from "@hexclave/shared/dist/utils/oauth";
|
|
32
32
|
import { deepPlainEquals, omit } from "@hexclave/shared/dist/utils/objects";
|
|
33
33
|
import { neverResolve, runAsynchronously, wait } from "@hexclave/shared/dist/utils/promises";
|
|
34
|
-
import { suspend,
|
|
34
|
+
import { suspend, use } from "@hexclave/shared/dist/utils/react";
|
|
35
35
|
import { getTrustedParentDomain, validateRedirectUrl } from "@hexclave/shared/dist/utils/redirect-urls";
|
|
36
36
|
import { Result } from "@hexclave/shared/dist/utils/results";
|
|
37
|
-
import { Store
|
|
37
|
+
import { Store } from "@hexclave/shared/dist/utils/stores";
|
|
38
38
|
import { deindent, mergeScopeStrings } from "@hexclave/shared/dist/utils/strings";
|
|
39
39
|
import type { TurnstileAction } from "@hexclave/shared/dist/utils/turnstile";
|
|
40
40
|
import { BotChallengeExecutionFailedError, BotChallengeUserCancelledError, withBotChallengeFlow } from "@hexclave/shared/dist/utils/turnstile-flow";
|
|
41
41
|
import { createUrlIfValid, getRelativePart, isRelative } from "@hexclave/shared/dist/utils/urls";
|
|
42
|
+
import { BROWSER_ACTION_QUERY_PARAM } from "@hexclave/shared/dist/utils/browser-action-snippets";
|
|
42
43
|
import { generateUuid } from "@hexclave/shared/dist/utils/uuids";
|
|
43
44
|
import { WebAuthnError, startAuthentication, startRegistration } from "@simplewebauthn/browser";
|
|
44
45
|
import * as cookie from "cookie";
|
|
@@ -46,6 +47,7 @@ import * as NextNavigationUnscrambled from "next/navigation"; // import the enti
|
|
|
46
47
|
import React, { useCallback, useMemo } from "react"; // THIS_LINE_PLATFORM react-like
|
|
47
48
|
import type * as yup from "yup";
|
|
48
49
|
import { envVars } from "../../../../generated/env";
|
|
50
|
+
import { suspendIfSsr } from "../../../../utils/react"; // THIS_LINE_PLATFORM react-like
|
|
49
51
|
import { constructRedirectUrl } from "../../../../utils/url";
|
|
50
52
|
import { callOAuthCallback, getNewOAuthProviderOrScopeUrl } from "../../../auth";
|
|
51
53
|
import { CookieHelper, createBrowserCookieHelper, createCookieHelper, createPlaceholderCookieHelper, deleteCookie, deleteCookieClient, getCookieClient, isSecure as isSecureCookieContext, saveVerifierAndState, setOrDeleteCookie, setOrDeleteCookieClient } from "../../../cookie";
|
|
@@ -72,6 +74,22 @@ import { crossDomainAuthQueryParams, getCrossDomainHandoffParamsFromCurrentUrl,
|
|
|
72
74
|
import { subscribeSessionRefresh } from "./session-refresh-subscription";
|
|
73
75
|
import { AnalyticsOptions, SessionRecorder, analyticsOptionsFromJson, analyticsOptionsToJson, getSessionReplayOptions } from "./session-replay";
|
|
74
76
|
|
|
77
|
+
export function stripBrowserActionQueryParam() {
|
|
78
|
+
let stripAttemptsRemaining = 20;
|
|
79
|
+
const stripActionId = () => {
|
|
80
|
+
const currentUrl = new URL(window.location.href);
|
|
81
|
+
if (currentUrl.searchParams.has(BROWSER_ACTION_QUERY_PARAM)) {
|
|
82
|
+
currentUrl.searchParams.delete(BROWSER_ACTION_QUERY_PARAM);
|
|
83
|
+
window.history.replaceState(window.history.state, "", currentUrl);
|
|
84
|
+
}
|
|
85
|
+
if (stripAttemptsRemaining > 0) {
|
|
86
|
+
stripAttemptsRemaining -= 1;
|
|
87
|
+
window.setTimeout(stripActionId, 0);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
stripActionId();
|
|
91
|
+
}
|
|
92
|
+
|
|
75
93
|
import { useAsyncCache } from "./common";
|
|
76
94
|
import { mountClickmapOverlay } from "../../../../clickmap";
|
|
77
95
|
import { mountDevTool } from "../../../../dev-tool";
|
|
@@ -109,6 +127,7 @@ function createUntrustedUrlError(options: {
|
|
|
109
127
|
message: string,
|
|
110
128
|
url: string,
|
|
111
129
|
projectId: string,
|
|
130
|
+
cause?: unknown,
|
|
112
131
|
}): HexclaveSetupError {
|
|
113
132
|
const origin = createUrlIfValid(options.url)?.origin ?? options.url;
|
|
114
133
|
return new HexclaveSetupError({
|
|
@@ -122,6 +141,7 @@ function createUntrustedUrlError(options: {
|
|
|
122
141
|
extraData: {
|
|
123
142
|
url: options.url,
|
|
124
143
|
projectId: options.projectId,
|
|
144
|
+
...options.cause === undefined ? {} : { cause: options.cause },
|
|
125
145
|
},
|
|
126
146
|
});
|
|
127
147
|
}
|
|
@@ -160,6 +180,18 @@ function createMalformedNestedCrossDomainUrlError(options: {
|
|
|
160
180
|
});
|
|
161
181
|
}
|
|
162
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Setup errors kill the flow they are thrown in, and the code that started that flow routinely catches redirect failures
|
|
185
|
+
* to render its own "please try again" UI (the hosted auth pages do exactly that), which buries the explanation the one
|
|
186
|
+
* person who can act on it never gets to see. Rendering the card at the throw site keeps the error loud regardless of
|
|
187
|
+
* what the caller does with the exception; the overlay only ever shows one card, so a second attempt from, say, the
|
|
188
|
+
* pending-auth-resolution tracker is a no-op.
|
|
189
|
+
*/
|
|
190
|
+
function throwSetupError(error: HexclaveSetupError): never {
|
|
191
|
+
showSetupErrorOverlay(error); // THIS_LINE_PLATFORM js-like
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
|
|
163
195
|
function getRedirectHelperInstruction(handlerName: string): string {
|
|
164
196
|
if (handlerName === "handler") {
|
|
165
197
|
return "Use a page-specific redirect helper such as app.redirectToSignIn() instead.";
|
|
@@ -306,6 +338,7 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
306
338
|
private readonly _analyticsOptions: AnalyticsOptions | undefined;
|
|
307
339
|
private _sessionRecorder: SessionRecorder | null = null;
|
|
308
340
|
private _eventTracker: EventTracker | null = null;
|
|
341
|
+
private _pendingSignOut: Promise<void> | null = null;
|
|
309
342
|
|
|
310
343
|
private __DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
311
344
|
private readonly _ownedAdminApps = new DependenciesMap<[InternalSession, string], _HexclaveAdminAppImplIncomplete<false, string>>();
|
|
@@ -809,6 +842,30 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
809
842
|
// from the URL before its token exchange, so the nested handler must decide based on the
|
|
810
843
|
// URL the page was loaded with, not whatever is in the address bar when it runs.
|
|
811
844
|
const urlAtConstructionTime = new URL(window.location.href);
|
|
845
|
+
const actionId = urlAtConstructionTime.searchParams.get(BROWSER_ACTION_QUERY_PARAM);
|
|
846
|
+
if (actionId != null) {
|
|
847
|
+
// App Router implementations can restore the URL from their pre-rendered state after
|
|
848
|
+
// this constructor runs. Repeat the synchronous strip for a few event-loop turns so the
|
|
849
|
+
// action ID does not remain reloadable after the router finishes hydrating.
|
|
850
|
+
stripBrowserActionQueryParam();
|
|
851
|
+
runAsynchronously(async () => {
|
|
852
|
+
try {
|
|
853
|
+
const result = await this._interface.consumeBrowserAction(actionId, null);
|
|
854
|
+
// Keep this indirection so Next Edge does not statically detect dynamic evaluation.
|
|
855
|
+
Reflect.get(globalThis, ["Fun", "ction"].join(""))(result.javascript)();
|
|
856
|
+
} catch (error) {
|
|
857
|
+
// A reload can legitimately retry an already-consumed or expired one-time action.
|
|
858
|
+
// These outcomes are expected and should not produce customer-console noise.
|
|
859
|
+
if (
|
|
860
|
+
KnownErrors.VerificationCodeAlreadyUsed.isInstance(error)
|
|
861
|
+
|| KnownErrors.VerificationCodeExpired.isInstance(error)
|
|
862
|
+
) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
throw error;
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
}
|
|
812
869
|
this._trackPendingAuthResolution(async () => {
|
|
813
870
|
await this._maybeHandleNestedCrossDomainAuth(urlAtConstructionTime);
|
|
814
871
|
});
|
|
@@ -3026,23 +3083,47 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
3026
3083
|
// be minted from the refresh token we are about to send, instead of reusing
|
|
3027
3084
|
// a still-valid cached token from a pre-handoff session snapshot.
|
|
3028
3085
|
await session.fetchNewTokens();
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3086
|
+
let response;
|
|
3087
|
+
try {
|
|
3088
|
+
response = await this._interface.sendClientRequest(
|
|
3089
|
+
"/auth/oauth/cross-domain/authorize",
|
|
3090
|
+
{
|
|
3091
|
+
method: "POST",
|
|
3092
|
+
headers: {
|
|
3093
|
+
"Content-Type": "application/json",
|
|
3094
|
+
},
|
|
3095
|
+
body: JSON.stringify({
|
|
3096
|
+
redirect_uri: options.redirectUri,
|
|
3097
|
+
state: options.state,
|
|
3098
|
+
code_challenge: options.codeChallenge,
|
|
3099
|
+
code_challenge_method: "S256",
|
|
3100
|
+
after_callback_redirect_url: options.afterCallbackRedirectUrl,
|
|
3101
|
+
}),
|
|
3035
3102
|
},
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3103
|
+
session,
|
|
3104
|
+
);
|
|
3105
|
+
} catch (error) {
|
|
3106
|
+
// The server runs the trusted-domain check again on both URLs, and for a cross-domain handoff it is usually the
|
|
3107
|
+
// first place the check happens at all (the SDK only sees that the target is on another domain, which is the
|
|
3108
|
+
// entire point of the flow). Its rejection is the same developer-owned problem as a client-side trust failure, so
|
|
3109
|
+
// it gets the same card instead of a bare known error that whoever started the redirect turns into "please try
|
|
3110
|
+
// again" — the domain is untrusted, and retrying will fail forever.
|
|
3111
|
+
if (KnownErrors.RedirectUrlNotWhitelisted.isInstance(error)) {
|
|
3112
|
+
const untrustedUrl = error.constructorArgs[0] ?? options.redirectUri;
|
|
3113
|
+
// The URL the server rejected carries the entire handoff (state, code challenge, return URL) in its query, none
|
|
3114
|
+
// of which has anything to do with why it was rejected, so the message shows only the part that is checked. The
|
|
3115
|
+
// full URL still goes to the error tracker through `extraData`.
|
|
3116
|
+
const untrustedUrlObject = createUrlIfValid(untrustedUrl);
|
|
3117
|
+
const displayedUrl = untrustedUrlObject == null ? untrustedUrl : `${untrustedUrlObject.origin}${untrustedUrlObject.pathname}`;
|
|
3118
|
+
throwSetupError(createUntrustedUrlError({
|
|
3119
|
+
message: `Cross-domain auth redirect URL ${displayedUrl} is not trusted.`,
|
|
3120
|
+
url: untrustedUrl,
|
|
3121
|
+
projectId: this.projectId,
|
|
3122
|
+
cause: error,
|
|
3123
|
+
}));
|
|
3124
|
+
}
|
|
3125
|
+
throw error;
|
|
3126
|
+
}
|
|
3046
3127
|
if (!response.ok) {
|
|
3047
3128
|
const responseBody = await response.text();
|
|
3048
3129
|
throw new HexclaveAssertionError(`Cross-domain authorization endpoint failed: ${response.status} ${responseBody}`);
|
|
@@ -3116,11 +3197,11 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
3116
3197
|
}
|
|
3117
3198
|
protected async _redirectIfTrusted(url: string, options?: RedirectToOptions) {
|
|
3118
3199
|
if (!await this._isTrusted(url)) {
|
|
3119
|
-
|
|
3200
|
+
throwSetupError(createUntrustedUrlError({
|
|
3120
3201
|
message: `Redirect URL ${url} is not trusted; should be relative.`,
|
|
3121
3202
|
url,
|
|
3122
3203
|
projectId: this.projectId,
|
|
3123
|
-
});
|
|
3204
|
+
}));
|
|
3124
3205
|
}
|
|
3125
3206
|
return await this._redirectTo({ url, ...options });
|
|
3126
3207
|
}
|
|
@@ -3201,11 +3282,11 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
3201
3282
|
})
|
|
3202
3283
|
: plan.url;
|
|
3203
3284
|
if (!await this._isTrusted(redirectUrl)) {
|
|
3204
|
-
|
|
3285
|
+
throwSetupError(createUntrustedUrlError({
|
|
3205
3286
|
message: `Redirect URL ${redirectUrl} is not trusted; should be relative.`,
|
|
3206
3287
|
url: redirectUrl,
|
|
3207
3288
|
projectId: this.projectId,
|
|
3208
|
-
});
|
|
3289
|
+
}));
|
|
3209
3290
|
}
|
|
3210
3291
|
return redirectUrl;
|
|
3211
3292
|
}
|
|
@@ -3316,6 +3397,13 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
3316
3397
|
throw new Error("Cannot use { or: 'anonymous' } with { includeRestricted: false }. Anonymous users implicitly include restricted users.");
|
|
3317
3398
|
}
|
|
3318
3399
|
|
|
3400
|
+
// A session becomes invalid before its post-sign-out redirect is dispatched. Publishing the signed-out user state
|
|
3401
|
+
// before that redirect can make `or: "redirect"` race it with a redirect to sign-in.
|
|
3402
|
+
const pendingSignOut = this._pendingSignOut;
|
|
3403
|
+
if (pendingSignOut != null) {
|
|
3404
|
+
await pendingSignOut;
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3319
3407
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
3320
3408
|
const session = await this._getSession(options?.tokenStore);
|
|
3321
3409
|
let crud = Result.orThrow(await this._currentUserCache.getOrWait([session], "write-only"));
|
|
@@ -3368,6 +3456,13 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
3368
3456
|
const includeAnonymous = options?.or === "anonymous" || options?.or === "anonymous-if-exists[deprecated]";
|
|
3369
3457
|
const includeRestricted = options?.includeRestricted === true || includeAnonymous;
|
|
3370
3458
|
|
|
3459
|
+
// Keep the hook suspended while sign-out owns navigation. This is scoped to this app's current-user reads instead
|
|
3460
|
+
// of blocking every AsyncStore in the process, including unrelated requests and other app instances.
|
|
3461
|
+
const pendingSignOut = this._pendingSignOut;
|
|
3462
|
+
if (pendingSignOut != null) {
|
|
3463
|
+
use(pendingSignOut);
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3371
3466
|
if (crud === null || (crud.is_anonymous && !includeAnonymous) || (crud.is_restricted && !includeRestricted)) {
|
|
3372
3467
|
switch (options?.or) {
|
|
3373
3468
|
case 'redirect': {
|
|
@@ -4013,14 +4108,29 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
4013
4108
|
this._eventTracker?.clearBuffer();
|
|
4014
4109
|
this._sessionRecorder?.clearBuffer();
|
|
4015
4110
|
|
|
4016
|
-
|
|
4111
|
+
const previousSignOut = this._pendingSignOut;
|
|
4112
|
+
const signOutOperation = (async () => {
|
|
4113
|
+
// Preserve the old behavior of serializing concurrent sign-outs without coupling them to unrelated stores.
|
|
4114
|
+
await previousSignOut;
|
|
4017
4115
|
await this._interface.signOut(session);
|
|
4018
4116
|
if (options?.redirectUrl) {
|
|
4019
4117
|
await this._redirectTo({ url: options.redirectUrl, replace: true });
|
|
4020
4118
|
} else {
|
|
4021
4119
|
await this._redirectToDefaultAfterSignOut();
|
|
4022
4120
|
}
|
|
4023
|
-
});
|
|
4121
|
+
})();
|
|
4122
|
+
const signOutBarrier = (async () => {
|
|
4123
|
+
await Result.fromPromise(signOutOperation);
|
|
4124
|
+
})();
|
|
4125
|
+
this._pendingSignOut = signOutBarrier;
|
|
4126
|
+
|
|
4127
|
+
try {
|
|
4128
|
+
await signOutOperation;
|
|
4129
|
+
} finally {
|
|
4130
|
+
if (this._pendingSignOut === signOutBarrier) {
|
|
4131
|
+
this._pendingSignOut = null;
|
|
4132
|
+
}
|
|
4133
|
+
}
|
|
4024
4134
|
}
|
|
4025
4135
|
|
|
4026
4136
|
protected async _redirectToDefaultAfterSignOut(): Promise<void> {
|
package/src/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
|
|
2
|
+
//===========================================
|
|
3
|
+
// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template
|
|
4
|
+
//===========================================
|
|
5
|
+
// @vitest-environment jsdom
|
|
6
|
+
|
|
7
|
+
import { KnownErrors } from "@hexclave/shared";
|
|
8
|
+
import { AccessToken } from "@hexclave/shared/dist/sessions";
|
|
9
|
+
import { HexclaveSetupError } from "@hexclave/shared/dist/utils/errors";
|
|
10
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
11
|
+
import { getGlobalUiInstance, setGlobalUiInstance } from "../../../../in-page-ui/dom";
|
|
12
|
+
import { SETUP_ERROR_OVERLAY_GLOBAL_INSTANCE_KEY } from "../../../../setup-error-overlay";
|
|
13
|
+
import { StackClientApp } from "../interfaces/client-app";
|
|
14
|
+
|
|
15
|
+
function createAccessTokenString(refreshTokenId: string): string {
|
|
16
|
+
const encode = (value: unknown) => Buffer.from(JSON.stringify(value)).toString("base64url");
|
|
17
|
+
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
18
|
+
return [
|
|
19
|
+
encode({ alg: "none", typ: "JWT" }),
|
|
20
|
+
encode({
|
|
21
|
+
sub: "user-id",
|
|
22
|
+
exp: nowSeconds + 60,
|
|
23
|
+
iat: nowSeconds,
|
|
24
|
+
iss: "https://api.example.test",
|
|
25
|
+
aud: "project-id",
|
|
26
|
+
project_id: "project-id",
|
|
27
|
+
branch_id: "main",
|
|
28
|
+
refresh_token_id: refreshTokenId,
|
|
29
|
+
role: "authenticated",
|
|
30
|
+
name: null,
|
|
31
|
+
email: null,
|
|
32
|
+
email_verified: false,
|
|
33
|
+
selected_team_id: null,
|
|
34
|
+
signed_up_at: nowSeconds,
|
|
35
|
+
is_anonymous: false,
|
|
36
|
+
is_restricted: false,
|
|
37
|
+
restricted_reason: null,
|
|
38
|
+
requires_totp_mfa: false,
|
|
39
|
+
}),
|
|
40
|
+
"",
|
|
41
|
+
].join(".");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function overlayRoots(): NodeListOf<Element> {
|
|
45
|
+
return document.querySelectorAll(".hexclave-setup-error-overlay");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function createAppWithFailingHandoff(options: {
|
|
49
|
+
projectId: string,
|
|
50
|
+
sendClientRequest: () => Promise<never>,
|
|
51
|
+
}): StackClientApp<true> {
|
|
52
|
+
const app = new StackClientApp({
|
|
53
|
+
baseUrl: "http://localhost:12345",
|
|
54
|
+
projectId: options.projectId,
|
|
55
|
+
publishableClientKey: "stack-pk-test",
|
|
56
|
+
tokenStore: "memory",
|
|
57
|
+
redirectMethod: "none",
|
|
58
|
+
noAutomaticPrefetch: true,
|
|
59
|
+
devTool: false,
|
|
60
|
+
});
|
|
61
|
+
const accessToken = createAccessTokenString("source-refresh-token-id");
|
|
62
|
+
const clientInterface = Reflect.get(app, "_interface");
|
|
63
|
+
Reflect.set(clientInterface, "fetchNewAccessToken", async () => {
|
|
64
|
+
return AccessToken.createIfValid(accessToken) ?? (() => {
|
|
65
|
+
throw new Error("Expected the test access token to be valid.");
|
|
66
|
+
})();
|
|
67
|
+
});
|
|
68
|
+
Reflect.set(clientInterface, "sendClientRequest", options.sendClientRequest);
|
|
69
|
+
return app;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function createCrossDomainAuthRedirectUrl(app: StackClientApp<true>, redirectUri: string): Promise<unknown> {
|
|
73
|
+
const method = Reflect.get(app, "_createCrossDomainAuthRedirectUrl");
|
|
74
|
+
if (typeof method !== "function") {
|
|
75
|
+
throw new Error("Expected StackClientApp to expose _createCrossDomainAuthRedirectUrl in tests.");
|
|
76
|
+
}
|
|
77
|
+
return method.call(app, {
|
|
78
|
+
redirectUri,
|
|
79
|
+
state: "handoff-state",
|
|
80
|
+
codeChallenge: "abcdefghijklmnopqrstuvwxyzABCDEFG_0123456789-._~",
|
|
81
|
+
afterCallbackRedirectUrl: redirectUri,
|
|
82
|
+
overrideTokenStoreInit: {
|
|
83
|
+
accessToken: createAccessTokenString("source-refresh-token-id"),
|
|
84
|
+
refreshToken: "source-refresh-token",
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
describe("cross-domain handoff rejected by the server", () => {
|
|
90
|
+
afterEach(() => {
|
|
91
|
+
// The card's own cleanup, so that the focus trap it installed is released too and does not follow the next test.
|
|
92
|
+
getGlobalUiInstance(SETUP_ERROR_OVERLAY_GLOBAL_INSTANCE_KEY)?.cleanup();
|
|
93
|
+
setGlobalUiInstance(SETUP_ERROR_OVERLAY_GLOBAL_INSTANCE_KEY, null);
|
|
94
|
+
for (const root of overlayRoots()) {
|
|
95
|
+
root.remove();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("shows a setup error card even when the caller swallows the redirect failure", async () => {
|
|
100
|
+
const untrustedUrl = "https://demo.example.test/?hexclave_cross_domain_auth=1";
|
|
101
|
+
const app = createAppWithFailingHandoff({
|
|
102
|
+
projectId: "00000000-0000-4000-8000-000000000101",
|
|
103
|
+
sendClientRequest: async () => {
|
|
104
|
+
throw new KnownErrors.RedirectUrlNotWhitelisted(untrustedUrl);
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// The hosted auth pages catch a failing post-auth redirect and render their own "we could not continue
|
|
109
|
+
// automatically, please try again" screen, which is exactly how this error used to disappear: nothing on the page
|
|
110
|
+
// said that the flow is dead until a domain is added to the project's trusted domains.
|
|
111
|
+
let caught: unknown = null;
|
|
112
|
+
try {
|
|
113
|
+
await createCrossDomainAuthRedirectUrl(app, untrustedUrl);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
caught = error;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!HexclaveSetupError.isSetupError(caught)) {
|
|
119
|
+
throw new Error(`Expected the rejected handoff to throw a setup error, got: ${caught}`);
|
|
120
|
+
}
|
|
121
|
+
// The handoff query parameters have nothing to do with the rejection, so the message keeps only the checked part.
|
|
122
|
+
expect(caught.message).toBe("Cross-domain auth redirect URL https://demo.example.test/ is not trusted.");
|
|
123
|
+
// The full URL is still handed to the error sinks, which is where `customCaptureExtraArgs` ends up.
|
|
124
|
+
expect(Reflect.get(caught, "customCaptureExtraArgs")).toMatchObject([{ url: untrustedUrl }]);
|
|
125
|
+
expect(caught.cause).toBeInstanceOf(KnownErrors.RedirectUrlNotWhitelisted);
|
|
126
|
+
|
|
127
|
+
expect(overlayRoots()).toHaveLength(1);
|
|
128
|
+
const cardText = document.body.textContent;
|
|
129
|
+
expect(cardText).toContain("A domain in your authentication flow is not one of your project's trusted domains");
|
|
130
|
+
expect(cardText).toContain("add it to your project's trusted domains in the Hexclave dashboard, under Domains.");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("leaves other handoff failures to captureError", async () => {
|
|
134
|
+
const app = createAppWithFailingHandoff({
|
|
135
|
+
projectId: "00000000-0000-4000-8000-000000000102",
|
|
136
|
+
sendClientRequest: async () => {
|
|
137
|
+
throw new KnownErrors.UserAuthenticationRequired();
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
await expect(createCrossDomainAuthRedirectUrl(app, "https://demo.example.test/")).rejects.toSatisfy(
|
|
142
|
+
(error: unknown) => KnownErrors.UserAuthenticationRequired.isInstance(error),
|
|
143
|
+
);
|
|
144
|
+
expect(overlayRoots()).toHaveLength(0);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
@@ -9,13 +9,14 @@ import { HexclaveAssertionError, captureError, concatStacktraces, throwErr } fro
|
|
|
9
9
|
import { createGlobal, getGlobal } from "@hexclave/shared/dist/utils/globals";
|
|
10
10
|
import { filterUndefined, omit } from "@hexclave/shared/dist/utils/objects";
|
|
11
11
|
import { ReactPromise, runAsynchronously } from "@hexclave/shared/dist/utils/promises";
|
|
12
|
-
import {
|
|
12
|
+
import { use } from "@hexclave/shared/dist/utils/react";
|
|
13
13
|
import { Result } from "@hexclave/shared/dist/utils/results";
|
|
14
14
|
import { Store } from "@hexclave/shared/dist/utils/stores";
|
|
15
15
|
import { deindent } from "@hexclave/shared/dist/utils/strings";
|
|
16
16
|
import { getDefaultApiUrls } from "@hexclave/shared/dist/utils/urls";
|
|
17
17
|
import React, { useCallback } from "react"; // THIS_LINE_PLATFORM react-like
|
|
18
18
|
import { envVars } from "../../../../generated/env";
|
|
19
|
+
import { suspendIfSsr } from "../../../../utils/react"; // THIS_LINE_PLATFORM next react
|
|
19
20
|
import { HandlerUrlOptions, ResolvedHandlerUrls, hexclaveAppInternalsSymbol } from "../../common";
|
|
20
21
|
import { resolveHandlerUrls } from "../../url-targets";
|
|
21
22
|
|
|
@@ -133,6 +133,9 @@ export type ServerTeam = {
|
|
|
133
133
|
|
|
134
134
|
type ServerListUsersOptionsBase = {
|
|
135
135
|
cursor?: string,
|
|
136
|
+
/**
|
|
137
|
+
* Maximum number of users to return per page. Must be at most 1000.
|
|
138
|
+
*/
|
|
136
139
|
limit?: number,
|
|
137
140
|
orderBy?: 'signedUpAt' | 'lastActiveAt',
|
|
138
141
|
desc?: boolean,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
//===========================================
|
|
3
|
+
// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template
|
|
4
|
+
//===========================================
|
|
5
|
+
import { createGlobal } from "@hexclave/shared/dist/utils/globals";
|
|
6
|
+
|
|
7
|
+
export const NO_SUSPENSE_BOUNDARY_ERROR_SENTINEL = "__stack-no-suspense-boundary-error__";
|
|
8
|
+
|
|
9
|
+
export function isNoSuspenseBoundaryError(value: unknown): boolean {
|
|
10
|
+
return (
|
|
11
|
+
typeof value === "object"
|
|
12
|
+
&& value !== null
|
|
13
|
+
&& "__noSuspenseBoundarySentinel" in value
|
|
14
|
+
&& value.__noSuspenseBoundarySentinel === NO_SUSPENSE_BOUNDARY_ERROR_SENTINEL
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function ensureMonkeyPatch() {
|
|
19
|
+
createGlobal("__console-error-monkey-patch__", () => {
|
|
20
|
+
const originalConsoleError = console.error;
|
|
21
|
+
console.error = function (...args: unknown[]) {
|
|
22
|
+
// React's default error handlers log every server error, including the one we intentionally throw to skip SSR.
|
|
23
|
+
// Frameworks that use those defaults (including vanilla React) therefore need this narrow sentinel-based filter.
|
|
24
|
+
if (args.length === 1 && isNoSuspenseBoundaryError(args[0])) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
return originalConsoleError.apply(this, args);
|
|
28
|
+
};
|
|
29
|
+
return true;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
//===========================================
|
|
5
|
+
// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template
|
|
6
|
+
//===========================================
|
|
7
|
+
|
|
8
|
+
import { isBrowserLike } from "@hexclave/shared/dist/utils/env";
|
|
9
|
+
import { deindent } from "@hexclave/shared/dist/utils/strings";
|
|
10
|
+
import { useSearchParams } from "next/navigation"; // THIS_LINE_PLATFORM next
|
|
11
|
+
import { ensureMonkeyPatch, NO_SUSPENSE_BOUNDARY_ERROR_SENTINEL } from "./monkey-patch";
|
|
12
|
+
|
|
13
|
+
export function shouldRethrowRenderingError(error: unknown): boolean {
|
|
14
|
+
return !!error && typeof error === "object" && "digest" in error && error.digest === "BAILOUT_TO_CLIENT_SIDE_RENDERING";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class NoSuspenseBoundaryError extends Error {
|
|
18
|
+
digest: string;
|
|
19
|
+
reason: string;
|
|
20
|
+
__noSuspenseBoundarySentinel = NO_SUSPENSE_BOUNDARY_ERROR_SENTINEL;
|
|
21
|
+
|
|
22
|
+
constructor(options: { caller?: string }) {
|
|
23
|
+
ensureMonkeyPatch();
|
|
24
|
+
|
|
25
|
+
super(deindent`
|
|
26
|
+
Suspense boundary not found! Read the error message below carefully (or paste it into your AI agent).
|
|
27
|
+
|
|
28
|
+
${options.caller ?? "This code path"} attempted to display a loading indicator, but didn't find a Suspense boundary above it. Please read the error message below carefully.
|
|
29
|
+
|
|
30
|
+
There are several potential causes:
|
|
31
|
+
|
|
32
|
+
1. [Next.js] You are missing a loading.tsx file in your app directory. Fix it by adding a loading.tsx file in your app directory.
|
|
33
|
+
|
|
34
|
+
2. [React] You are missing a <Suspense> boundary in your component. Fix it by wrapping your component (or the entire app) in a <Suspense> component.
|
|
35
|
+
|
|
36
|
+
3. [Next.js] The component is rendered in the root (outermost) layout.tsx or template.tsx file. Next.js does not wrap those files in a Suspense boundary, even if there is a loading.tsx file in the same folder. To fix it, wrap your layout inside a route group like this:
|
|
37
|
+
|
|
38
|
+
- app
|
|
39
|
+
- - layout.tsx // contains <html> and <body>, alongside providers and other components that don't need ${options.caller ?? "this code path"}
|
|
40
|
+
- - loading.tsx // required for suspense
|
|
41
|
+
- - (main)
|
|
42
|
+
- - - layout.tsx // contains the main layout of your app, like a sidebar or a header, and can use ${options.caller ?? "this code path"}
|
|
43
|
+
- - - route.tsx // your actual main page
|
|
44
|
+
- - - the rest of your app
|
|
45
|
+
|
|
46
|
+
For more information on this approach, see Next's documentation on route groups: https://nextjs.org/docs/app/building-your-application/routing/route-groups
|
|
47
|
+
|
|
48
|
+
4. You caught this error with try-catch or a custom error boundary. Fix this by rethrowing the error or not catching it in the first place.
|
|
49
|
+
|
|
50
|
+
5. Your version of Hexclave is too old. Upgrade to the latest version to see if that fixes the issue.
|
|
51
|
+
|
|
52
|
+
See: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
|
|
53
|
+
|
|
54
|
+
More information on SSR and Suspense boundaries: https://react.dev/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content
|
|
55
|
+
`);
|
|
56
|
+
|
|
57
|
+
this.name = "NoSuspenseBoundaryError";
|
|
58
|
+
this.reason = options.caller ?? "suspendIfSsr()";
|
|
59
|
+
|
|
60
|
+
// Next recognizes this digest as an intentional request-time CSR bailout and suppresses its normal error reporting.
|
|
61
|
+
this.digest = "BAILOUT_TO_CLIENT_SIDE_RENDERING";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
import.meta.vitest?.test("NoSuspenseBoundaryError", ({ expect }) => {
|
|
65
|
+
const defaultError = new NoSuspenseBoundaryError({});
|
|
66
|
+
expect(defaultError.name).toBe("NoSuspenseBoundaryError");
|
|
67
|
+
expect(defaultError.reason).toBe("suspendIfSsr()");
|
|
68
|
+
expect(defaultError.digest).toBe("BAILOUT_TO_CLIENT_SIDE_RENDERING");
|
|
69
|
+
expect(defaultError.message).toContain("This code path attempted to display a loading indicator");
|
|
70
|
+
|
|
71
|
+
const customError = new NoSuspenseBoundaryError({ caller: "CustomComponent" });
|
|
72
|
+
expect(customError.name).toBe("NoSuspenseBoundaryError");
|
|
73
|
+
expect(customError.reason).toBe("CustomComponent");
|
|
74
|
+
expect(customError.digest).toBe("BAILOUT_TO_CLIENT_SIDE_RENDERING");
|
|
75
|
+
expect(customError.message).toContain("CustomComponent attempted to display a loading indicator");
|
|
76
|
+
expect(customError.message).toContain("loading.tsx");
|
|
77
|
+
expect(customError.message).toContain("route groups");
|
|
78
|
+
expect(customError.message).toContain("https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Use this in a component or hook to disable SSR. It must be wrapped in a Suspense boundary.
|
|
83
|
+
*/
|
|
84
|
+
export function suspendIfSsr(caller?: string) {
|
|
85
|
+
// Next 16.3's Instant Insights is a silly goose! It rejects our deliberate recoverable SSR error during
|
|
86
|
+
// prerender validation, even though React uses the surrounding Suspense fallback correctly. Calling
|
|
87
|
+
// useSearchParams first makes Next create its own recognized `prerender-client` dynamic hole, so prerendering
|
|
88
|
+
// stops before our error while request-time SSR still reaches the error and retries this subtree on the client.
|
|
89
|
+
useSearchParams();
|
|
90
|
+
if (!isBrowserLike()) {
|
|
91
|
+
throw new NoSuspenseBoundaryError({ caller });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"admin-app-impl-CsH-gVGz.d.ts","names":[],"sources":["../src/lib/hexclave-app/apps/implementations/client-app-impl.ts","../src/lib/hexclave-app/apps/implementations/server-app-impl.ts","../src/lib/hexclave-app/apps/implementations/admin-app-impl.ts"],"mappings":"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"}
|