@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.
Files changed (231) hide show
  1. package/dist/{admin-app-impl-sTQD2d-3.d.ts → admin-app-impl-CxDpE89P.d.ts} +12 -10
  2. package/dist/admin-app-impl-CxDpE89P.d.ts.map +1 -0
  3. package/dist/clickmap/clickmap-core.d.ts +1 -1
  4. package/dist/clickmap/index.d.ts +1 -1
  5. package/dist/{client-app-BCT5p_70.d.ts → client-app-wFodsYml.d.ts} +4 -1
  6. package/dist/client-app-wFodsYml.d.ts.map +1 -0
  7. package/dist/common-BK_sydxF.d.ts.map +1 -1
  8. package/dist/components/elements/sidebar-layout.d.ts.map +1 -1
  9. package/dist/components/elements/sidebar-layout.js +12 -2
  10. package/dist/components/elements/sidebar-layout.js.map +1 -1
  11. package/dist/components/selected-team-switcher.d.ts +1 -1
  12. package/dist/components/team-icon.d.ts +1 -1
  13. package/dist/components/team-switcher.d.ts +1 -1
  14. package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
  15. package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
  16. package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
  17. package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
  18. package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
  19. package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
  20. package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
  21. package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
  22. package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
  23. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  24. package/dist/components-page/hexclave-handler.d.ts +1 -1
  25. package/dist/components-page/team-invitation-cache.d.ts +5 -0
  26. package/dist/components-page/team-invitation-cache.d.ts.map +1 -0
  27. package/dist/components-page/team-invitation-cache.js +12 -0
  28. package/dist/components-page/team-invitation-cache.js.map +1 -0
  29. package/dist/components-page/team-invitation-cache.test.d.ts +1 -0
  30. package/dist/components-page/team-invitation-cache.test.js +23 -0
  31. package/dist/components-page/team-invitation-cache.test.js.map +1 -0
  32. package/dist/components-page/team-invitation.js +8 -7
  33. package/dist/components-page/team-invitation.js.map +1 -1
  34. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  35. package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
  36. package/dist/dev-tool/dev-tool-core.js +2 -2
  37. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  38. package/dist/dev-tool/index.d.ts +1 -1
  39. package/dist/dev-tool/index.d.ts.map +1 -1
  40. package/dist/dev-tool/index.js +2 -8
  41. package/dist/dev-tool/index.js.map +1 -1
  42. package/dist/esm/components/elements/sidebar-layout.d.ts.map +1 -1
  43. package/dist/esm/components/elements/sidebar-layout.js +12 -2
  44. package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
  45. package/dist/esm/components-page/team-invitation-cache.d.ts +5 -0
  46. package/dist/esm/components-page/team-invitation-cache.d.ts.map +1 -0
  47. package/dist/esm/components-page/team-invitation-cache.js +11 -0
  48. package/dist/esm/components-page/team-invitation-cache.js.map +1 -0
  49. package/dist/esm/components-page/team-invitation-cache.test.d.ts +1 -0
  50. package/dist/esm/components-page/team-invitation-cache.test.js +24 -0
  51. package/dist/esm/components-page/team-invitation-cache.test.js.map +1 -0
  52. package/dist/esm/components-page/team-invitation.d.ts.map +1 -1
  53. package/dist/esm/components-page/team-invitation.js +8 -7
  54. package/dist/esm/components-page/team-invitation.js.map +1 -1
  55. package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
  56. package/dist/esm/dev-tool/dev-tool-core.js +1 -1
  57. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  58. package/dist/esm/dev-tool/index.d.ts.map +1 -1
  59. package/dist/esm/dev-tool/index.js +2 -8
  60. package/dist/esm/dev-tool/index.js.map +1 -1
  61. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  62. package/dist/esm/in-page-ui/dev-environment.d.ts +5 -0
  63. package/dist/esm/in-page-ui/dev-environment.d.ts.map +1 -0
  64. package/dist/esm/in-page-ui/dev-environment.js +18 -0
  65. package/dist/esm/in-page-ui/dev-environment.js.map +1 -0
  66. package/dist/esm/in-page-ui/issue-card.d.ts +52 -0
  67. package/dist/esm/in-page-ui/issue-card.d.ts.map +1 -0
  68. package/dist/esm/in-page-ui/issue-card.js +392 -0
  69. package/dist/esm/in-page-ui/issue-card.js.map +1 -0
  70. package/dist/esm/in-page-ui/issue-card.test.d.ts +1 -0
  71. package/dist/esm/in-page-ui/issue-card.test.js +60 -0
  72. package/dist/esm/in-page-ui/issue-card.test.js.map +1 -0
  73. package/dist/esm/in-page-ui/logo.d.ts +5 -0
  74. package/dist/esm/in-page-ui/logo.d.ts.map +1 -0
  75. package/dist/esm/in-page-ui/logo.js +6 -0
  76. package/dist/esm/in-page-ui/logo.js.map +1 -0
  77. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +4 -4
  78. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  79. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +30 -1
  80. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -1
  81. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +140 -15
  82. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  83. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +5 -3
  84. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  85. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +184 -28
  86. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  87. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.d.ts +1 -0
  88. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js +83 -0
  89. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js.map +1 -0
  90. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.d.ts +1 -0
  91. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js +120 -0
  92. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js.map +1 -0
  93. package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -1
  94. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +4 -3
  95. package/dist/esm/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  96. package/dist/esm/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  97. package/dist/esm/lib/hexclave-app/apps/implementations/index.js +1 -1
  98. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +1 -0
  99. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -1
  100. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +2 -2
  101. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
  102. package/dist/esm/lib/hexclave-app/teams/index.d.ts +3 -0
  103. package/dist/esm/lib/hexclave-app/teams/index.d.ts.map +1 -1
  104. package/dist/esm/lib/hexclave-app/teams/index.js.map +1 -1
  105. package/dist/esm/pushed-config-error-overlay/index.d.ts.map +1 -1
  106. package/dist/esm/pushed-config-error-overlay/index.js +42 -343
  107. package/dist/esm/pushed-config-error-overlay/index.js.map +1 -1
  108. package/dist/esm/setup-error-overlay/index.d.ts +16 -0
  109. package/dist/esm/setup-error-overlay/index.d.ts.map +1 -0
  110. package/dist/esm/setup-error-overlay/index.js +106 -0
  111. package/dist/esm/setup-error-overlay/index.js.map +1 -0
  112. package/dist/esm/setup-error-overlay/index.test.d.ts +1 -0
  113. package/dist/esm/setup-error-overlay/index.test.js +125 -0
  114. package/dist/esm/setup-error-overlay/index.test.js.map +1 -0
  115. package/dist/esm/utils/monkey-patch.d.ts +7 -0
  116. package/dist/esm/utils/monkey-patch.d.ts.map +1 -0
  117. package/dist/esm/utils/monkey-patch.js +20 -0
  118. package/dist/esm/utils/monkey-patch.js.map +1 -0
  119. package/dist/esm/utils/react.d.ts +17 -0
  120. package/dist/esm/utils/react.d.ts.map +1 -0
  121. package/dist/esm/utils/react.js +60 -0
  122. package/dist/esm/utils/react.js.map +1 -0
  123. package/dist/generated/quetzal-translations.d.ts +1 -1
  124. package/dist/{hexclave-provider-BKxi3Vy-.d.ts → hexclave-provider-CMz2mt4I.d.ts} +3 -3
  125. package/dist/{hexclave-provider-BKxi3Vy-.d.ts.map → hexclave-provider-CMz2mt4I.d.ts.map} +1 -1
  126. package/dist/{hooks-CUe5bc3s.d.ts → hooks-CUHt4Y9C.d.ts} +2 -2
  127. package/dist/{hooks-CUe5bc3s.d.ts.map → hooks-CUHt4Y9C.d.ts.map} +1 -1
  128. package/dist/in-page-ui/dev-environment.d.ts +5 -0
  129. package/dist/in-page-ui/dev-environment.d.ts.map +1 -0
  130. package/dist/in-page-ui/dev-environment.js +19 -0
  131. package/dist/in-page-ui/dev-environment.js.map +1 -0
  132. package/dist/in-page-ui/issue-card.d.ts +52 -0
  133. package/dist/in-page-ui/issue-card.d.ts.map +1 -0
  134. package/dist/in-page-ui/issue-card.js +397 -0
  135. package/dist/in-page-ui/issue-card.js.map +1 -0
  136. package/dist/in-page-ui/issue-card.test.d.ts +1 -0
  137. package/dist/in-page-ui/issue-card.test.js +59 -0
  138. package/dist/in-page-ui/issue-card.test.js.map +1 -0
  139. package/dist/in-page-ui/logo.d.ts +5 -0
  140. package/dist/in-page-ui/logo.d.ts.map +1 -0
  141. package/dist/in-page-ui/logo.js +7 -0
  142. package/dist/in-page-ui/logo.js.map +1 -0
  143. package/dist/{index-CvB7XacB.d.ts → index-fR0LkUK7.d.ts} +2 -2
  144. package/dist/{index-CvB7XacB.d.ts.map → index-fR0LkUK7.d.ts.map} +1 -1
  145. package/dist/index.d.ts +4 -4
  146. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  147. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +29 -0
  148. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -1
  149. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +140 -15
  150. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  151. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +2 -2
  152. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +182 -25
  153. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  154. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.d.ts +1 -0
  155. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js +82 -0
  156. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js.map +1 -0
  157. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.d.ts +1 -0
  158. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js +119 -0
  159. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js.map +1 -0
  160. package/dist/lib/hexclave-app/apps/implementations/common.js +4 -3
  161. package/dist/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  162. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  163. package/dist/lib/hexclave-app/apps/implementations/index.js +1 -1
  164. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +1 -0
  165. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -1
  166. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  167. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
  168. package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
  169. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
  170. package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
  171. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  172. package/dist/lib/hexclave-app/index.d.ts +1 -1
  173. package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
  174. package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
  175. package/dist/lib/hexclave-app/teams/index.js.map +1 -1
  176. package/dist/lib/hexclave-app/users/index.d.ts +1 -1
  177. package/dist/lib/hooks.d.ts +1 -1
  178. package/dist/providers/hexclave-context.d.ts +1 -1
  179. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  180. package/dist/providers/hexclave-provider.d.ts +1 -1
  181. package/dist/providers/translation-provider.d.ts +1 -1
  182. package/dist/pushed-config-error-overlay/index.d.ts +1 -1
  183. package/dist/pushed-config-error-overlay/index.d.ts.map +1 -1
  184. package/dist/pushed-config-error-overlay/index.js +41 -342
  185. package/dist/pushed-config-error-overlay/index.js.map +1 -1
  186. package/dist/{quetzal-translations-XeH3zQ9l.d.ts → quetzal-translations-B2jT2SWm.d.ts} +3 -3
  187. package/dist/{quetzal-translations-XeH3zQ9l.d.ts.map → quetzal-translations-B2jT2SWm.d.ts.map} +1 -1
  188. package/dist/setup-error-overlay/index.d.ts +16 -0
  189. package/dist/setup-error-overlay/index.d.ts.map +1 -0
  190. package/dist/setup-error-overlay/index.js +108 -0
  191. package/dist/setup-error-overlay/index.js.map +1 -0
  192. package/dist/setup-error-overlay/index.test.d.ts +1 -0
  193. package/dist/setup-error-overlay/index.test.js +124 -0
  194. package/dist/setup-error-overlay/index.test.js.map +1 -0
  195. package/dist/team-invitation-B5Ol7vdd.d.ts.map +1 -1
  196. package/dist/{translation-provider-WOaZXqAz.d.ts → translation-provider-6505O9P2.d.ts} +2 -2
  197. package/dist/{translation-provider-WOaZXqAz.d.ts.map → translation-provider-6505O9P2.d.ts.map} +1 -1
  198. package/dist/utils/monkey-patch.d.ts +7 -0
  199. package/dist/utils/monkey-patch.d.ts.map +1 -0
  200. package/dist/utils/monkey-patch.js +23 -0
  201. package/dist/utils/monkey-patch.js.map +1 -0
  202. package/dist/utils/react.d.ts +17 -0
  203. package/dist/utils/react.d.ts.map +1 -0
  204. package/dist/utils/react.js +63 -0
  205. package/dist/utils/react.js.map +1 -0
  206. package/package.json +4 -4
  207. package/src/components/elements/sidebar-layout.tsx +16 -1
  208. package/src/components-page/team-invitation-cache.test.ts +25 -0
  209. package/src/components-page/team-invitation-cache.ts +13 -0
  210. package/src/components-page/team-invitation.tsx +16 -7
  211. package/src/dev-tool/dev-tool-core.ts +1 -4
  212. package/src/dev-tool/index.ts +4 -15
  213. package/src/in-page-ui/dev-environment.ts +33 -0
  214. package/src/in-page-ui/issue-card.test.ts +67 -0
  215. package/src/in-page-ui/issue-card.ts +500 -0
  216. package/src/in-page-ui/logo.ts +8 -0
  217. package/src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts +38 -1
  218. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +157 -0
  219. package/src/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.ts +96 -0
  220. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +255 -37
  221. package/src/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.ts +146 -0
  222. package/src/lib/hexclave-app/apps/implementations/common.ts +2 -1
  223. package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.test.ts +1 -0
  224. package/src/lib/hexclave-app/teams/index.ts +3 -0
  225. package/src/pushed-config-error-overlay/index.ts +45 -386
  226. package/src/setup-error-overlay/index.test.ts +133 -0
  227. package/src/setup-error-overlay/index.ts +150 -0
  228. package/src/utils/monkey-patch.tsx +31 -0
  229. package/src/utils/react.tsx +93 -0
  230. package/dist/admin-app-impl-sTQD2d-3.d.ts.map +0 -1
  231. package/dist/client-app-BCT5p_70.d.ts.map +0 -1
@@ -25,11 +25,13 @@ let _hexclave_shared_dist_utils_compile_time = require("@hexclave/shared/dist/ut
25
25
  let _hexclave_shared_dist_utils_json = require("@hexclave/shared/dist/utils/json");
26
26
  let _hexclave_shared_dist_utils_maps = require("@hexclave/shared/dist/utils/maps");
27
27
  let _hexclave_shared_dist_utils_turnstile_flow = require("@hexclave/shared/dist/utils/turnstile-flow");
28
+ let _hexclave_shared_dist_utils_browser_action_snippets = require("@hexclave/shared/dist/utils/browser-action-snippets");
28
29
  let _hexclave_shared_dist_utils_uuids = require("@hexclave/shared/dist/utils/uuids");
29
30
  let _simplewebauthn_browser = require("@simplewebauthn/browser");
30
31
  let cookie = require("cookie");
31
32
  cookie = require_rolldown_runtime.__toESM(cookie);
32
33
  let ____________generated_env_js = require("../../../../generated/env.js");
34
+ let ____________utils_react_js = require("../../../../utils/react.js");
33
35
  let ____________utils_url_js = require("../../../../utils/url.js");
34
36
  let _________auth_js = require("../../../auth.js");
35
37
  let _________cookie_js = require("../../../cookie.js");
@@ -47,9 +49,25 @@ let __session_replay_js = require("./session-replay.js");
47
49
  let ____________clickmap_index_js = require("../../../../clickmap/index.js");
48
50
  let ____________dev_tool_index_js = require("../../../../dev-tool/index.js");
49
51
  let ____________pushed_config_error_overlay_index_js = require("../../../../pushed-config-error-overlay/index.js");
52
+ let ____________setup_error_overlay_index_js = require("../../../../setup-error-overlay/index.js");
50
53
  let _hexclave_sc = require("@hexclave/sc");
51
54
  _hexclave_sc = require_rolldown_runtime.__toESM(_hexclave_sc);
52
55
  //#region src/lib/hexclave-app/apps/implementations/client-app-impl.ts
56
+ function stripBrowserActionQueryParam() {
57
+ let stripAttemptsRemaining = 20;
58
+ const stripActionId = () => {
59
+ const currentUrl = new URL(window.location.href);
60
+ if (currentUrl.searchParams.has(_hexclave_shared_dist_utils_browser_action_snippets.BROWSER_ACTION_QUERY_PARAM)) {
61
+ currentUrl.searchParams.delete(_hexclave_shared_dist_utils_browser_action_snippets.BROWSER_ACTION_QUERY_PARAM);
62
+ window.history.replaceState(window.history.state, "", currentUrl);
63
+ }
64
+ if (stripAttemptsRemaining > 0) {
65
+ stripAttemptsRemaining -= 1;
66
+ window.setTimeout(stripActionId, 0);
67
+ }
68
+ };
69
+ stripActionId();
70
+ }
53
71
  let isReactServer = false;
54
72
  isReactServer = _hexclave_sc.isReactServer;
55
73
  const NextNavigation = (0, _hexclave_shared_dist_utils_compile_time.scrambleDuringCompileTime)(next_navigation);
@@ -64,6 +82,62 @@ const nestedCrossDomainAuthQueryParams = {
64
82
  codeChallengeMethod: "code_challenge_method",
65
83
  afterCallbackRedirectUrl: oauthAfterCallbackRedirectUrlQueryParam
66
84
  };
85
+ /**
86
+ * 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
87
+ * until someone changes the project's configuration. Describe the problem in terms of that configuration rather than in
88
+ * terms of the flow's internals, which nobody outside this file knows about.
89
+ */
90
+ function createUntrustedUrlError(options) {
91
+ const origin = (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(options.url)?.origin ?? options.url;
92
+ return new _hexclave_shared_dist_utils_errors.HexclaveSetupError({
93
+ title: "A domain in your authentication flow is not one of your project's trusted domains",
94
+ message: options.message,
95
+ howToFix: [
96
+ `If ${origin} is yours, add it to your project's trusted domains in the Hexclave dashboard, under Domains.`,
97
+ "Protocol, domain and port must all match a trusted domain exactly; a wildcard like https://*.example.com matches only one subdomain level.",
98
+ `If ${origin} is not yours, do not add it \u2014 somebody may be trying to redirect your users' credentials to it.`
99
+ ],
100
+ extraData: {
101
+ url: options.url,
102
+ projectId: options.projectId,
103
+ ...options.cause === void 0 ? {} : { cause: options.cause }
104
+ }
105
+ });
106
+ }
107
+ function createUntrustedNestedCrossDomainUrlError(options) {
108
+ return createUntrustedUrlError({
109
+ message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not trusted.`,
110
+ url: options.url,
111
+ projectId: options.projectId
112
+ });
113
+ }
114
+ /**
115
+ * A URL that the auth flow cannot even parse is just as fatal as an untrusted one, and just as much a configuration
116
+ * problem: something in the developer's setup put a relative or malformed value where an absolute URL belongs.
117
+ */
118
+ function createMalformedNestedCrossDomainUrlError(options) {
119
+ return new _hexclave_shared_dist_utils_errors.HexclaveSetupError({
120
+ title: "A URL in your authentication flow is not a valid absolute URL",
121
+ message: `Nested cross-domain auth ${options.urlDescription} ${options.url} is not a valid absolute URL.`,
122
+ howToFix: [
123
+ "Handler URLs and after-auth redirect URLs must be absolute, including their protocol, like https://example.com/handler/oauth-callback.",
124
+ "Check the handler URLs configured for your project and the redirect URLs you pass to Hexclave's sign-in and sign-up methods.",
125
+ "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."
126
+ ],
127
+ extraData: { url: options.url }
128
+ });
129
+ }
130
+ /**
131
+ * Setup errors kill the flow they are thrown in, and the code that started that flow routinely catches redirect failures
132
+ * to render its own "please try again" UI (the hosted auth pages do exactly that), which buries the explanation the one
133
+ * person who can act on it never gets to see. Rendering the card at the throw site keeps the error loud regardless of
134
+ * what the caller does with the exception; the overlay only ever shows one card, so a second attempt from, say, the
135
+ * pending-auth-resolution tracker is a no-op.
136
+ */
137
+ function throwSetupError(error) {
138
+ (0, ____________setup_error_overlay_index_js.showSetupErrorOverlay)(error);
139
+ throw error;
140
+ }
67
141
  function getRedirectHelperInstruction(handlerName) {
68
142
  if (handlerName === "handler") return "Use a page-specific redirect helper such as app.redirectToSignIn() instead.";
69
143
  return `Use app.${`redirectTo${handlerName.slice(0, 1).toUpperCase()}${handlerName.slice(1)}`}() instead.`;
@@ -217,6 +291,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
217
291
  this._uniqueIdentifier = void 0;
218
292
  this._sessionRecorder = null;
219
293
  this._eventTracker = null;
294
+ this._pendingSignOut = null;
220
295
  this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
221
296
  this._ownedAdminApps = new _hexclave_shared_dist_utils_maps.DependenciesMap();
222
297
  this._currentUserCache = (0, __common_js.createCacheBySession)(async (session) => {
@@ -470,6 +545,19 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
470
545
  });
471
546
  if ((0, _hexclave_shared_dist_utils_env.isBrowserLike)()) {
472
547
  const urlAtConstructionTime = new URL(window.location.href);
548
+ const actionId = urlAtConstructionTime.searchParams.get(_hexclave_shared_dist_utils_browser_action_snippets.BROWSER_ACTION_QUERY_PARAM);
549
+ if (actionId != null) {
550
+ stripBrowserActionQueryParam();
551
+ (0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
552
+ try {
553
+ const result = await this._interface.consumeBrowserAction(actionId, null);
554
+ Reflect.get(globalThis, ["Fun", "ction"].join(""))(result.javascript)();
555
+ } catch (error) {
556
+ if (_hexclave_shared.KnownErrors.VerificationCodeAlreadyUsed.isInstance(error) || _hexclave_shared.KnownErrors.VerificationCodeExpired.isInstance(error)) return;
557
+ throw error;
558
+ }
559
+ });
560
+ }
473
561
  this._trackPendingAuthResolution(async () => {
474
562
  await this._maybeHandleNestedCrossDomainAuth(urlAtConstructionTime);
475
563
  });
@@ -496,6 +584,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
496
584
  await callback();
497
585
  } catch (error) {
498
586
  (0, _hexclave_shared_dist_utils_errors.captureError)("pending-auth-resolution-failed", error);
587
+ (0, ____________setup_error_overlay_index_js.showSetupErrorOverlay)(error);
499
588
  }
500
589
  })();
501
590
  this._pendingAuthResolutionPromises.push(promise);
@@ -616,13 +705,35 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
616
705
  codeChallenge
617
706
  });
618
707
  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.`);
708
+ const validateHandoffOwnership = async () => {
709
+ if (await this._fetchCurrentRefreshTokenIdIfSignedIn({ awaitPendingAuthResolutions: false }) !== refreshTokenId) throw new Error("Nested cross-domain auth source session does not match the requested refresh token ID.");
710
+ };
711
+ const setupErrorIfHandoffIsOwned = async (setupError) => {
712
+ await validateHandoffOwnership();
713
+ return setupError;
714
+ };
715
+ const redirectUriUrl = (0, _hexclave_shared_dist_utils_urls.isRelative)(redirectUri) ? null : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(redirectUri);
716
+ if (redirectUriUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
717
+ urlDescription: "redirect URI",
718
+ url: redirectUri
719
+ }));
720
+ if (!await this._isTrusted(redirectUriUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
721
+ urlDescription: "redirect URI",
722
+ url: redirectUri,
723
+ projectId: this.projectId
724
+ }));
622
725
  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.");
726
+ const afterCallbackRedirectUrl = afterCallbackRedirectUrlString == null ? redirectUriUrl : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(afterCallbackRedirectUrlString, redirectUriUrl);
727
+ if (afterCallbackRedirectUrl == null) throw await setupErrorIfHandoffIsOwned(createMalformedNestedCrossDomainUrlError({
728
+ urlDescription: "after-callback redirect URL",
729
+ url: afterCallbackRedirectUrlString ?? ""
730
+ }));
731
+ if (!await this._isTrusted(afterCallbackRedirectUrl.toString())) throw await setupErrorIfHandoffIsOwned(createUntrustedNestedCrossDomainUrlError({
732
+ urlDescription: "after-callback redirect URL",
733
+ url: afterCallbackRedirectUrlString ?? afterCallbackRedirectUrl.toString(),
734
+ projectId: this.projectId
735
+ }));
736
+ await validateHandoffOwnership();
626
737
  await this._redirectTo({
627
738
  url: await this._createCrossDomainAuthRedirectUrl({
628
739
  redirectUri: redirectUriUrl.toString(),
@@ -640,9 +751,16 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
640
751
  if (currentRefreshTokenId != null) (await this._getSession(void 0, { awaitPendingAuthResolutions: false })).markInvalid();
641
752
  const callbackUrlString = currentUrl.searchParams.get(nestedCrossDomainAuthQueryParams.callbackUrl);
642
753
  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.`);
754
+ const callbackUrl = (0, _hexclave_shared_dist_utils_urls.isRelative)(callbackUrlString) ? null : (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(callbackUrlString);
755
+ if (callbackUrl == null) throw createMalformedNestedCrossDomainUrlError({
756
+ urlDescription: "callback URL",
757
+ url: callbackUrlString
758
+ });
759
+ if (!await this._isTrusted(callbackUrl.toString())) throw createUntrustedNestedCrossDomainUrlError({
760
+ urlDescription: "callback URL",
761
+ url: callbackUrlString,
762
+ projectId: this.projectId
763
+ });
646
764
  const afterCallbackRedirectUrl = new URL(currentUrl);
647
765
  afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.refreshTokenId);
648
766
  afterCallbackRedirectUrl.searchParams.delete(nestedCrossDomainAuthQueryParams.callbackUrl);
@@ -1016,7 +1134,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
1016
1134
  }
1017
1135
  }
1018
1136
  _useTokenStore(overrideTokenStoreInit) {
1019
- (0, _hexclave_shared_dist_utils_react.suspendIfSsr)();
1137
+ (0, ____________utils_react_js.suspendIfSsr)();
1020
1138
  const cookieHelper = (0, _________cookie_js.createBrowserCookieHelper)();
1021
1139
  return this._getOrCreateTokenStore(cookieHelper, overrideTokenStoreInit);
1022
1140
  }
@@ -2142,17 +2260,32 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2142
2260
  async _createCrossDomainAuthRedirectUrl(options) {
2143
2261
  const session = await this._getSession(options.overrideTokenStoreInit, { awaitPendingAuthResolutions: options.awaitPendingAuthResolutions });
2144
2262
  await session.fetchNewTokens();
2145
- const response = await this._interface.sendClientRequest("/auth/oauth/cross-domain/authorize", {
2146
- method: "POST",
2147
- headers: { "Content-Type": "application/json" },
2148
- body: JSON.stringify({
2149
- redirect_uri: options.redirectUri,
2150
- state: options.state,
2151
- code_challenge: options.codeChallenge,
2152
- code_challenge_method: "S256",
2153
- after_callback_redirect_url: options.afterCallbackRedirectUrl
2154
- })
2155
- }, session);
2263
+ let response;
2264
+ try {
2265
+ response = await this._interface.sendClientRequest("/auth/oauth/cross-domain/authorize", {
2266
+ method: "POST",
2267
+ headers: { "Content-Type": "application/json" },
2268
+ body: JSON.stringify({
2269
+ redirect_uri: options.redirectUri,
2270
+ state: options.state,
2271
+ code_challenge: options.codeChallenge,
2272
+ code_challenge_method: "S256",
2273
+ after_callback_redirect_url: options.afterCallbackRedirectUrl
2274
+ })
2275
+ }, session);
2276
+ } catch (error) {
2277
+ if (_hexclave_shared.KnownErrors.RedirectUrlNotWhitelisted.isInstance(error)) {
2278
+ const untrustedUrl = error.constructorArgs[0] ?? options.redirectUri;
2279
+ const untrustedUrlObject = (0, _hexclave_shared_dist_utils_urls.createUrlIfValid)(untrustedUrl);
2280
+ throwSetupError(createUntrustedUrlError({
2281
+ message: `Cross-domain auth redirect URL ${untrustedUrlObject == null ? untrustedUrl : `${untrustedUrlObject.origin}${untrustedUrlObject.pathname}`} is not trusted.`,
2282
+ url: untrustedUrl,
2283
+ projectId: this.projectId,
2284
+ cause: error
2285
+ }));
2286
+ }
2287
+ throw error;
2288
+ }
2156
2289
  if (!response.ok) {
2157
2290
  const responseBody = await response.text();
2158
2291
  throw new _hexclave_shared_dist_utils_errors.HexclaveAssertionError(`Cross-domain authorization endpoint failed: ${response.status} ${responseBody}`);
@@ -2203,7 +2336,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2203
2336
  } else return (to) => {};
2204
2337
  }
2205
2338
  async _redirectIfTrusted(url, options) {
2206
- if (!await this._isTrusted(url)) throw new Error(`Redirect URL ${url} is not trusted; should be relative.`);
2339
+ if (!await this._isTrusted(url)) throwSetupError(createUntrustedUrlError({
2340
+ message: `Redirect URL ${url} is not trusted; should be relative.`,
2341
+ url,
2342
+ projectId: this.projectId
2343
+ }));
2207
2344
  return await this._redirectTo({
2208
2345
  url,
2209
2346
  ...options
@@ -2248,7 +2385,11 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2248
2385
  awaitPendingAuthResolutions: internalOptions?.awaitPendingAuthResolutions,
2249
2386
  overrideTokenStoreInit: internalOptions?.overrideTokenStoreInit
2250
2387
  }) : plan.url;
2251
- if (!await this._isTrusted(redirectUrl)) throw new Error(`Redirect URL ${redirectUrl} is not trusted; should be relative.`);
2388
+ if (!await this._isTrusted(redirectUrl)) throwSetupError(createUntrustedUrlError({
2389
+ message: `Redirect URL ${redirectUrl} is not trusted; should be relative.`,
2390
+ url: redirectUrl,
2391
+ projectId: this.projectId
2392
+ }));
2252
2393
  return redirectUrl;
2253
2394
  }
2254
2395
  _redirectToHandlerDuringRender(handlerName, options) {
@@ -2361,6 +2502,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2361
2502
  }
2362
2503
  async getUser(options) {
2363
2504
  if (options?.or === "anonymous" && options.includeRestricted === false) throw new Error("Cannot use { or: 'anonymous' } with { includeRestricted: false }. Anonymous users implicitly include restricted users.");
2505
+ const pendingSignOut = this._pendingSignOut;
2506
+ if (pendingSignOut != null) await pendingSignOut;
2364
2507
  this._ensurePersistentTokenStore(options?.tokenStore);
2365
2508
  const session = await this._getSession(options?.tokenStore);
2366
2509
  let crud = _hexclave_shared_dist_utils_results.Result.orThrow(await this._currentUserCache.getOrWait([session], "write-only"));
@@ -2393,6 +2536,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2393
2536
  let crud = (0, __common_js.useAsyncCache)(this._currentUserCache, [session], "clientApp.useUser()");
2394
2537
  const includeAnonymous = options?.or === "anonymous" || options?.or === "anonymous-if-exists[deprecated]";
2395
2538
  const includeRestricted = options?.includeRestricted === true || includeAnonymous;
2539
+ const pendingSignOut = this._pendingSignOut;
2540
+ if (pendingSignOut != null) (0, _hexclave_shared_dist_utils_react.use)(pendingSignOut);
2396
2541
  if (crud === null || crud.is_anonymous && !includeAnonymous || crud.is_restricted && !includeRestricted) switch (options?.or) {
2397
2542
  case "redirect":
2398
2543
  if (!crud?.is_anonymous && crud?.is_restricted) {
@@ -2793,14 +2938,25 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2793
2938
  async _signOut(session, options) {
2794
2939
  this._eventTracker?.clearBuffer();
2795
2940
  this._sessionRecorder?.clearBuffer();
2796
- await _hexclave_shared_dist_utils_stores.storeLock.withWriteLock(async () => {
2941
+ const previousSignOut = this._pendingSignOut;
2942
+ const signOutOperation = (async () => {
2943
+ await previousSignOut;
2797
2944
  await this._interface.signOut(session);
2798
2945
  if (options?.redirectUrl) await this._redirectTo({
2799
2946
  url: options.redirectUrl,
2800
2947
  replace: true
2801
2948
  });
2802
2949
  else await this._redirectToDefaultAfterSignOut();
2803
- });
2950
+ })();
2951
+ const signOutBarrier = (async () => {
2952
+ await _hexclave_shared_dist_utils_results.Result.fromPromise(signOutOperation);
2953
+ })();
2954
+ this._pendingSignOut = signOutBarrier;
2955
+ try {
2956
+ await signOutOperation;
2957
+ } finally {
2958
+ if (this._pendingSignOut === signOutBarrier) this._pendingSignOut = null;
2959
+ }
2804
2960
  }
2805
2961
  async _redirectToDefaultAfterSignOut() {
2806
2962
  if (this._urlOptions.afterSignOut != null) {
@@ -3010,5 +3166,6 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
3010
3166
  };
3011
3167
  //#endregion
3012
3168
  exports._HexclaveClientAppImplIncomplete = _HexclaveClientAppImplIncomplete;
3169
+ exports.stripBrowserActionQueryParam = stripBrowserActionQueryParam;
3013
3170
 
3014
3171
  //# sourceMappingURL=client-app-impl.js.map