@hexclave/next 1.0.51 → 1.0.53

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 (167) hide show
  1. package/dist/{admin-app-impl-BGNL1KyZ.d.ts → admin-app-impl-Bga0o6cL.d.ts} +11 -8
  2. package/dist/{admin-app-impl-BGNL1KyZ.d.ts.map → admin-app-impl-Bga0o6cL.d.ts.map} +1 -1
  3. package/dist/clickmap/clickmap-core.d.ts +1 -1
  4. package/dist/clickmap/index.d.ts +1 -1
  5. package/dist/{client-app-Majjw8Xp.d.ts → client-app-B0kBC67Z.d.ts} +2 -1
  6. package/dist/{client-app-Majjw8Xp.d.ts.map → client-app-B0kBC67Z.d.ts.map} +1 -1
  7. package/dist/common-BK_sydxF.d.ts.map +1 -1
  8. package/dist/components/api-key-dialogs.d.ts +1 -1
  9. package/dist/components/selected-team-switcher.d.ts +1 -1
  10. package/dist/components/team-icon.d.ts +1 -1
  11. package/dist/components/team-switcher.d.ts +1 -1
  12. package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
  13. package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
  14. package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
  15. package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
  16. package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
  17. package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
  18. package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
  19. package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
  20. package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
  21. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  22. package/dist/components-page/hexclave-handler.d.ts +1 -1
  23. package/dist/components-page/sign-out.js +11 -2
  24. package/dist/components-page/sign-out.js.map +1 -1
  25. package/dist/components-page/sign-out.test.d.ts +1 -0
  26. package/dist/components-page/sign-out.test.js +157 -0
  27. package/dist/components-page/sign-out.test.js.map +1 -0
  28. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  29. package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
  30. package/dist/dev-tool/dev-tool-core.js +58 -28
  31. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  32. package/dist/dev-tool/dev-tool-styles.js +35 -0
  33. package/dist/dev-tool/dev-tool-styles.js.map +1 -1
  34. package/dist/dev-tool/index.d.ts +1 -1
  35. package/dist/esm/components/api-key-dialogs.d.ts +1 -1
  36. package/dist/esm/components-page/sign-out.d.ts.map +1 -1
  37. package/dist/esm/components-page/sign-out.js +12 -3
  38. package/dist/esm/components-page/sign-out.js.map +1 -1
  39. package/dist/esm/components-page/sign-out.test.d.ts +1 -0
  40. package/dist/esm/components-page/sign-out.test.js +156 -0
  41. package/dist/esm/components-page/sign-out.test.js.map +1 -0
  42. package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
  43. package/dist/esm/dev-tool/dev-tool-core.js +58 -28
  44. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  45. package/dist/esm/dev-tool/dev-tool-styles.js +35 -0
  46. package/dist/esm/dev-tool/dev-tool-styles.js.map +1 -1
  47. package/dist/esm/generated/global-css.d.ts +1 -1
  48. package/dist/esm/generated/global-css.js +1 -1
  49. package/dist/esm/generated/global-css.js.map +1 -1
  50. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  51. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +5 -4
  52. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  53. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +97 -0
  54. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  55. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +3 -2
  56. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  57. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +26 -1
  58. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  59. package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -1
  60. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +21 -4
  61. package/dist/esm/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  62. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts +37 -0
  63. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts.map +1 -0
  64. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.js +89 -0
  65. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.js.map +1 -0
  66. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.d.ts +1 -0
  67. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.js +134 -0
  68. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.js.map +1 -0
  69. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.d.ts +8 -0
  70. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.d.ts.map +1 -0
  71. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.js +73 -0
  72. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.js.map +1 -0
  73. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.d.ts +1 -0
  74. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.js +92 -0
  75. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.js.map +1 -0
  76. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -0
  77. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts.map +1 -1
  78. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +27 -6
  79. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -1
  80. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -0
  81. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -1
  82. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
  83. package/dist/esm/pushed-config-error-overlay/index.js +1 -1
  84. package/dist/esm/pushed-config-error-overlay/index.js.map +1 -1
  85. package/dist/esm/utils/session-storage.d.ts +12 -0
  86. package/dist/esm/utils/session-storage.d.ts.map +1 -0
  87. package/dist/esm/utils/session-storage.js +30 -0
  88. package/dist/esm/utils/session-storage.js.map +1 -0
  89. package/dist/generated/global-css.d.ts +1 -1
  90. package/dist/generated/global-css.js +1 -1
  91. package/dist/generated/global-css.js.map +1 -1
  92. package/dist/generated/quetzal-translations.d.ts +1 -1
  93. package/dist/{hexclave-provider-IAd7nlbi.d.ts → hexclave-provider-SQbs9rmZ.d.ts} +3 -3
  94. package/dist/{hexclave-provider-IAd7nlbi.d.ts.map → hexclave-provider-SQbs9rmZ.d.ts.map} +1 -1
  95. package/dist/{hooks-BKXOF6jh.d.ts → hooks-ykQ7Wsco.d.ts} +2 -2
  96. package/dist/{hooks-BKXOF6jh.d.ts.map → hooks-ykQ7Wsco.d.ts.map} +1 -1
  97. package/dist/{index-Ck1qKoin.d.ts → index-DwE1cNLH.d.ts} +2 -2
  98. package/dist/{index-Ck1qKoin.d.ts.map → index-DwE1cNLH.d.ts.map} +1 -1
  99. package/dist/index.d.ts +4 -4
  100. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  101. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +97 -0
  102. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  103. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
  104. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +26 -1
  105. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  106. package/dist/lib/hexclave-app/apps/implementations/common.js +21 -4
  107. package/dist/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  108. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  109. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts +37 -0
  110. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts.map +1 -0
  111. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.js +92 -0
  112. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.js.map +1 -0
  113. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.d.ts +1 -0
  114. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.js +133 -0
  115. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.js.map +1 -0
  116. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.d.ts +8 -0
  117. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.d.ts.map +1 -0
  118. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.js +74 -0
  119. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.js.map +1 -0
  120. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.d.ts +1 -0
  121. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.js +91 -0
  122. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.js.map +1 -0
  123. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  124. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +27 -6
  125. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -1
  126. package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
  127. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
  128. package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
  129. package/dist/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
  130. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  131. package/dist/lib/hexclave-app/index.d.ts +1 -1
  132. package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
  133. package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
  134. package/dist/lib/hexclave-app/users/index.d.ts +1 -1
  135. package/dist/lib/hooks.d.ts +1 -1
  136. package/dist/providers/hexclave-context.d.ts +1 -1
  137. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  138. package/dist/providers/hexclave-provider.d.ts +1 -1
  139. package/dist/providers/translation-provider.d.ts +1 -1
  140. package/dist/pushed-config-error-overlay/index.d.ts +1 -1
  141. package/dist/pushed-config-error-overlay/index.js +1 -1
  142. package/dist/pushed-config-error-overlay/index.js.map +1 -1
  143. package/dist/{quetzal-translations-XeH3zQ9l.d.ts → quetzal-translations-CK45_4Dm.d.ts} +3 -3
  144. package/dist/{quetzal-translations-XeH3zQ9l.d.ts.map → quetzal-translations-CK45_4Dm.d.ts.map} +1 -1
  145. package/dist/sign-out-DBnSkfDz.d.ts.map +1 -1
  146. package/dist/{translation-provider-WOaZXqAz.d.ts → translation-provider-DQ3BJepJ.d.ts} +2 -2
  147. package/dist/{translation-provider-WOaZXqAz.d.ts.map → translation-provider-DQ3BJepJ.d.ts.map} +1 -1
  148. package/dist/utils/session-storage.d.ts +12 -0
  149. package/dist/utils/session-storage.d.ts.map +1 -0
  150. package/dist/utils/session-storage.js +33 -0
  151. package/dist/utils/session-storage.js.map +1 -0
  152. package/package.json +4 -4
  153. package/src/components-page/sign-out.test.tsx +190 -0
  154. package/src/components-page/sign-out.tsx +22 -3
  155. package/src/dev-tool/dev-tool-core.ts +100 -35
  156. package/src/dev-tool/dev-tool-styles.ts +35 -0
  157. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +127 -0
  158. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +34 -1
  159. package/src/lib/hexclave-app/apps/implementations/common.ts +18 -1
  160. package/src/lib/hexclave-app/apps/implementations/redirect-back-state.test.ts +134 -0
  161. package/src/lib/hexclave-app/apps/implementations/redirect-back-state.ts +140 -0
  162. package/src/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.ts +127 -0
  163. package/src/lib/hexclave-app/apps/implementations/redirect-loop-breaker.ts +117 -0
  164. package/src/lib/hexclave-app/apps/implementations/server-app-impl.ts +31 -5
  165. package/src/lib/hexclave-app/apps/interfaces/client-app.ts +1 -0
  166. package/src/pushed-config-error-overlay/index.ts +1 -1
  167. package/src/utils/session-storage.ts +45 -0
@@ -0,0 +1,92 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { recordRedirectAndThrowIfLoopDetected } from "./redirect-loop-breaker.js";
3
+ //#region src/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.ts
4
+ function createMockSessionStorage() {
5
+ const map = /* @__PURE__ */ new Map();
6
+ return {
7
+ getItem: (key) => map.get(key) ?? null,
8
+ setItem: (key, value) => {
9
+ map.set(key, value);
10
+ },
11
+ removeItem: (key) => {
12
+ map.delete(key);
13
+ }
14
+ };
15
+ }
16
+ const previousWindow = Reflect.get(globalThis, "window");
17
+ const hadPreviousWindow = Reflect.has(globalThis, "window");
18
+ function record(from, to) {
19
+ recordRedirectAndThrowIfLoopDetected({
20
+ currentUrl: new URL(from),
21
+ targetUrl: new URL(to)
22
+ });
23
+ }
24
+ describe("recordRedirectAndThrowIfLoopDetected", () => {
25
+ beforeEach(() => {
26
+ Reflect.set(globalThis, "window", { sessionStorage: createMockSessionStorage() });
27
+ vi.useFakeTimers();
28
+ vi.setSystemTime(/* @__PURE__ */ new Date("2026-01-01T00:00:00Z"));
29
+ });
30
+ afterEach(() => {
31
+ vi.useRealTimers();
32
+ if (hadPreviousWindow) Reflect.set(globalThis, "window", previousWindow);
33
+ else Reflect.deleteProperty(globalThis, "window");
34
+ });
35
+ it("allows distinct redirects in quick succession", () => {
36
+ for (let i = 0; i < 20; i++) record(`https://app.example.test/page-${i}`, `https://app.example.test/page-${i + 1}`);
37
+ });
38
+ it("throws once the same redirect repeats 5 times within the window", () => {
39
+ for (let i = 0; i < 4; i++) {
40
+ record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
41
+ vi.advanceTimersByTime(1e3);
42
+ }
43
+ expect(() => {
44
+ record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
45
+ }).toThrowError(/Redirect loop detected/);
46
+ });
47
+ it("treats redirects that differ only in query params or hash as identical", () => {
48
+ for (let i = 0; i < 4; i++) record(`https://app.example.test/dashboard?code=code-${i}`, `https://hosted.example.test/handler/sign-in?state=state-${i}#frag-${i}`);
49
+ expect(() => {
50
+ record("https://app.example.test/dashboard?code=final", "https://hosted.example.test/handler/sign-in?state=final");
51
+ }).toThrowError(/Redirect loop detected/);
52
+ });
53
+ it("does not throw when the identical redirects are spread out beyond the window", () => {
54
+ for (let i = 0; i < 20; i++) {
55
+ record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
56
+ vi.advanceTimersByTime(31e3);
57
+ }
58
+ });
59
+ it("allows the same redirect again after a loop was broken", () => {
60
+ for (let i = 0; i < 4; i++) record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
61
+ expect(() => {
62
+ record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
63
+ }).toThrowError(/Redirect loop detected/);
64
+ record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
65
+ });
66
+ it("counts self-redirects (same origin and path) towards loops", () => {
67
+ for (let i = 0; i < 4; i++) record(`https://hosted.example.test/handler/sign-in?attempt=${i}`, "https://hosted.example.test/handler/sign-in");
68
+ expect(() => {
69
+ record("https://hosted.example.test/handler/sign-in?attempt=final", "https://hosted.example.test/handler/sign-in");
70
+ }).toThrowError(/Redirect loop detected/);
71
+ });
72
+ it("degrades to a no-op when sessionStorage is unavailable", () => {
73
+ Reflect.set(globalThis, "window", { get sessionStorage() {
74
+ throw new Error("Storage is disabled");
75
+ } });
76
+ for (let i = 0; i < 20; i++) record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
77
+ });
78
+ it("recovers from corrupted breadcrumb storage", () => {
79
+ const storage = createMockSessionStorage();
80
+ storage.setItem("hexclave-redirect-loop-breadcrumbs", "{not json");
81
+ Reflect.set(globalThis, "window", { sessionStorage: storage });
82
+ record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
83
+ for (let i = 0; i < 3; i++) record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
84
+ expect(() => {
85
+ record("https://app.example.test/dashboard", "https://hosted.example.test/handler/sign-in");
86
+ }).toThrowError(/Redirect loop detected/);
87
+ });
88
+ });
89
+ //#endregion
90
+ export {};
91
+
92
+ //# sourceMappingURL=redirect-loop-breaker.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect-loop-breaker.test.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { recordRedirectAndThrowIfLoopDetected } from \"./redirect-loop-breaker\";\n\nfunction createMockSessionStorage() {\n const map = new Map<string, string>();\n return {\n getItem: (key: string) => map.get(key) ?? null,\n setItem: (key: string, value: string) => {\n map.set(key, value);\n },\n removeItem: (key: string) => {\n map.delete(key);\n },\n };\n}\n\nconst previousWindow = Reflect.get(globalThis, \"window\");\nconst hadPreviousWindow = Reflect.has(globalThis, \"window\");\n\nfunction record(from: string, to: string) {\n recordRedirectAndThrowIfLoopDetected({\n currentUrl: new URL(from),\n targetUrl: new URL(to),\n });\n}\n\ndescribe(\"recordRedirectAndThrowIfLoopDetected\", () => {\n beforeEach(() => {\n Reflect.set(globalThis, \"window\", { sessionStorage: createMockSessionStorage() });\n vi.useFakeTimers();\n vi.setSystemTime(new Date(\"2026-01-01T00:00:00Z\"));\n });\n\n afterEach(() => {\n vi.useRealTimers();\n if (hadPreviousWindow) {\n Reflect.set(globalThis, \"window\", previousWindow);\n } else {\n Reflect.deleteProperty(globalThis, \"window\");\n }\n });\n\n it(\"allows distinct redirects in quick succession\", () => {\n for (let i = 0; i < 20; i++) {\n record(`https://app.example.test/page-${i}`, `https://app.example.test/page-${i + 1}`);\n }\n });\n\n it(\"throws once the same redirect repeats 5 times within the window\", () => {\n for (let i = 0; i < 4; i++) {\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n vi.advanceTimersByTime(1000);\n }\n expect(() => {\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n }).toThrowError(/Redirect loop detected/);\n });\n\n it(\"treats redirects that differ only in query params or hash as identical\", () => {\n // Real loops usually rotate nonce-style params (code, state, after_auth_return_to) each cycle.\n for (let i = 0; i < 4; i++) {\n record(\n `https://app.example.test/dashboard?code=code-${i}`,\n `https://hosted.example.test/handler/sign-in?state=state-${i}#frag-${i}`,\n );\n }\n expect(() => {\n record(\"https://app.example.test/dashboard?code=final\", \"https://hosted.example.test/handler/sign-in?state=final\");\n }).toThrowError(/Redirect loop detected/);\n });\n\n it(\"does not throw when the identical redirects are spread out beyond the window\", () => {\n for (let i = 0; i < 20; i++) {\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n vi.advanceTimersByTime(31_000);\n }\n });\n\n it(\"allows the same redirect again after a loop was broken\", () => {\n for (let i = 0; i < 4; i++) {\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n }\n expect(() => {\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n }).toThrowError(/Redirect loop detected/);\n // The breadcrumbs for the broken loop are dropped, so a manual retry isn't instantly blocked.\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n });\n\n it(\"counts self-redirects (same origin and path) towards loops\", () => {\n for (let i = 0; i < 4; i++) {\n record(`https://hosted.example.test/handler/sign-in?attempt=${i}`, \"https://hosted.example.test/handler/sign-in\");\n }\n expect(() => {\n record(\"https://hosted.example.test/handler/sign-in?attempt=final\", \"https://hosted.example.test/handler/sign-in\");\n }).toThrowError(/Redirect loop detected/);\n });\n\n it(\"degrades to a no-op when sessionStorage is unavailable\", () => {\n Reflect.set(globalThis, \"window\", {\n get sessionStorage(): Storage {\n throw new Error(\"Storage is disabled\");\n },\n });\n for (let i = 0; i < 20; i++) {\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n }\n });\n\n it(\"recovers from corrupted breadcrumb storage\", () => {\n const storage = createMockSessionStorage();\n storage.setItem(\"hexclave-redirect-loop-breadcrumbs\", \"{not json\");\n Reflect.set(globalThis, \"window\", { sessionStorage: storage });\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n // After recovery, loop detection works again.\n for (let i = 0; i < 3; i++) {\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n }\n expect(() => {\n record(\"https://app.example.test/dashboard\", \"https://hosted.example.test/handler/sign-in\");\n }).toThrowError(/Redirect loop detected/);\n });\n});\n"],"mappings":";;;AAOA,SAAS,2BAA2B;CAClC,MAAM,sBAAM,IAAI,IAAoB;CACpC,OAAO;EACL,UAAU,QAAgB,IAAI,IAAI,GAAG,KAAK;EAC1C,UAAU,KAAa,UAAkB;GACvC,IAAI,IAAI,KAAK,KAAK;EACpB;EACA,aAAa,QAAgB;GAC3B,IAAI,OAAO,GAAG;EAChB;CACF;AACF;AAEA,MAAM,iBAAiB,QAAQ,IAAI,YAAY,QAAQ;AACvD,MAAM,oBAAoB,QAAQ,IAAI,YAAY,QAAQ;AAE1D,SAAS,OAAO,MAAc,IAAY;CACxC,qCAAqC;EACnC,YAAY,IAAI,IAAI,IAAI;EACxB,WAAW,IAAI,IAAI,EAAE;CACvB,CAAC;AACH;AAEA,SAAS,8CAA8C;CACrD,iBAAiB;EACf,QAAQ,IAAI,YAAY,UAAU,EAAE,gBAAgB,yBAAyB,EAAE,CAAC;EAChF,GAAG,cAAc;EACjB,GAAG,8BAAc,IAAI,KAAK,sBAAsB,CAAC;CACnD,CAAC;CAED,gBAAgB;EACd,GAAG,cAAc;EACjB,IAAI,mBACF,QAAQ,IAAI,YAAY,UAAU,cAAc;OAEhD,QAAQ,eAAe,YAAY,QAAQ;CAE/C,CAAC;CAED,GAAG,uDAAuD;EACxD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KACtB,OAAO,iCAAiC,KAAK,iCAAiC,IAAI,GAAG;CAEzF,CAAC;CAED,GAAG,yEAAyE;EAC1E,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,OAAO,sCAAsC,6CAA6C;GAC1F,GAAG,oBAAoB,GAAI;EAC7B;EACA,aAAa;GACX,OAAO,sCAAsC,6CAA6C;EAC5F,CAAC,CAAC,CAAC,aAAa,wBAAwB;CAC1C,CAAC;CAED,GAAG,gFAAgF;EAEjF,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OACE,gDAAgD,KAChD,2DAA2D,EAAE,QAAQ,GACvE;EAEF,aAAa;GACX,OAAO,iDAAiD,yDAAyD;EACnH,CAAC,CAAC,CAAC,aAAa,wBAAwB;CAC1C,CAAC;CAED,GAAG,sFAAsF;EACvF,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;GAC3B,OAAO,sCAAsC,6CAA6C;GAC1F,GAAG,oBAAoB,IAAM;EAC/B;CACF,CAAC;CAED,GAAG,gEAAgE;EACjE,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OAAO,sCAAsC,6CAA6C;EAE5F,aAAa;GACX,OAAO,sCAAsC,6CAA6C;EAC5F,CAAC,CAAC,CAAC,aAAa,wBAAwB;EAExC,OAAO,sCAAsC,6CAA6C;CAC5F,CAAC;CAED,GAAG,oEAAoE;EACrE,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OAAO,uDAAuD,KAAK,6CAA6C;EAElH,aAAa;GACX,OAAO,6DAA6D,6CAA6C;EACnH,CAAC,CAAC,CAAC,aAAa,wBAAwB;CAC1C,CAAC;CAED,GAAG,gEAAgE;EACjE,QAAQ,IAAI,YAAY,UAAU,EAChC,IAAI,iBAA0B;GAC5B,MAAM,IAAI,MAAM,qBAAqB;EACvC,EACF,CAAC;EACD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KACtB,OAAO,sCAAsC,6CAA6C;CAE9F,CAAC;CAED,GAAG,oDAAoD;EACrD,MAAM,UAAU,yBAAyB;EACzC,QAAQ,QAAQ,sCAAsC,WAAW;EACjE,QAAQ,IAAI,YAAY,UAAU,EAAE,gBAAgB,QAAQ,CAAC;EAC7D,OAAO,sCAAsC,6CAA6C;EAE1F,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OAAO,sCAAsC,6CAA6C;EAE5F,aAAa;GACX,OAAO,sCAAsC,6CAA6C;EAC5F,CAAC,CAAC,CAAC,aAAa,wBAAwB;CAC1C,CAAC;AACH,CAAC"}
@@ -35,6 +35,7 @@ declare class _HexclaveServerAppImplIncomplete<HasTokenStore extends boolean, Pr
35
35
  private readonly _serverUsersCache;
36
36
  private readonly _serverUserCache;
37
37
  private readonly _serverTeamsCache;
38
+ private readonly _serverTeamCache;
38
39
  protected _refreshTeamMembership(teamId: string, userId: string): Promise<void>;
39
40
  private readonly _serverUserTeamInvitationsCache;
40
41
  private readonly _serverTeamUserPermissionsCache;
@@ -1 +1 @@
1
- {"version":3,"file":"server-app-impl.d.ts","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/server-app-impl.ts"],"mappings":"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"}
1
+ {"version":3,"file":"server-app-impl.d.ts","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/server-app-impl.ts"],"mappings":"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"}
@@ -6,6 +6,7 @@ import { suspend } from "@hexclave/shared/dist/utils/react";
6
6
  import { Result } from "@hexclave/shared/dist/utils/results";
7
7
  import { clientVersion, createCache, createCacheBySession, getDefaultExtraRequestHeaders, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey, resolveApiUrls, resolveConstructorOptions, useAsyncCache } from "./common.js";
8
8
  import { InternalSession } from "@hexclave/shared/dist/sessions";
9
+ import { isUuid } from "@hexclave/shared/dist/utils/uuids";
9
10
  import { WebAuthnError, startRegistration } from "@simplewebauthn/browser";
10
11
  import { constructRedirectUrl } from "../../../../utils/url.js";
11
12
  import { apiKeyCreationOptionsToCrud, apiKeyUpdateOptionsToCrud } from "../../api-keys/index.js";
@@ -225,6 +226,15 @@ var _HexclaveServerAppImplIncomplete = class extends _HexclaveClientAppImplIncom
225
226
  query
226
227
  });
227
228
  });
229
+ this._serverTeamCache = createCache(async ([teamId]) => {
230
+ if (!isUuid(teamId)) return null;
231
+ try {
232
+ return await this._interface.getServerTeam(teamId);
233
+ } catch (error) {
234
+ if (KnownErrors.TeamNotFound.isInstance(error)) return null;
235
+ throw error;
236
+ }
237
+ });
228
238
  this._serverUserTeamInvitationsCache = createCache(async ([userId]) => {
229
239
  return await this._interface.listServerUserTeamInvitations(userId);
230
240
  });
@@ -831,11 +841,19 @@ var _HexclaveServerAppImplIncomplete = class extends _HexclaveClientAppImplIncom
831
841
  serverMetadata: crud.server_metadata,
832
842
  async update(update) {
833
843
  await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
834
- await Promise.all([app._serverTeamsCache.refreshWhere(() => true), app._serverUsersCache.refreshWhere(() => true)]);
844
+ await Promise.all([
845
+ app._serverTeamCache.refresh([crud.id]),
846
+ app._serverTeamsCache.refreshWhere(() => true),
847
+ app._serverUsersCache.refreshWhere(() => true)
848
+ ]);
835
849
  },
836
850
  async delete() {
837
851
  await app._interface.deleteServerTeam(crud.id);
838
- await Promise.all([app._serverTeamsCache.refreshWhere(() => true), app._serverUsersCache.refreshWhere(() => true)]);
852
+ await Promise.all([
853
+ app._serverTeamCache.refresh([crud.id]),
854
+ app._serverTeamsCache.refreshWhere(() => true),
855
+ app._serverUsersCache.refreshWhere(() => true)
856
+ ]);
839
857
  },
840
858
  async listUsers() {
841
859
  return Result.orThrow(await app._serverTeamMemberProfilesCache.getOrWait([crud.id], "write-only")).map((u) => app._serverTeamUserFromCrud(u));
@@ -1254,6 +1272,7 @@ var _HexclaveServerAppImplIncomplete = class extends _HexclaveClientAppImplIncom
1254
1272
  }
1255
1273
  async createTeam(data) {
1256
1274
  const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
1275
+ await this._serverTeamCache.refresh([team.id]);
1257
1276
  await this._serverTeamsCache.refreshWhere(() => true);
1258
1277
  return this._serverTeamFromCrud(team);
1259
1278
  }
@@ -1304,17 +1323,19 @@ var _HexclaveServerAppImplIncomplete = class extends _HexclaveClientAppImplIncom
1304
1323
  if (typeof options === "object" && "apiKey" in options) return await this._getTeamByApiKey(options.apiKey);
1305
1324
  else {
1306
1325
  const teamId = options;
1307
- return (await this.listTeams()).find((t) => t.id === teamId) ?? null;
1326
+ if (teamId == null) return null;
1327
+ const team = Result.orThrow(await this._serverTeamCache.getOrWait([teamId], "write-only"));
1328
+ return team == null ? null : this._serverTeamFromCrud(team);
1308
1329
  }
1309
1330
  }
1310
1331
  useTeam(options) {
1311
1332
  if (typeof options === "object" && "apiKey" in options) return this._useTeamByApiKey(options.apiKey);
1312
1333
  else {
1313
1334
  const teamId = options;
1314
- const teams = this.useTeams();
1335
+ const team = useAsyncCache(this._serverTeamCache, [teamId ?? ""], "serverApp.useTeam()");
1315
1336
  return useMemo(() => {
1316
- return teams.find((t) => t.id === teamId) ?? null;
1317
- }, [teams, teamId]);
1337
+ return team == null ? null : this._serverTeamFromCrud(team);
1338
+ }, [team]);
1318
1339
  }
1319
1340
  }
1320
1341
  _createServerDataVaultStore(id) {