@hexclave/next 1.0.75 → 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.
Files changed (114) hide show
  1. package/dist/{admin-app-impl-sTQD2d-3.d.ts → admin-app-impl-CsH-gVGz.d.ts} +7 -7
  2. package/dist/{admin-app-impl-sTQD2d-3.d.ts.map → admin-app-impl-CsH-gVGz.d.ts.map} +1 -1
  3. package/dist/components/api-key-dialogs.d.ts +1 -1
  4. package/dist/components/elements/sidebar-layout.js +1 -1
  5. package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
  6. package/dist/dev-tool/dev-tool-core.js +2 -2
  7. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  8. package/dist/dev-tool/index.d.ts.map +1 -1
  9. package/dist/dev-tool/index.js +2 -8
  10. package/dist/dev-tool/index.js.map +1 -1
  11. package/dist/esm/components/api-key-dialogs.d.ts +1 -1
  12. package/dist/esm/components/elements/sidebar-layout.js +1 -1
  13. package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
  14. package/dist/esm/dev-tool/dev-tool-core.js +1 -1
  15. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  16. package/dist/esm/dev-tool/index.d.ts.map +1 -1
  17. package/dist/esm/dev-tool/index.js +2 -8
  18. package/dist/esm/dev-tool/index.js.map +1 -1
  19. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  20. package/dist/esm/in-page-ui/dev-environment.d.ts +5 -0
  21. package/dist/esm/in-page-ui/dev-environment.d.ts.map +1 -0
  22. package/dist/esm/in-page-ui/dev-environment.js +18 -0
  23. package/dist/esm/in-page-ui/dev-environment.js.map +1 -0
  24. package/dist/esm/in-page-ui/issue-card.d.ts +52 -0
  25. package/dist/esm/in-page-ui/issue-card.d.ts.map +1 -0
  26. package/dist/esm/in-page-ui/issue-card.js +392 -0
  27. package/dist/esm/in-page-ui/issue-card.js.map +1 -0
  28. package/dist/esm/in-page-ui/issue-card.test.d.ts +1 -0
  29. package/dist/esm/in-page-ui/issue-card.test.js +60 -0
  30. package/dist/esm/in-page-ui/issue-card.test.js.map +1 -0
  31. package/dist/esm/in-page-ui/logo.d.ts +5 -0
  32. package/dist/esm/in-page-ui/logo.d.ts.map +1 -0
  33. package/dist/esm/in-page-ui/logo.js +6 -0
  34. package/dist/esm/in-page-ui/logo.js.map +1 -0
  35. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +4 -4
  36. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  37. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +140 -15
  38. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  39. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +2 -2
  40. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  41. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +95 -12
  42. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  43. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
  44. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +1 -0
  45. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -1
  46. package/dist/esm/pushed-config-error-overlay/index.d.ts.map +1 -1
  47. package/dist/esm/pushed-config-error-overlay/index.js +42 -343
  48. package/dist/esm/pushed-config-error-overlay/index.js.map +1 -1
  49. package/dist/esm/setup-error-overlay/index.d.ts +16 -0
  50. package/dist/esm/setup-error-overlay/index.d.ts.map +1 -0
  51. package/dist/esm/setup-error-overlay/index.js +106 -0
  52. package/dist/esm/setup-error-overlay/index.js.map +1 -0
  53. package/dist/esm/setup-error-overlay/index.test.d.ts +1 -0
  54. package/dist/esm/setup-error-overlay/index.test.js +125 -0
  55. package/dist/esm/setup-error-overlay/index.test.js.map +1 -0
  56. package/dist/generated/quetzal-translations.d.ts +1 -1
  57. package/dist/{hexclave-provider-BKxi3Vy-.d.ts → hexclave-provider-BA97jMlx.d.ts} +2 -2
  58. package/dist/{hexclave-provider-BKxi3Vy-.d.ts.map → hexclave-provider-BA97jMlx.d.ts.map} +1 -1
  59. package/dist/in-page-ui/dev-environment.d.ts +5 -0
  60. package/dist/in-page-ui/dev-environment.d.ts.map +1 -0
  61. package/dist/in-page-ui/dev-environment.js +19 -0
  62. package/dist/in-page-ui/dev-environment.js.map +1 -0
  63. package/dist/in-page-ui/issue-card.d.ts +52 -0
  64. package/dist/in-page-ui/issue-card.d.ts.map +1 -0
  65. package/dist/in-page-ui/issue-card.js +397 -0
  66. package/dist/in-page-ui/issue-card.js.map +1 -0
  67. package/dist/in-page-ui/issue-card.test.d.ts +1 -0
  68. package/dist/in-page-ui/issue-card.test.js +59 -0
  69. package/dist/in-page-ui/issue-card.test.js.map +1 -0
  70. package/dist/in-page-ui/logo.d.ts +5 -0
  71. package/dist/in-page-ui/logo.d.ts.map +1 -0
  72. package/dist/in-page-ui/logo.js +7 -0
  73. package/dist/in-page-ui/logo.js.map +1 -0
  74. package/dist/index.d.ts +1 -1
  75. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  76. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +140 -15
  77. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  78. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
  79. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +94 -11
  80. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  81. package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
  82. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  83. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +1 -0
  84. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -1
  85. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  86. package/dist/providers/hexclave-provider.d.ts +1 -1
  87. package/dist/providers/translation-provider.d.ts +1 -1
  88. package/dist/pushed-config-error-overlay/index.d.ts.map +1 -1
  89. package/dist/pushed-config-error-overlay/index.js +41 -342
  90. package/dist/pushed-config-error-overlay/index.js.map +1 -1
  91. package/dist/{quetzal-translations-XeH3zQ9l.d.ts → quetzal-translations-CK45_4Dm.d.ts} +3 -3
  92. package/dist/{quetzal-translations-XeH3zQ9l.d.ts.map → quetzal-translations-CK45_4Dm.d.ts.map} +1 -1
  93. package/dist/setup-error-overlay/index.d.ts +16 -0
  94. package/dist/setup-error-overlay/index.d.ts.map +1 -0
  95. package/dist/setup-error-overlay/index.js +108 -0
  96. package/dist/setup-error-overlay/index.js.map +1 -0
  97. package/dist/setup-error-overlay/index.test.d.ts +1 -0
  98. package/dist/setup-error-overlay/index.test.js +124 -0
  99. package/dist/setup-error-overlay/index.test.js.map +1 -0
  100. package/dist/{translation-provider-WOaZXqAz.d.ts → translation-provider-DQ3BJepJ.d.ts} +2 -2
  101. package/dist/{translation-provider-WOaZXqAz.d.ts.map → translation-provider-DQ3BJepJ.d.ts.map} +1 -1
  102. package/package.json +4 -4
  103. package/src/dev-tool/dev-tool-core.ts +1 -4
  104. package/src/dev-tool/index.ts +4 -15
  105. package/src/in-page-ui/dev-environment.ts +33 -0
  106. package/src/in-page-ui/issue-card.test.ts +67 -0
  107. package/src/in-page-ui/issue-card.ts +500 -0
  108. package/src/in-page-ui/logo.ts +8 -0
  109. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +158 -0
  110. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +125 -17
  111. package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.test.ts +1 -0
  112. package/src/pushed-config-error-overlay/index.ts +45 -386
  113. package/src/setup-error-overlay/index.test.ts +133 -0
  114. package/src/setup-error-overlay/index.ts +150 -0
@@ -47,6 +47,7 @@ let __session_replay_js = require("./session-replay.js");
47
47
  let ____________clickmap_index_js = require("../../../../clickmap/index.js");
48
48
  let ____________dev_tool_index_js = require("../../../../dev-tool/index.js");
49
49
  let ____________pushed_config_error_overlay_index_js = require("../../../../pushed-config-error-overlay/index.js");
50
+ let ____________setup_error_overlay_index_js = require("../../../../setup-error-overlay/index.js");
50
51
  let _hexclave_sc = require("@hexclave/sc");
51
52
  _hexclave_sc = require_rolldown_runtime.__toESM(_hexclave_sc);
52
53
  //#region src/lib/hexclave-app/apps/implementations/client-app-impl.ts
@@ -64,6 +65,50 @@ const nestedCrossDomainAuthQueryParams = {
64
65
  codeChallengeMethod: "code_challenge_method",
65
66
  afterCallbackRedirectUrl: oauthAfterCallbackRedirectUrlQueryParam
66
67
  };
68
+ /**
69
+ * 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
70
+ * until someone changes the project's configuration. Describe the problem in terms of that configuration rather than in
71
+ * terms of the flow's internals, which nobody outside this file knows about.
72
+ */
73
+ function createUntrustedUrlError(options) {
74
+ const origin = (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(options.url)?.origin ?? options.url;
75
+ return new _hexclave_shared_dist_utils_errors.HexclaveSetupError({
76
+ title: "A domain in your authentication flow is not one of your project's trusted domains",
77
+ message: options.message,
78
+ howToFix: [
79
+ `If ${origin} is yours, add it to your project's trusted domains in the Hexclave dashboard, under Domains.`,
80
+ "Protocol, domain and port must all match a trusted domain exactly; a wildcard like https://*.example.com matches only one subdomain level.",
81
+ `If ${origin} is not yours, do not add it \u2014 somebody may be trying to redirect your users' credentials to it.`
82
+ ],
83
+ extraData: {
84
+ url: options.url,
85
+ projectId: options.projectId
86
+ }
87
+ });
88
+ }
89
+ function createUntrustedNestedCrossDomainUrlError(options) {
90
+ return createUntrustedUrlError({
91
+ message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not trusted.`,
92
+ url: options.url,
93
+ projectId: options.projectId
94
+ });
95
+ }
96
+ /**
97
+ * A URL that the auth flow cannot even parse is just as fatal as an untrusted one, and just as much a configuration
98
+ * problem: something in the developer's setup put a relative or malformed value where an absolute URL belongs.
99
+ */
100
+ function createMalformedNestedCrossDomainUrlError(options) {
101
+ return new _hexclave_shared_dist_utils_errors.HexclaveSetupError({
102
+ title: "A URL in your authentication flow is not a valid absolute URL",
103
+ message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not a valid absolute URL.`,
104
+ howToFix: [
105
+ "Handler URLs and after-auth redirect URLs must be absolute, including their protocol, like https://example.com/handler/oauth-callback.",
106
+ "Check the handler URLs configured for your project and the redirect URLs you pass to Hexclave's sign-in and sign-up methods.",
107
+ "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."
108
+ ],
109
+ extraData: { url: options.url }
110
+ });
111
+ }
67
112
  function getRedirectHelperInstruction(handlerName) {
68
113
  if (handlerName === "handler") return "Use a page-specific redirect helper such as app.redirectToSignIn() instead.";
69
114
  return `Use app.${`redirectTo${handlerName.slice(0, 1).toUpperCase()}${handlerName.slice(1)}`}() instead.`;
@@ -496,6 +541,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
496
541
  await callback();
497
542
  } catch (error) {
498
543
  (0, _hexclave_shared_dist_utils_errors.captureError)("pending-auth-resolution-failed", error);
544
+ (0, ____________setup_error_overlay_index_js.showSetupErrorOverlay)(error);
499
545
  }
500
546
  })();
501
547
  this._pendingAuthResolutionPromises.push(promise);
@@ -616,13 +662,35 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
616
662
  codeChallenge
617
663
  });
618
664
  if ((currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.codeChallengeMethod) ?? "S256") !== "S256") throw new _hexclave_shared_dist_utils_errors.HexclaveAssertionError("Nested cross-domain auth only supports S256 PKCE");
619
- if ((0, _hexclave_shared_dist_utils_urls.isRelative)(redirectUri)) throw new Error("Nested cross-domain auth redirect URI must be absolute.");
620
- const redirectUriUrl = new URL(redirectUri);
621
- if (!await this._isTrusted(redirectUriUrl.toString())) throw new Error(`Nested cross-domain auth redirect URI ${redirectUri} is not trusted.`);
665
+ const validateHandoffOwnership = async () => {
666
+ if (await this._fetchCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) !== refreshTokenId) throw new Error("Nested cross-domain auth source session does not match the requested refresh token ID.");
667
+ };
668
+ const setupErrorIfHandoffIsOwned = async (setupError) => {
669
+ await validateHandoffOwnership();
670
+ return setupError;
671
+ };
672
+ const redirectUriUrl = (0, _hexclave_shared_dist_utils_urls.isRelative)(redirectUri) ? null : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(redirectUri);
673
+ if (redirectUriUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
674
+ urlDescription: "redirect URI",
675
+ url: redirectUri
676
+ }));
677
+ if (!await this._isTrusted(redirectUriUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
678
+ urlDescription: "redirect URI",
679
+ url: redirectUri,
680
+ projectId: this.projectId
681
+ }));
622
682
  const afterCallbackRedirectUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.afterCallbackRedirectUrl);
623
- const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl : new URL(afterCallbackRedirectUrlString, redirectUriUrl);
624
- if (!await this._isTrusted(afterCallbackRedirectUrl.toString())) throw new Error(`Nested cross-domain auth after-callback redirect URL ${afterCallbackRedirectUrlString} is not trusted.`);
625
- if (await this._fetchCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) !== refreshTokenId) throw new Error("Nested cross-domain auth source session does not match the requested refresh token ID.");
683
+ const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(afterCallbackRedirectUrlString, redirectUriUrl);
684
+ if (afterCallbackRedirectUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
685
+ urlDescription: "after-callback redirect URL",
686
+ url: afterCallbackRedirectUrlString ?? ""
687
+ }));
688
+ if (!await this._isTrusted(afterCallbackRedirectUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
689
+ urlDescription: "after-callback redirect URL",
690
+ url: afterCallbackRedirectUrlString ?? afterCallbackRedirectUrl.toString(),
691
+ projectId: this.projectId
692
+ }));
693
+ await validateHandoffOwnership();
626
694
  await this._redirectTo({
627
695
  url: await this._createCrossDomainAuthRedirectUrl({
628
696
  redirectUri: redirectUriUrl.toString(),
@@ -640,9 +708,16 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
640
708
  if (currentRefreshTokenId != null) (await this._getSession(void 0, { awaitPendingAuthResolutions: false })).markInvalid();
641
709
  const callbackUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.callbackUrl);
642
710
  if (callbackUrlString == null) throw new _hexclave_shared_dist_utils_errors.HexclaveAssertionError("Nested cross-domain auth URL is missing callback URL");
643
- if ((0, _hexclave_shared_dist_utils_urls.isRelative)(callbackUrlString)) throw new Error("Nested cross-domain auth callback URL must be absolute.");
644
- const callbackUrl = new URL(callbackUrlString);
645
- if (!await this._isTrusted(callbackUrl.toString())) throw new Error(`Nested cross-domain auth callback URL ${callbackUrlString} is not trusted.`);
711
+ const callbackUrl = (0, _hexclave_shared_dist_utils_urls.isRelative)(callbackUrlString) ? null : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(callbackUrlString);
712
+ if (callbackUrl == null) throw createMalformedNestedCrossDomainUrlError({
713
+ urlDescription: "callback URL",
714
+ url: callbackUrlString
715
+ });
716
+ if (!await this._isTrusted(callbackUrl.toString())) throw createUntrustedNestedCrossDomainUrlError({
717
+ urlDescription: "callback URL",
718
+ url: callbackUrlString,
719
+ projectId: this.projectId
720
+ });
646
721
  const afterCallbackRedirectUrl = new URL(currentUrl);
647
722
  afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.refreshTokenId);
648
723
  afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.callbackUrl);
@@ -2203,7 +2278,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2203
2278
  } else return (to) => {};
2204
2279
  }
2205
2280
  async _redirectIfTrusted(url, options) {
2206
- if (!await this._isTrusted(url)) throw new Error(`Redirect URL ${url} is not trusted; should be relative.`);
2281
+ if (!await this._isTrusted(url)) throw createUntrustedUrlError({
2282
+ message: `Redirect URL ${url} is not trusted; should be relative.`,
2283
+ url,
2284
+ projectId: this.projectId
2285
+ });
2207
2286
  return await this._redirectTo({
2208
2287
  url,
2209
2288
  ...options
@@ -2248,7 +2327,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2248
2327
  awaitPendingAuthResolutions: internalOptions?.awaitPendingAuthResolutions,
2249
2328
  overrideTokenStoreInit: internalOptions?.overrideTokenStoreInit
2250
2329
  }) : plan.url;
2251
- if (!await this._isTrusted(redirectUrl)) throw new Error(`Redirect URL ${redirectUrl} is not trusted; should be relative.`);
2330
+ if (!await this._isTrusted(redirectUrl)) throw createUntrustedUrlError({
2331
+ message: `Redirect URL ${redirectUrl} is not trusted; should be relative.`,
2332
+ url: redirectUrl,
2333
+ projectId: this.projectId
2334
+ });
2252
2335
  return redirectUrl;
2253
2336
  }
2254
2337
  _redirectToHandlerDuringRender(handlerName, options) {