Skip to content

fix: align identity, CORS, and event payload shape with real platform behavior - #2

Merged
kalwiggins merged 1 commit into
mainfrom
fix/real-platform-contract-dry-run
Jul 21, 2026
Merged

fix: align identity, CORS, and event payload shape with real platform behavior#2
kalwiggins merged 1 commit into
mainfrom
fix/real-platform-contract-dry-run

Conversation

@kalwiggins

Copy link
Copy Markdown
Contributor

Why

A live end-to-end dry run against production (register → private publish → install → iframe launch → bootstrap → connectivity ping → real order.created) surfaced three bugs that each independently break a real integration, despite the full test suite passing — the suite validated invented contracts, not the platform's real ones.

Fixes

1. Launch-token verification rejected every real token (packages/throttle/src/identity.ts)
requiredClaims demanded nbf, but platform launch tokens carry iss/sub/aud/iat/exp only (verified by decoding a real token; the identity docs never promise nbf). Dropped nbf from the required list — jose still validates nbf when present (the "future nbf" rejection test is unchanged). The "missing nbf" test now asserts acceptance.

2. Worker CORS blocked its own UI (apps/cloudflare/src/app.ts)
CORS allowed only THROTTLE_DASHBOARD_ORIGIN, but the iframe UI calls the Worker from the UI's own origin — every request failed preflight (OPTIONS /api/installation 403) in the documented split-origin deployment. New optional EXTENSION_UI_ORIGIN var (exact-HTTPS-origin validated at boot, same rules as the dashboard origin) is allowed alongside the dashboard origin. Documented in wrangler.jsonc (commented example), README secret table, cloudflare-deployment.md, and local-development.md (tunnel workflow).

3. Demo connector couldn't process a real event (examples/demo-connector)
It read event.data.orderId, but real deliveries carry the full order under data.order (platform emit site: data: { order, fromCart }). The demo terminal-failed on its first real event. Now reads data.order.id; the order-created.json fixture and every event literal in tests now model the real payload shape.

Also repairs two breaks that landed on main via #1

That PR's final verification ran stale — apologies. main currently fails pnpm check:

  • unused-var lint error in contracts.test.ts (rest-destructure _version)
  • 3 webhook-verification tests whose signed rawBody fixture predates the now-required version field (verifyThrottleWebhook schema-parses after signature checks → null). Fixture updated + HMAC digest recomputed.

Verification

  • pnpm check exit 0 (format, lint, typecheck, all package suites + 137 root tests, wrangler dry-run build)
  • The dry run itself completed green end-to-end with exactly these three fixes applied locally: ping 202 + queue-processed, real order.created delivered, signature-verified, and processed by the demo provider on attempt 1.

🤖 Generated with Claude Code

… behavior

Found by a live end-to-end dry run against production (register → install →
iframe launch → bootstrap → ping → real order.created). Three bugs meant the
starter could not complete a real integration out of the box:

1. Identity verification rejected every real launch token: requiredClaims
   demanded `nbf`, but platform tokens carry iss/sub/aud/iat/exp only (and
   the docs never promise nbf). Dropped nbf from requiredClaims — jose still
   validates it when present. The "missing nbf" test now asserts acceptance.

2. Worker CORS only allowed the dashboard origin, but the iframe UI calls
   the Worker from the UI's OWN origin, so every UI request failed
   preflight in the documented split-origin deployment. Added an optional
   EXTENSION_UI_ORIGIN var (exact HTTPS origin, validated at boot) that is
   allowed alongside the dashboard origin; documented in wrangler.jsonc,
   README, cloudflare-deployment.md, and local-development.md.

3. The demo connector read `event.data.orderId`, but real order.created
   deliveries carry the full order under `data.order` — the demo terminal-
   failed on its first real event while its invented fixture kept tests
   green. Now reads data.order.id; the fixture and every event literal in
   tests model the real payload shape.

Also repairs two breaks that slipped into main via #1 (its final check ran
stale): an unused-var lint error in contracts.test.ts and three webhook
verification tests whose signed rawBody fixture predated the required
`version` field (digest recomputed).

Verified: pnpm check (format, lint, typecheck, 137 root + all package
tests, wrangler dry-run build) exit 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kalwiggins
kalwiggins merged commit 238037e into main Jul 21, 2026
2 checks passed
@kalwiggins
kalwiggins deleted the fix/real-platform-contract-dry-run branch July 21, 2026 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant