@hexclave/js 1.0.74 → 1.0.76
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-BgUMxiV3.d.ts → admin-app-impl-B86v7B0O.d.ts} +2 -2
- package/dist/{admin-app-impl-BgUMxiV3.d.ts.map → admin-app-impl-B86v7B0O.d.ts.map} +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.map +1 -1
- package/dist/dev-tool/index.js +2 -8
- package/dist/dev-tool/index.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/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 +1 -1
- 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.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.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +95 -12
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
- 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/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/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/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +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 +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +94 -11
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/lib/hexclave-app/apps/implementations/index.d.ts +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/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/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/package.json +2 -2
- 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.cross-domain.test.ts +158 -0
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +125 -17
- package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.test.ts +1 -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
|
@@ -40,6 +40,7 @@ let __session_replay_js = require("./session-replay.js");
|
|
|
40
40
|
let ____________clickmap_index_js = require("../../../../clickmap/index.js");
|
|
41
41
|
let ____________dev_tool_index_js = require("../../../../dev-tool/index.js");
|
|
42
42
|
let ____________pushed_config_error_overlay_index_js = require("../../../../pushed-config-error-overlay/index.js");
|
|
43
|
+
let ____________setup_error_overlay_index_js = require("../../../../setup-error-overlay/index.js");
|
|
43
44
|
//#region src/lib/hexclave-app/apps/implementations/client-app-impl.ts
|
|
44
45
|
const prefetchedCrossDomainHandoffTtlMs = 3300 * 1e3;
|
|
45
46
|
const oauthAfterCallbackRedirectUrlQueryParam = "after_callback_redirect_url";
|
|
@@ -52,6 +53,50 @@ const nestedCrossDomainAuthQueryParams = {
|
|
|
52
53
|
codeChallengeMethod: "code_challenge_method",
|
|
53
54
|
afterCallbackRedirectUrl: oauthAfterCallbackRedirectUrlQueryParam
|
|
54
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* 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
|
|
58
|
+
* until someone changes the project's configuration. Describe the problem in terms of that configuration rather than in
|
|
59
|
+
* terms of the flow's internals, which nobody outside this file knows about.
|
|
60
|
+
*/
|
|
61
|
+
function createUntrustedUrlError(options) {
|
|
62
|
+
const origin = (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(options.url)?.origin ?? options.url;
|
|
63
|
+
return new _hexclave_shared_dist_utils_errors.HexclaveSetupError({
|
|
64
|
+
title: "A domain in your authentication flow is not one of your project's trusted domains",
|
|
65
|
+
message: options.message,
|
|
66
|
+
howToFix: [
|
|
67
|
+
`If ${origin} is yours, add it to your project's trusted domains in the Hexclave dashboard, under Domains.`,
|
|
68
|
+
"Protocol, domain and port must all match a trusted domain exactly; a wildcard like https://*.example.com matches only one subdomain level.",
|
|
69
|
+
`If ${origin} is not yours, do not add it \u2014 somebody may be trying to redirect your users' credentials to it.`
|
|
70
|
+
],
|
|
71
|
+
extraData: {
|
|
72
|
+
url: options.url,
|
|
73
|
+
projectId: options.projectId
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function createUntrustedNestedCrossDomainUrlError(options) {
|
|
78
|
+
return createUntrustedUrlError({
|
|
79
|
+
message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not trusted.`,
|
|
80
|
+
url: options.url,
|
|
81
|
+
projectId: options.projectId
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A URL that the auth flow cannot even parse is just as fatal as an untrusted one, and just as much a configuration
|
|
86
|
+
* problem: something in the developer's setup put a relative or malformed value where an absolute URL belongs.
|
|
87
|
+
*/
|
|
88
|
+
function createMalformedNestedCrossDomainUrlError(options) {
|
|
89
|
+
return new _hexclave_shared_dist_utils_errors.HexclaveSetupError({
|
|
90
|
+
title: "A URL in your authentication flow is not a valid absolute URL",
|
|
91
|
+
message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not a valid absolute URL.`,
|
|
92
|
+
howToFix: [
|
|
93
|
+
"Handler URLs and after-auth redirect URLs must be absolute, including their protocol, like https://example.com/handler/oauth-callback.",
|
|
94
|
+
"Check the handler URLs configured for your project and the redirect URLs you pass to Hexclave's sign-in and sign-up methods.",
|
|
95
|
+
"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."
|
|
96
|
+
],
|
|
97
|
+
extraData: { url: options.url }
|
|
98
|
+
});
|
|
99
|
+
}
|
|
55
100
|
function getRedirectHelperInstruction(handlerName) {
|
|
56
101
|
if (handlerName === "handler") return "Use a page-specific redirect helper such as app.redirectToSignIn() instead.";
|
|
57
102
|
return `Use app.${`redirectTo${handlerName.slice(0, 1).toUpperCase()}${handlerName.slice(1)}`}() instead.`;
|
|
@@ -457,6 +502,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
457
502
|
await callback();
|
|
458
503
|
} catch (error) {
|
|
459
504
|
(0, _hexclave_shared_dist_utils_errors.captureError)("pending-auth-resolution-failed", error);
|
|
505
|
+
(0, ____________setup_error_overlay_index_js.showSetupErrorOverlay)(error);
|
|
460
506
|
}
|
|
461
507
|
})();
|
|
462
508
|
this._pendingAuthResolutionPromises.push(promise);
|
|
@@ -573,13 +619,35 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
573
619
|
codeChallenge
|
|
574
620
|
});
|
|
575
621
|
if ((currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.codeChallengeMethod) ?? "S256") !== "S256") throw new _hexclave_shared_dist_utils_errors.HexclaveAssertionError("Nested cross-domain auth only supports S256 PKCE");
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
622
|
+
const validateHandoffOwnership = async () => {
|
|
623
|
+
if (await this._fetchCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) !== refreshTokenId) throw new Error("Nested cross-domain auth source session does not match the requested refresh token ID.");
|
|
624
|
+
};
|
|
625
|
+
const setupErrorIfHandoffIsOwned = async (setupError) => {
|
|
626
|
+
await validateHandoffOwnership();
|
|
627
|
+
return setupError;
|
|
628
|
+
};
|
|
629
|
+
const redirectUriUrl = (0, _hexclave_shared_dist_utils_urls.isRelative)(redirectUri) ? null : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(redirectUri);
|
|
630
|
+
if (redirectUriUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
|
|
631
|
+
urlDescription: "redirect URI",
|
|
632
|
+
url: redirectUri
|
|
633
|
+
}));
|
|
634
|
+
if (!await this._isTrusted(redirectUriUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
|
|
635
|
+
urlDescription: "redirect URI",
|
|
636
|
+
url: redirectUri,
|
|
637
|
+
projectId: this.projectId
|
|
638
|
+
}));
|
|
579
639
|
const afterCallbackRedirectUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.afterCallbackRedirectUrl);
|
|
580
|
-
const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl :
|
|
581
|
-
if (
|
|
582
|
-
|
|
640
|
+
const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(afterCallbackRedirectUrlString, redirectUriUrl);
|
|
641
|
+
if (afterCallbackRedirectUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
|
|
642
|
+
urlDescription: "after-callback redirect URL",
|
|
643
|
+
url: afterCallbackRedirectUrlString ?? ""
|
|
644
|
+
}));
|
|
645
|
+
if (!await this._isTrusted(afterCallbackRedirectUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
|
|
646
|
+
urlDescription: "after-callback redirect URL",
|
|
647
|
+
url: afterCallbackRedirectUrlString ?? afterCallbackRedirectUrl.toString(),
|
|
648
|
+
projectId: this.projectId
|
|
649
|
+
}));
|
|
650
|
+
await validateHandoffOwnership();
|
|
583
651
|
await this._redirectTo({
|
|
584
652
|
url: await this._createCrossDomainAuthRedirectUrl({
|
|
585
653
|
redirectUri: redirectUriUrl.toString(),
|
|
@@ -597,9 +665,16 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
597
665
|
if (currentRefreshTokenId != null) (await this._getSession(void 0, { awaitPendingAuthResolutions: false })).markInvalid();
|
|
598
666
|
const callbackUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.callbackUrl);
|
|
599
667
|
if (callbackUrlString == null) throw new _hexclave_shared_dist_utils_errors.HexclaveAssertionError("Nested cross-domain auth URL is missing callback URL");
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
668
|
+
const callbackUrl = (0, _hexclave_shared_dist_utils_urls.isRelative)(callbackUrlString) ? null : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(callbackUrlString);
|
|
669
|
+
if (callbackUrl == null) throw createMalformedNestedCrossDomainUrlError({
|
|
670
|
+
urlDescription: "callback URL",
|
|
671
|
+
url: callbackUrlString
|
|
672
|
+
});
|
|
673
|
+
if (!await this._isTrusted(callbackUrl.toString())) throw createUntrustedNestedCrossDomainUrlError({
|
|
674
|
+
urlDescription: "callback URL",
|
|
675
|
+
url: callbackUrlString,
|
|
676
|
+
projectId: this.projectId
|
|
677
|
+
});
|
|
603
678
|
const afterCallbackRedirectUrl = new URL(currentUrl);
|
|
604
679
|
afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.refreshTokenId);
|
|
605
680
|
afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.callbackUrl);
|
|
@@ -1943,7 +2018,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
1943
2018
|
await (0, _hexclave_shared_dist_utils_promises.wait)(2e3);
|
|
1944
2019
|
}
|
|
1945
2020
|
async _redirectIfTrusted(url, options) {
|
|
1946
|
-
if (!await this._isTrusted(url)) throw
|
|
2021
|
+
if (!await this._isTrusted(url)) throw createUntrustedUrlError({
|
|
2022
|
+
message: `Redirect URL ${url} is not trusted; should be relative.`,
|
|
2023
|
+
url,
|
|
2024
|
+
projectId: this.projectId
|
|
2025
|
+
});
|
|
1947
2026
|
return await this._redirectTo({
|
|
1948
2027
|
url,
|
|
1949
2028
|
...options
|
|
@@ -1988,7 +2067,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
1988
2067
|
awaitPendingAuthResolutions: internalOptions?.awaitPendingAuthResolutions,
|
|
1989
2068
|
overrideTokenStoreInit: internalOptions?.overrideTokenStoreInit
|
|
1990
2069
|
}) : plan.url;
|
|
1991
|
-
if (!await this._isTrusted(redirectUrl)) throw
|
|
2070
|
+
if (!await this._isTrusted(redirectUrl)) throw createUntrustedUrlError({
|
|
2071
|
+
message: `Redirect URL ${redirectUrl} is not trusted; should be relative.`,
|
|
2072
|
+
url: redirectUrl,
|
|
2073
|
+
projectId: this.projectId
|
|
2074
|
+
});
|
|
1992
2075
|
return redirectUrl;
|
|
1993
2076
|
}
|
|
1994
2077
|
_redirectToHandlerDuringRender(handlerName, options) {
|