mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
feat(geo): make ipwho.is the default IP-location provider again
ipwho.is is free, needs no key, and resolves a city/country for the login overview out of the box. It is the default online lookup again; the offline GeoLite2 MMDB tier stays strictly optional (consulted only on an online miss, skipped when the databases are absent). Operators whose egress ipwho.is rejects can point IP_GEO_LOOKUP_URL at ip-api.com — the parser accepts both response shapes, so the swap needs no code change.
This commit is contained in:
1 parent
2500dbeb1a
commit
abb4c71d0c
2 files changed
+17
-16
No files matched your search
@@ -84,14 +84,15 @@ describe("lookupIpLocation IP-geolocation HTTPS guard", () => {
|
||||
);
|
||||
}
|
||||
|
||||
it("uses the ip-api.com HTTPS endpoint by default", async () => {
|
||||
// v1.18.11 (W3): default provider is ip-api.com (ipwho.is 403s on
|
||||
// datacentre egress). The wire URL must be the ip-api.com JSON path
|
||||
// and the parser must accept its `status`/`countryCode` shape.
|
||||
it("uses the ipwho.is HTTPS endpoint by default", async () => {
|
||||
// v1.25.5: ipwho.is is the default provider again. The wire URL must be
|
||||
// the ipwho.is path and the parser must accept its `success`/`country_code`
|
||||
// shape. (Operators whose egress ipwho.is rejects override IP_GEO_LOOKUP_URL
|
||||
// to ip-api.com — the parser still accepts that shape; covered below.)
|
||||
const fetchSpy = vi
|
||||
.fn()
|
||||
.mockResolvedValue(
|
||||
jsonOk({ status: "success", city: "Berlin", countryCode: "DE" }),
|
||||
jsonOk({ success: true, city: "Berlin", country_code: "DE" }),
|
||||
);
|
||||
vi.stubGlobal("fetch", fetchSpy);
|
||||
const { lookupIpLocation } = await import("../geo");
|
||||
@@ -99,7 +100,7 @@ describe("lookupIpLocation IP-geolocation HTTPS guard", () => {
|
||||
expect(await lookupIpLocation("8.8.8.8")).toBe("Berlin, DE");
|
||||
const url = fetchSpy.mock.calls[0]?.[0] as string;
|
||||
expect(url.startsWith("https://")).toBe(true);
|
||||
expect(url).toBe("https://ip-api.com/json/8.8.8.8");
|
||||
expect(url).toBe("https://ipwho.is/8.8.8.8");
|
||||
});
|
||||
|
||||
it("refuses to call non-HTTPS configured providers", async () => {
|
||||
|
||||
+10
-10
@@ -90,16 +90,16 @@ type GeoResponse = IpwhoIsResponse & IpApiProResponse;
|
||||
const PRIVATE_IP =
|
||||
/^(127\.|10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.|::1|fc|fd|fe80|localhost|unknown)/;
|
||||
|
||||
// v1.18.11 (W3) — the default online provider is ip-api.com, not ipwho.is.
|
||||
// ipwho.is rejects datacentre / free-plan server egress with a 403
|
||||
// ("CORS is not supported on the Free plan"), which silently produced the
|
||||
// "—" location on prod (every server-side lookup failed). The base is
|
||||
// `https://ip-api.com/json`; `buildLookupUrl` appends `/<ip>` so the wire
|
||||
// URL is `https://ip-api.com/json/<ip>`. The parser already accepts the
|
||||
// ip-api.com shape (`status:"success"` + `countryCode`). Operators who need
|
||||
// a different / keyed provider override via `IP_GEO_LOOKUP_URL`; the HTTPS
|
||||
// egress guard in `buildLookupUrl` still applies to any override.
|
||||
const DEFAULT_GEO_URL = "https://ip-api.com/json";
|
||||
// v1.25.5 — ipwho.is is the default online provider again (free, no key, no
|
||||
// per-minute cap on the standard endpoint). The base is `https://ipwho.is`;
|
||||
// `buildLookupUrl` appends `/<ip>` so the wire URL is `https://ipwho.is/<ip>`.
|
||||
// The parser accepts BOTH the ipwho.is shape (`success` + `country_code`) and
|
||||
// the ip-api.com shape (`status` + `countryCode`), so operators whose egress
|
||||
// ipwho.is rejects can point `IP_GEO_LOOKUP_URL` at `https://ip-api.com/json`
|
||||
// (or any keyed provider matching one of those shapes) with no code change.
|
||||
// The offline GeoLite2 MMDB tier stays OPTIONAL — consulted only when the
|
||||
// online lookup misses, and skipped entirely when the databases are absent.
|
||||
const DEFAULT_GEO_URL = "https://ipwho.is";
|
||||
|
||||
function geoLiteDir(): string {
|
||||
return process.env.GEOLITE2_DIR ?? "/opt/geolite2";
|
||||
|
||||
Reference in new issue
Block a user