fix(gateway): allow the native WebView origin via CORS (native stuck-offline) #270

Merged
developer merged 1 commits from feature/native-cors into development 2026-07-14 19:38:28 +00:00
Owner

Root cause (confirmed)

Native emulator bug "starts offline, can't go online." The Capacitor app serves the bundled SPA from https://localhost, so its Connect calls to erudit-game.ru are cross-origin, and the gateway had no CORS handling — a preflight OPTIONS to the edge returns 405 with no Access-Control-Allow-Origin, so the WebView blocks every RPC (incl. the offline→online auth.guest reconcile). Verified vs prod: OPTIONS .../scrabble.edge.v1.Gateway/Execute with Origin: https://localhost → 405, no CORS headers. The native online path was never exercised on-device (D's smoke was airplane-mode only).

Fix

withNativeCORS middleware (under h2c + abuseGuard, before the mux): answers the preflight and sets CORS headers for the native localhost origins (https/http/capacitor://localhost), reflecting the requested headers, exposing X-Update-Recommended. Web is same-origin and untouched.

Deploy note

Must reach PROD (erudit-game.ru) for the native app to go online — the debug APK targets prod. Merge → development (contour) → master → manual prod deploy. No APK rebuild (server-side; the existing APK works once prod has CORS).

Verification

go build/vet ./gateway/..., gofmt clean; new TestWithNativeCORS + the connectsrv suite green.

## Root cause (confirmed) Native emulator bug **"starts offline, can't go online."** The Capacitor app serves the bundled SPA from `https://localhost`, so its Connect calls to `erudit-game.ru` are **cross-origin**, and the gateway had **no CORS handling** — a preflight `OPTIONS` to the edge returns `405` with no `Access-Control-Allow-Origin`, so the WebView blocks **every** RPC (incl. the offline→online `auth.guest` reconcile). Verified vs prod: `OPTIONS .../scrabble.edge.v1.Gateway/Execute` with `Origin: https://localhost` → 405, no CORS headers. The native online path was never exercised on-device (D's smoke was airplane-mode only). ## Fix `withNativeCORS` middleware (under h2c + abuseGuard, before the mux): answers the preflight and sets CORS headers for the native localhost origins (`https`/`http`/`capacitor://localhost`), reflecting the requested headers, exposing `X-Update-Recommended`. Web is same-origin and untouched. ## Deploy note **Must reach PROD** (`erudit-game.ru`) for the native app to go online — the debug APK targets prod. Merge → development (contour) → master → **manual prod deploy**. **No APK rebuild** (server-side; the existing APK works once prod has CORS). ## Verification `go build/vet ./gateway/...`, `gofmt` clean; new `TestWithNativeCORS` + the connectsrv suite green.
developer added 1 commit 2026-07-14 19:22:21 +00:00
fix(gateway): allow the native WebView origin via CORS
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 23s
CI / ui (pull_request) Has been skipped
CI / conformance (pull_request) Successful in 11s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m54s
f0b7ad47d4
The packaged native app (Capacitor) serves the bundled SPA from a localhost scheme, so its Connect calls to erudit-game.ru are cross-origin. The gateway had no CORS handling, so the preflight OPTIONS returned 405 with no Access-Control-Allow-Origin and the WebView blocked every RPC — a native build could never reach the gateway and stayed stuck offline (the native online path was never exercised on-device; on-device D was airplane-mode only). Add a CORS middleware that answers the preflight and sets the response headers for the native localhost origins (https/http/capacitor://localhost); web is same-origin and untouched. Fixes the native emulator 'starts offline, can't go online' report.
owner approved these changes 2026-07-14 19:31:31 +00:00
developer merged commit d89438040b into development 2026-07-14 19:38:28 +00:00
developer deleted branch feature/native-cors 2026-07-14 19:38:28 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/scrabble-game#270