@hexclave/js 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-BhrjJlxj.d.ts → admin-app-impl-CHQtsn4f.d.ts} +11 -9
- package/dist/admin-app-impl-CHQtsn4f.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-WOX3pOo1.d.ts → client-app-R5X8wyeV.d.ts} +4 -1
- package/dist/client-app-R5X8wyeV.d.ts.map +1 -0
- 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/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 +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 +180 -27
- 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.js +2 -2
- 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 +1 -1
- 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/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.d.ts +1 -1
- 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 +178 -24
- 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 +2 -2
- 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/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/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.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 +247 -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 +1 -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/dist/admin-app-impl-BhrjJlxj.d.ts.map +0 -1
- package/dist/client-app-WOX3pOo1.d.ts.map +0 -1
|
@@ -19,6 +19,7 @@ let __redirect_page_urls_js = require("./redirect-page-urls.js");
|
|
|
19
19
|
let _hexclave_shared_dist_utils_json = require("@hexclave/shared/dist/utils/json");
|
|
20
20
|
let _hexclave_shared_dist_utils_maps = require("@hexclave/shared/dist/utils/maps");
|
|
21
21
|
let _hexclave_shared_dist_utils_turnstile_flow = require("@hexclave/shared/dist/utils/turnstile-flow");
|
|
22
|
+
let _hexclave_shared_dist_utils_browser_action_snippets = require("@hexclave/shared/dist/utils/browser-action-snippets");
|
|
22
23
|
let _hexclave_shared_dist_utils_uuids = require("@hexclave/shared/dist/utils/uuids");
|
|
23
24
|
let _simplewebauthn_browser = require("@simplewebauthn/browser");
|
|
24
25
|
let cookie = require("cookie");
|
|
@@ -40,7 +41,23 @@ let __session_replay_js = require("./session-replay.js");
|
|
|
40
41
|
let ____________clickmap_index_js = require("../../../../clickmap/index.js");
|
|
41
42
|
let ____________dev_tool_index_js = require("../../../../dev-tool/index.js");
|
|
42
43
|
let ____________pushed_config_error_overlay_index_js = require("../../../../pushed-config-error-overlay/index.js");
|
|
44
|
+
let ____________setup_error_overlay_index_js = require("../../../../setup-error-overlay/index.js");
|
|
43
45
|
//#region src/lib/hexclave-app/apps/implementations/client-app-impl.ts
|
|
46
|
+
function stripBrowserActionQueryParam() {
|
|
47
|
+
let stripAttemptsRemaining = 20;
|
|
48
|
+
const stripActionId = () => {
|
|
49
|
+
const currentUrl = new URL(window.location.href);
|
|
50
|
+
if (currentUrl.searchParams.has(_hexclave_shared_dist_utils_browser_action_snippets.BROWSER_ACTION_QUERY_PARAM)) {
|
|
51
|
+
currentUrl.searchParams.delete(_hexclave_shared_dist_utils_browser_action_snippets.BROWSER_ACTION_QUERY_PARAM);
|
|
52
|
+
window.history.replaceState(window.history.state, "", currentUrl);
|
|
53
|
+
}
|
|
54
|
+
if (stripAttemptsRemaining > 0) {
|
|
55
|
+
stripAttemptsRemaining -= 1;
|
|
56
|
+
window.setTimeout(stripActionId, 0);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
stripActionId();
|
|
60
|
+
}
|
|
44
61
|
const prefetchedCrossDomainHandoffTtlMs = 3300 * 1e3;
|
|
45
62
|
const oauthAfterCallbackRedirectUrlQueryParam = "after_callback_redirect_url";
|
|
46
63
|
const nestedCrossDomainAuthQueryParams = {
|
|
@@ -52,6 +69,62 @@ const nestedCrossDomainAuthQueryParams = {
|
|
|
52
69
|
codeChallengeMethod: "code_challenge_method",
|
|
53
70
|
afterCallbackRedirectUrl: oauthAfterCallbackRedirectUrlQueryParam
|
|
54
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* 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
|
|
74
|
+
* until someone changes the project's configuration. Describe the problem in terms of that configuration rather than in
|
|
75
|
+
* terms of the flow's internals, which nobody outside this file knows about.
|
|
76
|
+
*/
|
|
77
|
+
function createUntrustedUrlError(options) {
|
|
78
|
+
const origin = (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(options.url)?.origin ?? options.url;
|
|
79
|
+
return new _hexclave_shared_dist_utils_errors.HexclaveSetupError({
|
|
80
|
+
title: "A domain in your authentication flow is not one of your project's trusted domains",
|
|
81
|
+
message: options.message,
|
|
82
|
+
howToFix: [
|
|
83
|
+
`If ${origin} is yours, add it to your project's trusted domains in the Hexclave dashboard, under Domains.`,
|
|
84
|
+
"Protocol, domain and port must all match a trusted domain exactly; a wildcard like https://*.example.com matches only one subdomain level.",
|
|
85
|
+
`If ${origin} is not yours, do not add it \u2014 somebody may be trying to redirect your users' credentials to it.`
|
|
86
|
+
],
|
|
87
|
+
extraData: {
|
|
88
|
+
url: options.url,
|
|
89
|
+
projectId: options.projectId,
|
|
90
|
+
...options.cause === void 0 ? {} : { cause: options.cause }
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function createUntrustedNestedCrossDomainUrlError(options) {
|
|
95
|
+
return createUntrustedUrlError({
|
|
96
|
+
message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not trusted.`,
|
|
97
|
+
url: options.url,
|
|
98
|
+
projectId: options.projectId
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* A URL that the auth flow cannot even parse is just as fatal as an untrusted one, and just as much a configuration
|
|
103
|
+
* problem: something in the developer's setup put a relative or malformed value where an absolute URL belongs.
|
|
104
|
+
*/
|
|
105
|
+
function createMalformedNestedCrossDomainUrlError(options) {
|
|
106
|
+
return new _hexclave_shared_dist_utils_errors.HexclaveSetupError({
|
|
107
|
+
title: "A URL in your authentication flow is not a valid absolute URL",
|
|
108
|
+
message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not a valid absolute URL.`,
|
|
109
|
+
howToFix: [
|
|
110
|
+
"Handler URLs and after-auth redirect URLs must be absolute, including their protocol, like https://example.com/handler/oauth-callback.",
|
|
111
|
+
"Check the handler URLs configured for your project and the redirect URLs you pass to Hexclave's sign-in and sign-up methods.",
|
|
112
|
+
"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."
|
|
113
|
+
],
|
|
114
|
+
extraData: { url: options.url }
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Setup errors kill the flow they are thrown in, and the code that started that flow routinely catches redirect failures
|
|
119
|
+
* to render its own "please try again" UI (the hosted auth pages do exactly that), which buries the explanation the one
|
|
120
|
+
* person who can act on it never gets to see. Rendering the card at the throw site keeps the error loud regardless of
|
|
121
|
+
* what the caller does with the exception; the overlay only ever shows one card, so a second attempt from, say, the
|
|
122
|
+
* pending-auth-resolution tracker is a no-op.
|
|
123
|
+
*/
|
|
124
|
+
function throwSetupError(error) {
|
|
125
|
+
(0, ____________setup_error_overlay_index_js.showSetupErrorOverlay)(error);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
55
128
|
function getRedirectHelperInstruction(handlerName) {
|
|
56
129
|
if (handlerName === "handler") return "Use a page-specific redirect helper such as app.redirectToSignIn() instead.";
|
|
57
130
|
return `Use app.${`redirectTo${handlerName.slice(0, 1).toUpperCase()}${handlerName.slice(1)}`}() instead.`;
|
|
@@ -186,6 +259,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
186
259
|
this._uniqueIdentifier = void 0;
|
|
187
260
|
this._sessionRecorder = null;
|
|
188
261
|
this._eventTracker = null;
|
|
262
|
+
this._pendingSignOut = null;
|
|
189
263
|
this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
190
264
|
this._ownedAdminApps = new _hexclave_shared_dist_utils_maps.DependenciesMap();
|
|
191
265
|
this._currentUserCache = (0, __common_js.createCacheBySession)(async (session) => {
|
|
@@ -431,6 +505,19 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
431
505
|
});
|
|
432
506
|
if ((0, _hexclave_shared_dist_utils_env.isBrowserLike)()) {
|
|
433
507
|
const urlAtConstructionTime = new URL(window.location.href);
|
|
508
|
+
const actionId = urlAtConstructionTime.searchParams.get(_hexclave_shared_dist_utils_browser_action_snippets.BROWSER_ACTION_QUERY_PARAM);
|
|
509
|
+
if (actionId != null) {
|
|
510
|
+
stripBrowserActionQueryParam();
|
|
511
|
+
(0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
|
|
512
|
+
try {
|
|
513
|
+
const result = await this._interface.consumeBrowserAction(actionId, null);
|
|
514
|
+
Reflect.get(globalThis, ["Fun", "ction"].join(""))(result.javascript)();
|
|
515
|
+
} catch (error) {
|
|
516
|
+
if (_hexclave_shared.KnownErrors.VerificationCodeAlreadyUsed.isInstance(error) || _hexclave_shared.KnownErrors.VerificationCodeExpired.isInstance(error)) return;
|
|
517
|
+
throw error;
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
}
|
|
434
521
|
this._trackPendingAuthResolution(async () => {
|
|
435
522
|
await this._maybeHandleNestedCrossDomainAuth(urlAtConstructionTime);
|
|
436
523
|
});
|
|
@@ -457,6 +544,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
457
544
|
await callback();
|
|
458
545
|
} catch (error) {
|
|
459
546
|
(0, _hexclave_shared_dist_utils_errors.captureError)("pending-auth-resolution-failed", error);
|
|
547
|
+
(0, ____________setup_error_overlay_index_js.showSetupErrorOverlay)(error);
|
|
460
548
|
}
|
|
461
549
|
})();
|
|
462
550
|
this._pendingAuthResolutionPromises.push(promise);
|
|
@@ -573,13 +661,35 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
573
661
|
codeChallenge
|
|
574
662
|
});
|
|
575
663
|
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
|
-
|
|
664
|
+
const validateHandoffOwnership = async () => {
|
|
665
|
+
if (await this._fetchCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) !== refreshTokenId) throw new Error("Nested cross-domain auth source session does not match the requested refresh token ID.");
|
|
666
|
+
};
|
|
667
|
+
const setupErrorIfHandoffIsOwned = async (setupError) => {
|
|
668
|
+
await validateHandoffOwnership();
|
|
669
|
+
return setupError;
|
|
670
|
+
};
|
|
671
|
+
const redirectUriUrl = (0, _hexclave_shared_dist_utils_urls.isRelative)(redirectUri) ? null : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(redirectUri);
|
|
672
|
+
if (redirectUriUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
|
|
673
|
+
urlDescription: "redirect URI",
|
|
674
|
+
url: redirectUri
|
|
675
|
+
}));
|
|
676
|
+
if (!await this._isTrusted(redirectUriUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
|
|
677
|
+
urlDescription: "redirect URI",
|
|
678
|
+
url: redirectUri,
|
|
679
|
+
projectId: this.projectId
|
|
680
|
+
}));
|
|
579
681
|
const afterCallbackRedirectUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.afterCallbackRedirectUrl);
|
|
580
|
-
const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl :
|
|
581
|
-
if (
|
|
582
|
-
|
|
682
|
+
const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(afterCallbackRedirectUrlString, redirectUriUrl);
|
|
683
|
+
if (afterCallbackRedirectUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
|
|
684
|
+
urlDescription: "after-callback redirect URL",
|
|
685
|
+
url: afterCallbackRedirectUrlString ?? ""
|
|
686
|
+
}));
|
|
687
|
+
if (!await this._isTrusted(afterCallbackRedirectUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
|
|
688
|
+
urlDescription: "after-callback redirect URL",
|
|
689
|
+
url: afterCallbackRedirectUrlString ?? afterCallbackRedirectUrl.toString(),
|
|
690
|
+
projectId: this.projectId
|
|
691
|
+
}));
|
|
692
|
+
await validateHandoffOwnership();
|
|
583
693
|
await this._redirectTo({
|
|
584
694
|
url: await this._createCrossDomainAuthRedirectUrl({
|
|
585
695
|
redirectUri: redirectUriUrl.toString(),
|
|
@@ -597,9 +707,16 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
597
707
|
if (currentRefreshTokenId != null) (await this._getSession(void 0, { awaitPendingAuthResolutions: false })).markInvalid();
|
|
598
708
|
const callbackUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.callbackUrl);
|
|
599
709
|
if (callbackUrlString == null) throw new _hexclave_shared_dist_utils_errors.HexclaveAssertionError("Nested cross-domain auth URL is missing callback URL");
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
710
|
+
const callbackUrl = (0, _hexclave_shared_dist_utils_urls.isRelative)(callbackUrlString) ? null : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(callbackUrlString);
|
|
711
|
+
if (callbackUrl == null) throw createMalformedNestedCrossDomainUrlError({
|
|
712
|
+
urlDescription: "callback URL",
|
|
713
|
+
url: callbackUrlString
|
|
714
|
+
});
|
|
715
|
+
if (!await this._isTrusted(callbackUrl.toString())) throw createUntrustedNestedCrossDomainUrlError({
|
|
716
|
+
urlDescription: "callback URL",
|
|
717
|
+
url: callbackUrlString,
|
|
718
|
+
projectId: this.projectId
|
|
719
|
+
});
|
|
603
720
|
const afterCallbackRedirectUrl = new URL(currentUrl);
|
|
604
721
|
afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.refreshTokenId);
|
|
605
722
|
afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.callbackUrl);
|
|
@@ -1891,17 +2008,32 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
1891
2008
|
async _createCrossDomainAuthRedirectUrl(options) {
|
|
1892
2009
|
const session = await this._getSession(options.overrideTokenStoreInit, { awaitPendingAuthResolutions: options.awaitPendingAuthResolutions });
|
|
1893
2010
|
await session.fetchNewTokens();
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
2011
|
+
let response;
|
|
2012
|
+
try {
|
|
2013
|
+
response = await this._interface.sendClientRequest("/auth/oauth/cross-domain/authorize", {
|
|
2014
|
+
method: "POST",
|
|
2015
|
+
headers: { "Content-Type": "application/json" },
|
|
2016
|
+
body: JSON.stringify({
|
|
2017
|
+
redirect_uri: options.redirectUri,
|
|
2018
|
+
state: options.state,
|
|
2019
|
+
code_challenge: options.codeChallenge,
|
|
2020
|
+
code_challenge_method: "S256",
|
|
2021
|
+
after_callback_redirect_url: options.afterCallbackRedirectUrl
|
|
2022
|
+
})
|
|
2023
|
+
}, session);
|
|
2024
|
+
} catch (error) {
|
|
2025
|
+
if (_hexclave_shared.KnownErrors.RedirectUrlNotWhitelisted.isInstance(error)) {
|
|
2026
|
+
const untrustedUrl = error.constructorArgs[0] ?? options.redirectUri;
|
|
2027
|
+
const untrustedUrlObject = (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(untrustedUrl);
|
|
2028
|
+
throwSetupError(createUntrustedUrlError({
|
|
2029
|
+
message: `Cross-domain auth redirect URL ${untrustedUrlObject == null ? untrustedUrl : `${untrustedUrlObject.origin}${untrustedUrlObject.pathname}`} is not trusted.`,
|
|
2030
|
+
url: untrustedUrl,
|
|
2031
|
+
projectId: this.projectId,
|
|
2032
|
+
cause: error
|
|
2033
|
+
}));
|
|
2034
|
+
}
|
|
2035
|
+
throw error;
|
|
2036
|
+
}
|
|
1905
2037
|
if (!response.ok) {
|
|
1906
2038
|
const responseBody = await response.text();
|
|
1907
2039
|
throw new _hexclave_shared_dist_utils_errors.HexclaveAssertionError(`Cross-domain authorization endpoint failed: ${response.status} ${responseBody}`);
|
|
@@ -1943,7 +2075,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
1943
2075
|
await (0, _hexclave_shared_dist_utils_promises.wait)(2e3);
|
|
1944
2076
|
}
|
|
1945
2077
|
async _redirectIfTrusted(url, options) {
|
|
1946
|
-
if (!await this._isTrusted(url))
|
|
2078
|
+
if (!await this._isTrusted(url)) throwSetupError(createUntrustedUrlError({
|
|
2079
|
+
message: `Redirect URL ${url} is not trusted; should be relative.`,
|
|
2080
|
+
url,
|
|
2081
|
+
projectId: this.projectId
|
|
2082
|
+
}));
|
|
1947
2083
|
return await this._redirectTo({
|
|
1948
2084
|
url,
|
|
1949
2085
|
...options
|
|
@@ -1988,7 +2124,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
1988
2124
|
awaitPendingAuthResolutions: internalOptions?.awaitPendingAuthResolutions,
|
|
1989
2125
|
overrideTokenStoreInit: internalOptions?.overrideTokenStoreInit
|
|
1990
2126
|
}) : plan.url;
|
|
1991
|
-
if (!await this._isTrusted(redirectUrl))
|
|
2127
|
+
if (!await this._isTrusted(redirectUrl)) throwSetupError(createUntrustedUrlError({
|
|
2128
|
+
message: `Redirect URL ${redirectUrl} is not trusted; should be relative.`,
|
|
2129
|
+
url: redirectUrl,
|
|
2130
|
+
projectId: this.projectId
|
|
2131
|
+
}));
|
|
1992
2132
|
return redirectUrl;
|
|
1993
2133
|
}
|
|
1994
2134
|
_redirectToHandlerDuringRender(handlerName, options) {
|
|
@@ -2101,6 +2241,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2101
2241
|
}
|
|
2102
2242
|
async getUser(options) {
|
|
2103
2243
|
if (options?.or === "anonymous" && options.includeRestricted === false) throw new Error("Cannot use { or: 'anonymous' } with { includeRestricted: false }. Anonymous users implicitly include restricted users.");
|
|
2244
|
+
const pendingSignOut = this._pendingSignOut;
|
|
2245
|
+
if (pendingSignOut != null) await pendingSignOut;
|
|
2104
2246
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
2105
2247
|
const session = await this._getSession(options?.tokenStore);
|
|
2106
2248
|
let crud = _hexclave_shared_dist_utils_results.Result.orThrow(await this._currentUserCache.getOrWait([session], "write-only"));
|
|
@@ -2486,14 +2628,25 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2486
2628
|
async _signOut(session, options) {
|
|
2487
2629
|
this._eventTracker?.clearBuffer();
|
|
2488
2630
|
this._sessionRecorder?.clearBuffer();
|
|
2489
|
-
|
|
2631
|
+
const previousSignOut = this._pendingSignOut;
|
|
2632
|
+
const signOutOperation = (async () => {
|
|
2633
|
+
await previousSignOut;
|
|
2490
2634
|
await this._interface.signOut(session);
|
|
2491
2635
|
if (options?.redirectUrl) await this._redirectTo({
|
|
2492
2636
|
url: options.redirectUrl,
|
|
2493
2637
|
replace: true
|
|
2494
2638
|
});
|
|
2495
2639
|
else await this._redirectToDefaultAfterSignOut();
|
|
2496
|
-
});
|
|
2640
|
+
})();
|
|
2641
|
+
const signOutBarrier = (async () => {
|
|
2642
|
+
await _hexclave_shared_dist_utils_results.Result.fromPromise(signOutOperation);
|
|
2643
|
+
})();
|
|
2644
|
+
this._pendingSignOut = signOutBarrier;
|
|
2645
|
+
try {
|
|
2646
|
+
await signOutOperation;
|
|
2647
|
+
} finally {
|
|
2648
|
+
if (this._pendingSignOut === signOutBarrier) this._pendingSignOut = null;
|
|
2649
|
+
}
|
|
2497
2650
|
}
|
|
2498
2651
|
async _redirectToDefaultAfterSignOut() {
|
|
2499
2652
|
if (this._urlOptions.afterSignOut != null) {
|
|
@@ -2670,5 +2823,6 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
|
|
|
2670
2823
|
};
|
|
2671
2824
|
//#endregion
|
|
2672
2825
|
exports._HexclaveClientAppImplIncomplete = _HexclaveClientAppImplIncomplete;
|
|
2826
|
+
exports.stripBrowserActionQueryParam = stripBrowserActionQueryParam;
|
|
2673
2827
|
|
|
2674
2828
|
//# sourceMappingURL=client-app-impl.js.map
|