@hexclave/next 1.0.75 → 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-sTQD2d-3.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/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/dev-tool-core.d.ts.map +1 -1
- package/dist/dev-tool/dev-tool-core.js +2 -2
- package/dist/dev-tool/dev-tool-core.js.map +1 -1
- package/dist/dev-tool/index.d.ts +1 -1
- package/dist/dev-tool/index.d.ts.map +1 -1
- package/dist/dev-tool/index.js +2 -8
- package/dist/dev-tool/index.js.map +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/dev-tool/dev-tool-core.d.ts.map +1 -1
- package/dist/esm/dev-tool/dev-tool-core.js +1 -1
- package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
- package/dist/esm/dev-tool/index.d.ts.map +1 -1
- package/dist/esm/dev-tool/index.js +2 -8
- package/dist/esm/dev-tool/index.js.map +1 -1
- package/dist/esm/generated/quetzal-translations.d.ts +2 -2
- package/dist/esm/in-page-ui/dev-environment.d.ts +5 -0
- package/dist/esm/in-page-ui/dev-environment.d.ts.map +1 -0
- package/dist/esm/in-page-ui/dev-environment.js +18 -0
- package/dist/esm/in-page-ui/dev-environment.js.map +1 -0
- package/dist/esm/in-page-ui/issue-card.d.ts +52 -0
- package/dist/esm/in-page-ui/issue-card.d.ts.map +1 -0
- package/dist/esm/in-page-ui/issue-card.js +392 -0
- package/dist/esm/in-page-ui/issue-card.js.map +1 -0
- package/dist/esm/in-page-ui/issue-card.test.d.ts +1 -0
- package/dist/esm/in-page-ui/issue-card.test.js +60 -0
- package/dist/esm/in-page-ui/issue-card.test.js.map +1 -0
- package/dist/esm/in-page-ui/logo.d.ts +5 -0
- package/dist/esm/in-page-ui/logo.d.ts.map +1 -0
- package/dist/esm/in-page-ui/logo.js +6 -0
- package/dist/esm/in-page-ui/logo.js.map +1 -0
- 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 +140 -15
- 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 +184 -28
- 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/redirect-page-urls.test.js +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +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/pushed-config-error-overlay/index.d.ts.map +1 -1
- package/dist/esm/pushed-config-error-overlay/index.js +42 -343
- package/dist/esm/pushed-config-error-overlay/index.js.map +1 -1
- package/dist/esm/setup-error-overlay/index.d.ts +16 -0
- package/dist/esm/setup-error-overlay/index.d.ts.map +1 -0
- package/dist/esm/setup-error-overlay/index.js +106 -0
- package/dist/esm/setup-error-overlay/index.js.map +1 -0
- package/dist/esm/setup-error-overlay/index.test.d.ts +1 -0
- package/dist/esm/setup-error-overlay/index.test.js +125 -0
- package/dist/esm/setup-error-overlay/index.test.js.map +1 -0
- 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-BKxi3Vy-.d.ts → hexclave-provider-CMz2mt4I.d.ts} +3 -3
- package/dist/{hexclave-provider-BKxi3Vy-.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/in-page-ui/dev-environment.d.ts +5 -0
- package/dist/in-page-ui/dev-environment.d.ts.map +1 -0
- package/dist/in-page-ui/dev-environment.js +19 -0
- package/dist/in-page-ui/dev-environment.js.map +1 -0
- package/dist/in-page-ui/issue-card.d.ts +52 -0
- package/dist/in-page-ui/issue-card.d.ts.map +1 -0
- package/dist/in-page-ui/issue-card.js +397 -0
- package/dist/in-page-ui/issue-card.js.map +1 -0
- package/dist/in-page-ui/issue-card.test.d.ts +1 -0
- package/dist/in-page-ui/issue-card.test.js +59 -0
- package/dist/in-page-ui/issue-card.test.js.map +1 -0
- package/dist/in-page-ui/logo.d.ts +5 -0
- package/dist/in-page-ui/logo.d.ts.map +1 -0
- package/dist/in-page-ui/logo.js +7 -0
- package/dist/in-page-ui/logo.js.map +1 -0
- 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 +140 -15
- 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 +182 -25
- 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/redirect-page-urls.test.js +1 -0
- package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +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/pushed-config-error-overlay/index.d.ts.map +1 -1
- package/dist/pushed-config-error-overlay/index.js +41 -342
- package/dist/pushed-config-error-overlay/index.js.map +1 -1
- package/dist/{quetzal-translations-XeH3zQ9l.d.ts → quetzal-translations-B2jT2SWm.d.ts} +3 -3
- package/dist/{quetzal-translations-XeH3zQ9l.d.ts.map → quetzal-translations-B2jT2SWm.d.ts.map} +1 -1
- package/dist/setup-error-overlay/index.d.ts +16 -0
- package/dist/setup-error-overlay/index.d.ts.map +1 -0
- package/dist/setup-error-overlay/index.js +108 -0
- package/dist/setup-error-overlay/index.js.map +1 -0
- package/dist/setup-error-overlay/index.test.d.ts +1 -0
- package/dist/setup-error-overlay/index.test.js +124 -0
- package/dist/setup-error-overlay/index.test.js.map +1 -0
- package/dist/team-invitation-B5Ol7vdd.d.ts.map +1 -1
- package/dist/{translation-provider-WOaZXqAz.d.ts → translation-provider-6505O9P2.d.ts} +2 -2
- package/dist/{translation-provider-WOaZXqAz.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/dev-tool/dev-tool-core.ts +1 -4
- package/src/dev-tool/index.ts +4 -15
- package/src/in-page-ui/dev-environment.ts +33 -0
- package/src/in-page-ui/issue-card.test.ts +67 -0
- package/src/in-page-ui/issue-card.ts +500 -0
- package/src/in-page-ui/logo.ts +8 -0
- 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 +157 -0
- 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 +255 -37
- 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/apps/implementations/redirect-page-urls.test.ts +1 -0
- package/src/lib/hexclave-app/teams/index.ts +3 -0
- package/src/pushed-config-error-overlay/index.ts +45 -386
- package/src/setup-error-overlay/index.test.ts +133 -0
- package/src/setup-error-overlay/index.ts +150 -0
- package/src/utils/monkey-patch.tsx +31 -0
- package/src/utils/react.tsx +93 -0
- package/dist/admin-app-impl-sTQD2d-3.d.ts.map +0 -1
- package/dist/client-app-BCT5p_70.d.ts.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { neverResolve, runAsynchronously, wait } from "@hexclave/shared/dist/utils/promises";
|
|
2
2
|
import { deindent, mergeScopeStrings } from "@hexclave/shared/dist/utils/strings";
|
|
3
|
-
import { HexclaveAssertionError, captureError, throwErr } from "@hexclave/shared/dist/utils/errors";
|
|
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,
|
|
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
|
|
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";
|
|
@@ -42,9 +44,25 @@ import { SessionRecorder, analyticsOptionsFromJson, analyticsOptionsToJson, getS
|
|
|
42
44
|
import { mountClickmapOverlay } from "../../../../clickmap/index.js";
|
|
43
45
|
import { mountDevTool } from "../../../../dev-tool/index.js";
|
|
44
46
|
import { mountPushedConfigErrorOverlay } from "../../../../pushed-config-error-overlay/index.js";
|
|
47
|
+
import { showSetupErrorOverlay } from "../../../../setup-error-overlay/index.js";
|
|
45
48
|
import * as sc from "@hexclave/sc";
|
|
46
49
|
import { cookies } from "@hexclave/sc";
|
|
47
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
|
+
}
|
|
48
66
|
let isReactServer = false;
|
|
49
67
|
isReactServer = sc.isReactServer;
|
|
50
68
|
const NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
|
|
@@ -59,6 +77,62 @@ const nestedCrossDomainAuthQueryParams = {
|
|
|
59
77
|
codeChallengeMethod: "code_challenge_method",
|
|
60
78
|
afterCallbackRedirectUrl: oauthAfterCallbackRedirectUrlQueryParam
|
|
61
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* An auth flow can only ever send the user to a URL that the project trusts, so an untrusted one means the flow is dead
|
|
82
|
+
* until someone changes the project's configuration. Describe the problem in terms of that configuration rather than in
|
|
83
|
+
* terms of the flow's internals, which nobody outside this file knows about.
|
|
84
|
+
*/
|
|
85
|
+
function createUntrustedUrlError(options) {
|
|
86
|
+
const origin = createUrlIfValid(options.url)?.origin ?? options.url;
|
|
87
|
+
return new HexclaveSetupError({
|
|
88
|
+
title: "A domain in your authentication flow is not one of your project's trusted domains",
|
|
89
|
+
message: options.message,
|
|
90
|
+
howToFix: [
|
|
91
|
+
`If ${origin} is yours, add it to your project's trusted domains in the Hexclave dashboard, under Domains.`,
|
|
92
|
+
"Protocol, domain and port must all match a trusted domain exactly; a wildcard like https://*.example.com matches only one subdomain level.",
|
|
93
|
+
`If ${origin} is not yours, do not add it \u2014 somebody may be trying to redirect your users' credentials to it.`
|
|
94
|
+
],
|
|
95
|
+
extraData: {
|
|
96
|
+
url: options.url,
|
|
97
|
+
projectId: options.projectId,
|
|
98
|
+
...options.cause === void 0 ? {} : { cause: options.cause }
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function createUntrustedNestedCrossDomainUrlError(options) {
|
|
103
|
+
return createUntrustedUrlError({
|
|
104
|
+
message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not trusted.`,
|
|
105
|
+
url: options.url,
|
|
106
|
+
projectId: options.projectId
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A URL that the auth flow cannot even parse is just as fatal as an untrusted one, and just as much a configuration
|
|
111
|
+
* problem: something in the developer's setup put a relative or malformed value where an absolute URL belongs.
|
|
112
|
+
*/
|
|
113
|
+
function createMalformedNestedCrossDomainUrlError(options) {
|
|
114
|
+
return new HexclaveSetupError({
|
|
115
|
+
title: "A URL in your authentication flow is not a valid absolute URL",
|
|
116
|
+
message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not a valid absolute URL.`,
|
|
117
|
+
howToFix: [
|
|
118
|
+
"Handler URLs and after-auth redirect URLs must be absolute, including their protocol, like https://example.com/handler/oauth-callback.",
|
|
119
|
+
"Check the handler URLs configured for your project and the redirect URLs you pass to Hexclave's sign-in and sign-up methods.",
|
|
120
|
+
"If none of those look wrong, check whether a proxy or rewrite in front of your app is rewriting the authentication flow's query parameters."
|
|
121
|
+
],
|
|
122
|
+
extraData: { url: options.url }
|
|
123
|
+
});
|
|
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
|
+
}
|
|
62
136
|
function getRedirectHelperInstruction(handlerName) {
|
|
63
137
|
if (handlerName === "handler") return "Use a page-specific redirect helper such as app.redirectToSignIn() instead.";
|
|
64
138
|
return `Use app.${`redirectTo${handlerName.slice(0, 1).toUpperCase()}${handlerName.slice(1)}`}() instead.`;
|
|
@@ -212,6 +286,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
212
286
|
this._uniqueIdentifier = void 0;
|
|
213
287
|
this._sessionRecorder = null;
|
|
214
288
|
this._eventTracker = null;
|
|
289
|
+
this._pendingSignOut = null;
|
|
215
290
|
this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
216
291
|
this._ownedAdminApps = new DependenciesMap();
|
|
217
292
|
this._currentUserCache = createCacheBySession(async (session) => {
|
|
@@ -465,6 +540,19 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
465
540
|
});
|
|
466
541
|
if (isBrowserLike()) {
|
|
467
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
|
+
}
|
|
468
556
|
this._trackPendingAuthResolution(async () => {
|
|
469
557
|
await this._maybeHandleNestedCrossDomainAuth(urlAtConstructionTime);
|
|
470
558
|
});
|
|
@@ -491,6 +579,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
491
579
|
await callback();
|
|
492
580
|
} catch (error) {
|
|
493
581
|
captureError("pending-auth-resolution-failed", error);
|
|
582
|
+
showSetupErrorOverlay(error);
|
|
494
583
|
}
|
|
495
584
|
})();
|
|
496
585
|
this._pendingAuthResolutionPromises.push(promise);
|
|
@@ -611,13 +700,35 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
611
700
|
codeChallenge
|
|
612
701
|
});
|
|
613
702
|
if ((currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.codeChallengeMethod) ?? "S256") !== "S256") throw new HexclaveAssertionError("Nested cross-domain auth only supports S256 PKCE");
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
703
|
+
const validateHandoffOwnership = async () => {
|
|
704
|
+
if (await this._fetchCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) !== refreshTokenId) throw new Error("Nested cross-domain auth source session does not match the requested refresh token ID.");
|
|
705
|
+
};
|
|
706
|
+
const setupErrorIfHandoffIsOwned = async (setupError) => {
|
|
707
|
+
await validateHandoffOwnership();
|
|
708
|
+
return setupError;
|
|
709
|
+
};
|
|
710
|
+
const redirectUriUrl = isRelative(redirectUri) ? null : createUrlIfValid(redirectUri);
|
|
711
|
+
if (redirectUriUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
|
|
712
|
+
urlDescription: "redirect URI",
|
|
713
|
+
url: redirectUri
|
|
714
|
+
}));
|
|
715
|
+
if (!await this._isTrusted(redirectUriUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
|
|
716
|
+
urlDescription: "redirect URI",
|
|
717
|
+
url: redirectUri,
|
|
718
|
+
projectId: this.projectId
|
|
719
|
+
}));
|
|
617
720
|
const afterCallbackRedirectUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.afterCallbackRedirectUrl);
|
|
618
|
-
const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl :
|
|
619
|
-
if (
|
|
620
|
-
|
|
721
|
+
const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl : createUrlIfValid(afterCallbackRedirectUrlString, redirectUriUrl);
|
|
722
|
+
if (afterCallbackRedirectUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
|
|
723
|
+
urlDescription: "after-callback redirect URL",
|
|
724
|
+
url: afterCallbackRedirectUrlString ?? ""
|
|
725
|
+
}));
|
|
726
|
+
if (!await this._isTrusted(afterCallbackRedirectUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
|
|
727
|
+
urlDescription: "after-callback redirect URL",
|
|
728
|
+
url: afterCallbackRedirectUrlString ?? afterCallbackRedirectUrl.toString(),
|
|
729
|
+
projectId: this.projectId
|
|
730
|
+
}));
|
|
731
|
+
await validateHandoffOwnership();
|
|
621
732
|
await this._redirectTo({
|
|
622
733
|
url: await this._createCrossDomainAuthRedirectUrl({
|
|
623
734
|
redirectUri: redirectUriUrl.toString(),
|
|
@@ -635,9 +746,16 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
635
746
|
if (currentRefreshTokenId != null) (await this._getSession(void 0, { awaitPendingAuthResolutions: false })).markInvalid();
|
|
636
747
|
const callbackUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.callbackUrl);
|
|
637
748
|
if (callbackUrlString == null) throw new HexclaveAssertionError("Nested cross-domain auth URL is missing callback URL");
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
749
|
+
const callbackUrl = isRelative(callbackUrlString) ? null : createUrlIfValid(callbackUrlString);
|
|
750
|
+
if (callbackUrl == null) throw createMalformedNestedCrossDomainUrlError({
|
|
751
|
+
urlDescription: "callback URL",
|
|
752
|
+
url: callbackUrlString
|
|
753
|
+
});
|
|
754
|
+
if (!await this._isTrusted(callbackUrl.toString())) throw createUntrustedNestedCrossDomainUrlError({
|
|
755
|
+
urlDescription: "callback URL",
|
|
756
|
+
url: callbackUrlString,
|
|
757
|
+
projectId: this.projectId
|
|
758
|
+
});
|
|
641
759
|
const afterCallbackRedirectUrl = new URL(currentUrl);
|
|
642
760
|
afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.refreshTokenId);
|
|
643
761
|
afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.callbackUrl);
|
|
@@ -2137,17 +2255,32 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2137
2255
|
async _createCrossDomainAuthRedirectUrl(options) {
|
|
2138
2256
|
const session = await this._getSession(options.overrideTokenStoreInit, { awaitPendingAuthResolutions: options.awaitPendingAuthResolutions });
|
|
2139
2257
|
await session.fetchNewTokens();
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
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
|
+
}
|
|
2151
2284
|
if (!response.ok) {
|
|
2152
2285
|
const responseBody = await response.text();
|
|
2153
2286
|
throw new HexclaveAssertionError(`Cross-domain authorization endpoint failed: ${response.status} ${responseBody}`);
|
|
@@ -2198,7 +2331,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2198
2331
|
} else return (to) => {};
|
|
2199
2332
|
}
|
|
2200
2333
|
async _redirectIfTrusted(url, options) {
|
|
2201
|
-
if (!await this._isTrusted(url))
|
|
2334
|
+
if (!await this._isTrusted(url)) throwSetupError(createUntrustedUrlError({
|
|
2335
|
+
message: `Redirect URL ${url} is not trusted; should be relative.`,
|
|
2336
|
+
url,
|
|
2337
|
+
projectId: this.projectId
|
|
2338
|
+
}));
|
|
2202
2339
|
return await this._redirectTo({
|
|
2203
2340
|
url,
|
|
2204
2341
|
...options
|
|
@@ -2243,7 +2380,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2243
2380
|
awaitPendingAuthResolutions: internalOptions?.awaitPendingAuthResolutions,
|
|
2244
2381
|
overrideTokenStoreInit: internalOptions?.overrideTokenStoreInit
|
|
2245
2382
|
}) : plan.url;
|
|
2246
|
-
if (!await this._isTrusted(redirectUrl))
|
|
2383
|
+
if (!await this._isTrusted(redirectUrl)) throwSetupError(createUntrustedUrlError({
|
|
2384
|
+
message: `Redirect URL ${redirectUrl} is not trusted; should be relative.`,
|
|
2385
|
+
url: redirectUrl,
|
|
2386
|
+
projectId: this.projectId
|
|
2387
|
+
}));
|
|
2247
2388
|
return redirectUrl;
|
|
2248
2389
|
}
|
|
2249
2390
|
_redirectToHandlerDuringRender(handlerName, options) {
|
|
@@ -2356,6 +2497,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2356
2497
|
}
|
|
2357
2498
|
async getUser(options) {
|
|
2358
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;
|
|
2359
2502
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
2360
2503
|
const session = await this._getSession(options?.tokenStore);
|
|
2361
2504
|
let crud = Result.orThrow(await this._currentUserCache.getOrWait([session], "write-only"));
|
|
@@ -2388,6 +2531,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2388
2531
|
let crud = useAsyncCache(this._currentUserCache, [session], "clientApp.useUser()");
|
|
2389
2532
|
const includeAnonymous = options?.or === "anonymous" || options?.or === "anonymous-if-exists[deprecated]";
|
|
2390
2533
|
const includeRestricted = options?.includeRestricted === true || includeAnonymous;
|
|
2534
|
+
const pendingSignOut = this._pendingSignOut;
|
|
2535
|
+
if (pendingSignOut != null) use(pendingSignOut);
|
|
2391
2536
|
if (crud === null || crud.is_anonymous && !includeAnonymous || crud.is_restricted && !includeRestricted) switch (options?.or) {
|
|
2392
2537
|
case "redirect":
|
|
2393
2538
|
if (!crud?.is_anonymous && crud?.is_restricted) {
|
|
@@ -2788,14 +2933,25 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2788
2933
|
async _signOut(session, options) {
|
|
2789
2934
|
this._eventTracker?.clearBuffer();
|
|
2790
2935
|
this._sessionRecorder?.clearBuffer();
|
|
2791
|
-
|
|
2936
|
+
const previousSignOut = this._pendingSignOut;
|
|
2937
|
+
const signOutOperation = (async () => {
|
|
2938
|
+
await previousSignOut;
|
|
2792
2939
|
await this._interface.signOut(session);
|
|
2793
2940
|
if (options?.redirectUrl) await this._redirectTo({
|
|
2794
2941
|
url: options.redirectUrl,
|
|
2795
2942
|
replace: true
|
|
2796
2943
|
});
|
|
2797
2944
|
else await this._redirectToDefaultAfterSignOut();
|
|
2798
|
-
});
|
|
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
|
+
}
|
|
2799
2955
|
}
|
|
2800
2956
|
async _redirectToDefaultAfterSignOut() {
|
|
2801
2957
|
if (this._urlOptions.afterSignOut != null) {
|
|
@@ -3004,6 +3160,6 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
3004
3160
|
}
|
|
3005
3161
|
};
|
|
3006
3162
|
//#endregion
|
|
3007
|
-
export { _HexclaveClientAppImplIncomplete };
|
|
3163
|
+
export { _HexclaveClientAppImplIncomplete, stripBrowserActionQueryParam };
|
|
3008
3164
|
|
|
3009
3165
|
//# sourceMappingURL=client-app-impl.js.map
|