(url)
| 97 | |
| 98 | // Resolve domain registration data via whoiser, with rdap.org as a fallback for TLD gaps |
| 99 | const whoisHandler = async (url) => { |
| 100 | const { hostname } = parseTarget(url); |
| 101 | if (net.isIP(hostname)) { |
| 102 | return { skipped: 'WHOIS lookups apply to domains, not IP addresses' }; |
| 103 | } |
| 104 | const target = baseDomain(hostname); |
| 105 | let results = {}; |
| 106 | try { |
| 107 | results = await whoisDomain(target, { follow: 2, timeout: TIMEOUT }); |
| 108 | } catch (error) { |
| 109 | log.debug(`whoisDomain failed for ${target}: ${error.message}`); |
| 110 | } |
| 111 | if (!hasUsefulData(results)) { |
| 112 | const rdap = await fetchRdapFallback(target); |
| 113 | if (rdap) results = { ...results, 'rdap.org': rdap }; |
| 114 | } |
| 115 | if (!hasUsefulData(results)) { |
| 116 | return { skipped: 'No WHOIS data available for this domain' }; |
| 117 | } |
| 118 | return { |
| 119 | domain: pick(results, 'Domain Name') || target, |
| 120 | registrar: pick(results, 'Registrar'), |
| 121 | registrarUrl: pick(results, 'Registrar URL'), |
| 122 | registrarIanaId: pick(results, 'Registrar IANA ID'), |
| 123 | registrarWhoisServer: pick(results, 'Registrar WHOIS Server'), |
| 124 | registryDomainId: pick(results, 'Registry Domain ID'), |
| 125 | created: toIso(pick(results, 'Created Date', 'Creation Date')), |
| 126 | updated: toIso(pick(results, 'Updated Date')), |
| 127 | expires: toIso(pick(results, 'Expiry Date', 'Registry Expiry Date', 'Expiration Date')), |
| 128 | nameservers: cleanNs(pick(results, 'Name Server')), |
| 129 | status: pick(results, 'Domain Status'), |
| 130 | dnssec: pick(results, 'DNSSEC'), |
| 131 | }; |
| 132 | }; |
| 133 | |
| 134 | export const handler = middleware(whoisHandler); |
| 135 | export default handler; |
nothing calls this directly
no test coverage detected