forked from sindresorhus/is-online
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
87 lines (73 loc) · 1.85 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
'use strict';
const os = require('os');
const got = require('got');
const publicIp = require('public-ip');
const pAny = require('p-any');
const pTimeout = require('p-timeout');
// Use Array#flat when targeting Node.js 12
const flat = array => [].concat(...array);
const appleCheck = options => {
const gotPromise = got('https://captive.apple.com/hotspot-detect.html', {
timeout: options.timeout,
dnsLookupIpVersion: options.ipVersion === 6 ? 'ipv6' : 'ipv4',
headers: {
'user-agent': 'CaptiveNetworkSupport/1.0 wispr'
}
});
const promise = (async () => {
try {
const {body} = await gotPromise;
if (!body || !body.includes('Success')) {
throw new Error('Apple check failed');
}
} catch (error) {
if (!(error instanceof got.CancelError)) {
throw error;
}
}
})();
promise.cancel = gotPromise.cancel;
return promise;
};
const isOnline = options => {
options = {
timeout: 5000,
ipVersion: 4,
...options
};
if (flat(Object.values(os.networkInterfaces())).every(({internal}) => internal)) {
return Promise.resolve(false);
}
if (![4, 6].includes(options.ipVersion)) {
throw new TypeError('`ipVersion` must be 4 or 6');
}
const publicIpFunctionName = options.ipVersion === 4 ? 'v4' : 'v6';
const queries = [];
const promise = pAny([
(async () => {
const query = publicIp[publicIpFunctionName](options);
queries.push(query);
await query;
return true;
})(),
(async () => {
const query = publicIp[publicIpFunctionName]({...options, onlyHttps: true});
queries.push(query);
await query;
return true;
})(),
(async () => {
const query = appleCheck(options);
queries.push(query);
await query;
return true;
})()
]);
return pTimeout(promise, options.timeout).catch(() => {
for (const query of queries) {
query.cancel();
}
return false;
});
};
module.exports = isOnline;