Skip to content

Commit fd80f45

Browse files
committed
Feat: improve whois detect [skip ci]
1 parent c3e792e commit fd80f45

File tree

2 files changed

+66
-112
lines changed

2 files changed

+66
-112
lines changed

Build/lib/is-domain-alive.test.ts

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,10 @@
11
import { describe, it } from 'mocha';
22

3-
import { isDomainAlive, noWhois } from './is-domain-alive';
3+
import { isDomainAlive } from './is-domain-alive';
44
import { expect } from 'expect';
55

66
import process from 'node:process';
77

8-
describe('whoisExists', () => {
9-
it('.cryptocrawler.io', () => {
10-
expect(noWhois({
11-
'whois.nic.io': {
12-
'Domain Status': [],
13-
'Name Server': [],
14-
'>>> Last update of WHOIS database': '2025-01-05T11:06:38Z <<<',
15-
text: [
16-
'Domain not found.',
17-
'',
18-
'Terms of Use: Access to WHOIS'
19-
]
20-
}
21-
})).toBe('Domain not found.');
22-
});
23-
24-
it('.tunevideo.ru', () => {
25-
expect(noWhois({
26-
'whois.tcinet.ru': {
27-
'Domain Status': [],
28-
'Name Server': [],
29-
text: [
30-
'% TCI Whois Service. Terms of use:',
31-
'% https://tcinet.ru/documents/whois_ru_rf.pdf (in Russian)',
32-
'% https://tcinet.ru/documents/whois_su.pdf (in Russian)',
33-
'',
34-
'No entries found for the selected source(s).',
35-
'',
36-
'Last updated on 2025-01-05T11:03:01Z'
37-
]
38-
}
39-
})).toBe('No entries found for the selected source(s).');
40-
});
41-
42-
it('nosuchpool.cl', () => {
43-
expect(noWhois({
44-
'whois.nic.cl': {
45-
'Domain Status': [],
46-
'Name Server': [],
47-
'nosuchpool.cl': 'no entries found.',
48-
text: [
49-
'%%',
50-
'%% This is the NIC Chile Whois server (whois.nic.cl).',
51-
'%%',
52-
'%% Rights restricted by copyright.',
53-
'%% See https://www.nic.cl/normativa/politica-publicacion-de-datos-cl.pdf',
54-
'%%'
55-
]
56-
}
57-
})).toBe('nosuchpool.cl: no entries found.');
58-
});
59-
60-
it('whois.domain-registry.nl', () => {
61-
expect(noWhois({
62-
'whois.domain-registry.nl': {
63-
'Domain Status': [],
64-
'Name Server': [],
65-
text: [
66-
'spookyplanet.nl is free'
67-
]
68-
}
69-
})).toBe('spookyplanet.nl is free');
70-
});
71-
});
72-
738
describe('isDomainAlive', function () {
749
this.timeout(10000);
7510

@@ -105,8 +40,8 @@ describe('isDomainAlive', function () {
10540
// expect((await isDomainAlive('.tayfundogdas.me', true))[1]).toEqual(true);
10641
// });
10742

108-
it('spookyplanet.nl', async () => {
43+
it('ecdasoin.it', async () => {
10944
process.env.DEBUG = 'true';
110-
expect((await isDomainAlive('.spookyplanet.nl', true))[1]).toEqual(false);
45+
expect((await isDomainAlive('.ecdasoin.it', true))[1]).toEqual(false);
11146
});
11247
});

Build/lib/is-domain-alive.ts

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ const resolve = createResolve(dohServers);
107107
const domesticResolve = createResolve(domesticDohServers);
108108

109109
async function getWhois(domain: string) {
110-
return asyncRetry(() => whoiser.domain(domain), { retries: 5 });
110+
return asyncRetry(() => whoiser.domain(domain, { raw: true }), { retries: 5 });
111111
}
112112

113113
const domainAliveMap = new Map<string, boolean>();
@@ -206,7 +206,7 @@ async function isApexDomainAlive(apexDomain: string): Promise<[string, boolean]>
206206
try {
207207
whois = await getWhois(apexDomain);
208208
} catch (e) {
209-
console.log(picocolors.red('[domain dead]'), 'whois error', { domain: apexDomain }, e);
209+
console.log(picocolors.red('[whois error]'), { domain: apexDomain }, e);
210210
return onDomainAlive(apexDomain);
211211
}
212212

@@ -241,7 +241,8 @@ const whoisNotFoundKeywordTest = createKeywordFilter([
241241
'status: available',
242242
' is free',
243243
'no object found',
244-
'nothing found'
244+
'nothing found',
245+
'status: free'
245246
]);
246247

247248
// whois server can redirect, so whoiser might/will get info from multiple whois servers
@@ -254,51 +255,69 @@ export function noWhois(whois: whoiser.WhoisSearchResult): null | string {
254255
if (Object.hasOwn(whois, key)) {
255256
empty = false;
256257

257-
if (key === 'error') {
258-
// if (
259-
// (typeof whois.error === 'string' && whois.error)
260-
// || (Array.isArray(whois.error) && whois.error.length > 0)
261-
// ) {
262-
// console.error(whois);
263-
// return true;
264-
// }
265-
continue;
266-
}
267-
268-
if (key === 'text') {
269-
if (Array.isArray(whois.text)) {
270-
for (const value of whois.text) {
271-
if (whoisNotFoundKeywordTest(value.toLowerCase())) {
272-
return value;
273-
}
274-
}
258+
// if (key === 'error') {
259+
// // if (
260+
// // (typeof whois.error === 'string' && whois.error)
261+
// // || (Array.isArray(whois.error) && whois.error.length > 0)
262+
// // ) {
263+
// // console.error(whois);
264+
// // return true;
265+
// // }
266+
// continue;
267+
// }
268+
269+
// if (key === 'text') {
270+
// if (Array.isArray(whois.text)) {
271+
// for (const value of whois.text) {
272+
// if (whoisNotFoundKeywordTest(value.toLowerCase())) {
273+
// return value;
274+
// }
275+
// }
276+
// }
277+
// continue;
278+
// }
279+
// if (key === 'Name Server') {
280+
// // if (Array.isArray(whois[key]) && whois[key].length === 0) {
281+
// // return false;
282+
// // }
283+
// continue;
284+
// }
285+
286+
// if (key === 'Domain Status') {
287+
// if (Array.isArray(whois[key])) {
288+
// for (const status of whois[key]) {
289+
// if (status === 'free' || status === 'AVAILABLE') {
290+
// return key + ': ' + status;
291+
// }
292+
// if (whoisNotFoundKeywordTest(status.toLowerCase())) {
293+
// return key + ': ' + status;
294+
// }
295+
// }
296+
// }
297+
298+
// continue;
299+
// }
300+
301+
// if (typeof whois[key] === 'string' && whois[key]) {
302+
// if (whoisNotFoundKeywordTest(whois[key].toLowerCase())) {
303+
// return key + ': ' + whois[key];
304+
// }
305+
306+
// continue;
307+
// }
308+
309+
if (key === '__raw' && typeof whois.__raw === 'string') {
310+
const lines = whois.__raw.trim().toLowerCase().replaceAll(/[\t ]+/g, ' ').split(/\r?\n/);
311+
312+
if (process.env.DEBUG) {
313+
console.log({ lines });
275314
}
276-
continue;
277-
}
278-
if (key === 'Name Server') {
279-
// if (Array.isArray(whois[key]) && whois[key].length === 0) {
280-
// return false;
281-
// }
282-
continue;
283-
}
284315

285-
if (key === 'Domain Status') {
286-
if (Array.isArray(whois[key])) {
287-
for (const status of whois[key]) {
288-
if (whoisNotFoundKeywordTest(status.toLowerCase())) {
289-
return key + ': ' + status;
290-
}
316+
for (const line of lines) {
317+
if (whoisNotFoundKeywordTest(line)) {
318+
return line;
291319
}
292320
}
293-
294-
continue;
295-
}
296-
297-
if (typeof whois[key] === 'string' && whois[key]) {
298-
if (whoisNotFoundKeywordTest(whois[key].toLowerCase())) {
299-
return key + ': ' + whois[key];
300-
}
301-
302321
continue;
303322
}
304323

0 commit comments

Comments
 (0)