Skip to content

CORS errors in dev when accessing Gastown/Wasteland via LAN IP or loopback address #4011

@IamCoder18

Description

@IamCoder18

In development, requests to Gastown and Wasteland APIs from any origin that isn't exactly http://localhost:<port> are rejected by CORS. This breaks legitimate local development scenarios: accessing the dev server via http://192.168.x.x:8803 from a phone on the same WiFi, using http://10.x.x.x from a LAN VM, or hitting http://127.0.0.1:<port> directly. Error in browser console looks like a standard CORS preflight rejection with no Access-Control-Allow-Origin header.

Steps to reproduce:

  1. Run pnpm --filter {./services/gastown} run dev --port 8803 --inspector-port 18803 --ip 0.0.0.0 --local locally.
  2. From a different device machine, open a browser and navigate to http://<your-machine-ip>:8803.
  3. Open the dev console / network tab and observe the CORS error on any /api/* or /trpc/* request.

PR Description

chore(cors): broaden local origin matching for dev environments

The previous localhost-only prefix check caused CORS failures when developers accessed the dev server via LAN IP (10.x, 172.16-31.x, 192.168.x), loopback (127.x), or IPv6 link-local/ULA addresses. This is common when using mobile devices on the same LAN for testing or when tunneling into the dev environment.

Both gastown and wasteland were updated to use the same regex so they stay in sync.

## Summary

The dev-environment CORS check in both services used `origin.startsWith('http://localhost:')`, which rejects every other loopback/LAN address even though they are still local-only. Replaced that with a regex matching RFC1918 private ranges, loopback, and
common IPv6 local addresses.

- services/gastown/src/gastown.worker.ts
- services/wasteland/src/wasteland.worker.ts

## Verification

- [ ] Verified locally that `http://192.168.x.x` and `http://127.0.0.1`
  origins are accepted in dev; non-local origins and production origins
  are still rejected as before.

## Visual Changes

N/A

## Reviewer Notes

This regex is intentionally consistent between gastown and wasteland so
the two services don't drift on what "local" means. If we ever want to
additionally allow `host.docker.internal` or `.local` mDNS names, that
belongs in a follow-up change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions