9612ef558fc0e9da4dfb4cebe9b9f497f3cf213f
User reported the Search tab is 403'ing on the deployed app — visible on their phone, but route-explorer.com itself loads in their phone's Safari. So the gating differentiates between Safari/WKWebView and URLSession: same network, same UA strings, different verdict. Most likely TLS-fingerprint-based. Solution: route both /api/token and /api/flight-search through the existing WebViewFetcher service (originally built for the same purpose against an Akamai-protected airline API). XHRs run from inside a WKWebView navigated to route-explorer.com, so the request hits the edge with Safari's TLS fingerprint and any first-party cookies the gate expects. Touched: - RouteExplorerClient.currentToken — now goes via WKWebView XHR - callFlightSearch — same, with one retry on token rotation - searchSchedule — same path - New fetchViaWebView helper takes (method, apiPath, headers, body) and returns the response body string Trade-offs: - Each call now starts with a WKWebView navigation (~2s). Token is cached for 30 min so this hits once per session for most usage. - Searches are slower than before. Can pool the WKWebView later if needed; for now correctness > speed. - Per-call WKWebView allocation runs on MainActor (forced by WebViewFetcher's @MainActor isolation). Awaiting from the actor is fine — the bridge is automatic. If route-explorer relaxes the gate later we can switch back to URLSession by reverting this commit; the URLSession code path was preserved up to deletion. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Description
No description provided
Languages
Swift
57.9%
HTML
33.9%
JavaScript
4.5%
Python
3.5%
Shell
0.2%