From 6e273c2676ce29cef057d117e4427e031886e743 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Fri, 17 Jul 2026 10:39:17 -0500 Subject: v4.7.0: Add domain reputation/blocklist data source - New DomainReputationResult model (status: clean/listed/unknown, listed sources, checked-at) and a `reputation(domain:)` method on ExternalDataService, mirroring the existing pluggable-URL enrichment pattern (ownership history, DNS history, extended subdomains, pricing). With no endpoint configured (the default; DomainDig ships no bundled third-party reputation dependency) it resolves to unavailable rather than "clean". - New .reputation FeatureCapability/DataCapability, gated Pro+ like domainPricing. - Threaded reputation/reputationError through LookupSnapshot and HistoryEntry (backward-compatible decode) so results persist with history entries. - Auto-fetched in performLookup alongside pricing; surfaced as a "Reputation" info row, folded into DomainInsightEngine's risk score/factors and top-level insights (a listed domain raises risk score and adds a factor/insight), and exported in text, CSV, and JSON report output. - Reputation-driven risk changes ride the existing change-severity pipeline, so a listed status flip is visible to monitoring the same way any other risk delta is, without bespoke monitoring wiring. --- DomainReportExporter.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'DomainReportExporter.swift') diff --git a/DomainReportExporter.swift b/DomainReportExporter.swift index 55b7372..05ecff9 100644 --- a/DomainReportExporter.swift +++ b/DomainReportExporter.swift @@ -69,7 +69,8 @@ enum DomainReportExporter { "Email: \(report.email.summary)", "Subdomains: \(report.subdomains.count)", "Extended Subdomains: \(report.extendedSubdomains.count)", - "External Price: \(report.domainPricing?.estimatedPrice ?? "Unavailable")" + "External Price: \(report.domainPricing?.estimatedPrice ?? "Unavailable")", + "Reputation: \(report.reputation?.status.title ?? "Unavailable")" ] } @@ -406,6 +407,8 @@ enum DomainReportExporter { "pricing_resale_signal", "pricing_auction_signal", "pricing_source", + "reputation_status", + "reputation_listed_sources", "open_ports", "reachability_summary", "geolocation_summary", @@ -438,6 +441,8 @@ enum DomainReportExporter { let subdomainGroups = report.subdomainGroups.map { "\($0.label):\($0.subdomains.count)" }.joined(separator: " | ") let ownershipHistory = report.ownershipHistory.map { "\($0.date.ISO8601Format()) \($0.summary)" }.joined(separator: " | ") let dnsHistory = report.dnsHistory.map { "\($0.date.ISO8601Format()) \($0.summary)" }.joined(separator: " | ") + let reputationStatus = report.reputation?.status.rawValue ?? "" + let reputationListedSources = report.reputation?.listedSources.joined(separator: " | ") ?? "" return [ report.domain, @@ -483,6 +488,8 @@ enum DomainReportExporter { report.domainPricing?.resaleSignal ?? "", report.domainPricing?.auctionSignal ?? "", report.domainPricing?.source ?? "", + reputationStatus, + reputationListedSources, openPorts, report.network.reachabilitySummary, report.network.geolocationSummary, -- cgit v1.2.3