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:
@@ -307,6 +307,18 @@ Base: `ApiConfigService.getBaseUrl()`. Headers on every call (`apiHeadersInterce
|
||||
| `/items/{id}/questiion` | POST | `{ question, sessionID, timestamp }` | `{ message }` — **literal typo `questiion`, preserve it, matches the client** |
|
||||
| `/purchase-email` | POST | `{ email, phone?, telegramUserId, items[] }` | `{ message }` |
|
||||
| `/regions` | GET | — | `Region[]` — client falls back **silently** to 6 hardcoded regions on any error |
|
||||
| `/geo/resolve` | GET | — | `GeoIpResponse` — **not built yet**, see below |
|
||||
|
||||
**`/geo/resolve` — new, required.** Resolves the *caller's* IP to a coarse location so the storefront can pre-select a region. The server reads the client IP (behind the proxy, so honour `X-Forwarded-For` with `trustProxy`); the browser sends nothing and receives no third-party payload.
|
||||
|
||||
Response is the existing `GeoIpResponse` shape (`src/app/models/location.model.ts`): `{ city, country, countryCode, region?, timezone?, lat?, lon? }`.
|
||||
|
||||
Rules:
|
||||
- City-level precision only. Do not return coordinates finer than the city centroid, and do not persist the lookup against a customer record — this runs for anonymous visitors.
|
||||
- Any failure returns a non-2xx. The client already treats every error as "stay on the manual picker", so a degraded geo provider must never block the storefront.
|
||||
- Rate-limit per IP; it is an unauthenticated endpoint.
|
||||
|
||||
This replaces a direct browser call to `http://ip-api.com`, which leaked every visitor's IP to a third party and — being plaintext on an HTTPS origin — was blocked as mixed content, so region auto-detect never actually worked in production. Until this endpoint ships the client silently falls back to the manual region picker, which is the same behaviour production has had all along.
|
||||
|
||||
### 6.1 Products — the tolerance contract
|
||||
|
||||
|
||||
Reference in New Issue
Block a user