🚩 增加自定义Whois后缀功能
This commit is contained in:
parent
e74f8b1e24
commit
999d8b7076
@ -8,6 +8,7 @@ Nuxt-Whois 是一个基于 Nuxt3、Tailwind CSS 和 Xep-Whois 构建的Whois查
|
|||||||
- **语言切换**:提供多语言支持,方便不同语言用户使用。
|
- **语言切换**:提供多语言支持,方便不同语言用户使用。
|
||||||
- **时区切换**:支持时区设置,确保时间信息的准确性。
|
- **时区切换**:支持时区设置,确保时间信息的准确性。
|
||||||
- **Dns查询**:支持Dns查询,方便用户查看域名的Dns信息。
|
- **Dns查询**:支持Dns查询,方便用户查看域名的Dns信息。
|
||||||
|
- **自定义后缀**:支持自定义Whois服务器后缀,方便用户查询不同后缀的域名。
|
||||||
|
|
||||||
### 环境要求
|
### 环境要求
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
"@nuxtjs/tailwindcss": "^6.11.4",
|
"@nuxtjs/tailwindcss": "^6.11.4",
|
||||||
"@pinia/nuxt": "^0.5.1",
|
"@pinia/nuxt": "^0.5.1",
|
||||||
"nuxt": "^3.10.3",
|
"nuxt": "^3.10.3",
|
||||||
|
"socks": "^2.8.1",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
"vue-router": "^4.3.0",
|
"vue-router": "^4.3.0"
|
||||||
"xep-whois": "^1.0.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxtjs/i18n": "^8.1.1",
|
"@nuxtjs/i18n": "^8.1.1",
|
||||||
|
69
pnpm-lock.yaml
generated
69
pnpm-lock.yaml
generated
@ -17,15 +17,15 @@ dependencies:
|
|||||||
nuxt:
|
nuxt:
|
||||||
specifier: ^3.10.3
|
specifier: ^3.10.3
|
||||||
version: 3.10.3(rollup@4.12.0)(typescript@5.3.3)(vite@5.1.4)
|
version: 3.10.3(rollup@4.12.0)(typescript@5.3.3)(vite@5.1.4)
|
||||||
|
socks:
|
||||||
|
specifier: ^2.8.1
|
||||||
|
version: 2.8.1
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.4.21
|
specifier: ^3.4.21
|
||||||
version: 3.4.21(typescript@5.3.3)
|
version: 3.4.21(typescript@5.3.3)
|
||||||
vue-router:
|
vue-router:
|
||||||
specifier: ^4.3.0
|
specifier: ^4.3.0
|
||||||
version: 4.3.0(vue@3.4.21)
|
version: 4.3.0(vue@3.4.21)
|
||||||
xep-whois:
|
|
||||||
specifier: ^1.0.2
|
|
||||||
version: 1.0.2(typescript@5.3.3)
|
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@nuxtjs/i18n':
|
'@nuxtjs/i18n':
|
||||||
@ -2146,12 +2146,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/node@18.19.21:
|
|
||||||
resolution: {integrity: sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==}
|
|
||||||
dependencies:
|
|
||||||
undici-types: 5.26.5
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@types/node@20.11.24:
|
/@types/node@20.11.24:
|
||||||
resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==}
|
resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -2990,10 +2984,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
|
resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
/ansi-sequence-parser@1.1.1:
|
|
||||||
resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/ansi-styles@3.2.1:
|
/ansi-styles@3.2.1:
|
||||||
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
|
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -4940,10 +4930,6 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
yallist: 4.0.0
|
yallist: 4.0.0
|
||||||
|
|
||||||
/lunr@2.3.9:
|
|
||||||
resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/magic-string-ast@0.3.0:
|
/magic-string-ast@0.3.0:
|
||||||
resolution: {integrity: sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA==}
|
resolution: {integrity: sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA==}
|
||||||
engines: {node: '>=16.14.0'}
|
engines: {node: '>=16.14.0'}
|
||||||
@ -4987,12 +4973,6 @@ packages:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
/marked@4.3.0:
|
|
||||||
resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==}
|
|
||||||
engines: {node: '>= 12'}
|
|
||||||
hasBin: true
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/mdn-data@2.0.28:
|
/mdn-data@2.0.28:
|
||||||
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
||||||
|
|
||||||
@ -6639,15 +6619,6 @@ packages:
|
|||||||
/shell-quote@1.8.1:
|
/shell-quote@1.8.1:
|
||||||
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
|
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
|
||||||
|
|
||||||
/shiki@0.14.7:
|
|
||||||
resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==}
|
|
||||||
dependencies:
|
|
||||||
ansi-sequence-parser: 1.1.1
|
|
||||||
jsonc-parser: 3.2.1
|
|
||||||
vscode-oniguruma: 1.7.0
|
|
||||||
vscode-textmate: 8.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/shiki@1.0.0-beta.3:
|
/shiki@1.0.0-beta.3:
|
||||||
resolution: {integrity: sha512-z7cHTNSSvwGx2DfeLwjSNLo+HcVxifgNIzLm6Ye52eXcIwNHXT0wHbhy7FDOKSKveuEHBwt9opfj3Hoc8LE1Yg==}
|
resolution: {integrity: sha512-z7cHTNSSvwGx2DfeLwjSNLo+HcVxifgNIzLm6Ye52eXcIwNHXT0wHbhy7FDOKSKveuEHBwt9opfj3Hoc8LE1Yg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -7124,20 +7095,6 @@ packages:
|
|||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/typedoc@0.24.8(typescript@5.3.3):
|
|
||||||
resolution: {integrity: sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==}
|
|
||||||
engines: {node: '>= 14.14'}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x
|
|
||||||
dependencies:
|
|
||||||
lunr: 2.3.9
|
|
||||||
marked: 4.3.0
|
|
||||||
minimatch: 9.0.3
|
|
||||||
shiki: 0.14.7
|
|
||||||
typescript: 5.3.3
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/typescript@5.3.3:
|
/typescript@5.3.3:
|
||||||
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
|
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
|
||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
@ -7621,14 +7578,6 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
vscode-languageserver-protocol: 3.16.0
|
vscode-languageserver-protocol: 3.16.0
|
||||||
|
|
||||||
/vscode-oniguruma@1.7.0:
|
|
||||||
resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/vscode-textmate@8.0.0:
|
|
||||||
resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/vscode-uri@3.0.8:
|
/vscode-uri@3.0.8:
|
||||||
resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
|
resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
|
||||||
|
|
||||||
@ -7818,18 +7767,6 @@ packages:
|
|||||||
utf-8-validate:
|
utf-8-validate:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/xep-whois@1.0.2(typescript@5.3.3):
|
|
||||||
resolution: {integrity: sha512-P3hA4+yaSgJdgYya5XtcgI7bPs+QozHpmJE7kCpp73AhI5kC7WHnbVY1+AYKwFjWiuZsBLF2RzofJFIcelgmMg==}
|
|
||||||
dependencies:
|
|
||||||
'@types/node': 18.19.21
|
|
||||||
node-fetch: 2.7.0
|
|
||||||
socks: 2.8.1
|
|
||||||
typedoc: 0.24.8(typescript@5.3.3)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- encoding
|
|
||||||
- typescript
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/y18n@5.0.8:
|
/y18n@5.0.8:
|
||||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {whois, WhoIsOptions} from 'xep-whois';
|
import {whois} from "~/server/whois/whois";
|
||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
const body = await readBody(event)
|
const body = await readBody(event)
|
||||||
|
4
server/whois/json/parameters.json
Normal file
4
server/whois/json/parameters.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"whois.denic.de" : "-T dn,ace",
|
||||||
|
"whois.nic.fr": "-V Md5.2"
|
||||||
|
}
|
319
server/whois/json/whois-servers.json
Normal file
319
server/whois/json/whois-servers.json
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
{
|
||||||
|
"br.com":"whois.centralnic.net",
|
||||||
|
"cn.com":"whois.centralnic.net",
|
||||||
|
"de.com":"whois.centralnic.net",
|
||||||
|
"eu.com":"whois.centralnic.net",
|
||||||
|
"gb.com":"whois.centralnic.net",
|
||||||
|
"gb.net":"whois.centralnic.net",
|
||||||
|
"gr.com":"whois.centralnic.net",
|
||||||
|
"hu.com":"whois.centralnic.net",
|
||||||
|
"in.net":"whois.centralnic.net",
|
||||||
|
"no.com":"whois.centralnic.net",
|
||||||
|
"qc.com":"whois.centralnic.net",
|
||||||
|
"ru.com":"whois.centralnic.net",
|
||||||
|
"sa.com":"whois.centralnic.net",
|
||||||
|
"se.com":"whois.centralnic.net",
|
||||||
|
"se.net":"whois.centralnic.net",
|
||||||
|
"uk.com":"whois.centralnic.net",
|
||||||
|
"uk.net":"whois.centralnic.net",
|
||||||
|
"us.com":"whois.centralnic.net",
|
||||||
|
"uy.com":"whois.centralnic.net",
|
||||||
|
"za.com":"whois.centralnic.net",
|
||||||
|
"jpn.com":"whois.centralnic.ne",
|
||||||
|
"web.com":"whois.centralnic.ne",
|
||||||
|
"com":"whois.verisign-grs.com",
|
||||||
|
"za.net":"whois.za.net",
|
||||||
|
"net":"whois.verisign-grs.com",
|
||||||
|
"eu.org":"whois.eu.org",
|
||||||
|
"za.org":"whois.za.org",
|
||||||
|
"org":"whois.pir.org",
|
||||||
|
"llyw.cymru":"whois.nic.llyw.cymru",
|
||||||
|
"gov.scot":"whois.nic.gov.scot",
|
||||||
|
"gov.wales":"whois.nic.gov.wales",
|
||||||
|
"edu":"whois.educause.edu",
|
||||||
|
"gov":"whois.dotgov.gov",
|
||||||
|
"int":"whois.iana.org",
|
||||||
|
"e164.arpa":"whois.ripe.net",
|
||||||
|
"arpa":"whois.iana.org",
|
||||||
|
"aero":"whois.aero",
|
||||||
|
"asia":"whois.nic.asia",
|
||||||
|
"biz":"whois.nic.biz",
|
||||||
|
"cat":"whois.nic.cat",
|
||||||
|
"coop":"whois.nic.coop",
|
||||||
|
"info":"whois.afilias.net",
|
||||||
|
"jobs":"whois.nic.jobs",
|
||||||
|
"mobi":"whois.afilias.net",
|
||||||
|
"museum":"whois.nic.museum",
|
||||||
|
"name":"whois.nic.name",
|
||||||
|
"post":"whois.dotpostregistry.net",
|
||||||
|
"pro":"whois.nic.pro",
|
||||||
|
"tel":"whois.nic.tel",
|
||||||
|
"travel":"whois.nic.travel",
|
||||||
|
"xxx":"whois.nic.xxx",
|
||||||
|
"ac":"whois.nic.ac",
|
||||||
|
"ae":"whois.aeda.net.ae",
|
||||||
|
"af":"whois.nic.af",
|
||||||
|
"ag":"whois.nic.ag",
|
||||||
|
"ai":"whois.nic.ai",
|
||||||
|
"am":"whois.amnic.net",
|
||||||
|
"ar":"whois.nic.ar",
|
||||||
|
"as":"whois.nic.as",
|
||||||
|
"priv.at":"whois.nic.priv.at",
|
||||||
|
"at":"whois.nic.at",
|
||||||
|
"au":"whois.auda.org.au",
|
||||||
|
"aw":"whois.nic.aw",
|
||||||
|
"ax":"whois.ax",
|
||||||
|
"be":"whois.dns.be",
|
||||||
|
"bf":"whois.registre.bf",
|
||||||
|
"bg":"whois.register.bg",
|
||||||
|
"bh":"whois.nic.bh",
|
||||||
|
"bi":"whois1.nic.bi",
|
||||||
|
"bj":"whois.nic.bj",
|
||||||
|
"bm":"whois.afilias-srs.net",
|
||||||
|
"bn":"whois.bnnic.bn",
|
||||||
|
"bo":"whois.nic.bo",
|
||||||
|
"br":"whois.registro.br",
|
||||||
|
"by":"whois.cctld.by",
|
||||||
|
"bw":"whois.nic.net.bw",
|
||||||
|
"bz":"whois.afilias-grs.info",
|
||||||
|
"co.ca":"whois.co.ca",
|
||||||
|
"ca":"whois.cira.ca",
|
||||||
|
"cc":"ccwhois.verisign-grs.com",
|
||||||
|
"cd":"whois.nic.cd",
|
||||||
|
"ch":"whois.nic.ch",
|
||||||
|
"ci":"whois.nic.ci",
|
||||||
|
"cl":"whois.nic.cl",
|
||||||
|
"cm":"whois.netcom.cm",
|
||||||
|
"edu.cn":"whois.edu.cn",
|
||||||
|
"cn":"whois.cnnic.cn",
|
||||||
|
"uk.co":"whois.uk.co",
|
||||||
|
"co":"whois.nic.co",
|
||||||
|
"cr":"whois.nic.cr",
|
||||||
|
"cx":"whois.nic.cx",
|
||||||
|
"cz":"whois.nic.cz",
|
||||||
|
"de":"whois.denic.de",
|
||||||
|
"dk":"whois.dk-hostmaster.dk",
|
||||||
|
"dm":"whois.dmdomains.dm",
|
||||||
|
"do":"whois.nic.do",
|
||||||
|
"dz":"whois.nic.dz",
|
||||||
|
"ec":"whois.nic.ec",
|
||||||
|
"ee":"whois.tld.ee",
|
||||||
|
"eu":"whois.eu",
|
||||||
|
"fi":"whois.fi",
|
||||||
|
"fj":"www.whois.fj",
|
||||||
|
"fm":"whois.nic.fm",
|
||||||
|
"fo":"whois.nic.fo",
|
||||||
|
"fr":"whois.nic.fr",
|
||||||
|
"gd":"whois.nic.gd",
|
||||||
|
"ge":"whois.nic.ge",
|
||||||
|
"gf":"whois.mediaserv.net",
|
||||||
|
"gg":"whois.gg",
|
||||||
|
"gh":"whois.nic.gh",
|
||||||
|
"gi":"whois2.afilias-grs.net",
|
||||||
|
"gl":"whois.nic.gl",
|
||||||
|
"gp":"whois.nic.gp",
|
||||||
|
"gq":"whois.dominio.gq",
|
||||||
|
"gs":"whois.nic.gs",
|
||||||
|
"gy":"whois.registry.gy",
|
||||||
|
"hk":"whois.hkirc.hk",
|
||||||
|
"hm":"whois.registry.hm",
|
||||||
|
"hn":"whois.nic.hn",
|
||||||
|
"hr":"whois.dns.hr",
|
||||||
|
"ht":"whois.nic.ht",
|
||||||
|
"hu":"whois.nic.hu",
|
||||||
|
"id":"whois.id",
|
||||||
|
"ie":"whois.weare.ie",
|
||||||
|
"il":"whois.isoc.org.il",
|
||||||
|
"im":"whois.nic.im",
|
||||||
|
"in":"whois.registry.in",
|
||||||
|
"io":"whois.nic.io",
|
||||||
|
"iq":"whois.cmc.iq",
|
||||||
|
"ir":"whois.nic.ir",
|
||||||
|
"is":"whois.isnic.is",
|
||||||
|
"it":"whois.nic.it",
|
||||||
|
"je":"whois.je",
|
||||||
|
"jp":"whois.jprs.jp",
|
||||||
|
"ke":"whois.kenic.or.ke",
|
||||||
|
"kg":"whois.kg",
|
||||||
|
"ki":"whois.nic.ki",
|
||||||
|
"kn":"whois.nic.kn",
|
||||||
|
"kr":"whois.kr",
|
||||||
|
"kw":"whois.nic.kw",
|
||||||
|
"ky":"whois.kyregistry.ky",
|
||||||
|
"kz":"whois.nic.kz",
|
||||||
|
"la":"whois.nic.la",
|
||||||
|
"lb":"whois.lbdr.org.lb",
|
||||||
|
"lc":"whois2.afilias-grs.net",
|
||||||
|
"li":"whois.nic.li",
|
||||||
|
"lk":"whois.nic.lk",
|
||||||
|
"ls":"whois.nic.ls",
|
||||||
|
"lt":"whois.domreg.lt",
|
||||||
|
"lu":"whois.dns.lu",
|
||||||
|
"lv":"whois.nic.lv",
|
||||||
|
"ly":"whois.nic.ly",
|
||||||
|
"ma":"whois.registre.ma",
|
||||||
|
"md":"whois.nic.md",
|
||||||
|
"me":"whois.nic.me",
|
||||||
|
"mg":"whois.nic.mg",
|
||||||
|
"mk":"whois.marnet.mk",
|
||||||
|
"ml":"whois.dot.ml",
|
||||||
|
"mm":"whois.registry.gov.mm",
|
||||||
|
"mn":"whois.nic.mn",
|
||||||
|
"mq":"whois.mediaserv.net",
|
||||||
|
"mr":"whois.nic.mr",
|
||||||
|
"ms":"whois.nic.ms",
|
||||||
|
"mt":"whois.nic.org.mt",
|
||||||
|
"mu":"whois.nic.mu",
|
||||||
|
"mw":"whois.nic.mw",
|
||||||
|
"mx":"whois.mx",
|
||||||
|
"my":"whois.mynic.my",
|
||||||
|
"mz":"whois.nic.mz",
|
||||||
|
"na":"whois.na-nic.com.na",
|
||||||
|
"nc":"whois.nc",
|
||||||
|
"nf":"whois.nic.nf",
|
||||||
|
"ng":"whois.nic.net.ng",
|
||||||
|
"nl":"whois.domain-registry.nl",
|
||||||
|
"no":"whois.norid.no",
|
||||||
|
"nu":"whois.iis.nu",
|
||||||
|
"nz":"whois.irs.net.nz",
|
||||||
|
"om":"whois.registry.om",
|
||||||
|
"pe":"kero.yachay.pe",
|
||||||
|
"pf":"whois.registry.pf",
|
||||||
|
"pk":"whois.pknic.net.pk",
|
||||||
|
"co.pl":"whois.co.pl",
|
||||||
|
"pl":"whois.dns.pl",
|
||||||
|
"pm":"whois.nic.pm",
|
||||||
|
"pr":"whois.afilias-srs.net",
|
||||||
|
"ps":"whois.pnina.ps",
|
||||||
|
"pt":"whois.dns.pt",
|
||||||
|
"pw":"whois.nic.pw",
|
||||||
|
"qa":"whois.registry.qa",
|
||||||
|
"re":"whois.nic.re",
|
||||||
|
"ro":"whois.rotld.ro",
|
||||||
|
"rs":"whois.rnids.rs",
|
||||||
|
"ac.ru":"whois.free.net",
|
||||||
|
"edu.ru":"whois.informika.ru",
|
||||||
|
"com.ru":"whois.flexireg.net",
|
||||||
|
"msk.ru":"whois.flexireg.net",
|
||||||
|
"net.ru":"whois.nic.net.ru",
|
||||||
|
"nov.ru":"whois.flexireg.net",
|
||||||
|
"org.ru":"whois.nic.net.ru",
|
||||||
|
"pp.ru":"whois.nic.net.ru",
|
||||||
|
"spb.ru":"whois.flexireg.net",
|
||||||
|
"ru":"whois.tcinet.ru",
|
||||||
|
"rw":"whois.ricta.org.rw",
|
||||||
|
"sa":"whois.nic.net.sa",
|
||||||
|
"sb":"whois.nic.net.sb",
|
||||||
|
"sc":"whois2.afilias-grs.net",
|
||||||
|
"sd":"whois.sdnic.sd",
|
||||||
|
"se":"whois.iis.se",
|
||||||
|
"sg":"whois.sgnic.sg",
|
||||||
|
"sh":"whois.nic.sh",
|
||||||
|
"si":"whois.register.si",
|
||||||
|
"sk":"whois.sk-nic.sk",
|
||||||
|
"sl":"whois.nic.sl",
|
||||||
|
"sm":"whois.nic.sm",
|
||||||
|
"sn":"whois.nic.sn",
|
||||||
|
"so":"whois.nic.so",
|
||||||
|
"ss":"whois.nic.ss",
|
||||||
|
"st":"whois.nic.st",
|
||||||
|
"msk.su":"whois.flexireg.net",
|
||||||
|
"nov.su":"whois.flexireg.net",
|
||||||
|
"spb.su":"whois.flexireg.net",
|
||||||
|
"su":"whois.tcinet.ru",
|
||||||
|
"sx":"whois.sx",
|
||||||
|
"sy":"whois.tld.sy",
|
||||||
|
"tc":"whois.nic.tc",
|
||||||
|
"td":"whois.nic.td",
|
||||||
|
"tf":"whois.nic.tf",
|
||||||
|
"tg":"whois.nic.tg",
|
||||||
|
"th":"whois.thnic.co.th",
|
||||||
|
"tk":"whois.dot.tk",
|
||||||
|
"tl":"whois.nic.tl",
|
||||||
|
"tm":"whois.nic.tm",
|
||||||
|
"tn":"whois.ati.tn",
|
||||||
|
"to":"whois.tonic.to",
|
||||||
|
"tr":"whois.trabis.gov.tr",
|
||||||
|
"tv":"whois.nic.tv",
|
||||||
|
"tw":"whois.twnic.net.tw",
|
||||||
|
"tz":"whois.tznic.or.tz",
|
||||||
|
"biz.ua":"whois.biz.ua",
|
||||||
|
"co.ua":"whois.co.ua",
|
||||||
|
"pp.ua":"whois.pp.ua",
|
||||||
|
"ua":"whois.ua",
|
||||||
|
"ug":"whois.co.ug",
|
||||||
|
"ac.uk":"whois.nic.ac.uk",
|
||||||
|
"gov.uk":"whois.gov.uk",
|
||||||
|
"uk":"whois.nic.uk",
|
||||||
|
"fed.us":"whois.nic.gov",
|
||||||
|
"us":"whois.nic.us",
|
||||||
|
"uy":"whois.nic.org.uy",
|
||||||
|
"uz":"whois.cctld.uz",
|
||||||
|
"vc":"whois2.afilias-grs.net",
|
||||||
|
"ve":"whois.nic.ve",
|
||||||
|
"vg":"whois.nic.vg",
|
||||||
|
"vu":"whois.dnrs.vu",
|
||||||
|
"wf":"whois.nic.wf",
|
||||||
|
"ws":"whois.website.ws",
|
||||||
|
"yt":"whois.nic.yt",
|
||||||
|
"ac.za":"whois.ac.za",
|
||||||
|
"co.za":"whois.registry.net.za",
|
||||||
|
"gov.za":"whois.gov.za",
|
||||||
|
"net.za":"net-whois.registry.net.za",
|
||||||
|
"org.za":"org-whois.registry.net.za",
|
||||||
|
"web.za":"web-whois.registry.net.za",
|
||||||
|
"zm":"whois.zicta.zm",
|
||||||
|
"xn--2scrj9c":"whois.registry.in",
|
||||||
|
"xn--3e0b707e":"whois.kr",
|
||||||
|
"xn--3hcrj9c":"whois.registry.in",
|
||||||
|
"xn--45br5cyl":"whois.registry.in",
|
||||||
|
"xn--45brj9c":"whois.registry.in",
|
||||||
|
"xn--4dbrk0ce":"whois.isoc.org.il",
|
||||||
|
"xn--80ao21a":"whois.nic.kz",
|
||||||
|
"xn--90a3ac":"whois.rnids.rs",
|
||||||
|
"xn--90ae":"whois.imena.bg",
|
||||||
|
"xn--90ais":"whois.cctld.by",
|
||||||
|
"xn--clchc0ea0b2g2a9gcd":"whois.sgnic.sg",
|
||||||
|
"xn--d1alf":"whois.marnet.mk",
|
||||||
|
"xn--e1a4c":"whois.eu",
|
||||||
|
"xn--fiqs8s":"cwhois.cnnic.cn",
|
||||||
|
"xn--fiqz9s":"cwhois.cnnic.cn",
|
||||||
|
"xn--fpcrj9c3d":"whois.registry.in",
|
||||||
|
"xn--fzc2c9e2c":"whois.nic.lk",
|
||||||
|
"xn--gecrj9c":"whois.registry.in",
|
||||||
|
"xn--h2breg3eve":"whois.registry.in",
|
||||||
|
"xn--h2brj9c8c":"whois.registry.in",
|
||||||
|
"xn--h2brj9c":"whois.registry.in",
|
||||||
|
"xn--j1amh":"whois.dotukr.com",
|
||||||
|
"xn--j6w193g":"whois.hkirc.hk",
|
||||||
|
"xn--kprw13d":"whois.twnic.net.tw",
|
||||||
|
"xn--kpry57d":"whois.twnic.net.tw",
|
||||||
|
"xn--lgbbat1ad8j":"whois.nic.dz",
|
||||||
|
"xn--mgb9awbf":"whois.registry.om",
|
||||||
|
"xn--mgba3a4f16a":"whois.nic.ir",
|
||||||
|
"xn--mgbaam7a8h":"whois.aeda.net.ae",
|
||||||
|
"xn--mgbah1a3hjkrd":"whois.nic.mr",
|
||||||
|
"xn--mgbbh1a71e":"whois.registry.in",
|
||||||
|
"xn--mgbbh1a":"whois.registry.in",
|
||||||
|
"xn--mgberp4a5d4ar":"whois.nic.net.sa",
|
||||||
|
"xn--mgbgu82a":"whois.registry.in",
|
||||||
|
"xn--mgbtx2b":"whois.cmc.iq",
|
||||||
|
"xn--mgbx4cd0ab":"whois.mynic.my",
|
||||||
|
"xn--node":"whois.itdc.ge",
|
||||||
|
"xn--o3cw4h":"whois.thnic.co.th",
|
||||||
|
"xn--ogbpf8fl":"whois.tld.sy",
|
||||||
|
"xn--p1ai":"whois.tcinet.ru",
|
||||||
|
"xn--pgbs0dh":"whois.ati.tn",
|
||||||
|
"xn--q7ce6a":"whois.nic.la",
|
||||||
|
"xn--qxa6a":"whois.eu",
|
||||||
|
"xn--rvc1e0am3e":"whois.registry.in",
|
||||||
|
"xn--s9brj9c":"whois.registry.in",
|
||||||
|
"xn--wgbh1c":"whois.dotmasr.eg",
|
||||||
|
"xn--wgbl6a":"whois.registry.qa",
|
||||||
|
"xn--xkc2al3hye2a":"whois.nic.lk",
|
||||||
|
"xn--xkc2dl3a5ee0h":"whois.registry.in",
|
||||||
|
"xn--y9a3aq":"whois.amnic.net",
|
||||||
|
"xn--yfro4i67o":"whois.sgnic.sg",
|
||||||
|
"xn--ygbi2ammx":"whois.pnina.ps",
|
||||||
|
"xyz":"whois.nic.xyz"
|
||||||
|
}
|
496
server/whois/whois.ts
Normal file
496
server/whois/whois.ts
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
import { SocksClient,SocksClientOptions } from 'socks';
|
||||||
|
import Net from 'net';
|
||||||
|
|
||||||
|
import serversData from '~/server/whois/json/whois-servers.json';
|
||||||
|
import parametersData from '~/server/whois/json/parameters.json';
|
||||||
|
|
||||||
|
const IANA_CHK_URL = 'https://www.iana.org/whois?q=';
|
||||||
|
|
||||||
|
|
||||||
|
interface IServers {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SERVERS: IServers = serversData as IServers;
|
||||||
|
const PARAMETERS: IServers = parametersData as IServers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the WhoIs server for the TLD from IANA WhoIs service. The TLD is be searched and the HTML response is parsed to extract the WhoIs server
|
||||||
|
*
|
||||||
|
* @param tld TLD of the domain
|
||||||
|
* @returns WhoIs server which hosts the information for the domains of the TLD
|
||||||
|
*/
|
||||||
|
async function findWhoIsServer(tld: string): Promise<string> {
|
||||||
|
const chkURL = IANA_CHK_URL + tld
|
||||||
|
|
||||||
|
try{
|
||||||
|
const res = await fetch(chkURL);
|
||||||
|
if (res.ok) {
|
||||||
|
const body = await res.text();
|
||||||
|
const server = body.match(/whois:\s+(.*)\s+/);
|
||||||
|
if (server) {
|
||||||
|
return server[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error in getting WhoIs server data from IANA', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Copy an Object with its values
|
||||||
|
*
|
||||||
|
* @param obj Object which needs to be copied
|
||||||
|
* @returns A copy of the object
|
||||||
|
*/
|
||||||
|
function shallowCopy<T extends any>(obj: T): T {
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
return obj.slice() as T; // Clone the array
|
||||||
|
} else if (typeof obj === 'object' && obj !== null) {
|
||||||
|
const copy: any = {};
|
||||||
|
for (const key in obj) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||||
|
copy[key] = shallowCopy(obj[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return copy as T;
|
||||||
|
} else {
|
||||||
|
return obj; // For primitive values, return as is
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whois server of the tld from servers list
|
||||||
|
*
|
||||||
|
* @param tld TLD of the domain
|
||||||
|
* @returns WhoIs server which hosts the information for the domains of the TLD
|
||||||
|
*/
|
||||||
|
function getWhoIsServer(tld: string): string|undefined {
|
||||||
|
return SERVERS[tld];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract TLD from domain name.
|
||||||
|
* If the TLD is in whois-servers.json file, then the TLD is returned.
|
||||||
|
* If TLD is not found within the file, then determined by taking the last element after splitting the domain name from '.'
|
||||||
|
*
|
||||||
|
* @param domain Domain name
|
||||||
|
* @returns TLD
|
||||||
|
*/
|
||||||
|
function getTLD(domain: string): string {
|
||||||
|
let tld = '';
|
||||||
|
let domainStr = domain;
|
||||||
|
while (true) {
|
||||||
|
const domainData = domainStr.split('.');
|
||||||
|
if (domainData.length < 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const tldCheck = domainData.slice(1).join('.')
|
||||||
|
const server = SERVERS[tldCheck];
|
||||||
|
if (server) {
|
||||||
|
tld = tldCheck;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
domainStr = tldCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tld != '') {
|
||||||
|
return tld;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug('TLD is not found in server list. Returning last element after split as TLD!');
|
||||||
|
|
||||||
|
const domainData = domain.split('.');
|
||||||
|
return domainData[domainData.length-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// get whois query parameters if exist on parameters.json for whois server
|
||||||
|
function getParameters(server: string): string|undefined {
|
||||||
|
return PARAMETERS[server];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of the proxy. Either SOCKS4 or SOCKS5
|
||||||
|
* @enum
|
||||||
|
*/
|
||||||
|
export enum ProxyType {
|
||||||
|
/**
|
||||||
|
* SOCKS4 type of proxy
|
||||||
|
*/
|
||||||
|
SOCKS4 = 0,
|
||||||
|
/**
|
||||||
|
* SOCKS5 type of proxy
|
||||||
|
*/
|
||||||
|
SOCKS5 = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy related data
|
||||||
|
* @interface
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export interface ProxyData {
|
||||||
|
/**
|
||||||
|
* Proxy IP
|
||||||
|
*/
|
||||||
|
ip: string,
|
||||||
|
/**
|
||||||
|
* Proxy port
|
||||||
|
*/
|
||||||
|
port: number,
|
||||||
|
/**
|
||||||
|
* Username to connect to the proxy
|
||||||
|
*/
|
||||||
|
username?: string | null,
|
||||||
|
/**
|
||||||
|
* Password to connect to the proxy
|
||||||
|
*/
|
||||||
|
password?: string | null,
|
||||||
|
/**
|
||||||
|
* {@link ProxyType}
|
||||||
|
*/
|
||||||
|
type: ProxyType
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WhoIs options
|
||||||
|
* @interface
|
||||||
|
*/
|
||||||
|
export interface WhoIsOptions {
|
||||||
|
/**
|
||||||
|
* TLD of the domain. If the {@link tld} is not provided (or null), then it will be automatically determined as to the given domain name
|
||||||
|
*/
|
||||||
|
tld?: string | null,
|
||||||
|
/**
|
||||||
|
* The encoding type used for WhoIs server and response. By default UTF-8 is used.
|
||||||
|
*/
|
||||||
|
encoding?: string | null,
|
||||||
|
|
||||||
|
/**{@link ProxyData} */
|
||||||
|
proxy?: ProxyData | null,
|
||||||
|
/**
|
||||||
|
* The WhoIs server to collect data from. If not provided, the server will automatically determined using the {@link tld}
|
||||||
|
*/
|
||||||
|
server?: string | null,
|
||||||
|
/**
|
||||||
|
* The port of the WhoIs server. By default, port 43 is used.
|
||||||
|
*/
|
||||||
|
serverPort?: number | null,
|
||||||
|
/**
|
||||||
|
* Which data needs to be extracted/parsed from the WhoIs response.
|
||||||
|
* An object can be passed which contains keys of the fields of the WhoIs response.
|
||||||
|
* A copy of the provided object will be returned with the values filled for the provided keys.
|
||||||
|
*
|
||||||
|
* The keys can have default value of empty string. However, if the WhoIs response has multiple values for the same field (eg: 'Domain Status'),
|
||||||
|
* then all the values can be collected by providing a default value of an Array([]).
|
||||||
|
*
|
||||||
|
* Following example shows an object used to collect 'Domain Name', 'Domain Status' (multiple values) and 'Registrar' from WhoIs response
|
||||||
|
*
|
||||||
|
* @example {'Domain Name': '', 'Domain Status': [], 'Registrar': ''}
|
||||||
|
*/
|
||||||
|
parseData?: Object | null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response returned from whois function. Contains the raw text from WhoIs server and parsed/fornatted WhoIs data (if parsed is true)
|
||||||
|
*
|
||||||
|
* @interface
|
||||||
|
*/
|
||||||
|
export interface WhoIsResponse {
|
||||||
|
/**
|
||||||
|
* Raw text response from WhoIs server
|
||||||
|
*/
|
||||||
|
_raw: string,
|
||||||
|
/**
|
||||||
|
* Parsed/Formatted key-value pairs of the response (if parsed is true)
|
||||||
|
*/
|
||||||
|
parsedData: any | null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse collected raw WhoIs data
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
export class WhoIsParser {
|
||||||
|
/**
|
||||||
|
* Iterated through the complete text and returns extracted values
|
||||||
|
*
|
||||||
|
* @param rawData raw text from WhoIs server
|
||||||
|
* @param outputData Data which needs to be extracted from the raw text (key/value pairs). Keys are used to extract from raw text and values are filled.
|
||||||
|
* @returns Filled {@link outputData}
|
||||||
|
*/
|
||||||
|
private static iterParse(rawData: string, outputData: any) {
|
||||||
|
let lastStr = '';
|
||||||
|
let lastField: string | null = null;
|
||||||
|
let lastLetter = '';
|
||||||
|
|
||||||
|
for (let i = 0; i < rawData.length; i++) {
|
||||||
|
let letter = rawData[i];
|
||||||
|
if (letter == '\n' || (lastLetter == ':' && letter == ' ')) {
|
||||||
|
if (lastStr.trim() in outputData) {
|
||||||
|
lastField = lastStr.trim();
|
||||||
|
} else if (lastField !== null) {
|
||||||
|
let x = lastStr.trim();
|
||||||
|
if (x != '') {
|
||||||
|
let obj = outputData[lastField];
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
obj.push(x);
|
||||||
|
} else {
|
||||||
|
outputData[lastField] = x;
|
||||||
|
}
|
||||||
|
lastField = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastStr = '';
|
||||||
|
} else if (letter != ':') {
|
||||||
|
lastStr = lastStr + letter;
|
||||||
|
}
|
||||||
|
lastLetter = letter;
|
||||||
|
if (lastStr == 'Record maintained by' || lastStr == '>>>') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the raw WhoIs text and returns extracted values
|
||||||
|
*
|
||||||
|
* @param rawData raw text from WhoIs server
|
||||||
|
* @param outputData Data which needs to be extracted from the raw text (key/value pairs). Keys are used to extract from raw text and values are filled.
|
||||||
|
* @returns Filled {@link outputData}
|
||||||
|
*/
|
||||||
|
public static parseData(rawData: string, outputData: any | null): any {
|
||||||
|
if (!outputData) {
|
||||||
|
outputData = {
|
||||||
|
'Domain Name': '',
|
||||||
|
'Creation Date': '',
|
||||||
|
'Updated Date': '',
|
||||||
|
'Registry Expiry Date': '',
|
||||||
|
'Domain Status': [],
|
||||||
|
"Registrar": '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputData = WhoIsParser.iterParse(rawData, outputData);
|
||||||
|
|
||||||
|
return outputData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to the provided {@link server}:{@link port} through TCP (through a proxy if a proxy is given), run the WhoIs query and returns the response
|
||||||
|
*
|
||||||
|
* @param domain Domain name
|
||||||
|
* @param queryOptions Query options which can be used with the specific WhoIs server to get the complete response
|
||||||
|
* @param server WhoIs server
|
||||||
|
* @param port WhoIs server port
|
||||||
|
* @param encoding Encoding used by the WhoIs server
|
||||||
|
* @param proxy {@link ProxyData}
|
||||||
|
* @returns The {string} WhoIs response for the query. Empty string is returned for errors
|
||||||
|
*/
|
||||||
|
export async function tcpWhois(domain: string, queryOptions: string, server: string, port: number, encoding: string, proxy: ProxyData | null): Promise<string> {
|
||||||
|
const decoder = new TextDecoder(encoding);
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
|
||||||
|
if (!proxy) {
|
||||||
|
const socket = new Net.Socket();
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
socket.connect({port: port, host: server}, function() {
|
||||||
|
if (queryOptions != '') {
|
||||||
|
socket.write(encoder.encode(`${queryOptions} ${domain}\r\n`));
|
||||||
|
} else {
|
||||||
|
socket.write(encoder.encode(`${domain}\r\n`));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('data', (data) => {
|
||||||
|
resolve(decoder.decode(data));
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('error', (error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
} catch (e){
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const options: SocksClientOptions = {
|
||||||
|
proxy: {
|
||||||
|
host: proxy.ip,
|
||||||
|
port: proxy.port,
|
||||||
|
type: proxy.type == ProxyType.SOCKS5 ? 5 : 4
|
||||||
|
},
|
||||||
|
|
||||||
|
command: 'connect',
|
||||||
|
|
||||||
|
destination: {
|
||||||
|
host: server,
|
||||||
|
port: port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxy.username && proxy.password) {
|
||||||
|
options.proxy.userId = proxy.username;
|
||||||
|
options.proxy.password = proxy.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
SocksClient.createConnection(options, function(err, info) {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
if (!info) {
|
||||||
|
reject(new Error('No socket info received!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryOptions != '') {
|
||||||
|
info?.socket.write(
|
||||||
|
encoder.encode(`${queryOptions} ${domain}\r\n`)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
info?.socket.write(
|
||||||
|
encoder.encode(`${domain}\r\n`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
info?.socket.on('data', (data) => {
|
||||||
|
resolve(decoder.decode(data));
|
||||||
|
});
|
||||||
|
|
||||||
|
info?.socket.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect WhoIs data for the mentioned {@link domain}. Parse the reveived response if {@link parse} is true, accordingly.
|
||||||
|
*
|
||||||
|
* @param domain Domain name
|
||||||
|
* @param parse Whether the raw text needs to be parsed/formatted or not
|
||||||
|
* @param options {@link WhoIsOptions}
|
||||||
|
* @returns {@link WhoIsResponse}
|
||||||
|
*/
|
||||||
|
export async function whois(domain: string, parse: boolean = false, options: WhoIsOptions | null = null): Promise<WhoIsResponse> {
|
||||||
|
let tld: string;
|
||||||
|
let port = 43;
|
||||||
|
let server = '';
|
||||||
|
let queryOptions: string;
|
||||||
|
let proxy: ProxyData | null;
|
||||||
|
let encoding = 'utf-8';
|
||||||
|
|
||||||
|
if (!options) {
|
||||||
|
tld = getTLD(domain);
|
||||||
|
proxy = null;
|
||||||
|
} else {
|
||||||
|
tld = options.tld ? options.tld : getTLD(domain);
|
||||||
|
encoding = options.encoding ? options.encoding : 'utf-8';
|
||||||
|
proxy = options.proxy ? options.proxy : null;
|
||||||
|
server = options.server ? options.server : '';
|
||||||
|
port = options.serverPort ? options.serverPort : 43;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server == '') {
|
||||||
|
let serverData = getWhoIsServer(tld);
|
||||||
|
if (!serverData) {
|
||||||
|
console.debug(`No WhoIs server found for TLD: ${tld}! Attempting IANA WhoIs database for server!`);
|
||||||
|
serverData = await findWhoIsServer(tld);
|
||||||
|
if (!serverData) {
|
||||||
|
console.debug('WhoIs server could not be found!');
|
||||||
|
return {
|
||||||
|
_raw: '',
|
||||||
|
parsedData: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.debug(`WhoIs sever found for ${tld}: ${server}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
server = serverData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const qOptions = getParameters(server);
|
||||||
|
queryOptions = qOptions ? qOptions : '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
let rawData = await tcpWhois(domain, queryOptions, server, port, encoding, proxy);
|
||||||
|
if (!parse) {
|
||||||
|
return {
|
||||||
|
_raw: rawData,
|
||||||
|
parsedData: null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let outputData: any | null = null;
|
||||||
|
if (options && options.parseData) {
|
||||||
|
outputData = shallowCopy(options.parseData);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const parsedData = WhoIsParser.parseData(rawData, outputData);
|
||||||
|
return {
|
||||||
|
_raw: rawData,
|
||||||
|
parsedData: parsedData
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
return {
|
||||||
|
_raw: rawData,
|
||||||
|
parsedData: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return {
|
||||||
|
_raw: '',
|
||||||
|
parsedData: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects (and parse/format if set to be true) for the provided {@link domains}. If {@link parallel} is set to be true, multiple threads will be used to batch process the domains according to {@link threads} mentioned.
|
||||||
|
* If <i>options.parsedData</i> is mentioned, then it will be used to parse <b>all</b> the responses.
|
||||||
|
* If a proxy is mentioned in {@link options}, then the proxy will be used to collect <b>all</b> the WhoIs data.
|
||||||
|
*
|
||||||
|
* @param domains Domains Names
|
||||||
|
* @param parallel Whether data should be collected parallally or not
|
||||||
|
* @param threads Batch size (for parallel processing)
|
||||||
|
* @param parse Whether the raw text needs to be parsed/formatted or not
|
||||||
|
* @param options {@link WhoIsOptions}
|
||||||
|
* @returns Array of {@link WhoIsResponse} for all the domains. Order is not guaranteed
|
||||||
|
*/
|
||||||
|
export async function batchWhois(domains: string[], parallel: boolean = false, threads: number = 1, parse: boolean = false, options: WhoIsOptions | null = null): Promise<WhoIsResponse[]> {
|
||||||
|
let response: WhoIsResponse[] = [];
|
||||||
|
|
||||||
|
if (parallel) {
|
||||||
|
if (threads > domains.length) {
|
||||||
|
threads = domains.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < domains.length; i+= threads) {
|
||||||
|
const batch = domains.slice(i, i+threads);
|
||||||
|
let resp = await Promise.all(batch.map(async domain => {
|
||||||
|
return await whois(domain, parse, options);
|
||||||
|
}));
|
||||||
|
|
||||||
|
response = response.concat(resp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < domains.length; i++) {
|
||||||
|
const res = await whois(domains[i], parse, options);
|
||||||
|
response.push(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
// br.com,cn.com,de.com,eu.com,gb.com,gb.net,gr.com,hu.com,in.net,no.com,qc.com,ru.com,sa.com,se.com,se.net,uk.com,uk.net,us.com,uy.com,za.com,jpn.com,web.com,com,za.net,net,eu.org,za.org,org,llyw.cymru,gov.scot,gov.wales,edu,gov,int,e164.arpa,arpa,aero,asia,biz,cat,coop,info,jobs,mobi,museum,name,post,pro,tel,travel,xxx,ac,ae,af,ag,ai,am,ar,as,priv.at,at,au,aw,ax,be,bf,bg,bh,bi,bj,bm,bn,bo,br,by,bw,bz,co.ca,ca,cc,cd,ch,ci,cl,cm,edu.cn,cn,uk.co,co,cr,cx,cz,de,dk,dm,do,dz,ec,ee,eu,fi,fj,fm,fo,fr,gd,ge,gf,gg,gh,gi,gl,gp,gq,gs,gy,hk,hm,hn,hr,ht,hu,id,ie,il,im,in,io,iq,ir,is,it,je,jp,ke,kg,ki,kn,kr,kw,ky,kz,la,lb,lc,li,lk,ls,lt,lu,lv,ly,ma,md,me,mg,mk,ml,mm,mn,mq,mr,ms,mt,mu,mw,mx,my,mz,na,nc,nf,ng,nl,no,nu,nz,om,pe,pf,pk,co.pl,pl,pm,pr,ps,pt,pw,qa,re,ro,rs,ac.ru,edu.ru,com.ru,msk.ru,net.ru,nov.ru,org.ru,pp.ru,spb.ru,ru,rw,sa,sb,sc,sd,se,sg,sh,si,sk,sl,sm,sn,so,ss,st,msk.su,nov.su,spb.su,su,sx,sy,tc,td,tf,tg,th,tk,tl,tm,tn,to,tr,tv,tw,tz,biz.ua,co.ua,pp.ua,ua,ug,ac.uk,gov.uk,uk,fed.us,us,uy,uz,vc,ve,vg,vu,wf,ws,yt,ac.za,co.za,gov.za,net.za,org.za,web.za,zm,xn--2scrj9c,xn--3e0b707e,xn--3hcrj9c,xn--45br5cyl,xn--45brj9c,xn--4dbrk0ce,xn--80ao21a,xn--90a3ac,xn--90ae,xn--90ais,xn--clchc0ea0b2g2a9gcd,xn--d1alf,xn--e1a4c,xn--fiqs8s,xn--fiqz9s,xn--fpcrj9c3d,xn--fzc2c9e2c,xn--gecrj9c,xn--h2breg3eve,xn--h2brj9c8c,xn--h2brj9c,xn--j1amh,xn--j6w193g,xn--kprw13d,xn--kpry57d,xn--lgbbat1ad8j,xn--mgb9awbf,xn--mgba3a4f16a,xn--mgbaam7a8h,xn--mgbah1a3hjkrd,xn--mgbbh1a71e,xn--mgbbh1a,xn--mgberp4a5d4ar,xn--mgbgu82a,xn--mgbtx2b,xn--mgbx4cd0ab,xn--node,xn--o3cw4h,xn--ogbpf8fl,xn--p1ai,xn--pgbs0dh,xn--q7ce6a,xn--qxa6a,xn--rvc1e0am3e,xn--s9brj9c,xn--wgbh1c,xn--wgbl6a,xn--xkc2al3hye2a,xn--xkc2dl3a5ee0h,xn--y9a3aq,xn--yfro4i67o,xn--ygbi2ammx
|
// br.com,cn.com,de.com,eu.com,gb.com,gb.net,gr.com,hu.com,in.net,no.com,qc.com,ru.com,sa.com,se.com,se.net,uk.com,uk.net,us.com,uy.com,za.com,jpn.com,web.com,com,za.net,net,eu.org,za.org,org,llyw.cymru,gov.scot,gov.wales,edu,gov,int,e164.arpa,arpa,aero,asia,biz,cat,coop,info,jobs,mobi,museum,name,post,pro,tel,travel,xxx,ac,ae,af,ag,ai,am,ar,as,priv.at,at,au,aw,ax,be,bf,bg,bh,bi,bj,bm,bn,bo,br,by,bw,bz,co.ca,ca,cc,cd,ch,ci,cl,cm,edu.cn,cn,uk.co,co,cr,cx,cz,de,dk,dm,do,dz,ec,ee,eu,fi,fj,fm,fo,fr,gd,ge,gf,gg,gh,gi,gl,gp,gq,gs,gy,hk,hm,hn,hr,ht,hu,id,ie,il,im,in,io,iq,ir,is,it,je,jp,ke,kg,ki,kn,kr,kw,ky,kz,la,lb,lc,li,lk,ls,lt,lu,lv,ly,ma,md,me,mg,mk,ml,mm,mn,mq,mr,ms,mt,mu,mw,mx,my,mz,na,nc,nf,ng,nl,no,nu,nz,om,pe,pf,pk,co.pl,pl,pm,pr,ps,pt,pw,qa,re,ro,rs,ac.ru,edu.ru,com.ru,msk.ru,net.ru,nov.ru,org.ru,pp.ru,spb.ru,ru,rw,sa,sb,sc,sd,se,sg,sh,si,sk,sl,sm,sn,so,ss,st,msk.su,nov.su,spb.su,su,sx,sy,tc,td,tf,tg,th,tk,tl,tm,tn,to,tr,tv,tw,tz,biz.ua,co.ua,pp.ua,ua,ug,ac.uk,gov.uk,uk,fed.us,us,uy,uz,vc,ve,vg,vu,wf,ws,yt,ac.za,co.za,gov.za,net.za,org.za,web.za,zm,xn--2scrj9c,xn--3e0b707e,xn--3hcrj9c,xn--45br5cyl,xn--45brj9c,xn--4dbrk0ce,xn--80ao21a,xn--90a3ac,xn--90ae,xn--90ais,xn--clchc0ea0b2g2a9gcd,xn--d1alf,xn--e1a4c,xn--fiqs8s,xn--fiqz9s,xn--fpcrj9c3d,xn--fzc2c9e2c,xn--gecrj9c,xn--h2breg3eve,xn--h2brj9c8c,xn--h2brj9c,xn--j1amh,xn--j6w193g,xn--kprw13d,xn--kpry57d,xn--lgbbat1ad8j,xn--mgb9awbf,xn--mgba3a4f16a,xn--mgbaam7a8h,xn--mgbah1a3hjkrd,xn--mgbbh1a71e,xn--mgbbh1a,xn--mgberp4a5d4ar,xn--mgbgu82a,xn--mgbtx2b,xn--mgbx4cd0ab,xn--node,xn--o3cw4h,xn--ogbpf8fl,xn--p1ai,xn--pgbs0dh,xn--q7ce6a,xn--qxa6a,xn--rvc1e0am3e,xn--s9brj9c,xn--wgbh1c,xn--wgbl6a,xn--xkc2al3hye2a,xn--xkc2dl3a5ee0h,xn--y9a3aq,xn--yfro4i67o,xn--ygbi2ammx
|
||||||
|
|
||||||
export const SupportedTLDs = new Set(["br.com", "cn.com", "de.com", "eu.com", "gb.com", "gb.net", "gr.com", "hu.com", "in.net", "no.com", "qc.com", "ru.com", "sa.com", "se.com", "se.net", "uk.com", "uk.net", "us.com", "uy.com", "za.com", "jpn.com", "web.com", "com", "za.net", "net", "eu.org", "za.org", "org", "llyw.cymru", "gov.scot", "gov.wales", "edu", "gov", "int", "e164.arpa", "arpa", "aero", "asia", "biz", "cat", "coop", "info", "jobs", "mobi", "museum", "name", "post", "pro", "tel", "travel", "xxx", "ac", "ae", "af", "ag", "ai", "am", "ar", "as", "priv.at", "at", "au", "aw", "ax", "be", "bf", "bg", "bh", "bi", "bj", "bm", "bn", "bo", "br", "by", "bw", "bz", "co.ca", "ca", "cc", "cd", "ch", "ci", "cl", "cm", "edu.cn", "cn", "uk.co", "co", "cr", "cx", "cz", "de", "dk", "dm", "do", "dz", "ec", "ee", "eu", "fi", "fj", "fm", "fo", "fr", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gp", "gq", "gs", "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in", "io", "iq", "ir", "is", "it", "je", "jp", "ke", "kg", "ki", "kn", "kr", "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "ls", "lt", "lu", "lv", "ly", "ma", "md", "me", "mg", "mk", "ml", "mm", "mn", "mq", "mr", "ms", "mt", "mu", "mw", "mx", "my", "mz", "na", "nc", "nf", "ng", "nl", "no", "nu", "nz", "om", "pe", "pf", "pk", "co.pl", "pl", "pm", "pr", "ps", "pt", "pw", "qa", "re", "ro", "rs", "ac.ru", "edu.ru", "com.ru", "msk.ru", "net.ru", "nov.ru", "org.ru", "pp.ru", "spb.ru", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si", "sk", "sl", "sm", "sn", "so", "ss", "st", "msk.su", "nov.su", "spb.su", "su", "sx", "sy", "tc", "td", "tf", "tg", "th", "tk", "tl", "tm", "tn", "to", "tr", "tv", "tw", "tz", "biz.ua", "co.ua", "pp.ua", "ua", "ug", "ac.uk", "gov.uk", "uk", "fed.us", "us", "uy", "uz", "vc", "ve", "vg", "vu", "wf", "ws", "yt", "ac.za", "co.za", "gov.za", "net.za", "org.za", "web.za", "zm", "xn--2scrj9c", "xn--3e0b707e", "xn--3hcrj9c", "xn--45br5cyl", "xn--45brj9c", "xn--4dbrk0ce", "xn--80ao21a", "xn--90a3ac", "xn--90ae", "xn--90ais", "xn--clchc0ea0b2g2a9gcd", "xn--d1alf", "xn--e1a4c", "xn--fiqs8s", "xn--fiqz9s", "xn--fpcrj9c3d", "xn--fzc2c9e2c", "xn--gecrj9c", "xn--h2breg3eve", "xn--h2brj9c8c", "xn--h2brj9c", "xn--j1amh", "xn--j6w193g", "xn--kprw13d", "xn--kpry57d", "xn--lgbbat1ad8j", "xn--mgb9awbf", "xn--mgba3a4f16a", "xn--mgbaam7a8h", "xn--mgbah1a3hjkrd", "xn--mgbbh1a71e", "xn--mgbbh1a", "xn--mgberp4a5d4ar", "xn--mgbgu82a", "xn--mgbtx2b", "xn--mgbx4cd0ab", "xn--node", "xn--o3cw4h", "xn--ogbpf8fl", "xn--p1ai", "xn--pgbs0dh", "xn--q7ce6a", "xn--qxa6a", "xn--rvc1e0am3e", "xn--s9brj9c", "xn--wgbh1c", "xn--wgbl6a", "xn--xkc2al3hye2a", "xn--xkc2dl3a5ee0h", "xn--y9a3aq", "xn--yfro4i67o", "xn--ygbi2ammx"]);
|
export const SupportedTLDs = new Set(["br.com", "cn.com", "de.com", "eu.com", "gb.com", "gb.net", "gr.com", "hu.com", "in.net", "no.com", "qc.com", "ru.com", "sa.com", "se.com", "se.net", "uk.com", "uk.net", "us.com", "uy.com", "za.com", "jpn.com", "web.com", "com", "za.net", "net", "eu.org", "za.org", "org", "llyw.cymru", "gov.scot", "gov.wales", "edu", "gov", "int", "e164.arpa", "arpa", "aero", "asia", "biz", "cat", "coop", "info", "jobs", "mobi", "museum", "name", "post", "pro", "tel", "travel", "xxx", "ac", "ae", "af", "ag", "ai", "am", "ar", "as", "priv.at", "at", "au", "aw", "ax", "be", "bf", "bg", "bh", "bi", "bj", "bm", "bn", "bo", "br", "by", "bw", "bz", "co.ca", "ca", "cc", "cd", "ch", "ci", "cl", "cm", "edu.cn", "cn", "uk.co", "co", "cr", "cx", "cz", "de", "dk", "dm", "do", "dz", "ec", "ee", "eu", "fi", "fj", "fm", "fo", "fr", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gp", "gq", "gs", "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in", "io", "iq", "ir", "is", "it", "je", "jp", "ke", "kg", "ki", "kn", "kr", "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "ls", "lt", "lu", "lv", "ly", "ma", "md", "me", "mg", "mk", "ml", "mm", "mn", "mq", "mr", "ms", "mt", "mu", "mw", "mx", "my", "mz", "na", "nc", "nf", "ng", "nl", "no", "nu", "nz", "om", "pe", "pf", "pk", "co.pl", "pl", "pm", "pr", "ps", "pt", "pw", "qa", "re", "ro", "rs", "ac.ru", "edu.ru", "com.ru", "msk.ru", "net.ru", "nov.ru", "org.ru", "pp.ru", "spb.ru", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si", "sk", "sl", "sm", "sn", "so", "ss", "st", "msk.su", "nov.su", "spb.su", "su", "sx", "sy", "tc", "td", "tf", "tg", "th", "tk", "tl", "tm", "tn", "to", "tr", "tv", "tw", "tz", "biz.ua", "co.ua", "pp.ua", "ua", "ug", "ac.uk", "gov.uk", "uk", "fed.us", "us", "uy", "uz", "vc", "ve", "vg", "vu", "wf", "ws", "yt", "ac.za", "co.za", "gov.za", "net.za", "org.za", "web.za", "zm", "xn--2scrj9c", "xn--3e0b707e", "xn--3hcrj9c", "xn--45br5cyl", "xn--45brj9c", "xn--4dbrk0ce", "xn--80ao21a", "xn--90a3ac", "xn--90ae", "xn--90ais", "xn--clchc0ea0b2g2a9gcd", "xn--d1alf", "xn--e1a4c", "xn--fiqs8s", "xn--fiqz9s", "xn--fpcrj9c3d", "xn--fzc2c9e2c", "xn--gecrj9c", "xn--h2breg3eve", "xn--h2brj9c8c", "xn--h2brj9c", "xn--j1amh", "xn--j6w193g", "xn--kprw13d", "xn--kpry57d", "xn--lgbbat1ad8j", "xn--mgb9awbf", "xn--mgba3a4f16a", "xn--mgbaam7a8h", "xn--mgbah1a3hjkrd", "xn--mgbbh1a71e", "xn--mgbbh1a", "xn--mgberp4a5d4ar", "xn--mgbgu82a", "xn--mgbtx2b", "xn--mgbx4cd0ab", "xn--node", "xn--o3cw4h", "xn--ogbpf8fl", "xn--p1ai", "xn--pgbs0dh", "xn--q7ce6a", "xn--qxa6a", "xn--rvc1e0am3e", "xn--s9brj9c", "xn--wgbh1c", "xn--wgbl6a", "xn--xkc2al3hye2a", "xn--xkc2dl3a5ee0h", "xn--y9a3aq", "xn--yfro4i67o",
|
||||||
|
"xn--ygbi2ammx","xyz"
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user