@rubytech/create-maxy-code 0.1.444 → 0.1.446

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 (192) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/graph-style/dist/index.d.ts +4 -0
  3. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/graph-style/dist/index.js +37 -1
  5. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  6. package/payload/platform/lib/graph-style/src/__tests__/parity.test.ts +39 -0
  7. package/payload/platform/lib/graph-style/src/index.ts +41 -0
  8. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.d.ts +2 -0
  9. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.d.ts.map +1 -0
  10. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js +46 -0
  11. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js.map +1 -0
  12. package/payload/platform/lib/storage-broker/dist/__tests__/authorize.test.d.ts +2 -0
  13. package/payload/platform/lib/storage-broker/dist/__tests__/authorize.test.d.ts.map +1 -0
  14. package/payload/platform/lib/storage-broker/dist/__tests__/authorize.test.js +27 -0
  15. package/payload/platform/lib/storage-broker/dist/__tests__/authorize.test.js.map +1 -0
  16. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.d.ts +2 -0
  17. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.d.ts.map +1 -0
  18. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +51 -0
  19. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -0
  20. package/payload/platform/lib/storage-broker/dist/__tests__/house-credential.test.d.ts +2 -0
  21. package/payload/platform/lib/storage-broker/dist/__tests__/house-credential.test.d.ts.map +1 -0
  22. package/payload/platform/lib/storage-broker/dist/__tests__/house-credential.test.js +39 -0
  23. package/payload/platform/lib/storage-broker/dist/__tests__/house-credential.test.js.map +1 -0
  24. package/payload/platform/lib/storage-broker/dist/__tests__/registry.test.d.ts +2 -0
  25. package/payload/platform/lib/storage-broker/dist/__tests__/registry.test.d.ts.map +1 -0
  26. package/payload/platform/lib/storage-broker/dist/__tests__/registry.test.js +59 -0
  27. package/payload/platform/lib/storage-broker/dist/__tests__/registry.test.js.map +1 -0
  28. package/payload/platform/lib/storage-broker/dist/__tests__/remediate-run.test.d.ts +2 -0
  29. package/payload/platform/lib/storage-broker/dist/__tests__/remediate-run.test.d.ts.map +1 -0
  30. package/payload/platform/lib/storage-broker/dist/__tests__/remediate-run.test.js +77 -0
  31. package/payload/platform/lib/storage-broker/dist/__tests__/remediate-run.test.js.map +1 -0
  32. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.d.ts +2 -0
  33. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.d.ts.map +1 -0
  34. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.js +23 -0
  35. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.js.map +1 -0
  36. package/payload/platform/lib/storage-broker/dist/audit.d.ts +19 -0
  37. package/payload/platform/lib/storage-broker/dist/audit.d.ts.map +1 -0
  38. package/payload/platform/lib/storage-broker/dist/audit.js +41 -0
  39. package/payload/platform/lib/storage-broker/dist/audit.js.map +1 -0
  40. package/payload/platform/lib/storage-broker/dist/authorize.d.ts +11 -0
  41. package/payload/platform/lib/storage-broker/dist/authorize.d.ts.map +1 -0
  42. package/payload/platform/lib/storage-broker/dist/authorize.js +17 -0
  43. package/payload/platform/lib/storage-broker/dist/authorize.js.map +1 -0
  44. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.d.ts +25 -0
  45. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.d.ts.map +1 -0
  46. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.js +131 -0
  47. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.js.map +1 -0
  48. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +20 -0
  49. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -0
  50. package/payload/platform/lib/storage-broker/dist/cf-exec.js +53 -0
  51. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -0
  52. package/payload/platform/lib/storage-broker/dist/house-credential.d.ts +6 -0
  53. package/payload/platform/lib/storage-broker/dist/house-credential.d.ts.map +1 -0
  54. package/payload/platform/lib/storage-broker/dist/house-credential.js +33 -0
  55. package/payload/platform/lib/storage-broker/dist/house-credential.js.map +1 -0
  56. package/payload/platform/lib/storage-broker/dist/index.d.ts +7 -0
  57. package/payload/platform/lib/storage-broker/dist/index.d.ts.map +1 -0
  58. package/payload/platform/lib/storage-broker/dist/index.js +30 -0
  59. package/payload/platform/lib/storage-broker/dist/index.js.map +1 -0
  60. package/payload/platform/lib/storage-broker/dist/registry.d.ts +18 -0
  61. package/payload/platform/lib/storage-broker/dist/registry.d.ts.map +1 -0
  62. package/payload/platform/lib/storage-broker/dist/registry.js +45 -0
  63. package/payload/platform/lib/storage-broker/dist/registry.js.map +1 -0
  64. package/payload/platform/lib/storage-broker/dist/remediate.d.ts +7 -0
  65. package/payload/platform/lib/storage-broker/dist/remediate.d.ts.map +1 -0
  66. package/payload/platform/lib/storage-broker/dist/remediate.js +25 -0
  67. package/payload/platform/lib/storage-broker/dist/remediate.js.map +1 -0
  68. package/payload/platform/lib/storage-broker/src/__tests__/audit.test.ts +49 -0
  69. package/payload/platform/lib/storage-broker/src/__tests__/authorize.test.ts +28 -0
  70. package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +52 -0
  71. package/payload/platform/lib/storage-broker/src/__tests__/house-credential.test.ts +35 -0
  72. package/payload/platform/lib/storage-broker/src/__tests__/registry.test.ts +64 -0
  73. package/payload/platform/lib/storage-broker/src/__tests__/remediate-run.test.ts +79 -0
  74. package/payload/platform/lib/storage-broker/src/__tests__/remediate.test.ts +21 -0
  75. package/payload/platform/lib/storage-broker/src/audit.ts +55 -0
  76. package/payload/platform/lib/storage-broker/src/authorize.ts +22 -0
  77. package/payload/platform/lib/storage-broker/src/bin/remediate-run.ts +156 -0
  78. package/payload/platform/lib/storage-broker/src/cf-exec.ts +73 -0
  79. package/payload/platform/lib/storage-broker/src/house-credential.ts +32 -0
  80. package/payload/platform/lib/storage-broker/src/index.ts +14 -0
  81. package/payload/platform/lib/storage-broker/src/registry.ts +85 -0
  82. package/payload/platform/lib/storage-broker/src/remediate.ts +31 -0
  83. package/payload/platform/lib/storage-broker/tsconfig.json +8 -0
  84. package/payload/platform/package.json +2 -2
  85. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  86. package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +1 -0
  87. package/payload/platform/plugins/admin/mcp/dist/index.js +13 -3
  88. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  89. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts +8 -0
  90. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts.map +1 -1
  91. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js +20 -3
  92. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js.map +1 -1
  93. package/payload/platform/plugins/cloudflare/PLUGIN.md +4 -1
  94. package/payload/platform/plugins/cloudflare/bin/__tests__/cf-schema-check.test.sh +128 -0
  95. package/payload/platform/plugins/cloudflare/bin/__tests__/cf-store-name.test.sh +77 -0
  96. package/payload/platform/plugins/cloudflare/bin/cf-schema-check.sh +60 -0
  97. package/payload/platform/plugins/cloudflare/bin/cf-store-name.sh +37 -0
  98. package/payload/platform/plugins/cloudflare/bin/remediate-storage-isolation.sh +36 -0
  99. package/payload/platform/plugins/cloudflare/references/api.md +4 -0
  100. package/payload/platform/plugins/cloudflare/references/d1-data-capture.md +58 -0
  101. package/payload/platform/plugins/cloudflare/references/r2-object-storage.md +39 -0
  102. package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +2 -0
  103. package/payload/platform/plugins/cloudflare/skills/site-deploy/SKILL.md +2 -0
  104. package/payload/platform/plugins/outlook/PLUGIN.md +1 -1
  105. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.js +23 -0
  106. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.js.map +1 -1
  107. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-registry.test.js +34 -1
  108. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-registry.test.js.map +1 -1
  109. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.d.ts +26 -0
  110. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.d.ts.map +1 -1
  111. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.js +20 -3
  112. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.js.map +1 -1
  113. package/payload/platform/plugins/outlook/mcp/dist/index.js +2 -2
  114. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  115. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.d.ts +7 -0
  116. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.d.ts.map +1 -1
  117. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.js +4 -1
  118. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.js.map +1 -1
  119. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +9 -3
  120. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js +11 -4
  121. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js.map +1 -1
  122. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +15 -10
  123. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  124. package/payload/platform/plugins/storage-broker/.claude-plugin/plugin.json +21 -0
  125. package/payload/platform/plugins/storage-broker/PLUGIN.md +48 -0
  126. package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/index.js +193 -0
  127. package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/package.json +3 -0
  128. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/caller-scope-headers.test.d.ts +2 -0
  129. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/caller-scope-headers.test.d.ts.map +1 -0
  130. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/caller-scope-headers.test.js +16 -0
  131. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/caller-scope-headers.test.js.map +1 -0
  132. package/payload/platform/plugins/storage-broker/mcp/dist/call-api.d.ts +8 -0
  133. package/payload/platform/plugins/storage-broker/mcp/dist/call-api.d.ts.map +1 -0
  134. package/payload/platform/plugins/storage-broker/mcp/dist/call-api.js +39 -0
  135. package/payload/platform/plugins/storage-broker/mcp/dist/call-api.js.map +1 -0
  136. package/payload/platform/plugins/storage-broker/mcp/dist/caller-scope-headers.d.ts +7 -0
  137. package/payload/platform/plugins/storage-broker/mcp/dist/caller-scope-headers.d.ts.map +1 -0
  138. package/payload/platform/plugins/storage-broker/mcp/dist/caller-scope-headers.js +16 -0
  139. package/payload/platform/plugins/storage-broker/mcp/dist/caller-scope-headers.js.map +1 -0
  140. package/payload/platform/plugins/storage-broker/mcp/dist/index.d.ts +8 -0
  141. package/payload/platform/plugins/storage-broker/mcp/dist/index.d.ts.map +1 -0
  142. package/payload/platform/plugins/storage-broker/mcp/dist/index.js +98 -0
  143. package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -0
  144. package/payload/platform/plugins/storage-broker/mcp/package.json +10 -0
  145. package/payload/platform/plugins/storage-broker/mcp/vitest.config.ts +4 -0
  146. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  147. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +6 -0
  148. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  149. package/payload/server/chunk-4W6IEUFE.js +175 -0
  150. package/payload/server/public/assets/{AdminLoginScreens-BJVwtpLH.js → AdminLoginScreens-D9L-CuWi.js} +1 -1
  151. package/payload/server/public/assets/{AdminShell-CMu8_Xwn.js → AdminShell-DSQrvZXq.js} +1 -1
  152. package/payload/server/public/assets/{Checkbox-CzD0ORqA.js → Checkbox-CFdt8ljo.js} +1 -1
  153. package/payload/server/public/assets/{admin-D0yk2LMq.js → admin-Ch4n-G0j.js} +1 -1
  154. package/payload/server/public/assets/{browser-CvfbgznO.js → browser-B2AIxiuk.js} +1 -1
  155. package/payload/server/public/assets/{calendar-fw4WethJ.js → calendar-BvItH3B0.js} +1 -1
  156. package/payload/server/public/assets/chat-eQFMaX9y.js +1 -0
  157. package/payload/server/public/assets/chevron-left-D2AnCEyE.js +1 -0
  158. package/payload/server/public/assets/data-BzOmbHoe.js +1 -0
  159. package/payload/server/public/assets/{file-download-Px4s0Bhp.js → file-download-CK9j_Jx2.js} +1 -1
  160. package/payload/server/public/assets/graph-DrE7KupQ.js +51 -0
  161. package/payload/server/public/assets/graph-labels-CwEtvIRV.js +1 -0
  162. package/payload/server/public/assets/{maximize-2-BwphzI9S.js → maximize-2-CuzEom3K.js} +1 -1
  163. package/payload/server/public/assets/{operator-88m0DMl2.js → operator-DlboYPPu.js} +1 -1
  164. package/payload/server/public/assets/page-BuWH5gNK.js +1 -0
  165. package/payload/server/public/assets/page-Co9E8U5x.js +32 -0
  166. package/payload/server/public/assets/{public-BX2MjsFY.js → public-DtFpPMTG.js} +1 -1
  167. package/payload/server/public/assets/{rotate-ccw-C7BqkMec.js → rotate-ccw-Cqp4oqHV.js} +1 -1
  168. package/payload/server/public/assets/{tasks-DlgiCafL.js → tasks-bQKOhMga.js} +1 -1
  169. package/payload/server/public/assets/{time-entry-format-CyNYVDkq.js → time-entry-format-BIL4ZaDK.js} +1 -1
  170. package/payload/server/public/assets/useCopyFeedback-rB8QuqyH.js +1 -0
  171. package/payload/server/public/assets/{useSubAccountSwitcher-1izQvPiD.css → useSubAccountSwitcher-CVHKTSst.css} +1 -1
  172. package/payload/server/public/assets/{useVoiceRecorder-XgpWvXpk.js → useVoiceRecorder-Ctny8qWx.js} +1 -1
  173. package/payload/server/public/browser.html +5 -5
  174. package/payload/server/public/calendar.html +6 -6
  175. package/payload/server/public/chat.html +12 -12
  176. package/payload/server/public/data.html +10 -10
  177. package/payload/server/public/graph.html +11 -11
  178. package/payload/server/public/index.html +13 -13
  179. package/payload/server/public/operator.html +14 -14
  180. package/payload/server/public/public.html +12 -12
  181. package/payload/server/public/tasks.html +5 -5
  182. package/payload/server/server.js +1033 -837
  183. package/payload/server/src-BQ2NYMOT.js +24 -0
  184. package/payload/server/public/assets/chat-Dq-X-ia8.js +0 -1
  185. package/payload/server/public/assets/chevron-left-B3xSeEDR.js +0 -1
  186. package/payload/server/public/assets/data-CUnDzDox.js +0 -1
  187. package/payload/server/public/assets/graph-DbT8nA6R.js +0 -51
  188. package/payload/server/public/assets/graph-labels-C1YIyLiA.js +0 -1
  189. package/payload/server/public/assets/page-BRfxFXyi.js +0 -32
  190. package/payload/server/public/assets/page-CfQFAJia.js +0 -1
  191. package/payload/server/public/assets/useCopyFeedback-ByGUMN94.js +0 -1
  192. /package/payload/server/public/assets/{useSubAccountSwitcher-s6WlRn52.js → useSubAccountSwitcher-CHEt_m6q.js} +0 -0
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = __importDefault(require("node:test"));
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = require("node:path");
10
+ const node_os_1 = require("node:os");
11
+ const remediate_run_js_1 = require("../bin/remediate-run.js");
12
+ function fixture() {
13
+ const root = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "sb-remediate-"));
14
+ const accountsDir = (0, node_path_1.join)(root, "data", "accounts");
15
+ for (const acc of ["acc-a", "acc-b"]) {
16
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(accountsDir, acc, "secrets"), { recursive: true });
17
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(accountsDir, acc, "secrets", "cloudflare.env"), `CLOUDFLARE_ACCOUNT_ID=shared\nCLOUDFLARE_API_TOKEN=cfat_master\nCF_PAGES_D1_TOKEN=cfat_pd\nCF_DNS_TOKEN=keep\n`);
18
+ }
19
+ return { root, accountsDir, configPath: (0, node_path_1.join)(root, "config", "cloudflare-house.env") };
20
+ }
21
+ function baseDeps(f, registered) {
22
+ return {
23
+ cfD1: async () => [{ name: "gls-leads", cfResourceId: "u1" }],
24
+ cfR2: async () => [],
25
+ mapping: { "gls-leads": "acc-a" },
26
+ register: async (r) => { registered.push(r); },
27
+ accountsDir: f.accountsDir,
28
+ master: { apiToken: "cfat_master", accountId: "shared" },
29
+ configPath: f.configPath,
30
+ };
31
+ }
32
+ (0, node_test_1.default)("fails closed on an unmapped resource and writes nothing", async () => {
33
+ const f = fixture();
34
+ const registered = [];
35
+ const deps = { ...baseDeps(f, registered), cfD1: async () => [
36
+ { name: "gls-leads", cfResourceId: "u1" },
37
+ { name: "beagle-investors", cfResourceId: "u2" },
38
+ ] };
39
+ try {
40
+ await strict_1.default.rejects(() => (0, remediate_run_js_1.runRemediation)(deps), /unmapped resources: beagle-investors/);
41
+ strict_1.default.equal(registered.length, 0, "no resource registered on abort");
42
+ strict_1.default.equal((0, node_fs_1.existsSync)(f.configPath), false, "no house config written on abort");
43
+ const secrets = (0, node_fs_1.readFileSync)((0, node_path_1.join)(f.accountsDir, "acc-a", "secrets", "cloudflare.env"), "utf8");
44
+ strict_1.default.match(secrets, /CLOUDFLARE_API_TOKEN=cfat_master/, "secrets untouched on abort");
45
+ }
46
+ finally {
47
+ (0, node_fs_1.rmSync)(f.root, { recursive: true, force: true });
48
+ }
49
+ });
50
+ (0, node_test_1.default)("registers, relocates the master, and strips every account-wide token", async () => {
51
+ const f = fixture();
52
+ const registered = [];
53
+ try {
54
+ const result = await (0, remediate_run_js_1.runRemediation)(baseDeps(f, registered));
55
+ strict_1.default.equal(result.registered, 1);
56
+ strict_1.default.deepEqual(registered, [
57
+ { accountId: "acc-a", kind: "d1", name: "gls-leads", cfResourceId: "u1" },
58
+ ]);
59
+ // House config now holds the master.
60
+ const house = (0, node_fs_1.readFileSync)(f.configPath, "utf8");
61
+ strict_1.default.match(house, /CLOUDFLARE_API_TOKEN=cfat_master/);
62
+ strict_1.default.match(house, /CLOUDFLARE_ACCOUNT_ID=shared/);
63
+ // Both sub-account secrets are stripped of account-wide tokens, scoped kept.
64
+ for (const acc of ["acc-a", "acc-b"]) {
65
+ const s = (0, node_fs_1.readFileSync)((0, node_path_1.join)(f.accountsDir, acc, "secrets", "cloudflare.env"), "utf8");
66
+ strict_1.default.doesNotMatch(s, /CLOUDFLARE_API_TOKEN=/);
67
+ strict_1.default.doesNotMatch(s, /CF_PAGES_D1_TOKEN=/);
68
+ strict_1.default.match(s, /CF_DNS_TOKEN=keep/);
69
+ strict_1.default.match(s, /CLOUDFLARE_ACCOUNT_ID=shared/);
70
+ }
71
+ strict_1.default.equal(result.strippedFiles.length, 2);
72
+ }
73
+ finally {
74
+ (0, node_fs_1.rmSync)(f.root, { recursive: true, force: true });
75
+ }
76
+ });
77
+ //# sourceMappingURL=remediate-run.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remediate-run.test.js","sourceRoot":"","sources":["../../src/__tests__/remediate-run.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=remediate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remediate.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/remediate.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = __importDefault(require("node:test"));
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const remediate_js_1 = require("../remediate.js");
9
+ (0, node_test_1.default)("fails closed on an unmapped resource", () => {
10
+ const r = (0, remediate_js_1.validateMapping)(["gls-leads", "beagle-investors"], { "gls-leads": "acc-a" });
11
+ strict_1.default.deepEqual(r, { ok: false, missing: ["beagle-investors"] });
12
+ });
13
+ (0, node_test_1.default)("passes when every resource is mapped", () => {
14
+ strict_1.default.deepEqual((0, remediate_js_1.validateMapping)(["gls-leads"], { "gls-leads": "acc-a" }), {
15
+ ok: true,
16
+ missing: [],
17
+ });
18
+ });
19
+ (0, node_test_1.default)("strips only account-wide token lines, keeps the account id and scoped tokens", () => {
20
+ const before = "CLOUDFLARE_ACCOUNT_ID=acc\nCLOUDFLARE_API_TOKEN=cfat_x\nCF_PAGES_D1_TOKEN=y\nCF_DNS_TOKEN=keep\n";
21
+ strict_1.default.equal((0, remediate_js_1.stripAccountWideTokens)(before), "CLOUDFLARE_ACCOUNT_ID=acc\nCF_DNS_TOKEN=keep\n");
22
+ });
23
+ //# sourceMappingURL=remediate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remediate.test.js","sourceRoot":"","sources":["../../src/__tests__/remediate.test.ts"],"names":[],"mappings":";;;;;AAAA,0DAA6B;AAC7B,gEAAwC;AACxC,kDAA0E;AAE1E,IAAA,mBAAI,EAAC,sCAAsC,EAAE,GAAG,EAAE;IAChD,MAAM,CAAC,GAAG,IAAA,8BAAe,EAAC,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;IACvF,gBAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC,CAAC,CAAC;AAEH,IAAA,mBAAI,EAAC,sCAAsC,EAAE,GAAG,EAAE;IAChD,gBAAM,CAAC,SAAS,CAAC,IAAA,8BAAe,EAAC,CAAC,WAAW,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,EAAE;QACzE,EAAE,EAAE,IAAI;QACR,OAAO,EAAE,EAAE;KACZ,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,mBAAI,EAAC,8EAA8E,EAAE,GAAG,EAAE;IACxF,MAAM,MAAM,GACV,kGAAkG,CAAC;IACrG,gBAAM,CAAC,KAAK,CAAC,IAAA,qCAAsB,EAAC,MAAM,CAAC,EAAE,gDAAgD,CAAC,CAAC;AACjG,CAAC,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ export type StrayKind = "unattributed-d1" | "unattributed-r2" | "account-wide-token";
2
+ export interface Stray {
3
+ kind: StrayKind;
4
+ detail: string;
5
+ }
6
+ export interface AuditDeps {
7
+ cfD1(): Promise<string[]>;
8
+ cfR2(): Promise<string[]>;
9
+ registeredNames(kind: "d1" | "r2"): Promise<string[]>;
10
+ accountSecretsFiles(): Promise<Array<{
11
+ accountId: string;
12
+ path: string;
13
+ contents: string;
14
+ }>>;
15
+ }
16
+ export declare function reconcileStorage(deps: AuditDeps): Promise<{
17
+ strays: Stray[];
18
+ }>;
19
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,SAAS,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAErF,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,SAAS;IACxB,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1B,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1B,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD,mBAAmB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CAC9F;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,KAAK,EAAE,CAAA;CAAE,CAAC,CA8BpF"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ // The standing audit: an independent periodic reconcile, not a per-action log,
3
+ // because the failure mode is a no-event blind spot. A mis-registered resource
4
+ // or a stray account-wide token leaks nothing until an agent happens to touch
5
+ // it. This reconciles what Cloudflare has against what the registry records and
6
+ // against what the per-account secrets files still carry.
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.reconcileStorage = reconcileStorage;
9
+ // Keys that must never remain in a sub-account's cloudflare.env after
10
+ // remediation. Each is an account-wide capability.
11
+ const ACCOUNT_WIDE_KEYS = ["CLOUDFLARE_API_TOKEN", "CF_PAGES_D1_TOKEN", "CF_PAGES_TOKEN"];
12
+ async function reconcileStorage(deps) {
13
+ const strays = [];
14
+ const [cfD1, cfR2, regD1, regR2, secretsFiles] = await Promise.all([
15
+ deps.cfD1(),
16
+ deps.cfR2(),
17
+ deps.registeredNames("d1"),
18
+ deps.registeredNames("r2"),
19
+ deps.accountSecretsFiles(),
20
+ ]);
21
+ const regD1Set = new Set(regD1);
22
+ for (const name of cfD1) {
23
+ if (!regD1Set.has(name))
24
+ strays.push({ kind: "unattributed-d1", detail: name });
25
+ }
26
+ const regR2Set = new Set(regR2);
27
+ for (const name of cfR2) {
28
+ if (!regR2Set.has(name))
29
+ strays.push({ kind: "unattributed-r2", detail: name });
30
+ }
31
+ for (const file of secretsFiles) {
32
+ for (const line of file.contents.split("\n")) {
33
+ const key = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)=/)?.[1];
34
+ if (key && ACCOUNT_WIDE_KEYS.includes(key)) {
35
+ strays.push({ kind: "account-wide-token", detail: `${file.accountId}:${key}` });
36
+ }
37
+ }
38
+ }
39
+ return { strays };
40
+ }
41
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,0DAA0D;;AAoB1D,4CA8BC;AAzCD,sEAAsE;AACtE,mDAAmD;AACnD,MAAM,iBAAiB,GAAG,CAAC,sBAAsB,EAAE,mBAAmB,EAAE,gBAAgB,CAAC,CAAC;AASnF,KAAK,UAAU,gBAAgB,CAAC,IAAe;IACpD,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACjE,IAAI,CAAC,IAAI,EAAE;QACX,IAAI,CAAC,IAAI,EAAE;QACX,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,mBAAmB,EAAE;KAC3B,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7D,IAAI,GAAG,IAAI,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export type StorageAction = "list" | "read" | "write";
2
+ export interface AccessDecision {
3
+ allow: boolean;
4
+ reason: string;
5
+ }
6
+ export declare function authorizeAccess(params: {
7
+ caller: string;
8
+ owner: string | null;
9
+ action: StorageAction;
10
+ }): AccessDecision;
11
+ //# sourceMappingURL=authorize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../src/authorize.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,aAAa,CAAC;CACvB,GAAG,cAAc,CAKjB"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ // The pure ownership decision at the centre of the storage broker. No I/O:
3
+ // given who is calling and who owns a resource, decide allow or deny. The
4
+ // caller identity is always the trusted header value the service resolved,
5
+ // never an agent-supplied argument.
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.authorizeAccess = authorizeAccess;
8
+ function authorizeAccess(params) {
9
+ if (!params.caller)
10
+ return { allow: false, reason: "no-caller" };
11
+ if (params.owner === null)
12
+ return { allow: false, reason: "unregistered" };
13
+ if (params.owner !== params.caller)
14
+ return { allow: false, reason: "cross-account" };
15
+ return { allow: true, reason: "owner" };
16
+ }
17
+ //# sourceMappingURL=authorize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../src/authorize.ts"],"names":[],"mappings":";AAAA,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,oCAAoC;;AASpC,0CASC;AATD,SAAgB,eAAe,CAAC,MAI/B;IACC,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACjE,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAC3E,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACrF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type StorageResource } from "../registry.js";
2
+ export interface RemediationDeps {
3
+ cfD1(): Promise<Array<{
4
+ name: string;
5
+ cfResourceId: string;
6
+ }>>;
7
+ cfR2(): Promise<Array<{
8
+ name: string;
9
+ cfResourceId: string;
10
+ }>>;
11
+ mapping: Record<string, string>;
12
+ register(r: StorageResource): Promise<void>;
13
+ accountsDir: string;
14
+ master: {
15
+ apiToken: string;
16
+ accountId: string;
17
+ };
18
+ configPath: string;
19
+ }
20
+ export interface RemediationResult {
21
+ registered: number;
22
+ strippedFiles: string[];
23
+ }
24
+ export declare function runRemediation(deps: RemediationDeps): Promise<RemediationResult>;
25
+ //# sourceMappingURL=remediate-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remediate-run.d.ts","sourceRoot":"","sources":["../../src/bin/remediate-run.ts"],"names":[],"mappings":"AAaA,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIxE,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC/D,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC/D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2CtF"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ // Operator-run remediation of an existing multi-tenant install. Registers every
3
+ // existing D1 database and R2 bucket to its owning account, relocates the master
4
+ // token into the house-only config file, and strips every account-wide token
5
+ // from every sub-account secrets file. Fails closed on any enumerated resource
6
+ // the operator did not map: ownership is never guessed.
7
+ //
8
+ // runRemediation is the testable core (all effects injected or against a given
9
+ // directory). main() wires the real deps and is the on-device entry the shell
10
+ // wrapper calls.
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.runRemediation = runRemediation;
13
+ const node_fs_1 = require("node:fs");
14
+ const node_path_1 = require("node:path");
15
+ const remediate_js_1 = require("../remediate.js");
16
+ const registry_js_1 = require("../registry.js");
17
+ const house_credential_js_1 = require("../house-credential.js");
18
+ const cf_exec_js_1 = require("../cf-exec.js");
19
+ async function runRemediation(deps) {
20
+ const d1 = await deps.cfD1();
21
+ const r2 = await deps.cfR2();
22
+ const enumerated = [...d1.map((x) => x.name), ...r2.map((x) => x.name)];
23
+ // Fail closed BEFORE any write: an enumerated resource with no mapped owner
24
+ // aborts the whole run, leaving the install untouched.
25
+ const validation = (0, remediate_js_1.validateMapping)(enumerated, deps.mapping);
26
+ if (!validation.ok) {
27
+ throw new Error(`storage-broker remediation: unmapped resources: ${validation.missing.join(", ")}`);
28
+ }
29
+ for (const x of d1) {
30
+ await deps.register({ accountId: deps.mapping[x.name], kind: "d1", name: x.name, cfResourceId: x.cfResourceId });
31
+ }
32
+ for (const x of r2) {
33
+ await deps.register({ accountId: deps.mapping[x.name], kind: "r2", name: x.name, cfResourceId: x.cfResourceId });
34
+ }
35
+ // Relocate the master into the house-only config file (read before stripping).
36
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(deps.configPath), { recursive: true });
37
+ (0, node_fs_1.writeFileSync)(deps.configPath, `CLOUDFLARE_API_TOKEN=${deps.master.apiToken}\nCLOUDFLARE_ACCOUNT_ID=${deps.master.accountId}\n`, { mode: 0o600 });
38
+ // Strip every account-wide token from every sub-account secrets file.
39
+ const strippedFiles = [];
40
+ if ((0, node_fs_1.existsSync)(deps.accountsDir)) {
41
+ for (const accountId of (0, node_fs_1.readdirSync)(deps.accountsDir)) {
42
+ const p = (0, node_path_1.join)(deps.accountsDir, accountId, "secrets", "cloudflare.env");
43
+ if (!(0, node_fs_1.existsSync)(p))
44
+ continue;
45
+ const before = (0, node_fs_1.readFileSync)(p, "utf8");
46
+ const after = (0, remediate_js_1.stripAccountWideTokens)(before);
47
+ if (after !== before) {
48
+ (0, node_fs_1.writeFileSync)(p, after, { mode: 0o600 });
49
+ strippedFiles.push(p);
50
+ }
51
+ }
52
+ }
53
+ return { registered: d1.length + r2.length, strippedFiles };
54
+ }
55
+ // --- on-device CLI (untested glue) ----------------------------------------
56
+ function findMasterFromAccounts(accountsDir) {
57
+ if (!(0, node_fs_1.existsSync)(accountsDir))
58
+ return null;
59
+ for (const accountId of (0, node_fs_1.readdirSync)(accountsDir)) {
60
+ const p = (0, node_path_1.join)(accountsDir, accountId, "secrets", "cloudflare.env");
61
+ if (!(0, node_fs_1.existsSync)(p))
62
+ continue;
63
+ const env = {};
64
+ for (const line of (0, node_fs_1.readFileSync)(p, "utf8").split("\n")) {
65
+ const m = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
66
+ if (m)
67
+ env[m[1]] = m[2].trim();
68
+ }
69
+ if (env.CLOUDFLARE_API_TOKEN && env.CLOUDFLARE_ACCOUNT_ID) {
70
+ return { apiToken: env.CLOUDFLARE_API_TOKEN, accountId: env.CLOUDFLARE_ACCOUNT_ID };
71
+ }
72
+ }
73
+ return null;
74
+ }
75
+ async function main() {
76
+ const mappingFile = process.argv[2];
77
+ if (!mappingFile || !(0, node_fs_1.existsSync)(mappingFile)) {
78
+ console.error(`[remediate] error: mapping file not found: ${mappingFile ?? "(none)"}`);
79
+ process.exit(2);
80
+ }
81
+ const platformRoot = process.env.PLATFORM_ROOT;
82
+ if (!platformRoot) {
83
+ console.error("[remediate] error: PLATFORM_ROOT not set");
84
+ process.exit(2);
85
+ }
86
+ const accountsDir = (0, node_path_1.resolve)(platformRoot, "..", "data", "accounts");
87
+ const configPath = (0, node_path_1.join)(platformRoot, "config", "cloudflare-house.env");
88
+ const mapping = JSON.parse((0, node_fs_1.readFileSync)(mappingFile, "utf8"));
89
+ // The master is wherever it lives today: the house file if already relocated,
90
+ // else the first sub-account secrets file that still carries it.
91
+ let master;
92
+ try {
93
+ master = (0, house_credential_js_1.readHouseCredential)(platformRoot);
94
+ }
95
+ catch {
96
+ const found = findMasterFromAccounts(accountsDir);
97
+ if (!found) {
98
+ console.error("[remediate] error: no Cloudflare master token found in house config or account secrets");
99
+ process.exit(2);
100
+ return;
101
+ }
102
+ master = found;
103
+ }
104
+ const cf = (0, cf_exec_js_1.makeCfExec)(master);
105
+ const neo4j = (await import("neo4j-driver"));
106
+ const driver = neo4j.default.driver(process.env.NEO4J_URI, neo4j.default.auth.basic(process.env.NEO4J_USER ?? "neo4j", process.env.NEO4J_PASSWORD ?? ""));
107
+ const session = driver.session();
108
+ try {
109
+ const result = await runRemediation({
110
+ cfD1: async () => (await cf.d1List()).map((d) => ({ name: d.name, cfResourceId: d.uuid })),
111
+ cfR2: async () => (await cf.r2List()).map((b) => ({ name: b.name, cfResourceId: b.name })),
112
+ mapping,
113
+ register: (r) => (0, registry_js_1.registerResource)(session, r),
114
+ accountsDir,
115
+ master,
116
+ configPath,
117
+ });
118
+ console.error(`[remediate] done registered=${result.registered} stripped=${result.strippedFiles.length}`);
119
+ }
120
+ finally {
121
+ await session.close();
122
+ await driver.close();
123
+ }
124
+ }
125
+ if (require.main === module) {
126
+ main().catch((err) => {
127
+ console.error(`[remediate] error: ${err.message}`);
128
+ process.exit(1);
129
+ });
130
+ }
131
+ //# sourceMappingURL=remediate-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remediate-run.js","sourceRoot":"","sources":["../../src/bin/remediate-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { HouseCredential } from "./house-credential.js";
2
+ export type RunFn = (cmd: string, args: string[], env: Record<string, string>) => Promise<{
3
+ stdout: string;
4
+ }>;
5
+ export interface CfExec {
6
+ d1List(): Promise<{
7
+ name: string;
8
+ uuid: string;
9
+ }[]>;
10
+ d1Create(name: string): Promise<{
11
+ uuid: string;
12
+ }>;
13
+ d1Query(name: string, sql: string): Promise<unknown>;
14
+ r2List(): Promise<{
15
+ name: string;
16
+ }[]>;
17
+ r2Create(name: string): Promise<void>;
18
+ }
19
+ export declare function makeCfExec(cred: HouseCredential, run?: RunFn): CfExec;
20
+ //# sourceMappingURL=cf-exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cf-exec.d.ts","sourceRoot":"","sources":["../src/cf-exec.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,KAAK,GAAG,CAClB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACxB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjC,MAAM,WAAW,MAAM;IACrB,MAAM,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAqBD,wBAAgB,UAAU,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,GAAE,KAAkB,GAAG,MAAM,CAgCjF"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ // The only place the account-wide Cloudflare credential is used to touch
3
+ // Cloudflare. Every method injects the house token into the child env and shells
4
+ // wrangler. `run` is injectable so the wiring is unit-testable without wrangler.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.makeCfExec = makeCfExec;
7
+ const node_child_process_1 = require("node:child_process");
8
+ const defaultRun = (cmd, args, env) => new Promise((resolve, reject) => {
9
+ (0, node_child_process_1.execFile)(cmd, args, { env }, (err, stdout, stderr) => {
10
+ if (err) {
11
+ reject(new Error(`${cmd} ${args.join(" ")} failed: ${err.message}\n${stderr}`));
12
+ return;
13
+ }
14
+ resolve({ stdout: stdout.toString() });
15
+ });
16
+ });
17
+ function parseJson(raw, context) {
18
+ try {
19
+ return JSON.parse(raw);
20
+ }
21
+ catch {
22
+ throw new Error(`storage-broker: ${context} returned non-JSON output: ${raw}`);
23
+ }
24
+ }
25
+ function makeCfExec(cred, run = defaultRun) {
26
+ const env = {
27
+ ...process.env,
28
+ CLOUDFLARE_API_TOKEN: cred.apiToken,
29
+ CLOUDFLARE_ACCOUNT_ID: cred.accountId,
30
+ };
31
+ return {
32
+ async d1List() {
33
+ const { stdout } = await run("wrangler", ["d1", "list", "--json"], env);
34
+ return parseJson(stdout, "d1 list");
35
+ },
36
+ async d1Create(name) {
37
+ const { stdout } = await run("wrangler", ["d1", "create", name, "--json"], env);
38
+ return parseJson(stdout, "d1 create");
39
+ },
40
+ async d1Query(name, sql) {
41
+ const { stdout } = await run("wrangler", ["d1", "execute", name, "--remote", "--json", "--command", sql], env);
42
+ return parseJson(stdout, "d1 execute");
43
+ },
44
+ async r2List() {
45
+ const { stdout } = await run("wrangler", ["r2", "bucket", "list", "--json"], env);
46
+ return parseJson(stdout, "r2 bucket list");
47
+ },
48
+ async r2Create(name) {
49
+ await run("wrangler", ["r2", "bucket", "create", name], env);
50
+ },
51
+ };
52
+ }
53
+ //# sourceMappingURL=cf-exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cf-exec.js","sourceRoot":"","sources":["../src/cf-exec.ts"],"names":[],"mappings":";AAAA,yEAAyE;AACzE,iFAAiF;AACjF,iFAAiF;;AAsCjF,gCAgCC;AApED,2DAA8C;AAiB9C,MAAM,UAAU,GAAU,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAC3C,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC9B,IAAA,6BAAQ,EAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QACnD,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC;YAChF,OAAO;QACT,CAAC;QACD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,SAAS,SAAS,CAAC,GAAW,EAAE,OAAe;IAC7C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,8BAA8B,GAAG,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAgB,UAAU,CAAC,IAAqB,EAAE,MAAa,UAAU;IACvE,MAAM,GAAG,GAAG;QACV,GAAG,OAAO,CAAC,GAAG;QACd,oBAAoB,EAAE,IAAI,CAAC,QAAQ;QACnC,qBAAqB,EAAE,IAAI,CAAC,SAAS;KACZ,CAAC;IAE5B,OAAO;QACL,KAAK,CAAC,MAAM;YACV,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;YACxE,OAAO,SAAS,CAAC,MAAM,EAAE,SAAS,CAAqC,CAAC;QAC1E,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;YAChF,OAAO,SAAS,CAAC,MAAM,EAAE,WAAW,CAAqB,CAAC;QAC5D,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;YACrB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAC1B,UAAU,EACV,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,CAAC,EAC/D,GAAG,CACJ,CAAC;YACF,OAAO,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACzC,CAAC;QACD,KAAK,CAAC,MAAM;YACV,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;YAClF,OAAO,SAAS,CAAC,MAAM,EAAE,gBAAgB,CAAuB,CAAC;QACnE,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,IAAI;YACjB,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/D,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface HouseCredential {
2
+ apiToken: string;
3
+ accountId: string;
4
+ }
5
+ export declare function readHouseCredential(platformRoot: string): HouseCredential;
6
+ //# sourceMappingURL=house-credential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"house-credential.d.ts","sourceRoot":"","sources":["../src/house-credential.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,CAkBzE"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ // Reads the single account-wide Cloudflare credential from the house-only
3
+ // config directory. This file is the one place the account-wide capability
4
+ // lives; sub-account spawns never source it. Parses KEY=value lines without
5
+ // polluting process.env (same discipline as reconcile-bookings' readEnvFile).
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.readHouseCredential = readHouseCredential;
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = require("node:path");
10
+ function readHouseCredential(platformRoot) {
11
+ const path = (0, node_path_1.join)(platformRoot, "config", "cloudflare-house.env");
12
+ let raw;
13
+ try {
14
+ raw = (0, node_fs_1.readFileSync)(path, "utf8");
15
+ }
16
+ catch {
17
+ throw new Error(`storage-broker: house credential not found at ${path}`);
18
+ }
19
+ const env = {};
20
+ for (const line of raw.split("\n")) {
21
+ const m = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
22
+ if (m)
23
+ env[m[1]] = m[2].trim();
24
+ }
25
+ const apiToken = env.CLOUDFLARE_API_TOKEN;
26
+ const accountId = env.CLOUDFLARE_ACCOUNT_ID;
27
+ if (!apiToken)
28
+ throw new Error(`storage-broker: CLOUDFLARE_API_TOKEN missing in ${path}`);
29
+ if (!accountId)
30
+ throw new Error(`storage-broker: CLOUDFLARE_ACCOUNT_ID missing in ${path}`);
31
+ return { apiToken, accountId };
32
+ }
33
+ //# sourceMappingURL=house-credential.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"house-credential.js","sourceRoot":"","sources":["../src/house-credential.ts"],"names":[],"mappings":";AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;;AAU9E,kDAkBC;AA1BD,qCAAuC;AACvC,yCAAiC;AAOjC,SAAgB,mBAAmB,CAAC,YAAoB;IACtD,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,YAAY,EAAE,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAClE,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iDAAiD,IAAI,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC3D,IAAI,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAoB,CAAC;IAC1C,MAAM,SAAS,GAAG,GAAG,CAAC,qBAAqB,CAAC;IAC5C,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,IAAI,EAAE,CAAC,CAAC;IAC1F,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,IAAI,EAAE,CAAC,CAAC;IAC5F,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from "./authorize.js";
2
+ export * from "./registry.js";
3
+ export * from "./house-credential.js";
4
+ export * from "./cf-exec.js";
5
+ export * from "./audit.js";
6
+ export * from "./remediate.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ // storage-broker: the per-account Cloudflare D1/R2 isolation core.
3
+ //
4
+ // The lib is pure and dependency-free at runtime: it opens no Neo4j connection
5
+ // and shells no process on its own. Consumers inject a SessionLike (the ui
6
+ // route uses neo4j-store's getSession; the remediation entry opens its own
7
+ // driver) and, for cf-exec, a RunFn. That keeps every unit testable in
8
+ // isolation and the isolation logic auditable in one place.
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ __exportStar(require("./authorize.js"), exports);
25
+ __exportStar(require("./registry.js"), exports);
26
+ __exportStar(require("./house-credential.js"), exports);
27
+ __exportStar(require("./cf-exec.js"), exports);
28
+ __exportStar(require("./audit.js"), exports);
29
+ __exportStar(require("./remediate.js"), exports);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,mEAAmE;AACnE,EAAE;AACF,+EAA+E;AAC/E,2EAA2E;AAC3E,2EAA2E;AAC3E,uEAAuE;AACvE,4DAA4D;;;;;;;;;;;;;;;;AAE5D,iDAA+B;AAC/B,gDAA8B;AAC9B,wDAAsC;AACtC,+CAA6B;AAC7B,6CAA2B;AAC3B,iDAA+B"}
@@ -0,0 +1,18 @@
1
+ export interface SessionLike {
2
+ run(cypher: string, params?: Record<string, unknown>): PromiseLike<{
3
+ records: Array<{
4
+ get(key: string): any;
5
+ }>;
6
+ }>;
7
+ }
8
+ export type ResourceKind = "d1" | "r2";
9
+ export interface StorageResource {
10
+ accountId: string;
11
+ kind: ResourceKind;
12
+ name: string;
13
+ cfResourceId: string;
14
+ }
15
+ export declare function registerResource(session: SessionLike, r: StorageResource): Promise<void>;
16
+ export declare function resolveOwner(session: SessionLike, kind: ResourceKind, name: string): Promise<string | null>;
17
+ export declare function listResources(session: SessionLike, accountId: string, kind: ResourceKind): Promise<StorageResource[]>;
18
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,WAAW;IAC1B,GAAG,CACD,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,WAAW,CAAC;QAAE,OAAO,EAAE,KAAK,CAAC;YAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,WAAW,EACpB,CAAC,EAAE,eAAe,GACjB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,eAAe,EAAE,CAAC,CAa5B"}