@tokenoftrust/storefront-runner 2.0.2 → 2.0.4

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 (254) hide show
  1. package/apps/storefront/.astro/content.d.ts +159 -0
  2. package/apps/storefront/.astro/integrations/_astrojs_cloudflare/cloudflare.d.ts +1 -0
  3. package/apps/storefront/.astro/types.d.ts +3 -0
  4. package/apps/storefront/node_modules/.bin/acorn +43 -0
  5. package/apps/storefront/node_modules/.bin/astro +43 -0
  6. package/apps/storefront/node_modules/.bin/astro-check +43 -0
  7. package/apps/storefront/node_modules/.bin/browserslist +43 -0
  8. package/apps/storefront/node_modules/.bin/cf-wrangler +43 -0
  9. package/apps/storefront/node_modules/.bin/depcruise +43 -0
  10. package/apps/storefront/node_modules/.bin/depcruise-baseline +43 -0
  11. package/apps/storefront/node_modules/.bin/depcruise-fmt +43 -0
  12. package/apps/storefront/node_modules/.bin/depcruise-wrap-stream-in-html +43 -0
  13. package/apps/storefront/node_modules/.bin/dependency-cruise +43 -0
  14. package/apps/storefront/node_modules/.bin/dependency-cruiser +43 -0
  15. package/apps/storefront/node_modules/.bin/drizzle-kit +43 -0
  16. package/apps/storefront/node_modules/.bin/esbuild +43 -0
  17. package/apps/storefront/node_modules/.bin/jiti +43 -0
  18. package/apps/storefront/node_modules/.bin/playwright +43 -0
  19. package/apps/storefront/node_modules/.bin/playwright-core +43 -0
  20. package/apps/storefront/node_modules/.bin/prettier +43 -0
  21. package/apps/storefront/node_modules/.bin/rollup +43 -0
  22. package/apps/storefront/node_modules/.bin/tsc +43 -0
  23. package/apps/storefront/node_modules/.bin/tsserver +43 -0
  24. package/apps/storefront/node_modules/.bin/tsx +43 -0
  25. package/apps/storefront/node_modules/.bin/vite +43 -0
  26. package/apps/storefront/node_modules/.bin/vitest +43 -0
  27. package/apps/storefront/node_modules/.bin/workerd +43 -0
  28. package/apps/storefront/node_modules/.bin/wrangler +43 -0
  29. package/apps/storefront/node_modules/.bin/wrangler2 +43 -0
  30. package/apps/storefront/node_modules/.bin/yaml +43 -0
  31. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_client__js.js +58 -0
  32. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_client__js.js.map +1 -0
  33. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_n_@preact_signals.js +741 -0
  34. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_n_@preact_signals.js.map +1 -0
  35. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_server__js.js +2549 -0
  36. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_server__js.js.map +1 -0
  37. package/apps/storefront/node_modules/.vite/deps/_metadata.json +150 -0
  38. package/apps/storefront/node_modules/.vite/deps/astro-BIHuWFxm.js +434 -0
  39. package/apps/storefront/node_modules/.vite/deps/astro-BIHuWFxm.js.map +1 -0
  40. package/apps/storefront/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
  41. package/apps/storefront/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
  42. package/apps/storefront/node_modules/.vite/deps/astro_n_axobject-query.js +2705 -0
  43. package/apps/storefront/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
  44. package/apps/storefront/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
  45. package/apps/storefront/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
  46. package/apps/storefront/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
  47. package/apps/storefront/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
  48. package/apps/storefront/node_modules/.vite/deps/audit-DKDpcdEI.js +1535 -0
  49. package/apps/storefront/node_modules/.vite/deps/audit-DKDpcdEI.js.map +1 -0
  50. package/apps/storefront/node_modules/.vite/deps/highlight-B9UoX1wa.js +48 -0
  51. package/apps/storefront/node_modules/.vite/deps/highlight-B9UoX1wa.js.map +1 -0
  52. package/apps/storefront/node_modules/.vite/deps/icons-BWi2wI9n.js +42 -0
  53. package/apps/storefront/node_modules/.vite/deps/icons-BWi2wI9n.js.map +1 -0
  54. package/apps/storefront/node_modules/.vite/deps/package.json +3 -0
  55. package/apps/storefront/node_modules/.vite/deps/preact.js +310 -0
  56. package/apps/storefront/node_modules/.vite/deps/preact.js.map +1 -0
  57. package/apps/storefront/node_modules/.vite/deps/preact_compat.js +420 -0
  58. package/apps/storefront/node_modules/.vite/deps/preact_compat.js.map +1 -0
  59. package/apps/storefront/node_modules/.vite/deps/preact_compat_jsx-runtime.js +4 -0
  60. package/apps/storefront/node_modules/.vite/deps/preact_debug.js +236 -0
  61. package/apps/storefront/node_modules/.vite/deps/preact_debug.js.map +1 -0
  62. package/apps/storefront/node_modules/.vite/deps/preact_devtools.js +12 -0
  63. package/apps/storefront/node_modules/.vite/deps/preact_devtools.js.map +1 -0
  64. package/apps/storefront/node_modules/.vite/deps/preact_hooks.js +192 -0
  65. package/apps/storefront/node_modules/.vite/deps/preact_hooks.js.map +1 -0
  66. package/apps/storefront/node_modules/.vite/deps/preact_jsx-dev-runtime.js +3 -0
  67. package/apps/storefront/node_modules/.vite/deps/preact_jsx-runtime.js +92 -0
  68. package/apps/storefront/node_modules/.vite/deps/preact_jsx-runtime.js.map +1 -0
  69. package/apps/storefront/node_modules/.vite/deps/preact_test-utils.js +59 -0
  70. package/apps/storefront/node_modules/.vite/deps/preact_test-utils.js.map +1 -0
  71. package/apps/storefront/node_modules/.vite/deps/rolldown-runtime-BPOCksWG.js +24 -0
  72. package/apps/storefront/node_modules/.vite/deps/settings-BVDV0Roj.js +189 -0
  73. package/apps/storefront/node_modules/.vite/deps/settings-BVDV0Roj.js.map +1 -0
  74. package/apps/storefront/node_modules/.vite/deps/static-html-DveYqwMo.js +13 -0
  75. package/apps/storefront/node_modules/.vite/deps/static-html-DveYqwMo.js.map +1 -0
  76. package/apps/storefront/node_modules/.vite/deps/toolbar-B3VIHCXg.js +458 -0
  77. package/apps/storefront/node_modules/.vite/deps/toolbar-B3VIHCXg.js.map +1 -0
  78. package/apps/storefront/node_modules/.vite/deps/ui-library-BK6ricUd.js +1016 -0
  79. package/apps/storefront/node_modules/.vite/deps/ui-library-BK6ricUd.js.map +1 -0
  80. package/apps/storefront/node_modules/.vite/deps/window-BvxDenKN.js +32 -0
  81. package/apps/storefront/node_modules/.vite/deps/window-BvxDenKN.js.map +1 -0
  82. package/apps/storefront/node_modules/.vite/deps/xray-YFiRUU0Z.js +113 -0
  83. package/apps/storefront/node_modules/.vite/deps/xray-YFiRUU0Z.js.map +1 -0
  84. package/apps/storefront/node_modules/.vite/deps_ssr/_metadata.json +8 -0
  85. package/apps/storefront/node_modules/.vite/deps_ssr/package.json +3 -0
  86. package/apps/storefront/src/layouts/Layout.astro +1 -1
  87. package/apps/storefront/src/lib/apps/registryAccess.ts +45 -0
  88. package/apps/storefront/src/lib/auth/adminEntry.ts +4 -4
  89. package/apps/storefront/src/lib/shared/capability.ts +68 -0
  90. package/apps/storefront/src/lib/shared/developerInvites.ts +1250 -0
  91. package/apps/storefront/src/lib/shared/invitePreflight.ts +123 -0
  92. package/apps/storefront/src/lib/webhooks/deliveryEngine.ts +38 -4
  93. package/apps/storefront/src/lib/webhooks/emit.ts +1 -1
  94. package/apps/storefront/src/lib/webhooks/getDispatcher.ts +1 -1
  95. package/apps/storefront/src/pages/api/auth/magic-exchange.ts +1 -1
  96. package/apps/storefront/src/pages/index.astro +1 -1
  97. package/apps/storefront/src/pages/products/[handle].astro +1 -1
  98. package/package.json +1 -1
  99. package/packages/public-runtime/node_modules/.bin/tsc +43 -0
  100. package/packages/public-runtime/node_modules/.bin/tsserver +43 -0
  101. package/packages/public-runtime/node_modules/.bin/vitest +43 -0
  102. package/pnpm-workspace.yaml +3 -0
  103. package/scripts/lib/tenant-dirs.mjs +80 -0
  104. package/scripts/tenant/lint-embeds.mjs +180 -0
  105. package/scripts/tenant/materialize-tenant-content.mjs +533 -0
  106. package/scripts/tenant/validate.mjs +837 -0
  107. package/apps/storefront/scripts/build-v84-clean-clone-standalone.mjs +0 -68
  108. package/apps/storefront/scripts/deny-v84-clean-clone-standalone-capabilities.mjs +0 -111
  109. package/apps/storefront/scripts/deny-v84-dogfood-capabilities.mjs +0 -2
  110. package/apps/storefront/scripts/deny-v84-lifecycle-capabilities.mjs +0 -247
  111. package/apps/storefront/scripts/dogfood-v84-nonportable-routes.ts +0 -73
  112. package/apps/storefront/scripts/fixed-v84-native-install-producer.ts +0 -79
  113. package/apps/storefront/scripts/generated/v84-clean-clone-replay.bundle.mjs +0 -10982
  114. package/apps/storefront/scripts/import-v84-through-ws2.ts +0 -38
  115. package/apps/storefront/scripts/initialize-v84-lifecycle-tooling-dependency.ts +0 -2
  116. package/apps/storefront/scripts/initialize-v84-lifecycle-tooling.ts +0 -4
  117. package/apps/storefront/scripts/install-v84-native-through-ws1.ts +0 -185
  118. package/apps/storefront/scripts/prove-clone-isolation.ts +0 -506
  119. package/apps/storefront/scripts/replay-v84-clean-clone-pass.ts +0 -148
  120. package/apps/storefront/scripts/replay-v84-clean-clone-standalone.ts +0 -35
  121. package/apps/storefront/scripts/replay-v84-clean-clone.ts +0 -214
  122. package/apps/storefront/scripts/run-fixed-v84-native-install-producer.mjs +0 -18
  123. package/apps/storefront/scripts/run-v84-clone-isolation-proof.mjs +0 -18
  124. package/apps/storefront/scripts/run-v84-clone-lifecycle-proof.mjs +0 -18
  125. package/apps/storefront/scripts/run-v84-import-through-ws2-proof.mjs +0 -17
  126. package/apps/storefront/scripts/run-v84-nonportable-route-dogfood.mjs +0 -15
  127. package/apps/storefront/scripts/sanitize-v84-proof-environment.mjs +0 -21
  128. package/apps/storefront/scripts/v84CleanCloneGraphPin.ts +0 -42
  129. package/apps/storefront/scripts/v84CleanCloneSourceGraph.ts +0 -145
  130. package/apps/storefront/scripts/validate-v84-clone-lifecycle.ts +0 -18
  131. package/apps/storefront/src/components/admin/AdminAIWorkflowsTab.astro +0 -531
  132. package/apps/storefront/src/components/admin/AdminBlogDetailRail.astro +0 -878
  133. package/apps/storefront/src/components/admin/AdminBlogTab.astro +0 -1435
  134. package/apps/storefront/src/components/admin/AdminCheckoutSettingsPanel.astro +0 -226
  135. package/apps/storefront/src/components/admin/AdminCustomersTab.astro +0 -593
  136. package/apps/storefront/src/components/admin/AdminFulfillmentTab.astro +0 -465
  137. package/apps/storefront/src/components/admin/AdminIntegrationsTab.astro +0 -105
  138. package/apps/storefront/src/components/admin/AdminProductsTab.astro +0 -901
  139. package/apps/storefront/src/components/admin/AdminPublishTab.astro +0 -2983
  140. package/apps/storefront/src/components/admin/AdminReportingTab.astro +0 -435
  141. package/apps/storefront/src/components/admin/AdminSettingsTab.astro +0 -782
  142. package/apps/storefront/src/components/admin/AdminSubscriptionsTab.astro +0 -611
  143. package/apps/storefront/src/components/admin/orders/OrdersWorkspace.astro +0 -1223
  144. package/apps/storefront/src/lib/apps/adminService.ts +0 -116
  145. package/apps/storefront/src/lib/apps/adminSession.ts +0 -214
  146. package/apps/storefront/src/lib/apps/apiAuth.ts +0 -91
  147. package/apps/storefront/src/lib/apps/apiRoute.ts +0 -35
  148. package/apps/storefront/src/lib/apps/catalogMapper.ts +0 -39
  149. package/apps/storefront/src/lib/apps/consentConfigStore.ts +0 -228
  150. package/apps/storefront/src/lib/apps/gtmMigrationInstall.ts +0 -447
  151. package/apps/storefront/src/lib/apps/gtmMigrationReport.ts +0 -367
  152. package/apps/storefront/src/lib/apps/gtmMigrationTab.ts +0 -315
  153. package/apps/storefront/src/lib/apps/healthAggregate.ts +0 -66
  154. package/apps/storefront/src/lib/apps/integrationLifecycle.ts +0 -614
  155. package/apps/storefront/src/lib/apps/integrationLifecycleController.ts +0 -125
  156. package/apps/storefront/src/lib/apps/integrationReadModel.ts +0 -563
  157. package/apps/storefront/src/lib/apps/integrationsTab.ts +0 -547
  158. package/apps/storefront/src/lib/apps/integrationsView.ts +0 -106
  159. package/apps/storefront/src/lib/apps/managedAnalyticsService.ts +0 -599
  160. package/apps/storefront/src/lib/apps/tenantIntegrationMaterialization.ts +0 -170
  161. package/apps/storefront/src/lib/apps/tokenIssuer.ts +0 -121
  162. package/apps/storefront/src/lib/apps/tokenVerifier.ts +0 -148
  163. package/apps/storefront/src/lib/apps/v84CleanCloneReplayContext.ts +0 -16
  164. package/apps/storefront/src/lib/apps/v84CloneLifecycleCacheEvidence.ts +0 -105
  165. package/apps/storefront/src/lib/apps/v84CloneLifecycleEvidence.ts +0 -177
  166. package/apps/storefront/src/lib/apps/v84CloneLifecycleMaterialization.ts +0 -251
  167. package/apps/storefront/src/lib/apps/v84CloneLifecycleSemantics.ts +0 -241
  168. package/apps/storefront/src/lib/apps/v84CloneMigrationEvidence.ts +0 -211
  169. package/apps/storefront/src/lib/apps/v84CloneNativeInstallEvidence.ts +0 -409
  170. package/apps/storefront/src/lib/apps/v84NonportableCodeCoaching.ts +0 -368
  171. package/apps/storefront/src/lib/apps/v84NonportableRouteContract.ts +0 -188
  172. package/apps/storefront/src/lib/apps/v84NonportableRouteDogfood.ts +0 -291
  173. package/apps/storefront/src/lib/apps/ws1ManagedAnalyticsClient.ts +0 -95
  174. package/apps/storefront/src/lib/content-edit/applyDiff.ts +0 -91
  175. package/apps/storefront/src/lib/content-edit/client.ts +0 -286
  176. package/apps/storefront/src/lib/content-edit/index.ts +0 -14
  177. package/apps/storefront/src/lib/content-edit/route.ts +0 -25
  178. package/apps/storefront/src/lib/content-edit/types.ts +0 -19
  179. package/apps/storefront/src/lib/dev/cockpitStore.ts +0 -57
  180. package/apps/storefront/src/lib/publish/adminPublishTab.ts +0 -4625
  181. package/apps/storefront/src/lib/publish/apex-readiness.ts +0 -360
  182. package/apps/storefront/src/lib/publish/buildStream.ts +0 -269
  183. package/apps/storefront/src/lib/publish/collapsePersistence.ts +0 -72
  184. package/apps/storefront/src/lib/publish/dispatchHealth.ts +0 -267
  185. package/apps/storefront/src/lib/publish/domainState.ts +0 -360
  186. package/apps/storefront/src/lib/publish/lifecycleState.ts +0 -369
  187. package/apps/storefront/src/lib/publish/liveReleaseSummary.ts +0 -29
  188. package/apps/storefront/src/lib/publish/mergeDoctorOnFailure.ts +0 -78
  189. package/apps/storefront/src/lib/publish/mergeHealthBanner.ts +0 -62
  190. package/apps/storefront/src/lib/publish/mergeRowFindings.ts +0 -124
  191. package/apps/storefront/src/lib/publish/mergeSupportEscalation.ts +0 -75
  192. package/apps/storefront/src/lib/publish/panelPolling.ts +0 -78
  193. package/apps/storefront/src/lib/publish/publish-guard.ts +0 -88
  194. package/apps/storefront/src/lib/publish/publishFormat.ts +0 -165
  195. package/apps/storefront/src/lib/publish/publishHero.ts +0 -177
  196. package/apps/storefront/src/lib/publish/reviewRelease/changeState.ts +0 -66
  197. package/apps/storefront/src/lib/publish/reviewRelease/copy.ts +0 -141
  198. package/apps/storefront/src/lib/publish/reviewRelease/index.ts +0 -41
  199. package/apps/storefront/src/lib/publish/reviewRelease/permissions.ts +0 -47
  200. package/apps/storefront/src/lib/publish/reviewRelease/releaseState.ts +0 -42
  201. package/apps/storefront/src/lib/publish/reviewRelease/types.ts +0 -59
  202. package/apps/storefront/src/lib/publish/reviewRelease/viewModel.ts +0 -440
  203. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/actions.ts +0 -161
  204. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/controller.ts +0 -325
  205. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/render.ts +0 -241
  206. package/apps/storefront/src/lib/publish/shipWorkspace.ts +0 -439
  207. package/apps/storefront/src/lib/publish/sseRoute.ts +0 -119
  208. package/apps/storefront/src/lib/publish/stageBundleUpload.ts +0 -215
  209. package/apps/storefront/src/lib/publish/streamLogConsole.ts +0 -142
  210. package/apps/storefront/src/lib/publish/versionNumber.ts +0 -52
  211. package/apps/storefront/src/pages/admin/ops-timeline.astro +0 -420
  212. package/apps/storefront/src/pages/admin/review-release.astro +0 -265
  213. package/apps/storefront/src/pages/admin/select.astro +0 -96
  214. package/apps/storefront/src/pages/admin.astro +0 -570
  215. package/apps/storefront/src/pages/api/apps/admin/credentials/rotate.ts +0 -86
  216. package/apps/storefront/src/pages/api/apps/admin/gtm-migration-install.ts +0 -174
  217. package/apps/storefront/src/pages/api/apps/admin/gtm-migration.ts +0 -96
  218. package/apps/storefront/src/pages/api/apps/admin/health.ts +0 -44
  219. package/apps/storefront/src/pages/api/apps/admin/install.ts +0 -125
  220. package/apps/storefront/src/pages/api/apps/admin/integration-lifecycle.ts +0 -118
  221. package/apps/storefront/src/pages/api/apps/admin/integrations.ts +0 -89
  222. package/apps/storefront/src/pages/api/apps/admin/list.ts +0 -26
  223. package/apps/storefront/src/pages/api/apps/admin/platform-adapters.ts +0 -85
  224. package/apps/storefront/src/pages/api/apps/admin/resume.ts +0 -79
  225. package/apps/storefront/src/pages/api/apps/admin/suspend.ts +0 -80
  226. package/apps/storefront/src/pages/api/apps/admin/uninstall.ts +0 -98
  227. package/apps/storefront/src/pages/api/apps/admin/update.ts +0 -126
  228. package/apps/storefront/src/pages/api/apps/admin/webhooks/deliveries/[deliveryId]/replay.ts +0 -70
  229. package/apps/storefront/src/pages/api/apps/admin/webhooks/deliveries.ts +0 -51
  230. package/apps/storefront/src/pages/api/apps/internal/order-forward.ts +0 -255
  231. package/apps/storefront/src/pages/api/apps/oauth/token.ts +0 -87
  232. package/apps/storefront/src/pages/api/apps/v1/attribution.ts +0 -162
  233. package/apps/storefront/src/pages/api/apps/v1/catalog/products/[handle].ts +0 -39
  234. package/apps/storefront/src/pages/api/apps/v1/catalog/products.ts +0 -49
  235. package/apps/storefront/src/pages/api/apps/v1/health.ts +0 -32
  236. package/apps/storefront/src/pages/api/apps/v1/inventory.ts +0 -59
  237. package/apps/storefront/src/pages/api/apps/v1/orders/[id].ts +0 -48
  238. package/apps/storefront/src/pages/api/apps/v1/orders.ts +0 -73
  239. package/apps/storefront/src/pages/api/apps/v1/reports.ts +0 -21
  240. package/apps/storefront/src/pages/api/apps/v1/webhooks/deliveries/[deliveryId]/replay.ts +0 -74
  241. package/apps/storefront/src/pages/api/apps/v1/webhooks/deliveries.ts +0 -47
  242. package/apps/storefront/src/pages/api/cache-purge.ts +0 -55
  243. package/apps/storefront/src/pages/api/compliance/tamper.ts +0 -88
  244. package/apps/storefront/src/pages/api/content-edit/ai-edit.ts +0 -164
  245. package/apps/storefront/src/pages/api/dashboard/enter-vendor.ts +0 -154
  246. package/apps/storefront/src/pages/api/dashboard/vendor-search.ts +0 -120
  247. package/apps/storefront/src/pages/api/integrations/v1/[operation].ts +0 -108
  248. package/apps/storefront/src/pages/api/publish/stage-bundle.ts +0 -70
  249. package/apps/storefront/src/pages/api/test/dev-session.ts +0 -133
  250. package/apps/storefront/src/pages/cockpit.astro +0 -1548
  251. package/apps/storefront/src/pages/dashboard/[appDomain]/apps/index.astro +0 -119
  252. package/apps/storefront/src/pages/dashboard/[appDomain]/index.astro +0 -105
  253. package/apps/storefront/src/pages/dashboard/[appDomain]/team.astro +0 -177
  254. package/apps/storefront/src/pages/dashboard/index.astro +0 -160
@@ -1,170 +0,0 @@
1
- /**
2
- * Control-plane materialization of a tenant's OWN (`tenant-local`) integration
3
- * declarations for the admin seams (ext-kernel-09).
4
- *
5
- * The middleware materializes these same declarations on the render hot path; this
6
- * module materializes them for the ADMIN plane — the ext-admin-02 read model and the
7
- * ext-admin-07 lifecycle route — so a declared integration shows its REAL effective
8
- * state (its resolved plan, compiled CSP, consent needs) instead of a null /
9
- * `not_materialized` placeholder. Resolution runs through the SAME interim marketing
10
- * bridge the render path uses, so a regulated tenant is refused identically (no
11
- * effective plan → the declaration surfaces honestly as unmaterialized) and an
12
- * eligible unregulated one resolves the exact plan it serves.
13
- *
14
- * A tenant-local declaration is a live-by-config integration (on-by-default), not a
15
- * candidate under review: its effective state is what the read model shows and what
16
- * the lifecycle route loads. It has no separate promotion gate — publishing an
17
- * on-by-default declaration would change nothing — so the lifecycle route surfaces
18
- * its live state and refuses a preview/publish with no candidate rather than
19
- * fabricating one.
20
- */
21
- import { loadTenantIntegrationDeclarations } from "@/lib/integration/tenantDeclarations";
22
- import {
23
- resolveInterimBridgePlan,
24
- compileIntegrationCspFromPlan,
25
- collectDeclaredCspProfiles,
26
- buildCandidateEvidence,
27
- defaultConsentSnapshot,
28
- ENVIRONMENT_SCHEMA_VERSION,
29
- type TenantConfig,
30
- type BrowserEnvironment,
31
- type IntegrationEnvironment,
32
- type IntegrationSiteSurface,
33
- type EffectivePlan,
34
- type CompiledIntegrationCsp,
35
- type ConsentSnapshot,
36
- type AssetVerificationResult,
37
- } from "@tot/public-runtime";
38
- import type { IntegrationReadModelInputItem } from "@/lib/apps/integrationReadModel.js";
39
- import {
40
- facetsFromEvidence,
41
- initialLifecycleState,
42
- type TenantIntegrationLifecycleState,
43
- } from "@/lib/apps/integrationLifecycle.js";
44
-
45
- /** Stable, synthetic install id for a tenant-local declaration (no registry install backs it). */
46
- export function tenantLocalInstallId(appId: string): string {
47
- return `tenant-local:${appId}`;
48
- }
49
-
50
- /** A same-origin (public/-committed) entry declares no R2 app assets — a clean zero verify. */
51
- const NO_R2_APP_ASSETS: AssetVerificationResult = { expected: 0, verified: 0, missing: [] };
52
-
53
- /** The admin-plane browser environment for a lifecycle stage — the `admin` surface. */
54
- function adminEnvironment(tenant: TenantConfig, stage: IntegrationEnvironment): BrowserEnvironment {
55
- const surface: IntegrationSiteSurface = "admin";
56
- return {
57
- schemaVersion: ENVIRONMENT_SCHEMA_VERSION,
58
- siteSurface: surface,
59
- environment: stage,
60
- canonicalHost: tenant.canonicalDomain || tenant.tenant_id,
61
- revision: `admin-${stage}`,
62
- };
63
- }
64
-
65
- /** The resolved plan + compiled CSP + consent snapshot for a tenant's tenant-local declarations. */
66
- export interface MaterializedTenantLocalPlan {
67
- plan: EffectivePlan;
68
- compiledCsp: CompiledIntegrationCsp;
69
- consentSnapshot: ConsentSnapshot;
70
- }
71
-
72
- /**
73
- * Resolve a tenant's tenant-local declarations into the effective plan + compiled CSP
74
- * for `stage`, through the interim bridge. Null when the tenant declares none, the
75
- * bridge refuses (regulated), or the plan/CSP fail closed — every "no effective state"
76
- * case an honest null, never a partial plan.
77
- */
78
- export function materializeTenantLocalPlan(
79
- tenant: TenantConfig,
80
- stage: IntegrationEnvironment,
81
- ): MaterializedTenantLocalPlan | null {
82
- const declarations = loadTenantIntegrationDeclarations(tenant);
83
- if (declarations.length === 0) return null;
84
- const bridge = resolveInterimBridgePlan({
85
- tenantPublicId: tenant.tenant_id,
86
- tenant,
87
- environment: adminEnvironment(tenant, stage),
88
- declarations,
89
- });
90
- if (!bridge.ok) return null;
91
- const compiled = compileIntegrationCspFromPlan(
92
- bridge.plan,
93
- collectDeclaredCspProfiles(declarations),
94
- );
95
- if (!compiled.ok) return null;
96
- return { plan: bridge.plan, compiledCsp: compiled.value, consentSnapshot: defaultConsentSnapshot() };
97
- }
98
-
99
- /**
100
- * Build the ext-admin-02 read-model input items for a tenant's tenant-local
101
- * declarations. Each carries the resolved effective plan + compiled CSP so the
102
- * assembler surfaces REAL effective state; a refused/failed resolution yields a null
103
- * effective plan, so the declaration surfaces as honestly unmaterialized (never a
104
- * fabricated live state).
105
- */
106
- export function tenantLocalReadModelItems(
107
- tenant: TenantConfig,
108
- stage: IntegrationEnvironment,
109
- ): IntegrationReadModelInputItem[] {
110
- const declarations = loadTenantIntegrationDeclarations(tenant);
111
- if (declarations.length === 0) return [];
112
- const materialized = materializeTenantLocalPlan(tenant, stage);
113
- return declarations.map((decl) => {
114
- const { app } = decl.manifest;
115
- return {
116
- install: {
117
- installId: tenantLocalInstallId(app.id),
118
- appId: app.id,
119
- appVersion: app.version,
120
- tenantId: tenant.tenant_id,
121
- status: "active",
122
- },
123
- purpose: app.name,
124
- desiredConfig: decl.publicConfig,
125
- effectivePlan: materialized?.plan ?? null,
126
- effectiveCsp: materialized?.compiledCsp ?? null,
127
- consentSnapshot: materialized?.consentSnapshot ?? null,
128
- };
129
- });
130
- }
131
-
132
- /**
133
- * Load the real lifecycle state for a tenant-local declared install — a live-by-config
134
- * integration whose effective plan occupies the resolved stage slot. Null when the
135
- * install id names no materialized tenant-local declaration for the tenant (so the
136
- * lifecycle route answers a fail-closed 409, never a fabricated state).
137
- */
138
- export function loadTenantLocalLifecycleState(
139
- tenant: TenantConfig,
140
- installId: string,
141
- stage: IntegrationEnvironment,
142
- ): TenantIntegrationLifecycleState | null {
143
- const declarations = loadTenantIntegrationDeclarations(tenant);
144
- const decl = declarations.find((d) => tenantLocalInstallId(d.manifest.app.id) === installId);
145
- if (!decl) return null;
146
- const materialized = materializeTenantLocalPlan(tenant, stage);
147
- if (!materialized) return null;
148
-
149
- const appId = decl.manifest.app.id;
150
- const evidence = buildCandidateEvidence({
151
- plan: materialized.plan,
152
- compiledCsp: materialized.compiledCsp,
153
- assets: NO_R2_APP_ASSETS,
154
- });
155
- if (!evidence.ok) return null;
156
- const facets = facetsFromEvidence(evidence.value, appId);
157
-
158
- const state = initialLifecycleState({
159
- tenantPublicId: tenant.tenant_id,
160
- installId,
161
- appId,
162
- });
163
- // A tenant-local declaration is live-by-config: its resolved plan IS the serving
164
- // (live) facet, and it is its own known-good rollback target.
165
- return {
166
- ...state,
167
- stages: { ...state.stages, live: facets },
168
- knownGood: [facets],
169
- };
170
- }
@@ -1,121 +0,0 @@
1
- /**
2
- * OAuth2 client-credentials token issuer — the Storefront App Gateway's
3
- * `POST /oauth/token` grant. Mints the
4
- * short-lived RS256 JWT a private app presents as a bearer token to the
5
- * scoped APIs.
6
- *
7
- * `tenant` and `env` are supplied by the CALLER (the route, from
8
- * host-resolved context — never from the request body) and checked against
9
- * the install's own `tenantId`/`env`: a credential minted for one
10
- * tenant/env can't be replayed against another, even if the secret leaked.
11
- *
12
- * Fails closed on every rejected path; `TokenError.code` uses the RFC 6749
13
- * §5.2 / §4.1.2.1 error vocabulary so the route can pass it straight through
14
- * as the OAuth2 `error` field. `invalid_client` deliberately covers "unknown
15
- * client_id", "wrong secret", AND "tenant/env mismatch" identically — none of
16
- * those should be distinguishable to a caller (no enumeration oracle).
17
- */
18
- import { SignJWT } from "jose";
19
- import type { AppRegistryService } from "./registryService.js";
20
- import {
21
- loadGatewaySigningConfig,
22
- GatewayKeyError,
23
- APP_GATEWAY_ALG,
24
- APP_TOKEN_TTL_SECONDS,
25
- type GatewayKeyOverrides,
26
- } from "./gatewayKeys.js";
27
-
28
- export type TokenErrorCode = "invalid_client" | "invalid_grant" | "temporarily_unavailable";
29
-
30
- export class TokenError extends Error {
31
- constructor(
32
- message: string,
33
- readonly code: TokenErrorCode,
34
- ) {
35
- super(message);
36
- this.name = "TokenError";
37
- }
38
- }
39
-
40
- /** The narrow secret-verification seam `AppTokenIssuer` depends on (`D1CredentialStore` satisfies it). */
41
- export interface SecretVerifier {
42
- verifySecret(clientId: string, presentedSecret: string): Promise<string | null>;
43
- }
44
-
45
- export interface IssueTokenRequest {
46
- clientId: string;
47
- secret: string;
48
- /** This request's host-resolved tenant (never client-supplied). */
49
- tenant: string;
50
- /** This deploy's own env tier (never client-supplied). */
51
- env: string;
52
- }
53
-
54
- export interface IssuedToken {
55
- accessToken: string;
56
- tokenType: "Bearer";
57
- expiresIn: number;
58
- scope: string;
59
- }
60
-
61
- export class AppTokenIssuer {
62
- constructor(
63
- private readonly registry: AppRegistryService,
64
- private readonly credentials: SecretVerifier,
65
- private readonly keyOverrides: GatewayKeyOverrides = {},
66
- private readonly now: () => number = () => Math.floor(Date.now() / 1000),
67
- ) {}
68
-
69
- async issueToken(req: IssueTokenRequest): Promise<IssuedToken> {
70
- const installId = await this.credentials.verifySecret(req.clientId, req.secret);
71
- if (!installId) {
72
- throw new TokenError("invalid client_id or client_secret", "invalid_client");
73
- }
74
-
75
- const install = await this.registry.get(installId);
76
- // An install row can't outlive its credential row (uninstall clears both),
77
- // but never let a lookup miss here leak any more detail than a bad secret.
78
- if (!install || install.tenantId !== req.tenant || install.env !== req.env) {
79
- throw new TokenError("invalid client_id or client_secret", "invalid_client");
80
- }
81
- if (install.status !== "active") {
82
- throw new TokenError(`install is ${install.status}; token issuance refused`, "invalid_grant");
83
- }
84
-
85
- let signing;
86
- try {
87
- signing = await loadGatewaySigningConfig(this.keyOverrides);
88
- } catch (cause) {
89
- if (cause instanceof GatewayKeyError) {
90
- throw new TokenError(cause.message, "temporarily_unavailable");
91
- }
92
- throw cause;
93
- }
94
-
95
- const nowSeconds = this.now();
96
- const accessToken = await new SignJWT({
97
- tenant: install.tenantId,
98
- env: install.env,
99
- scopes: install.scopes,
100
- // Discriminates this bearer token from a widget launch token so the two
101
- // can never be replayed for each other even though both
102
- // are RS256 JWTs signed by the same gateway key — see tokenVerifier.ts.
103
- token_use: "access",
104
- })
105
- .setProtectedHeader({ alg: APP_GATEWAY_ALG, kid: signing.kid, typ: "JWT" })
106
- .setIssuer(signing.issuer)
107
- .setSubject(install.installId)
108
- .setAudience(install.tenantId)
109
- .setJti(crypto.randomUUID())
110
- .setIssuedAt(nowSeconds)
111
- .setExpirationTime(nowSeconds + APP_TOKEN_TTL_SECONDS)
112
- .sign(signing.key);
113
-
114
- return {
115
- accessToken,
116
- tokenType: "Bearer",
117
- expiresIn: APP_TOKEN_TTL_SECONDS,
118
- scope: install.scopes.join(" "),
119
- };
120
- }
121
- }
@@ -1,148 +0,0 @@
1
- /**
2
- * Offline verification of the Storefront App Gateway's own OAuth2
3
- * client-credentials JWT — this is what the scoped-API boundary
4
- * imports to authorize an app's request.
5
- *
6
- * Modeled directly on `../auth/identityToken.ts`'s `IdentityAssertionVerifier`
7
- * (same `jwtVerify` + JWKS-by-`kid` shape, `aud`/`iss` pinning, alg allowlist),
8
- * but LOCAL only: this Worker signs its own tokens, so there's no remote host
9
- * to fetch a JWKS from — the public JWKS is derived in-process by
10
- * `gatewayKeys.ts` from the very key that signs, via `createLocalJWKSet`.
11
- */
12
- import {
13
- jwtVerify,
14
- createLocalJWKSet,
15
- decodeProtectedHeader,
16
- type JWTVerifyGetKey,
17
- } from "jose";
18
- import {
19
- loadGatewayJwks,
20
- GatewayKeyError,
21
- APP_GATEWAY_ALG,
22
- DEFAULT_APP_GATEWAY_ISSUER,
23
- APP_GATEWAY_ISSUER_ENV,
24
- type GatewayKeyOverrides,
25
- } from "./gatewayKeys.js";
26
- import { readEnv } from "@/lib/env";
27
-
28
- /** The verified app-token claims (the scoped API's authorization input). */
29
- export interface AppTokenClaims {
30
- iss: string;
31
- sub: string; // install id
32
- aud: string; // tenant
33
- tenant: string;
34
- env: string;
35
- scopes: string[];
36
- iat: number;
37
- exp: number;
38
- jti: string;
39
- }
40
-
41
- /** Normalize a jose JWT payload into typed {@link AppTokenClaims}, throwing on any missing claim. */
42
- function toAppTokenClaims(payload: Record<string, unknown>): AppTokenClaims {
43
- // The security-critical discriminator: a widget launch token
44
- // (`token_use: "widget_launch"`) is signed by this SAME gateway key, so
45
- // signature/aud/iss/exp checks alone can't tell it apart from a bearer
46
- // token. Requiring `token_use === "access"` here is what stops a launch
47
- // token — minted for a sandboxed iframe, short-TTL, no scopes checked —
48
- // from ever being replayed as an API bearer token.
49
- if (payload.token_use !== "access") {
50
- throw new Error("app token has the wrong `token_use`; expected an access token");
51
- }
52
- const tenant = payload.tenant;
53
- if (typeof tenant !== "string" || !tenant) {
54
- throw new Error("app token missing `tenant` claim");
55
- }
56
- const env = payload.env;
57
- if (typeof env !== "string" || !env) {
58
- throw new Error("app token missing `env` claim");
59
- }
60
- const jti = payload.jti;
61
- if (typeof jti !== "string" || !jti) {
62
- throw new Error("app token missing `jti` claim");
63
- }
64
- if (!Array.isArray(payload.scopes)) {
65
- throw new Error("app token missing `scopes` claim");
66
- }
67
- const scopes = payload.scopes.filter((s): s is string => typeof s === "string");
68
-
69
- return {
70
- iss: String(payload.iss ?? ""),
71
- sub: String(payload.sub ?? ""),
72
- aud: String(payload.aud ?? ""),
73
- tenant,
74
- env,
75
- scopes,
76
- iat: Number(payload.iat ?? 0),
77
- exp: Number(payload.exp ?? 0),
78
- jti,
79
- };
80
- }
81
-
82
- export interface AppTokenVerifierConfig {
83
- /** This request's tenant — pinned as the required `aud` (per-tenant, mirrors identityToken.ts). */
84
- tenant: string;
85
- issuer?: string;
86
- keys: JWTVerifyGetKey;
87
- }
88
-
89
- /**
90
- * Verifies app-gateway tokens offline against the LOCAL JWKS. One instance
91
- * per tenant (its `aud` pin is fixed).
92
- */
93
- export class AppTokenVerifier {
94
- private readonly tenant: string;
95
- private readonly issuer: string;
96
- private readonly keys: JWTVerifyGetKey;
97
-
98
- constructor(config: AppTokenVerifierConfig) {
99
- if (!config.tenant) {
100
- throw new Error("AppTokenVerifier requires a `tenant` (this request's resource)");
101
- }
102
- this.tenant = config.tenant;
103
- this.issuer = config.issuer ?? DEFAULT_APP_GATEWAY_ISSUER;
104
- this.keys = config.keys;
105
- }
106
-
107
- /**
108
- * Verify a compact JWS and return typed claims. Rejects (throws) on: any
109
- * `alg` other than RS256 (blocks `alg:none` and every HS*), bad signature,
110
- * wrong/absent `aud`, unlisted `iss`, or expired/not-yet-valid `exp`/`iat`.
111
- */
112
- async verify(token: string): Promise<AppTokenClaims> {
113
- const header = decodeProtectedHeader(token);
114
- if (header.alg !== APP_GATEWAY_ALG) {
115
- throw new Error(`unexpected JWT alg ${String(header.alg)}; only ${APP_GATEWAY_ALG} is accepted`);
116
- }
117
-
118
- const { payload } = await jwtVerify(token, this.keys, {
119
- issuer: this.issuer,
120
- audience: this.tenant,
121
- algorithms: [APP_GATEWAY_ALG],
122
- });
123
-
124
- return toAppTokenClaims(payload as Record<string, unknown>);
125
- }
126
- }
127
-
128
- /**
129
- * Get (or build) the verifier for one tenant, from the gateway's own
130
- * locally-derived JWKS. Returns `null` when the signing key isn't configured
131
- * — callers (the scoped-API routes) fail closed with 503, mirroring `getIdentityVerifier`.
132
- * Not cached across calls (unlike `identityToken.ts`'s remote-fetch verifier):
133
- * deriving the local JWKS is cheap (`gatewayKeys.ts` caches the export itself).
134
- */
135
- export async function getAppTokenVerifier(
136
- tenant: string,
137
- overrides: GatewayKeyOverrides = {},
138
- ): Promise<AppTokenVerifier | null> {
139
- let jwks;
140
- try {
141
- jwks = await loadGatewayJwks(overrides);
142
- } catch (cause) {
143
- if (cause instanceof GatewayKeyError) return null;
144
- throw cause;
145
- }
146
- const issuer = overrides.issuer ?? (await readEnv(APP_GATEWAY_ISSUER_ENV)) ?? DEFAULT_APP_GATEWAY_ISSUER;
147
- return new AppTokenVerifier({ tenant, issuer, keys: createLocalJWKSet(jwks) });
148
- }
@@ -1,16 +0,0 @@
1
- /** Shared fake/local state contract for one composed v84 clean-clone pass. */
2
- export const V84_REPLAY_SESSION_ID = "offline-v84-shared-clone-session" as const;
3
- export const V84_REPLAY_CLONE_TENANT = "tokenoftrust.com~clone~gtm-migration-v84" as const;
4
-
5
- export interface V84CleanCloneReplayContext {
6
- readonly sessionId: typeof V84_REPLAY_SESSION_ID;
7
- readonly cloneTenant: typeof V84_REPLAY_CLONE_TENANT;
8
- read<T>(key: string): T | undefined;
9
- write(key: string, value: unknown): void;
10
- delete(key: string): void;
11
- keys(prefix?: string): readonly string[];
12
- }
13
-
14
- export function sameV84ReplayValue(left: unknown, right: unknown): boolean {
15
- return JSON.stringify(left) === JSON.stringify(right);
16
- }
@@ -1,105 +0,0 @@
1
- /** Clone-only cold/warm cache evidence over local managed-install state. */
2
- import { getCachedPage, pageCacheKey, putCachedPage } from "../edgeCache.js";
3
- import type { V84DisabledInstallMaterializationResult } from "./v84CloneLifecycleMaterialization.js";
4
- import {
5
- V84_NATIVE_CLONE_TENANT,
6
- V84_NATIVE_SOURCE_TENANT,
7
- } from "./v84CloneNativeInstallEvidence.js";
8
- import type { V84CleanCloneReplayContext } from "./v84CleanCloneReplayContext.js";
9
-
10
- const CACHE_BODY = "<!-- offline v84 lifecycle cache artifact; no integration markup -->";
11
- const INTEGRATION_MARKUP = /<script|dataLayer|googletagmanager|GTM-|\beval\s*\(/i;
12
-
13
- function fakeCache(replayContext?: V84CleanCloneReplayContext) {
14
- const store = new Map<string, Response>();
15
- const reads: string[] = [];
16
- const writes: string[] = [];
17
- const cache = {
18
- async match(request: Request) {
19
- reads.push(request.url);
20
- if (replayContext) {
21
- const found = replayContext.read<{
22
- body: string;
23
- headers: Record<string, string>;
24
- status: number;
25
- }>(`stage/lifecycle/cache/${encodeURIComponent(request.url)}`);
26
- return found ? new Response(found.body, { headers: found.headers, status: found.status }) : undefined;
27
- }
28
- return store.get(request.url)?.clone();
29
- },
30
- async put(request: Request, response: Response) {
31
- writes.push(request.url);
32
- if (replayContext) {
33
- replayContext.write(`stage/lifecycle/cache/${encodeURIComponent(request.url)}`, {
34
- body: await response.clone().text(),
35
- headers: Object.fromEntries(response.headers.entries()),
36
- status: response.status,
37
- });
38
- return;
39
- }
40
- store.set(request.url, response.clone());
41
- },
42
- } as unknown as Cache;
43
- return { cache, reads, writes };
44
- }
45
-
46
- /** Exercise a true cold miss and warm clone-only hit without touching source keys. */
47
- export async function buildV84CloneCacheEvidence(
48
- materialization: V84DisabledInstallMaterializationResult,
49
- replayContext?: V84CleanCloneReplayContext,
50
- ) {
51
- const memory = fakeCache(replayContext);
52
- const disabledCacheKeyBefore = pageCacheKey(
53
- V84_NATIVE_CLONE_TENANT,
54
- "/v84-lifecycle",
55
- "",
56
- 1,
57
- materialization.candidatePlanBefore.planRevision,
58
- );
59
- const cloneCacheKey = pageCacheKey(
60
- V84_NATIVE_CLONE_TENANT,
61
- "/v84-lifecycle",
62
- "",
63
- 1,
64
- materialization.candidatePlanAfter.planRevision,
65
- );
66
- const sourceCacheKey = pageCacheKey(V84_NATIVE_SOURCE_TENANT, "/v84-lifecycle", "", 1);
67
- const cold = await getCachedPage(memory.cache, cloneCacheKey);
68
- await putCachedPage(memory.cache, cloneCacheKey, new Response(CACHE_BODY, {
69
- status: 200,
70
- headers: { "content-type": "text/html; charset=utf-8" },
71
- }));
72
- const warm = await getCachedPage(memory.cache, cloneCacheKey);
73
- const warmBody = warm ? await warm.text() : "";
74
- if (
75
- cold !== null ||
76
- !warm ||
77
- warmBody !== CACHE_BODY ||
78
- warm.headers.get("x-tot-cache") !== "hit" ||
79
- disabledCacheKeyBefore.url !== cloneCacheKey.url ||
80
- INTEGRATION_MARKUP.test(warmBody)
81
- ) {
82
- throw new Error("The clone-local warm-cache proof failed.");
83
- }
84
- if (memory.reads.includes(sourceCacheKey.url) || memory.writes.includes(sourceCacheKey.url)) {
85
- throw new Error("The warm-cache proof touched the source namespace.");
86
- }
87
-
88
- return {
89
- warmCache: {
90
- tenant: V84_NATIVE_CLONE_TENANT,
91
- coldMiss: true,
92
- warmHit: true,
93
- cloneWriteCount: memory.writes.length,
94
- sourceReadCount: memory.reads.filter((url) => url === sourceCacheKey.url).length,
95
- sourceWriteCount: memory.writes.filter((url) => url === sourceCacheKey.url).length,
96
- managedInstallStateChanged: materialization.managedInstallStateChanged,
97
- effectivePlanChanged:
98
- materialization.candidatePlanBefore.planRevision !== materialization.candidatePlanAfter.planRevision,
99
- disabledDraftsChangedCacheKey: disabledCacheKeyBefore.url !== cloneCacheKey.url,
100
- artifactContainsIntegrationMarkup: INTEGRATION_MARKUP.test(warmBody),
101
- },
102
- cloneCacheReads: memory.reads.length,
103
- cloneCacheWrites: memory.writes.length,
104
- };
105
- }