@k03mad/dns-leak 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -10
- package/app/api/IPLeak.js +0 -1
- package/app/api/IPWhois.js +44 -0
- package/app/api/index.js +2 -0
- package/app/helpers/text.js +27 -22
- package/app/{index.js → run.js} +6 -6
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# DNS leak test
|
|
2
2
|
|
|
3
|
-
Based on
|
|
3
|
+
Based on:\
|
|
4
|
+
— [ipleak.net](https://ipleak.net) ([API](https://airvpn.org/forums/topic/14737-api))\
|
|
5
|
+
— [ipwhois.io](https://ipwhois.io) ([API](https://ipwhois.io/documentation))
|
|
4
6
|
|
|
5
7
|
## Global
|
|
6
8
|
|
|
@@ -17,20 +19,21 @@ npm i @k03mad/dns-leak
|
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
```js
|
|
20
|
-
import IPLeak from '@k03mad/dns-leak';
|
|
22
|
+
import {IPLeak, IPWhois} from '@k03mad/dns-leak';
|
|
21
23
|
|
|
22
|
-
// default params (details at the
|
|
23
|
-
const
|
|
24
|
+
// default params (details at the ./app/api folder)
|
|
25
|
+
const LeakApi = new IPLeak();
|
|
26
|
+
const WhoisApi = new IPWhois();
|
|
24
27
|
|
|
25
28
|
// get current external ip info
|
|
26
|
-
await
|
|
29
|
+
await WhoisApi.getIpInfo();
|
|
30
|
+
await LeakApi.getIpInfo();
|
|
27
31
|
// get other ip info
|
|
28
|
-
await
|
|
32
|
+
await WhoisApi.getIpInfo({ip: '8.8.8.8'});
|
|
33
|
+
await LeakApi.getIpInfo({ip: '8.8.8.8'});
|
|
29
34
|
|
|
30
35
|
// dns leak check with one request (one request — fewer dns ips)
|
|
31
|
-
await
|
|
36
|
+
await LeakApi.getDnsInfoOnce();
|
|
32
37
|
// dns leak check with multi requests
|
|
33
|
-
await
|
|
38
|
+
await LeakApi.getDnsInfoMulti();
|
|
34
39
|
```
|
|
35
|
-
|
|
36
|
-
[Options and parameters with their default values](/app/api/IPLeak.js#L8)
|
package/app/api/IPLeak.js
CHANGED
|
@@ -9,7 +9,6 @@ import * as spinner from '../helpers/spinner.js';
|
|
|
9
9
|
export default class IPLeak {
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* All args are not required, the default ones works fine
|
|
13
12
|
* @param {object} [opts]
|
|
14
13
|
* @param {number} [opts.dnsRequestsCount] dns leak multi requests count with one session
|
|
15
14
|
* @param {number} [opts.dnsRequestsRps] dns leak requests rps
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {requestCache} from '@k03mad/request';
|
|
2
|
+
|
|
3
|
+
/** */
|
|
4
|
+
export default class IPWhois {
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} [opts]
|
|
8
|
+
* @param {number} [opts.ipRequestsCacheExpireMs] ip info requests cache ttl ms for same ip
|
|
9
|
+
* @param {number} [opts.ipRequestsRps] ip info requests rps
|
|
10
|
+
*/
|
|
11
|
+
constructor({
|
|
12
|
+
ipRequestsCacheExpireMs = 3_600_000,
|
|
13
|
+
ipRequestsRps = 2,
|
|
14
|
+
} = {}) {
|
|
15
|
+
this._ipRequestsCacheExpireMs = ipRequestsCacheExpireMs;
|
|
16
|
+
this._ipRequestsRps = ipRequestsRps;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** */
|
|
20
|
+
get _endpoints() {
|
|
21
|
+
return {
|
|
22
|
+
|
|
23
|
+
/** @param {string} ip */
|
|
24
|
+
ip: ip => `https://ipwho.is/${ip}`,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {object} [opts]
|
|
30
|
+
* @param {string} [opts.ip]
|
|
31
|
+
* @returns {Promise<object>}
|
|
32
|
+
*/
|
|
33
|
+
async getIpInfo({ip = ''} = {}) {
|
|
34
|
+
const ipEndpoint = this._endpoints.ip(ip);
|
|
35
|
+
|
|
36
|
+
const {body} = await requestCache(ipEndpoint, {}, {
|
|
37
|
+
expire: this._ipRequestsCacheExpireMs,
|
|
38
|
+
rps: this._ipRequestsRps,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return body;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
}
|
package/app/api/index.js
ADDED
package/app/helpers/text.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
/* eslint-disable camelcase */
|
|
2
|
-
|
|
3
1
|
import chalk from 'chalk';
|
|
4
|
-
import clm from 'country-locale-map';
|
|
5
2
|
|
|
6
|
-
const {bgBlackBright, blue, green, magenta, yellow} = chalk;
|
|
3
|
+
const {bgBlackBright, blue, gray, green, magenta, yellow} = chalk;
|
|
7
4
|
|
|
8
5
|
/**
|
|
9
6
|
* @param {any} msg
|
|
@@ -17,39 +14,47 @@ export const bar = msg => yellow(msg);
|
|
|
17
14
|
|
|
18
15
|
/**
|
|
19
16
|
* @param {object} [ipInfo]
|
|
20
|
-
* @param {string} [ipInfo.
|
|
21
|
-
* @param {string} [ipInfo.
|
|
22
|
-
* @param {string} [ipInfo.country_name]
|
|
17
|
+
* @param {string} [ipInfo.city]
|
|
18
|
+
* @param {string} [ipInfo.country]
|
|
23
19
|
* @param {string} [ipInfo.ip]
|
|
24
|
-
* @param {string} [ipInfo.
|
|
25
|
-
* @param {
|
|
20
|
+
* @param {string} [ipInfo.region]
|
|
21
|
+
* @param {object} [ipInfo.flag]
|
|
22
|
+
* @param {object} [ipInfo.connection]
|
|
26
23
|
*/
|
|
27
|
-
export const formatIpInfo = ({
|
|
24
|
+
export const formatIpInfo = ({city, connection, country, flag, ip, region} = {}) => {
|
|
28
25
|
let output = '';
|
|
29
26
|
|
|
30
27
|
if (ip) {
|
|
31
|
-
output += `${blue(ip)}
|
|
28
|
+
output += `${blue(ip)}\n`;
|
|
32
29
|
}
|
|
33
30
|
|
|
34
|
-
if (
|
|
35
|
-
output += green(
|
|
31
|
+
if (connection?.org) {
|
|
32
|
+
output += `${green(connection.org)} `;
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
if (connection?.isp && !connection?.org?.includes(connection?.isp)) {
|
|
36
|
+
if (connection?.org) {
|
|
37
|
+
output += green('/ ');
|
|
38
|
+
}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
output += `${green(connection.isp)} `;
|
|
41
|
+
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
if (connection?.domain) {
|
|
44
|
+
output += gray(`(${connection.domain})`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
output += '\n';
|
|
48
|
+
|
|
49
|
+
if (flag?.emoji) {
|
|
50
|
+
output += `${flag.emoji} `;
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
output += [
|
|
49
54
|
...new Set([
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
country,
|
|
56
|
+
region,
|
|
57
|
+
city,
|
|
53
58
|
]),
|
|
54
59
|
].filter(Boolean).join(' :: ');
|
|
55
60
|
|
package/app/{index.js → run.js}
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import IPLeak from './api/IPLeak.js';
|
|
2
|
+
import {IPLeak, IPWhois} from './api/index.js';
|
|
4
3
|
import {log} from './helpers/log.js';
|
|
5
4
|
import * as spinner from './helpers/spinner.js';
|
|
6
5
|
import {formatIpInfo, header} from './helpers/text.js';
|
|
7
6
|
|
|
8
|
-
const
|
|
7
|
+
const LeakApi = new IPLeak();
|
|
8
|
+
const WhoisApi = new IPWhois();
|
|
9
9
|
|
|
10
|
-
const currentIpInfo = await
|
|
10
|
+
const currentIpInfo = await WhoisApi.getIpInfo();
|
|
11
11
|
|
|
12
12
|
log(
|
|
13
13
|
'',
|
|
@@ -19,13 +19,13 @@ log(
|
|
|
19
19
|
'',
|
|
20
20
|
);
|
|
21
21
|
|
|
22
|
-
const dnsInfo = await
|
|
22
|
+
const dnsInfo = await LeakApi.getDnsInfoMulti({isSpinnerEnabled: true});
|
|
23
23
|
const dnsIps = [...new Set(Object.keys(dnsInfo.ip))];
|
|
24
24
|
|
|
25
25
|
spinner.start(currentIpInfo.ip, true);
|
|
26
26
|
|
|
27
27
|
const dnsData = await Promise.all(dnsIps.map(async ip => {
|
|
28
|
-
const data = await
|
|
28
|
+
const data = await WhoisApi.getIpInfo({ip});
|
|
29
29
|
spinner.count(currentIpInfo.ip, dnsIps.length);
|
|
30
30
|
return data;
|
|
31
31
|
}));
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@k03mad/dns-leak",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "DNS leak test",
|
|
5
5
|
"maintainers": [
|
|
6
6
|
"Kirill Molchanov <k03.mad@gmail.com"
|
|
7
7
|
],
|
|
8
|
-
"main": "app/api/
|
|
9
|
-
"bin": "app/
|
|
8
|
+
"main": "app/api/index.js",
|
|
9
|
+
"bin": "app/run.js",
|
|
10
10
|
"repository": "k03mad/dns-leak",
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"type": "module",
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@k03mad/request": "3.2.0",
|
|
18
18
|
"chalk": "5.3.0",
|
|
19
|
-
"country-locale-map": "1.8.15",
|
|
20
19
|
"nanoid": "5.0.2",
|
|
21
20
|
"nanoid-dictionary": "5.0.0-beta.1",
|
|
22
21
|
"ora": "7.0.1"
|