Commit Graph
18 Commits
Author SHA1 Message Date
ClintchizandClaude Opus 5 3eec9fd8c6 fix(rpc): close the four final-review blockers on inter-app RPC
- Resolve RPC call origins via a new WRNEXUS_INTERNAL_ORIGINS map (loopback
  origins the gateway hands each child before spawning it), falling back to
  the public appOrigin only when it is absent. Calls previously always went
  to the public gateway origin, which the gateway unconditionally 404s on
  the RPC prefix by design — every real cross-app call failed.
- Stop loadServices() from running ahead of routing and stop memoizing a
  rejected load: one bad file under app/services/ no longer permanently
  breaks every route in the app. A failed load logs loudly, is retried on
  the next RPC request, and the RPC path gets a structured RPC_UNKNOWN
  instead of an unhandled throw.
- Reject a service whose contract.name does not match the filename it is
  mounted under, naming both, instead of silently mounting under the
  filename while the typed client calls by contract name.
- Let ServiceError accept an explicit retryable and have the client pass the
  wire value through, instead of recomputing (and silently flipping) it from
  the error code alone.
- Document the gateway/X-Forwarded-* deployment requirement in the RPC
  README.

Each of the three code blockers has a new/extended test that was verified to
fail when its fix was reverted (rpc/test/integration.test.ts,
dev-server/test/rpc-services-loading.test.ts).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 20:36:31 +05:30
ClintchizandClaude Opus 5 ce68803471 fix(rpc): close the service-collision fail-open and the fix-wave gaps
Critical:
- router: fail loudly (WRN-SERVICE-COLLISION) when two app/services files
  scan to the same service name, instead of silently letting directory-walk
  order pick a winner.

Important:
- server.ts: wrap a throwing input schema so its raw message cannot escape
  invoke(); returns RPC_INVALID and logs server-side instead.
- client.ts: race timeoutMs against transport.call so a stalled transport
  cannot hang the caller; rejects with a ServiceError(RPC_TRANSPORT).
- client.ts: the proxy returns undefined for undeclared properties (incl.
  then/catch/finally) instead of a function that throws, closing the
  await-client thenable trap.
- gateway.ts / rpc-dispatch.ts: import RPC_PATH_PREFIX / RPC_INTERNAL_HEADER
  from @wrnexus/rpc instead of hardcoding local copies.
- gateway.test.ts: cover the RPC-prefix edge block and internal-header
  stripping across casing variants.
- http.test.ts / client.test.ts: cover anonymous-call header omission, the
  internal marker, the retryable-status sweep, network/malformed/HTML
  failures, AbortSignal propagation, the timeout path, and timer cleanup.

Minor:
- transport.ts: Object.hasOwn for handler lookup; note the entry-only abort
  check.
- client.ts: wrap a missing/invalid WRNEXUS_RPC_SECRET as a ServiceError
  (RPC_IDENTITY) instead of a bare Error.
- rpc/package.json: drop the unused @wrnexus/authz dependency.
- server.ts: implement() now throws at construction time if a declared
  procedure has no own handler.

Verified: reverting the service-collision check and the client timeout race
each make their new test fail, then restore green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 20:10:20 +05:30
ClintchizandClaude Opus 5 e01915823a feat(rpc): transport, server, client, http, mounting, docs (Tasks 5-11)
Brings the uncommitted body of work under version control so it cannot be
lost. Gates are green: 152 tests pass across rpc/router/dev-server,
typecheck, lint, format and check:public-api all clean.

NOT YET REVIEWED. None of Tasks 5-11 has had an independent task review, and
Task 4's second fix round was never re-reviewed either.

Known gaps against the plan, recorded here rather than discovered later:
- packages/rpc/test/{transport,server,client}.test.ts are ABSENT. The plan
  required a test file for each. server.ts holds the fail-closed identity and
  permission checks and currently has no direct coverage at all.
- rpc-endpoint.test.ts has 3 tests where the plan specified 9. Missing:
  unknown service, non-POST, malformed body, non-rpc passthrough, and the
  isInternalCaller sweep. This is the task where a reachable
  /__wrnexus/rpc/* makes every permission check in the workspace bypassable.
- http.test.ts has 3 of 7; integration.test.ts 2 of 3;
  services-discovery.test.ts 1 of 4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 19:38:04 +05:30
ClintchizandClaude Opus 5 c64434a131 fix(security): close SSRF, credential-leak, and auth bypass findings in 0.8.4
Audit of 0.8.4 found the repo's own gates green, so these came from manual
review; each is covered by a new regression test.

security/fetch.ts
- safeFetch re-attached Authorization/Cookie on a same-origin redirect that
  followed a cross-origin hop (a -> b -> b), handing credentials to the second
  host. Compare against the origin the caller trusted, not the previous hop.
- The private-network guard resolved the host, approved it, then let fetch
  resolve again, so a low-TTL record could answer public for the check and
  private for the connection. Pin the connection to the validated address,
  preserving Host and TLS serverName. Opt out with pinDns: false.
- 0:0:0:0:0:ffff:127.0.0.1, ::ffff:7f00:1 and fec0::1 were not treated as
  private. Add uncompressed IPv4-mapped forms, site-local IPv6, 198.18/15
  and 192.0.0/24.

security/url.ts
- sanitizeUrl returned "//evil.com" verbatim via the relative-path fast path,
  bypassing the host checks it had just run; in an href that navigates
  cross-origin. Resolve protocol-relative input instead.

dev-server/gateway.ts
- Malformed base64 in an Authorization header threw out of checkAuth on an
  unauthenticated path. Fail closed.
- split(":", 2) truncated passwords at the first colon, so a password
  containing ":" could never authenticate.
- The credential compare short-circuited on length mismatch, leaking length
  by timing. Extracted as verifyBasicAuth so it is testable.

authz/index.ts
- Namespace wildcards only matched the first segment, so "post:comment:*"
  did not grant "post:comment:delete". Match at every depth.

uploader/operations.ts
- Validate transcoder dimensions and bitrate rather than trusting the declared
  type, and reject ".." path segments.

package.json
- The brace-expansion override pinned 5.0.8, which is inside the advisory
  range >=4.0.0 <5.0.9. Bump to 5.0.9; bun audit is now clean.

Verified: check:production passes (typecheck, lint, 1033 tests, format,
ASVS, public-API baseline, editor checks).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 15:57:22 +05:30
Clintchiz 87507edf59 release: WRNexusJS 0.7.0 2026-08-01 10:04:42 +05:30
Clintchiz d1b0c55b53 release: WRNexusJS 0.5.10 2026-07-30 13:36:29 +05:30
Clintchiz 944f83d3f4 fix: use public origins for SSO redirects 2026-07-20 15:04:20 +05:30
Clintchiz 2b4083c6db fix: surface app errors in gateway logs 2026-07-20 14:26:27 +05:30
Clintchiz aa2595ec01 fix: log production request failures 2026-07-20 13:48:47 +05:30
Clintchiz b3e5e5b999 feat: configure workspace environment runtimes 2026-07-20 09:22:26 +05:30
Clintchiz 33730c68ab fix(gateway): keep production app ports private 2026-07-19 22:24:28 +05:30
Clintchiz 3cfdc747fa release: WRNexusJS 0.2.30 2026-07-14 20:01:16 +05:30
Clintchiz e6dbb5b0fc release: WRNexusJS 0.2.29 2026-07-14 17:34:51 +05:30
Clintchiz b273e30c2f fix: preserve original host through forward auth 2026-07-13 19:56:06 +05:30
Clintchiz cff420a29e feat: restore gateway HMR and add WRN formatting 2026-07-13 14:54:03 +05:30
Clintchiz b4e5fade19 feat: add helpers and improve workspace auth flows 2026-07-13 13:53:36 +05:30
Clintchiz 88e907783a fix: stabilize workspace gateway and scaffolding 2026-07-13 12:54:07 +05:30
Clintchiz ee98026cc5 first commit 2026-07-12 15:55:18 +05:30