Skip to content

fix(native): send iOS native-mode auth requests through NSURLSession - #475

Merged
Makisuo merged 1 commit into
mainfrom
fix/ios-native-auth-fetch
Nov 12, 2026
Merged

Makisuo merged 1 commit into
mainfrom
fix/ios-native-auth-fetch

fix(native): send iOS native-mode auth requests through NSURLSession

e89d8fc
Select commit
Loading
Failed to load commit list.
Maple Review Bot / Maple / review completed Nov 12, 2026 in 3m 9s

Confidence 4/10 · 2 issues to address

🔴 Confidence 4/10 · risky as written. The host transport follows redirects the auth client explicitly forbids, and nothing tests the new routing; that security gap decides the number.
2 warnings −2 · tests missing −2 · risk high −1 · 0/1 new units observable −1

Fixes iOS native-mode sign-in by sending those requests through the host's NSURLSession instead of WebKit's fetch, which stamps Origin. The mechanism is sound, but the host follows redirects the auth transport forbids and none of the new path is tested.

  • globalThis.fetch hands x-auth-mode: native requests to the host and answers from its reply
  • http.rs sends them with an ephemeral, cookieless NSURLSession, replying {id, status, headers, body}
  • The page gains __hazel.reply so host replies reach the worker

Before merge

  • Manual · Confirm sign-in on a physical TestFlight device before release; build 2970 shipped without it

Findings

🟠 Warning · F1 · Host path follows redirects the auth client forbids (redirect: "error")

security · apps/native/src/ios.ts:72

The auth runtime builds its client with redirect: "error" because the session travels in x-auth-request-session headers (apps/web-foldkit/src/platform/desktop-auth.ts:159). The payload sent to the host carries no redirect, and NSURLSession follows a redirect by default, so a 3xx re-sends those credential headers to the Location origin and the caller gets that response instead of a rejection.

Put `redirect: outgoing.redirect` in the payload, and have `http.rs` refuse the redirect (a task delegate answering `None`) so a 3xx surfaces as the load failure the client asked for.
🟠 Warning · F2 · New fetch routing and reply handling are covered by no test

tests · apps/native/src/ios.ts:62-63

apps/native/src tests its other global shims (shims.test.ts, and data-source.ts through offline-backend.test.ts), but nothing exercises this branch: a native request reaching the host, its id matching a late reply, a non-native request on WebKit's fetch, or { error } becoming a TypeError. The change's whole behavior is unverified in CI.

Extract the routing into `src/native-fetch.ts` taking the web fetch, `request` and a reply source, and test it: native routed, others passed through, an error reply throws.

Production impact

Production traffic of the changed files (last 7 days)
File Calls/day Busiest operations
apps/native/host/ios/src/http.rs 586 GET 330/day, 0.3% err
GET 256/day, 3.0% err
apps/native/src/ios.ts 586 GET 330/day, 0.3% err
GET 256/day, 3.0% err
What was checked
  • Header name and value agree: x-auth-mode set by OperationHttpClient, admitted as native at desktop-login.ts:101
  • The auth runtime's FetchHttpClient.layer reads globalThis.fetch per request, so the override sees sign-in, session and sign-out
  • No tracer in apps/native/src, so no client span was lost against the API's existing server span
Observability coverage: 0 of 1 changes observable
Change Kind Observable Evidence
native-mode HTTP request (worker → iOS host → API) outbound call no No OpenTelemetry in apps/native/src; the call shows only as the API's server span

e89d8fc · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

Annotations

Check warning on line 72 in apps/native/src/ios.ts

See this annotation in the file changed.

@maple-review-bot maple-review-bot / Maple / review

security: Host path follows redirects the auth client forbids (`redirect: "error"`)

The auth runtime builds its client with `redirect: "error"` because the session travels in `x-auth-request-session` headers (`apps/web-foldkit/src/platform/desktop-auth.ts:159`). The payload sent to the host carries no `redirect`, and `NSURLSession` follows a redirect by default, so a 3xx re-sends those credential headers to the `Location` origin and the caller gets that response instead of a rejection.

Check warning on line 63 in apps/native/src/ios.ts

See this annotation in the file changed.

@maple-review-bot maple-review-bot / Maple / review

tests: New `fetch` routing and reply handling are covered by no test

`apps/native/src` tests its other global shims (`shims.test.ts`, and `data-source.ts` through `offline-backend.test.ts`), but nothing exercises this branch: a native request reaching the host, its `id` matching a late reply, a non-native request on WebKit's fetch, or `{ error }` becoming a `TypeError`. The change's whole behavior is unverified in CI.