Skip to content

Fix connector asset routing deploy config - #443

Merged
kentcdodds merged 2 commits into
mainfrom
cursor/connector-assets-routing-deploy-fix-081d
May 12, 2026
Merged

kentcdodds merged 2 commits into
mainfrom
cursor/connector-assets-routing-deploy-fix-081d

Conversation

@kentcdodds

@kentcdodds kentcdodds commented May 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Copy the selected env asset routing block into the generated top-level Wrangler config so production/preview deploy artifacts explicitly include assets.run_worker_first for /connectors/* at the shape Cloudflare Assets documents.
  • Make wrangler-env.ts honor WRANGLER_CONFIG, so the pre-deploy build step in production/preview workflows uses the same generated config as the final deploy.
  • Reject unmatched /connectors/* paths before the static asset / SPA fallback, while keeping user-scoped connector WebSocket ingress on /connectors/u/{userId}/{kind}/{instanceId}.

Investigation notes

  • Current production is deployed at 9545255df1c6dc930e9e179471dccdab2d7657af.
  • Live /connectors/home/default is a legacy, non-user-scoped path; current code recognizes /connectors/u/{userId}/{kind}/{instanceId}.
  • Live user-scoped HTTP probe already returns 404 and user-scoped WebSocket probe returns server.ping, which shows /connectors/* is reaching the Worker; the unsafe part was unmatched connector paths falling through to the SPA shell.

Evidence / commands

  • curl -sS "https://heykody.dev/health" -> {"ok":true,"commitSha":"9545255df1c6dc930e9e179471dccdab2d7657af"}
  • curl -sS -D - -o /tmp/kody-prod-legacy-connector.html "https://heykody.dev/connectors/home/default" -> current prod HTTP/2 200, content-type: text/html; charset=UTF-8
  • curl -sS -D - -o /tmp/kody-prod-user-scoped-connector.txt "https://heykody.dev/connectors/u/probe-user/home/default" -> HTTP/2 404, content-length: 9
  • node --input-type=module -e "const ws = new WebSocket('wss://heykody.dev/connectors/u/probe-user/home/default'); const finish = (code) => { clearTimeout(timeout); try { ws.close(); } catch {} setTimeout(() => process.exit(code), 20); }; const timeout = setTimeout(() => { console.error('timeout waiting for websocket'); finish(1); }, 5000); ws.addEventListener('open', () => console.log('open')); ws.addEventListener('message', (event) => { console.log(String(event.data)); finish(0); }); ws.addEventListener('error', (event) => { console.error('websocket error', event.message ?? event.type); finish(1); });" -> open, {"type":"server.ping"}
  • node tools/ci/production-resources.ts ensure --dry-run --out-config packages/worker/wrangler-production.generated.json && CLOUDFLARE_ENV=production WRANGLER_CONFIG=/workspace/packages/worker/wrangler-production.generated.json node --env-file=packages/worker/.env ./wrangler-env.ts deploy --dry-run --outdir /tmp/kody-wrangler-dry-run-after --var APP_COMMIT_SHA:dry-run -> env.ASSETS binding present, production D1/KV dry-run IDs loaded, --dry-run: exiting now.
  • node tools/ci/preview-resources.ts ensure --dry-run --worker-name kody-pr-dry-run --out-config packages/worker/wrangler-preview.generated.json && CLOUDFLARE_ENV=preview WRANGLER_CONFIG=/workspace/packages/worker/wrangler-preview.generated.json node --env-file=packages/worker/.env ./wrangler-env.ts deploy --dry-run --name kody-pr-dry-run --outdir /tmp/kody-wrangler-preview-dry-run-after --var APP_COMMIT_SHA:dry-run -> env.ASSETS binding present, preview D1/KV dry-run IDs loaded, --dry-run: exiting now.
  • npx vitest run --project node-unit tools/ci/resource-utils.node.test.ts tools/wrangler-env-config.node.test.ts -> 2 files / 7 tests passed
  • npx vitest run --project workers-unit packages/worker/src/security/public-route-hardening.workers.test.ts -> 1 file / 4 tests passed
  • npm run format:check -> passed
  • npm run lint -> passed with 4 existing warnings in unrelated files
  • npm run typecheck -> passed
Open in Web Open in Cursor 

Summary by CodeRabbit

  • Security

    • Stricter rejection of unmatched connector requests, returning 404 for non-matching paths and non-WebSocket upgrades.
  • Documentation

    • Clarified security guidance about when connector routes are forwarded and which requests are rejected.
  • Tests

    • Added tests covering connector route hardening and config generation behavior.
  • Chores

    • Improved Wrangler config resolution and related tooling tests.

Review Change Stack

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented May 12, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b07a172-110e-4ad1-a72e-7d78819c5f45

📥 Commits

Reviewing files that changed from the base of the PR and between aa8c28e and 9a3c44d.

📒 Files selected for processing (2)
  • tools/ci/resource-utils.node.test.ts
  • tools/ci/resource-utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tools/ci/resource-utils.ts

📝 Walkthrough

Walkthrough

This PR rejects unmatched /connectors/* requests with 404 in the worker, updates docs and tests, adds wrangler config path helpers and integrates them into wrangler-env, and copies env..assets into generated wrangler configs with validation and tests.

Changes

Connector Security and Wrangler Config Hardening

Layer / File(s) Summary
Worker connector route rejection and security test
packages/worker/src/index.ts, packages/worker/src/security/public-route-hardening.workers.test.ts, docs/contributing/security.md
The worker request handler now returns HTTP 404 for any request whose pathname starts with /connectors/ before other routing. A test verifies both HTTP and WebSocket-upgrade requests to an unmatched connector path return 404 with exact 'Not Found' body. Docs clarify only user-scoped WebSocket connector routes are forwarded.
Wrangler config path resolution helpers
tools/wrangler-env-config.ts, tools/wrangler-env-config.node.test.ts
Adds defaultWranglerConfigPath, getDefaultWranglerConfigPath() to prefer WRANGLER_CONFIG or fall back, and resolveWranglerConfigPath() to normalize relative paths against a CWD. Tests cover fallback, env override, absolute preservation, and relative resolution.
Wrangler environment initialization using path helpers
wrangler-env.ts
wrangler-env.ts now uses the new path helpers to compute and resolve the wrangler config path and to check file existence instead of a hard-coded path.
Asset routing propagation in generated wrangler configs
tools/ci/resource-utils.ts, tools/ci/resource-utils.node.test.ts
writeGeneratedWranglerConfig() reads and validates env.<envName>.assets and copies it to top-level assets in the generated config; tests verify assets.run_worker_first (including /connectors/*) is preserved for production and preview and assert failure when env.assets is missing.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Worker.Handler
  participant Request.Router
  Client->>Worker.Handler: GET /connectors/home/default
  Worker.Handler->>Request.Router: inspect url.pathname
  Request.Router->>Worker.Handler: pathname startsWith /connectors/
  Worker.Handler->>Client: 404 Not Found
  Client->>Worker.Handler: WS upgrade /connectors/home/default
  Worker.Handler->>Request.Router: inspect url.pathname
  Request.Router->>Worker.Handler: pathname startsWith /connectors/
  Worker.Handler->>Client: 404 Not Found
Loading
sequenceDiagram
  participant WranglerEnv as wrangler-env.ts
  participant PathHelpers as tools/wrangler-env-config.ts
  participant Environment as process.env
  participant FileSystem as fs
  WranglerEnv->>PathHelpers: getDefaultWranglerConfigPath()
  PathHelpers->>Environment: read WRANGLER_CONFIG
  alt WRANGLER_CONFIG set
    Environment-->>PathHelpers: trimmed value
  else
    PathHelpers-->>WranglerEnv: defaultWranglerConfigPath
  end
  WranglerEnv->>PathHelpers: resolveWranglerConfigPath(path, cwd)
  PathHelpers->>PathHelpers: return absolute or join(cwd, relative)
  PathHelpers-->>WranglerEnv: resolvedPath
  WranglerEnv->>FileSystem: existsSync(resolvedPath)
  FileSystem-->>WranglerEnv: boolean
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • kentcdodds/kody#442: Related — both PRs change connector ingress/routing (wrangler assets run_worker_first for /connectors/* and worker request handling/404 behavior for /connectors/*).
  • kentcdodds/kody#227: Related — both modify writeGeneratedWranglerConfig in tools/ci/resource-utils.ts (this PR adds env.assets validation/propagation).
  • kentcdodds/kody#49: Related — both modify tools/ci/resource-utils.ts's writeGeneratedWranglerConfig (one changes env.assets propagation; the other changes vars merging).

Poem

🐰 I hop through routes both near and far,
Guarding connectors, each little star,
Four-oh-four greets paths unknown,
Config helpers find their own.
Hooray — security hops on home!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix connector asset routing deploy config' directly relates to the main objectives: copying env asset routing into generated Wrangler config and fixing connector path routing behavior.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/connector-assets-routing-deploy-fix-081d

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kentcdodds
kentcdodds marked this pull request as ready for review May 12, 2026 04:13
@github-actions

github-actions Bot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-443.kentcdodds.workers.dev

Worker: kody-pr-443
D1: kody-pr-443-db
KV: kody-pr-443-oauth-kv

Mocks:

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tools/ci/resource-utils.ts`:
- Around line 318-324: The current guard treating targetAssets with typeof ===
'object' allows arrays through; update the validation around targetAssets (the
value used to set config.assets in the code that calls config.assets = {
...(targetAssets as Record<string, unknown>) }) to explicitly reject arrays by
checking Array.isArray(targetAssets) and calling fail(...) with the same
diagnostic (including baseConfigPath and envName) when targetAssets is an array
or otherwise invalid; ensure you still allow plain objects (Record<string,
unknown>) and only proceed to assign config.assets after the array check passes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b5b27e58-eb16-4e4d-acde-6c5153932e0d

📥 Commits

Reviewing files that changed from the base of the PR and between 9545255 and aa8c28e.

📒 Files selected for processing (8)
  • docs/contributing/security.md
  • packages/worker/src/index.ts
  • packages/worker/src/security/public-route-hardening.workers.test.ts
  • tools/ci/resource-utils.node.test.ts
  • tools/ci/resource-utils.ts
  • tools/wrangler-env-config.node.test.ts
  • tools/wrangler-env-config.ts
  • wrangler-env.ts

Comment thread tools/ci/resource-utils.ts Outdated
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds merged commit bedb8ee into main May 12, 2026
5 checks passed
@kody-bot
kody-bot deleted the cursor/connector-assets-routing-deploy-fix-081d branch July 21, 2026 18:56
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.

2 participants