fix(geo): stop calling ip-api.com from the browser (FH-1.1)
detectLocation() fetched http://ip-api.com over plaintext from an HTTPS storefront. Browsers block mixed active content, so the request never completed and auto-detect only ever took its error branch - region detection has been dead in production, not merely insecure. The attempt also handed every visitor's IP to a third party from the page itself. Geo now resolves through the tenant API at {baseUrl}/geo/resolve, the same base /regions already uses. The server reads the client IP; the browser sends nothing and receives no third-party payload. The endpoint is specified in BACKEND-API-REFERENCE.md and is not built yet. Until it ships the client falls back to the manual region picker - identical to the behaviour production already had. Adds location.service.spec.ts: geo goes to the tenant API, no request leaves that origin or uses http://, failure degrades to the manual picker, and detection is not retried once attempted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,8 @@ Improvements only. Nothing here regresses our Angular version, test count, or ar
|
||||
|
||||
## Wave 1 — Live defects with a security benefit (Lane A, this sprint)
|
||||
|
||||
- [ ] **FH-1.1 — Kill the plaintext third-party geo call** · S · Lane A
|
||||
- [x] **FH-1.1 — Kill the plaintext third-party geo call** · S · Lane A · **done 2026-08-21**
|
||||
Now `GET {tenantApiBase}/geo/resolve`, same base as `/regions`. Server reads the client IP; nothing leaves our infrastructure. Endpoint specified in [BACKEND-API-REFERENCE.md](../BACKEND-API-REFERENCE.md) §6 — **not built yet**, and until it is the client falls back to the manual picker, which is what production has effectively had all along. Covered by `src/app/services/location.service.spec.ts` (4 tests, one of which fails the build on any off-origin or plaintext request from this service).
|
||||
`src/app/services/location.service.ts:75` calls `http://ip-api.com/json/?fields=…` from an HTTPS origin. Browsers block mixed active content, so `detectLocation()` has been silently taking its error branch in production — region auto-detect is dead, not just insecure. It is also a third-party geo leak on every session.
|
||||
**Do:** remove the direct call. Resolve region server-side (`GET /api/v1/geo/resolve`, backend reads the client IP) or drop auto-detect and keep the manual region picker.
|
||||
**Done when:** zero `http://` literals in `src/`; a unit test asserts `detectLocation()` issues no cross-origin request to a non-allowlisted host.
|
||||
@@ -37,7 +38,8 @@ Improvements only. Nothing here regresses our Angular version, test count, or ar
|
||||
**Do:** accept only an `https:` URL whose origin the backend returned in the payment response (backend allowlist, per their `safeHttpsUrl()`); navigate the current tab instead of framing.
|
||||
**Done when:** a non-https or non-allowlisted URL is refused with a visible payment error; a test covers both the accepted and the refused case.
|
||||
|
||||
- [ ] **FH-1.3 — Remove provider credentials from the browser** · M · Lane A · *depends on FH-0.2*
|
||||
- [x] **FH-1.3 — Remove provider credentials from the browser** · M · Lane A · **landed via the `@marketplaces/payment` migration**
|
||||
The legacy payment surface on `ApiService` was deleted wholesale in that work. `grep -ri "authorization-key\|userid-value\|web-97ec" src/` now returns nothing. Keep FH-3.5 (bundle secret scan) to stop it coming back.
|
||||
`src/app/services/api.service.ts:675` sets `authorization-key` and `userid-value` headers client-side. `api.service.ts:143` ships a partner ID literal (`'web-97ec-9c57-4dde-9037-3a68f7f83750'`) in the bundle. Their audit's most serious finding, and it is correct.
|
||||
**Do:** delete both header paths and the literal; the browser gets a checkout URL or a status endpoint, never a credential.
|
||||
**Done when:** `grep -ri "authorization-key\|userid-value" src/` returns nothing; no partner ID literal in `dist/`; a CI check greps the built bundle for both patterns.
|
||||
|
||||
Reference in New Issue
Block a user