diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e7dcad..e77706c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ CHANGELOG ========= +4.4.0 (unreleased) +------------------ + +* Added `residential` field to the `Anonymizer` response record via an + updated `geoip2` dependency. This is an `AnonymizerFeed` record containing + `confidence`, `networkLastSeen`, and `providerName` fields sourced from the + GeoIP Residential Proxy feed. Because the residential proxy feed is a + superset of the data used for the other `Anonymizer` fields, `residential` + may be populated even when none of the other fields on `Anonymizer` are + set. This requires `geoip2` 5.2.0 or greater. + 4.3.0 (2026-05-12) ------------------ diff --git a/src/test/java/com/maxmind/minfraud/response/InsightsResponseTest.java b/src/test/java/com/maxmind/minfraud/response/InsightsResponseTest.java index fd4f71e5..af3f8b98 100644 --- a/src/test/java/com/maxmind/minfraud/response/InsightsResponseTest.java +++ b/src/test/java/com/maxmind/minfraud/response/InsightsResponseTest.java @@ -6,6 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.fasterxml.jackson.jr.ob.JSON; +import com.maxmind.geoip2.record.AnonymizerFeed; import java.time.LocalDate; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -39,6 +40,11 @@ public void testInsights() throws Exception { .put("is_tor_exit_node", true) .put("network_last_seen", "2025-01-15") .put("provider_name", "TestVPN") + .startObjectField("residential") + .put("confidence", 82) + .put("network_last_seen", "2026-05-11") + .put("provider_name", "quickshift") + .end() .end() .startObjectField("country") .put("iso_code", "US") @@ -152,5 +158,24 @@ public void testInsights() throws Exception { "correct networkLastSeen" ); assertEquals("TestVPN", insights.ipAddress().anonymizer().providerName(), "correct providerName"); + + AnonymizerFeed residential = insights.ipAddress().anonymizer().residential(); + + assertNotNull(residential, "anonymizer.residential() returns null"); + assertEquals( + Integer.valueOf(82), + residential.confidence(), + "correct anonymizer.residential().confidence()" + ); + assertEquals( + LocalDate.parse("2026-05-11"), + residential.networkLastSeen(), + "correct anonymizer.residential().networkLastSeen()" + ); + assertEquals( + "quickshift", + residential.providerName(), + "correct anonymizer.residential().providerName()" + ); } } diff --git a/src/test/resources/test-data/factors-response.json b/src/test/resources/test-data/factors-response.json index 1e8b789b..75a64e82 100644 --- a/src/test/resources/test-data/factors-response.json +++ b/src/test/resources/test-data/factors-response.json @@ -24,7 +24,12 @@ "is_residential_proxy": true, "is_tor_exit_node": true, "network_last_seen": "2025-01-15", - "provider_name": "TestVPN" + "provider_name": "TestVPN", + "residential": { + "confidence": 82, + "network_last_seen": "2026-05-11", + "provider_name": "quickshift" + } }, "city": { "confidence": 42, diff --git a/src/test/resources/test-data/insights-response.json b/src/test/resources/test-data/insights-response.json index 643f09ab..a052cf20 100644 --- a/src/test/resources/test-data/insights-response.json +++ b/src/test/resources/test-data/insights-response.json @@ -24,7 +24,12 @@ "is_residential_proxy": true, "is_tor_exit_node": true, "network_last_seen": "2025-01-15", - "provider_name": "TestVPN" + "provider_name": "TestVPN", + "residential": { + "confidence": 82, + "network_last_seen": "2026-05-11", + "provider_name": "quickshift" + } }, "city": { "confidence": 42,