Repository navigation
[No QA] Run the Cloudflare Worker during local web development - #104525
Conversation
Catch CSP and security-header regressions before staging while preserving React Fast Refresh and Wrangler source reload. Use trusted local HTTPS and loopback HTTP instead of requiring ngrok.
|
npm has a |
…387-local-cloudflare-worker
…387-local-cloudflare-worker
…387-local-cloudflare-worker # Conflicts: # web/cloudflare-worker/tests/worker.test.ts
|
@abdulrahuman5196 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
arosiclair
left a comment
There was a problem hiding this comment.
Looks good and tests well for me 👍
|
@roryabraham fyi conflicts |
a9999d9
Node 26 types declare tls.getCACertificates, so the local module augmentation is no longer needed. Their stricter exec and webcrypto overloads needed an explicit encoding type in Git.ts, and Node buffer types in the CloudflareAccess test mocks.
|
@MelvinBot review |
|
@codex review |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / SafariScreen.Recording.2026-10-24.at.9.06.34.AM.movScreen.Recording.2026-10-24.at.9.07.34.AM.mov |
| }); | ||
| } | ||
|
|
||
| export default getWebCommands; |
There was a problem hiding this comment.
startWeb.ts default-exports getWebCommands
The file is named for the launcher but exports a different function so the test can import it. That breaks the checklist rule that files are named after what they export.
Fix: Move getWebCommands to scripts/utils/getWebCommands.ts, or use a named export.
ReviewI found no blocking issues. Your earlier review comments are all fixed on I have two suggestions:
I could not test this in a browser because the web dev server failed to start in my environment. This review comes from reading the code only. |
| @@ -0,0 +1,7 @@ | |||
| /** Local backends from `.env`, which the app calls and the launcher adds to the live Worker's CSP. */ | |||
| const LOCAL_BACKEND_URL_KEYS = ['EXPENSIFY_URL', 'SECURE_EXPENSIFY_URL', 'STAGING_EXPENSIFY_URL', 'STAGING_SECURE_EXPENSIFY_URL', 'NGROK_URL', 'SECURE_NGROK_URL']; | |||
There was a problem hiding this comment.
Dev CSP blocks the QA server and its Cloudflare Access sign-in
With QA configured in .env, the app calls QA_EXPENSIFY_URL/QA_SECURE_EXPENSIFY_URL directly with no proxy, and the Access flow fetches metadata from the QA host and tokens from https://<QA_CF_TEAM_DOMAIN>. LOCAL_BACKEND_URL_KEYS has no QA keys and the base CSP has no QA or Access host, so the dev connect-src blocks all of them. On main the dev server sends no CSP, so they work.
App/web/cloudflare-worker/src/csp.ts
Line 195 in 222c691
Lines 95 to 108 in 222c691
- Set
QA_EXPENSIFY_URL,QA_SECURE_EXPENSIFY_URL,QA_CF_TEAM_DOMAIN,QA_CF_OAUTH_CLIENT_IDandQA_AUTH_CHECK_PATHin.env - Run
npm run webwith the Worker on (default) - Go to Settings → Troubleshoot
- In the QA auth (Cloudflare) row, click Run probe
Expected: The Cloudflare sign-in starts or the probe succeeds, as on main.
Actual: The probe fails. Console shows connect-src CSP violations for the QA host.
Fix: Add the QA URL keys to LOCAL_BACKEND_URL_KEYS and allow https://${QA_CF_TEAM_DOMAIN} in dev connect-src.
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Regression checkI found one likely regression and one behavior change. Staging and production are not affected.
What I checked with no regression found
Low-risk items I could not verify:
I could not verify this in a browser because the web dev server failed to start in my environment. These findings come from reading the code. |
|
Confirmed: the dev CSP blocks QA. I checked the code at Fix (in
Evidence
|
startWeb.ts default-exported a different function so a test could import it, which breaks the rule that files are named after what they export.
…v CSP With QA configured, the app calls the QA hosts directly and the Access flow calls https://$QA_CF_TEAM_DOMAIN, but dev connect-src allowed neither, so the QA auth probe and sign-in failed. Add the QA URLs to the backend keys and allow the team domain, which must be a bare hostname.
npm install skips the Worker when CI is set, so npm run web failed in containers, cloud agents, and CI-run browser tests that worked on main. Warn and fall back to direct Rsbuild instead.
… fails postInstall runs under set -e, so an offline machine or a failed workerd download failed every App install, including for developers who never run the Worker. npm run web now serves Rsbuild directly without it, and the next install retries.
The job only typechecks and tests web/cloudflare-worker, which reads no launcher, Rsbuild, or root package files. Those have their own tests under tests/tooling.
On main, a second worktree's npm run web moved to the next free port and shared the first session's proxy on 9000. The launcher instead failed if 8082, 8083, or 9000 was busy, and nothing could get a second proxy-enabled session past 9000. Pick the first free ports unless WEB_PORT or WEB_INTERNAL_PORT is set, and reuse a running proxy.
|
MelvinBot's findings:
|
|
@roryabraham conflicts |
| @@ -0,0 +1,28 @@ | |||
| /** Local backends from `.env`, which the app calls and the launcher adds to the live Worker's CSP. */ | |||
| const LOCAL_BACKEND_URL_KEYS = [ | |||
There was a problem hiding this comment.
nab Seems kind of annoying to maintain, is there a better way to do this?
There was a problem hiding this comment.
Not sure I have a better suggestion - fortunately it just references keys in a .env, which makes it easy to configure per-workspace (such as if you're trying to set up parallel Docker stacks).
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/roryabraham in version: 9.5.21-0 🚀
|
|
🚧 roryabraham has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/roryabraham in version: 9.5.23-0 🚀
|
Explanation of Change
Run the real NewDot Worker in local workerd during
npm run webso CSP, nonce, security-header, and routing regressions are caught before staging.dist/, or Cloudflare credentials are needed..envsettings, public-origin readiness, browser opening, and process cleanup.concurrentlylifecycle management.Fixed Issues
$ #104387
Tests
npm i && npm run webOffline tests
n/a
QA Steps
None.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari