From cdb22a49fd2ef6a9dc93268d5ac438e453b239b7 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 16 Jul 2026 22:36:16 +0000 Subject: [PATCH 1/3] Require maxmind-geoip2 1.6 for residential data The maxmind-geoip2 gem's AnonymizerFeed/residential support was released in 1.6.0. Bump the dependency constraint so consumers resolve a version that includes it. Co-Authored-By: Claude Opus 4.8 --- Gemfile.lock | 6 +++--- minfraud.gemspec | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9c460a4..0ee1128 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,7 +4,7 @@ PATH minfraud (2.9.0) connection_pool (>= 2.2, < 4.0) http (>= 4.3, < 6.0) - maxmind-geoip2 (~> 1.4) + maxmind-geoip2 (~> 1.6) simpleidn (~> 0.1, >= 0.1.1) GEM @@ -53,9 +53,9 @@ GEM ffi-compiler (~> 1.0) rake (~> 13.0) maxmind-db (1.4.0) - maxmind-geoip2 (1.5.1) + maxmind-geoip2 (1.6.0) connection_pool (>= 2.2, < 4.0) - http (>= 4.3, < 6.0) + http (>= 4.3, < 7.0) maxmind-db (~> 1.4) parallel (1.28.0) parser (3.3.11.1) diff --git a/minfraud.gemspec b/minfraud.gemspec index eafb6f0..afece0c 100644 --- a/minfraud.gemspec +++ b/minfraud.gemspec @@ -31,7 +31,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'connection_pool', '>= 2.2', '< 4.0' spec.add_dependency 'http', '>= 4.3', '< 6.0' - spec.add_dependency 'maxmind-geoip2', '~> 1.4' + spec.add_dependency 'maxmind-geoip2', '~> 1.6' spec.add_dependency 'simpleidn', '~> 0.1', '>= 0.1.1' spec.add_development_dependency 'bundler', '~> 2.2' From 86752e52d97418801a7a3c744141caf4f2fd0153 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Fri, 10 Jul 2026 21:00:57 +0000 Subject: [PATCH 2/3] Add residential attribute to the anonymizer object The minFraud Insights and Factors web services now return a residential sub-object on ip_address.anonymizer containing residential proxy data for the network: a confidence score, the network last seen date, and the provider name. It may be populated even when no other anonymizer attributes are set. This is exposed automatically via MaxMind::GeoIP2::Record::Anonymizer#residential once the app is running maxmind-geoip2 >= 1.6.0, so no model changes are needed here, only updated fixtures, specs, and the changelog. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 6 ++++++ spec/fixtures/files/factors-response1.json | 7 ++++++- spec/fixtures/files/insights-response1.json | 7 ++++++- spec/model/insights_spec.rb | 6 ++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92548c5..93d24b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## v2.10.0 +* Added the `residential` attribute to the `anonymizer` object on + `Minfraud::Model::IPAddress`. This object contains residential proxy + data for the network, including a confidence score, the network last + seen date, and the provider name. It may be populated even when no + other anonymizer attributes are set. This is only available from the + minFraud Insights and Factors web services. * Added the `tracking_token` attribute to `Minfraud::Components::Device`. This is the token generated by the [Device Tracking Add-on](https://dev.maxmind.com/minfraud/track-devices) diff --git a/spec/fixtures/files/factors-response1.json b/spec/fixtures/files/factors-response1.json index 3242ffa..40bddaa 100644 --- a/spec/fixtures/files/factors-response1.json +++ b/spec/fixtures/files/factors-response1.json @@ -139,7 +139,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" + } } }, "billing_address": { diff --git a/spec/fixtures/files/insights-response1.json b/spec/fixtures/files/insights-response1.json index 9699671..84e3352 100644 --- a/spec/fixtures/files/insights-response1.json +++ b/spec/fixtures/files/insights-response1.json @@ -151,7 +151,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" + } } }, "billing_address": { diff --git a/spec/model/insights_spec.rb b/spec/model/insights_spec.rb index 369ff93..3dbe4d0 100644 --- a/spec/model/insights_spec.rb +++ b/spec/model/insights_spec.rb @@ -100,6 +100,12 @@ provider_name: 'TestVPN' ) + expect(m.ip_address.anonymizer.residential).to have_attributes( + confidence: 82, + network_last_seen: Date.new(2_026, 5, 11), + provider_name: 'quickshift' + ) + expect(m.billing_address.is_postal_in_city).to be false expect(m.billing_address.latitude).to eq 41.310571 expect(m.billing_address.longitude).to eq(-72.922891) From ab58357afb81124497a7c0f667cdd1cc5129a582 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 16 Jul 2026 22:38:44 +0000 Subject: [PATCH 3/3] Update mise tools Bump lychee 0.23.0 -> 0.24.2 and ruby 4.0.3 -> 4.0.6 via `mise up`. lychee 0.24 replaced the boolean `include_fragments` config key with a `FragmentMode` string (none/anchor-only/text-only/full). Migrate lychee.toml to `include_fragments = "full"`, which checks both anchor fragments (`#anchor`) and text fragments (`#:~:text=`). Co-Authored-By: Claude Opus 4.8 --- lychee.toml | 6 ++-- mise.lock | 80 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/lychee.toml b/lychee.toml index a757252..01037a9 100644 --- a/lychee.toml +++ b/lychee.toml @@ -4,8 +4,10 @@ # Run locally with: # lychee './**/*.md' './lib/**/*.rb' './*.gemspec' -# Include URL fragments in checks -include_fragments = true +# Include URL fragments in checks. lychee 0.24 replaced the boolean +# `include_fragments` with a mode string; `full` checks both `#anchor` +# fragments and text fragments (`#:~:text=`). +include_fragments = "full" # Don't allow any redirects, so links that have moved are surfaced and can be # updated to their canonical destination. diff --git a/mise.lock b/mise.lock index 9f4b126..5d0b4e8 100644 --- a/mise.lock +++ b/mise.lock @@ -1,60 +1,86 @@ # @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html [[tools.lychee]] -version = "0.23.0" +version = "0.24.2" backend = "aqua:lycheeverse/lychee" [tools.lychee."platforms.linux-arm64"] -checksum = "sha256:97eb93b02a7d78a752fc33e5b0983439ccaadbf3db952b68a0a4401acd92e6e0" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-aarch64-unknown-linux-gnu.tar.gz" +checksum = "sha256:5d0b0e3aeab240f41920c633a6eaf97599be6eedda034b36e858ede7dba5e535" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409958602" [tools.lychee."platforms.linux-arm64-musl"] -checksum = "sha256:97eb93b02a7d78a752fc33e5b0983439ccaadbf3db952b68a0a4401acd92e6e0" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-aarch64-unknown-linux-gnu.tar.gz" +checksum = "sha256:5d0b0e3aeab240f41920c633a6eaf97599be6eedda034b36e858ede7dba5e535" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409958602" [tools.lychee."platforms.linux-x64"] -checksum = "sha256:5538440d2c69a45a0a09983271e5dee0c2fe7137d8035d25b2632e10a66a090a" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-unknown-linux-musl.tar.gz" +checksum = "sha256:73657a111819a30c47c08352896796f23d64e4eb2b3ed39b6d32149241566fc5" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409959271" [tools.lychee."platforms.linux-x64-musl"] -checksum = "sha256:5538440d2c69a45a0a09983271e5dee0c2fe7137d8035d25b2632e10a66a090a" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-unknown-linux-musl.tar.gz" +checksum = "sha256:73657a111819a30c47c08352896796f23d64e4eb2b3ed39b6d32149241566fc5" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409959271" [tools.lychee."platforms.macos-arm64"] -checksum = "sha256:4c8034900e11083b68ac6f6582c377ff1f704e268991999e09d717973e493e7f" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-arm64-macos.dmg" +checksum = "sha256:c9d3740ea2d891854d37116c9fba840f37b6e7c89d330e7db84ac333631c4977" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-apple-darwin.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409957951" + +[tools.lychee."platforms.macos-x64"] +checksum = "sha256:887503a9cff667d322b8d0892b40bf49976eb9507af8483220a3706cdad55978" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-apple-darwin.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409957687" [tools.lychee."platforms.windows-x64"] -checksum = "sha256:0fda7ff0a60c0250939fc25361c2d4e6e7853c31c996733fdd5a1dd760bcb824" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-windows.exe" +checksum = "sha256:32975d1493ee1a975d6bb41e4fb56fe419cb442ded628bb772ba2e614acfacad" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-pc-windows-msvc.zip" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409959491" [[tools.ruby]] -version = "4.0.3" +version = "4.0.6" backend = "core:ruby" +[tools.ruby.options] +compile = "false" +precompiled_url = "jdx/ruby" +ruby_build_repo = "https://github.com/rbenv/ruby-build.git" +ruby_install = "false" + [tools.ruby."platforms.linux-arm64"] -checksum = "sha256:77964acc370d5c8375b9502e5ba6c13c03ef91ab9eb9f521c84fb42b9c9a6b0f" -url = "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.3.tar.gz" +checksum = "sha256:6144c26cd5a1ff85358beb7e68e592ada6d0319aa8093cf353465d60f10aa970" +url = "https://github.com/jdx/ruby/releases/download/4.0.6-1/ruby-4.0.6.arm64_linux.tar.gz" +provenance = "github-attestations" [tools.ruby."platforms.linux-arm64-musl"] -checksum = "sha256:77964acc370d5c8375b9502e5ba6c13c03ef91ab9eb9f521c84fb42b9c9a6b0f" -url = "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.3.tar.gz" +checksum = "sha256:6144c26cd5a1ff85358beb7e68e592ada6d0319aa8093cf353465d60f10aa970" +url = "https://github.com/jdx/ruby/releases/download/4.0.6-1/ruby-4.0.6.arm64_linux.tar.gz" +provenance = "github-attestations" [tools.ruby."platforms.linux-x64"] -checksum = "sha256:77964acc370d5c8375b9502e5ba6c13c03ef91ab9eb9f521c84fb42b9c9a6b0f" -url = "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.3.tar.gz" +checksum = "sha256:aefa111873bac3b15c5c416bfaaca84e793d5312d4496d651ad79c44521b200a" +url = "https://github.com/jdx/ruby/releases/download/4.0.6-1/ruby-4.0.6.x86_64_linux.tar.gz" +provenance = "github-attestations" [tools.ruby."platforms.linux-x64-musl"] -checksum = "sha256:77964acc370d5c8375b9502e5ba6c13c03ef91ab9eb9f521c84fb42b9c9a6b0f" -url = "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.3.tar.gz" +checksum = "sha256:aefa111873bac3b15c5c416bfaaca84e793d5312d4496d651ad79c44521b200a" +url = "https://github.com/jdx/ruby/releases/download/4.0.6-1/ruby-4.0.6.x86_64_linux.tar.gz" +provenance = "github-attestations" [tools.ruby."platforms.macos-arm64"] -checksum = "sha256:77964acc370d5c8375b9502e5ba6c13c03ef91ab9eb9f521c84fb42b9c9a6b0f" -url = "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.3.tar.gz" +checksum = "sha256:518c5849d7ab337790943963ded4f0b402d2d4ededea265288a5a19d4c8fee18" +url = "https://github.com/jdx/ruby/releases/download/4.0.6-1/ruby-4.0.6.macos.tar.gz" +provenance = "github-attestations" [tools.ruby."platforms.macos-x64"] -checksum = "sha256:77964acc370d5c8375b9502e5ba6c13c03ef91ab9eb9f521c84fb42b9c9a6b0f" -url = "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.3.tar.gz" +checksum = "sha256:837d299e8f7ddf2be31a229a7a7e019d354979825117989acb3b32b1a9be262a" +url = "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.6.tar.gz" + +[[tools.ruby]] +version = "4.0.6" +backend = "core:ruby" [tools.ruby."platforms.windows-x64"] -url = "https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-4.0.3-1/rubyinstaller-4.0.3-1-x64.7z" +url = "https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-4.0.6-1/rubyinstaller-4.0.6-1-x64.7z"