feat(domain-intelligence): add domain intelligence lookups with RDAP and DNS enrichment
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# @push.rocks/smartnetwork 🌐
|
||||
|
||||
Comprehensive network diagnostics and IP intelligence for Node.js — speed tests, port scanning, ICMP ping, traceroute, DNS, RDAP, ASN lookups, and geolocation in a single, promise-based toolkit.
|
||||
Comprehensive network diagnostics and intelligence for Node.js — speed tests, port scanning, ICMP ping, traceroute, DNS, IP & domain RDAP, ASN lookups, geolocation, and DNS record enrichment in a single, promise-based toolkit.
|
||||
|
||||
## Issue Reporting and Security
|
||||
|
||||
@@ -14,9 +14,9 @@ pnpm install @push.rocks/smartnetwork --save
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
**@push.rocks/smartnetwork** is your Swiss Army knife for network diagnostics in Node.js. Whether you're building monitoring dashboards, investigating IP ownership, or debugging connectivity — this library has you covered with a clean, async API and zero-config setup.
|
||||
**@push.rocks/smartnetwork** is your Swiss Army knife for network diagnostics in Node.js. Whether you're building monitoring dashboards, investigating IP/domain ownership, or debugging connectivity — this library has you covered with a clean, async API and zero-config setup.
|
||||
|
||||
Under the hood, system-level operations (ICMP ping, traceroute, raw-socket port checks, gateway detection) are powered by a bundled **Rust binary** for maximum performance and cross-platform reliability. Everything else — speed tests, DNS, public IP discovery, IP intelligence, HTTP health checks — runs in pure TypeScript.
|
||||
Under the hood, system-level operations (ICMP ping, traceroute, raw-socket port checks, gateway detection) are powered by a bundled **Rust binary** for maximum performance and cross-platform reliability. Everything else — speed tests, DNS, public IP discovery, IP & domain intelligence, HTTP health checks — runs in pure TypeScript.
|
||||
|
||||
### ✨ Key Features
|
||||
|
||||
@@ -27,6 +27,7 @@ Under the hood, system-level operations (ICMP ping, traceroute, raw-socket port
|
||||
| 📡 **Connectivity** | ICMP ping with stats, hop-by-hop traceroute, HTTP/HTTPS health checks |
|
||||
| 🌍 **DNS** | A, AAAA, MX resolution with system-first + DoH fallback strategy |
|
||||
| 🔍 **IP Intelligence** | ASN, organization, geolocation, RDAP registration — all from free public sources |
|
||||
| 🏢 **Domain Intelligence** | RDAP registrar/registrant, nameservers, events, DNSSEC, plus DNS enrichment (A/AAAA/MX/TXT/SOA) |
|
||||
| 🖥️ **Network Discovery** | Interfaces, default gateway, public IPv4/IPv6 |
|
||||
| ⚡ **Caching** | Built-in TTL cache for expensive lookups |
|
||||
| 🔧 **Extensible** | Plugin architecture for custom functionality |
|
||||
@@ -46,7 +47,7 @@ await network.start();
|
||||
|
||||
// ... use the network instance ...
|
||||
|
||||
// Clean up when done
|
||||
// Clean up when done — tears down both the Rust bridge and the smartdns backend
|
||||
await network.stop();
|
||||
```
|
||||
|
||||
@@ -126,6 +127,104 @@ interface IIpIntelligenceResult {
|
||||
|
||||
---
|
||||
|
||||
### 🏢 Domain Intelligence
|
||||
|
||||
Get comprehensive domain registration and DNS data. Runs an **RDAP layer** and a **DNS layer** in parallel, then merges results:
|
||||
|
||||
- **RDAP** — queries the correct registry RDAP server (discovered via the [IANA DNS bootstrap](https://data.iana.org/rdap/dns.json)) for registrar, registrant, events, status flags, DNSSEC, and abuse contacts
|
||||
- **DNS** — queries A, AAAA, NS, MX, TXT, and SOA records via `@push.rocks/smartdns` (system resolver first, DoH fallback)
|
||||
|
||||
For gTLDs (`.com`, `.org`, `.net`, etc.) you get the full picture from both layers. For ccTLDs without RDAP support (`.de`, `.fr`, `.nl`, etc.), the DNS layer fills in nameservers, resolved IPs, MX, TXT, and SOA — so you still get useful intelligence even when RDAP isn't available.
|
||||
|
||||
```typescript
|
||||
const info = await network.getDomainIntelligence('google.com');
|
||||
|
||||
console.log(info);
|
||||
// {
|
||||
// domain: 'google.com',
|
||||
// handle: '2138514_DOMAIN_COM-VRSN',
|
||||
// status: ['client delete prohibited', 'server transfer prohibited', ...],
|
||||
// registrationDate: '1997-09-15T04:00:00Z',
|
||||
// expirationDate: '2028-09-14T04:00:00Z',
|
||||
// lastChangedDate: '2019-09-09T15:39:04Z',
|
||||
// registrarName: 'MarkMonitor Inc.',
|
||||
// registrarIanaId: 292,
|
||||
// registrantOrg: null, // often redacted under GDPR
|
||||
// registrantCountry: null,
|
||||
// abuseEmail: 'abusecomplaints@markmonitor.com',
|
||||
// abusePhone: '+1.2086851750',
|
||||
// nameservers: ['ns1.google.com', 'ns2.google.com', 'ns3.google.com', 'ns4.google.com'],
|
||||
// dnssec: false,
|
||||
// nameserversSource: 'rdap',
|
||||
// resolvedIpv4: ['142.251.20.102', '142.251.20.113', ...],
|
||||
// resolvedIpv6: ['2a00:1450:4001:c15::8b', ...],
|
||||
// mxRecords: [{ priority: 10, exchange: 'smtp.google.com' }],
|
||||
// txtRecords: ['v=spf1 include:_spf.google.com ~all', ...],
|
||||
// soaRecord: 'ns1.google.com dns-admin.google.com 895796075 900 900 1800 60'
|
||||
// }
|
||||
```
|
||||
|
||||
Works with ccTLDs that don't have RDAP (like `.de`):
|
||||
|
||||
```typescript
|
||||
const deInfo = await network.getDomainIntelligence('bund.de');
|
||||
console.log(deInfo.registrarName); // null (no .de RDAP)
|
||||
console.log(deInfo.nameservers); // ['bamberg.bund.de', 'argon.bund.de', ...]
|
||||
console.log(deInfo.nameserversSource); // 'dns' — nameservers came from DNS, not RDAP
|
||||
console.log(deInfo.resolvedIpv4); // ['80.245.156.34']
|
||||
console.log(deInfo.mxRecords); // [{priority: 10, exchange: 'mx1.bund.de'}, ...]
|
||||
```
|
||||
|
||||
Handles IDN (internationalized domain names) automatically:
|
||||
|
||||
```typescript
|
||||
const idn = await network.getDomainIntelligence('münchen.de');
|
||||
console.log(idn.domain); // 'xn--mnchen-3ya.de' — normalized to punycode
|
||||
```
|
||||
|
||||
The `IDomainIntelligenceResult` interface:
|
||||
|
||||
```typescript
|
||||
interface IDomainIntelligenceResult {
|
||||
domain: string | null; // normalized ASCII form
|
||||
handle: string | null; // registry handle
|
||||
status: string[] | null; // EPP status codes
|
||||
|
||||
// Registration lifecycle (ISO 8601)
|
||||
registrationDate: string | null;
|
||||
expirationDate: string | null;
|
||||
lastChangedDate: string | null;
|
||||
|
||||
// Registrar
|
||||
registrarName: string | null;
|
||||
registrarIanaId: number | null;
|
||||
|
||||
// Registrant (often redacted under GDPR)
|
||||
registrantOrg: string | null;
|
||||
registrantCountry: string | null;
|
||||
|
||||
// Abuse contact
|
||||
abuseEmail: string | null;
|
||||
abusePhone: string | null;
|
||||
|
||||
// Technical
|
||||
nameservers: string[] | null;
|
||||
dnssec: boolean | null; // secureDNS.delegationSigned from RDAP
|
||||
nameserversSource: 'rdap' | 'dns' | null;
|
||||
|
||||
// DNS enrichment
|
||||
resolvedIpv4: string[] | null; // A records
|
||||
resolvedIpv6: string[] | null; // AAAA records
|
||||
mxRecords: { priority: number | null; exchange: string }[] | null;
|
||||
txtRecords: string[] | null; // SPF, DKIM, site verification, etc.
|
||||
soaRecord: string | null; // raw SOA value
|
||||
}
|
||||
```
|
||||
|
||||
> 💡 **RDAP vs DNS nameservers**: When RDAP is available (most gTLDs), `nameservers` comes from the registry's authoritative parent-zone delegation (`nameserversSource: 'rdap'`). When RDAP is unavailable (many ccTLDs), the DNS layer fills in nameservers via NS record resolution (`nameserversSource: 'dns'`). The `nameserversSource` field tells you which source won.
|
||||
|
||||
---
|
||||
|
||||
### 🏎️ Speed Testing
|
||||
|
||||
Measure network performance via Cloudflare's global infrastructure:
|
||||
@@ -263,7 +362,7 @@ console.log(`🌍 IPv6: ${publicIps.v6 || 'N/A'}`);
|
||||
|
||||
### ⚡ Caching
|
||||
|
||||
Caching applies to `getGateways()`, `getPublicIps()`, and `getIpIntelligence()`:
|
||||
Caching applies to `getGateways()`, `getPublicIps()`, `getIpIntelligence()`, and `getDomainIntelligence()`:
|
||||
|
||||
```typescript
|
||||
const network = new SmartNetwork({ cacheTtl: 60000 }); // 60s
|
||||
@@ -360,6 +459,11 @@ const monitor = async () => {
|
||||
console.log(`AS${intel.asn} (${intel.asnOrg}) — ${intel.city || intel.countryCode}`);
|
||||
}
|
||||
|
||||
// Domain recon
|
||||
const domain = await network.getDomainIntelligence('example.com');
|
||||
console.log(`Registrar: ${domain.registrarName}, expires: ${domain.expirationDate}`);
|
||||
console.log(`Nameservers (${domain.nameserversSource}):`, domain.nameservers);
|
||||
|
||||
await network.stop();
|
||||
};
|
||||
```
|
||||
@@ -368,7 +472,7 @@ const monitor = async () => {
|
||||
|
||||
| Method | Description | Requires Rust |
|
||||
|--------|-------------|:---:|
|
||||
| `start()` / `stop()` | Start/stop the Rust binary bridge | — |
|
||||
| `start()` / `stop()` | Start/stop the Rust bridge and smartdns backend | — |
|
||||
| `getSpeed(opts?)` | Cloudflare speed test (download + upload) | No |
|
||||
| `ping(host, opts?)` | ICMP ping with optional multi-ping stats | Yes |
|
||||
| `traceroute(host, opts?)` | Hop-by-hop network path analysis | Yes |
|
||||
@@ -381,6 +485,7 @@ const monitor = async () => {
|
||||
| `resolveDns(host)` | Resolve A, AAAA, MX records | No |
|
||||
| `checkEndpoint(url, opts?)` | HTTP/HTTPS health check with RTT | No |
|
||||
| `getIpIntelligence(ip)` | ASN + org + geo + RDAP registration | No |
|
||||
| `getDomainIntelligence(domain)` | Registrar, nameservers, events, DNS records, DNSSEC | No |
|
||||
|
||||
## License and Legal Information
|
||||
|
||||
@@ -396,7 +501,7 @@ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark G
|
||||
|
||||
### Company Information
|
||||
|
||||
Task Venture Capital GmbH
|
||||
Task Venture Capital GmbH
|
||||
Registered at District Court Bremen HRB 35230 HB, Germany
|
||||
|
||||
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
||||
|
||||
Reference in New Issue
Block a user