From a7535f42a9a61e7d15f4d08caf750e91f0a57f6e Mon Sep 17 00:00:00 2001 From: popeeyy <29686338+popeeyy@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:37:45 -0700 Subject: [PATCH] Add .tr WHOIS server & parsing --- src/parsers.js | 68 ++++++++++++++++++++++++++++++++++++++++++++----- src/whoiser.js | 2 +- test/domains.js | 9 +++++++ 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/parsers.js b/src/parsers.js index 8f7d641..bd12207 100644 --- a/src/parsers.js +++ b/src/parsers.js @@ -145,6 +145,7 @@ const parseDomainWhois = (domain, whois, ignorePrivacy) => { 'redacted for gdpr', 'redacted redacted', 'not available from registry', + 'hidden upon user request', ] // WHOIS labels to rename. "From" must be lowercase @@ -165,6 +166,7 @@ const parseDomainWhois = (domain, whois, ignorePrivacy) => { hostname: 'Name Server', 'domain nameservers': 'Name Server', 'domain servers in listed order': 'Name Server', // found in .ly + 'domain servers': 'Name Server', // found in .tr 'name servers dns': 'Name Server', // found in .mx flags: 'Domain Status', status: 'Domain Status', @@ -178,6 +180,7 @@ const parseDomainWhois = (domain, whois, ignorePrivacy) => { 'registrar............': 'Registrar', // found in .ax 'record maintained by': 'Registrar', 'sponsoring registrar': 'Registrar', + 'registrar organization name': 'Registrar', // found in .tr url: 'Registrar URL', 'registrar website': 'Registrar URL', 'registrar web': 'Registrar URL', // found in .it @@ -189,6 +192,7 @@ const parseDomainWhois = (domain, whois, ignorePrivacy) => { 'relevant dates registered on': 'Created Date', created: 'Created Date', 'created on': 'Created Date', // found in .mx + 'additional info created on..............': 'Created Date', // found in .tr 'registration time': 'Created Date', registered: 'Created Date', 'created..............': 'Created Date', // found in .ax @@ -211,6 +215,7 @@ const parseDomainWhois = (domain, whois, ignorePrivacy) => { 'expire date': 'Expiry Date', 'expiration date': 'Expiry Date', 'expires..............': 'Expiry Date', // found in .ax + 'additional info expires on..............': 'Expiry Date', // found in .tr 'paid-till': 'Expiry Date', 'expiry date': 'Expiry Date', expire: 'Expiry Date', @@ -220,16 +225,16 @@ const parseDomainWhois = (domain, whois, ignorePrivacy) => { 'registry registrantid': 'Registry Registrant ID', // found in .ai registrant: 'Registrant Name', // found in .ai 'registrant contact name': 'Registrant Name', - 'registrantname': 'Registrant Name', // found in .ai + registrantname: 'Registrant Name', // found in .ai 'registrant person': 'Registrant Name', // found in .ua 'registrant email': 'Registrant Email', // found in .ua 'registrant contact email': 'Registrant Email', - 'registrantemail': 'Registrant Email', // found in .ai - 'registrantstreet': 'Registrant Street', // found in .ai - 'registrantcity': 'Registrant City', // found in .ai - 'registrantcountry': 'Registrant Country', // found in .ai + registrantemail: 'Registrant Email', // found in .ai + registrantstreet: 'Registrant Street', // found in .ai + registrantcity: 'Registrant City', // found in .ai + registrantcountry: 'Registrant Country', // found in .ai 'registrant organisation': 'Registrant Organization', - 'registrantphone': 'Registrant Phone', + registrantphone: 'Registrant Phone', 'trading as': 'Registrant Organization', // found in .uk, .co.uk org: 'Registrant Organization', // found in .ru 'registrant state': 'Registrant State/Province', @@ -308,11 +313,15 @@ const parseDomainWhois = (domain, whois, ignorePrivacy) => { if (domain.endsWith('.jp')) { lines = handleJpLines(lines) } - + if (domain.endsWith('.it')) { lines = handleDotIt(lines) } + if (domain.endsWith('.tr')) { + lines = handleDotTr(lines) + } + lines = lines.map((l) => l.trim()) lines.forEach((line) => { @@ -373,6 +382,51 @@ const parseDomainWhois = (domain, whois, ignorePrivacy) => { return data } +const handleDotTr = (lines) => { + lines = lines.filter((line) => line.trim() !== '') // Remove blank lines + + const registrantLines = ['Name', undefined, undefined, undefined, undefined] // No clue what the other 4 fields are, all domains have them hidden + const replacement = [] + let section = '' + let sectionLine = 0 + + for (let line of lines) { + line = line.replace(/\s+/g, ' ').replace(' :', ':').trim() + + if (line.startsWith('** Domain')) { + // Keep line for domain name/nameservers + line = line.replace('** ', '') + } else if (line.includes('** ')) { + // Start new section + section = line.replace(':', '').replace('** ', '').trim() + sectionLine = 0 + continue + } else if (section === 'Registrant') { + // Add registrant info + if (!registrantLines[sectionLine]) continue + + line = `Registrant ${registrantLines[sectionLine]}: ${line}` + sectionLine++ + } else if (!line.includes(': ')) { + // Add multi-line information to one line (nameservers and address) + replacement[replacement.length - 1] += ` ${line}` + continue + } else if (section) { + // Append section name to each line + line = `${section} ${line}` + } + + // Remove period at end of dates + if (section === 'Additional Info') { + line = line.replace(/\.$/, '') + } + + replacement.push(line) + } + + return replacement +} + const handleDotUa = (lines) => { const types = ['Registrar', 'Registrant', 'Admin', 'Technical'] let flag = '' diff --git a/src/whoiser.js b/src/whoiser.js index c6ec61a..4d86e32 100644 --- a/src/whoiser.js +++ b/src/whoiser.js @@ -26,6 +26,7 @@ let cacheTldWhoisServer = { ro: 'whois.rotld.ro', rs: 'whois.rnids.rs', so: 'whois.nic.so', + tr: 'whois.nic.tr', us: 'whois.nic.us', ws: 'whois.website.ws', @@ -102,7 +103,6 @@ const whoisTld = async (query, { timeout = 15000, raw = false, domainTld = '' } // if no whois server found, search in more sources if (!data.whois) { - //todo // instead of using `domainTld`, split `query` in domain parts and request info for all tld combinations // example: query="example.com.tld" make 3 requests for "example.com.tld" / "com.tld" / "tld" diff --git a/test/domains.js b/test/domains.js index c0d97de..fa4885e 100644 --- a/test/domains.js +++ b/test/domains.js @@ -120,6 +120,15 @@ describe('#whoiser.domain()', function() { assert.equal(typeof whois['whois.nic.it'][label], 'string', `${label} does not exist, or is not a string`) } }) + + it('returns WHOIS for "trabis.gov.tr"', async function () { + let whois = await whoiser.domain('trabis.gov.tr') + assert.equal(whois['whois.nic.tr']['Domain Name'], 'trabis.gov.tr', 'Domain name doesn\'t match') + assert.equal(whois['whois.nic.tr']['Name Server'].length, 5, 'Incorrect number of NS returned') + assert.equal(whois['whois.nic.tr']['Registrar'], 'TRABİS KK', 'Registrar name doesn\'t match') + assert.equal(whois['whois.nic.tr']['Registrant Name'], 'Bilgi Teknolojileri ve İletişim Kurumu', 'Registrant name doesn\'t match') + assert.equal(whois['whois.nic.tr']['Created Date'], '2011-Mar-22', 'Creation date doesn\'t match') + }) }); });