@hyperwatch/hyperwatch 3.8.2 → 3.9.1
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/package.json +22 -22
- package/src/index.js +2 -2
- package/src/modules/address.js +4 -4
- package/src/modules/agent.js +2 -2
- package/src/modules/cloudflare.js +2 -2
- package/src/modules/dnsbl.js +2 -2
- package/src/modules/geoip.js +2 -2
- package/src/modules/hostname.js +2 -2
- package/src/modules/identity.js +8 -4
- package/src/modules/index.js +8 -8
- package/src/modules/language.js +2 -2
- package/src/modules/logs.js +2 -2
- package/src/modules/signature.js +4 -4
- package/src/modules/sparkline.js +2 -2
- package/src/modules/status.js +2 -2
- package/PARSER +0 -59
- package/TODO +0 -7
- package/USERAGENT +0 -96
- package/check-ips.js +0 -15
- package/data2 +0 -4242
- package/ips.js +0 -491
- package/scripts/benchmark-parser.js +0 -145
- package/scripts/compare-parser.js +0 -97
- package/scripts/hostname.js +0 -23
- package/scripts/test-update.js +0 -21
- package/scripts/update-uas.js +0 -30
- package/src/modules/user-agent.js +0 -31
- package/src/plugins/browser.js +0 -35
- package/src/plugins/reputation.js +0 -168
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
|
|
3
|
-
const useragent = require('../src/lib/useragent');
|
|
4
|
-
|
|
5
|
-
const date = new Date().toISOString().slice(0, 10);
|
|
6
|
-
// const date = '2020-09-18';
|
|
7
|
-
|
|
8
|
-
const filename = path.join(__dirname, '../data/ua', `${date}-parsed.json`);
|
|
9
|
-
|
|
10
|
-
let uas;
|
|
11
|
-
try {
|
|
12
|
-
uas = require(filename);
|
|
13
|
-
} catch (err) {
|
|
14
|
-
uas = [];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Transform Hyperwatch to their UAP Core equivalent
|
|
18
|
-
const mapping = {
|
|
19
|
-
'Coc Coc Browser': 'Coc Coc',
|
|
20
|
-
'DuckDuckBot-Https': 'DuckDuckBot',
|
|
21
|
-
'Google Search App': 'Google',
|
|
22
|
-
'Mobile Safari UI/WKWebView': 'Safari WebView',
|
|
23
|
-
'Chrome Mobile WebView': 'Chrome WebView',
|
|
24
|
-
'Mobile Safari': 'Safari Mobile',
|
|
25
|
-
'WordPress.com': 'WordPress',
|
|
26
|
-
'python-requests': 'Python Requests',
|
|
27
|
-
'Android WebView': 'Android',
|
|
28
|
-
PaleMoon: 'Pale Moon',
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// Transform UAP Core to their Hyperwatch equivalent
|
|
32
|
-
const uapCoreMapping = {
|
|
33
|
-
'Chrome Mobile WebView': 'Chrome WebView',
|
|
34
|
-
'Chrome Mobile': 'Chrome',
|
|
35
|
-
'Edge Mobile': 'Edge',
|
|
36
|
-
'Firefox Alpha': 'Firefox',
|
|
37
|
-
'Firefox Beta': 'Firefox',
|
|
38
|
-
'Firefox Mobile': 'Firefox',
|
|
39
|
-
'Mail.RU_Bot': 'Mail.RU Bot',
|
|
40
|
-
'Opera Mobile': 'Opera',
|
|
41
|
-
'Samsung Internet': 'SamsungBrowser',
|
|
42
|
-
bingbot: 'BingBot',
|
|
43
|
-
coccocbot: 'Coc Coc Bot',
|
|
44
|
-
GmailImageProxy: 'GoogleImageProxy',
|
|
45
|
-
LINE: 'Line',
|
|
46
|
-
'Chrome Mobile iOS': 'Chrome',
|
|
47
|
-
'QQ Browser': 'QQBrowser',
|
|
48
|
-
'UC Browser': 'UCBrowser',
|
|
49
|
-
'Firefox iOS': 'Firefox',
|
|
50
|
-
'QQ Browser Mobile': 'QQBrowser',
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
for (const [ua, json] of Object.entries(uas)) {
|
|
54
|
-
if (!json) {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
if (!json.family) {
|
|
58
|
-
console.log(`No result`, { hw: null }, ua);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Transform Hyperwatch to their UAP Core equivalent
|
|
63
|
-
if (json.family && mapping[json.family]) {
|
|
64
|
-
json.family = mapping[json.family];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// if (['Dalvik'].includes(json.family)) {
|
|
68
|
-
// continue;
|
|
69
|
-
// }
|
|
70
|
-
|
|
71
|
-
// Parse with UAP core only
|
|
72
|
-
const agent = useragent.parse(
|
|
73
|
-
ua,
|
|
74
|
-
/* enableCore */ false,
|
|
75
|
-
/* enableExtra */ false,
|
|
76
|
-
/* enableUapCore */ true
|
|
77
|
-
);
|
|
78
|
-
const result = agent.toJSON();
|
|
79
|
-
|
|
80
|
-
// if (['Electron'].includes(result.family)) {
|
|
81
|
-
// continue;
|
|
82
|
-
// }
|
|
83
|
-
|
|
84
|
-
// Transform UAP Core result to its Hyperwatch equivalent
|
|
85
|
-
if (result.family && uapCoreMapping[result.family]) {
|
|
86
|
-
result.family = uapCoreMapping[result.family];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!result.family) {
|
|
90
|
-
console.log(`New:`, { hw: json.family });
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (result.family !== json.family) {
|
|
95
|
-
console.log('Diff', { uap: result.family, hw: json.family });
|
|
96
|
-
}
|
|
97
|
-
}
|
package/scripts/hostname.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
const fetch = require('node-fetch');
|
|
2
|
-
|
|
3
|
-
fetch('http://localhost:3009/addresses?raw=1&limit=1000')
|
|
4
|
-
.then((response) => response.json())
|
|
5
|
-
.then((entries) => {
|
|
6
|
-
const hostnames = entries
|
|
7
|
-
.filter((entry) => entry.address && entry.address.hostname)
|
|
8
|
-
.filter((entry) => !entry.address.type)
|
|
9
|
-
.filter((entry) => entry.identity || entry.opencollective)
|
|
10
|
-
.map((entry) => entry.address.hostname)
|
|
11
|
-
.map((hostname) => {
|
|
12
|
-
const parts = hostname.split('.');
|
|
13
|
-
let extension = parts.pop();
|
|
14
|
-
let domain = parts.pop();
|
|
15
|
-
if (['com', 'net', 'on', 'ne', 'co', 'in'].includes(domain)) {
|
|
16
|
-
extension = `${domain}.${extension}`;
|
|
17
|
-
domain = parts.pop();
|
|
18
|
-
}
|
|
19
|
-
return `${domain}.${extension}`;
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
console.log([...new Set(hostnames)]);
|
|
23
|
-
});
|
package/scripts/test-update.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const fetch = require('node-fetch'); // eslint-disable-line node/no-unpublished-require
|
|
5
|
-
const yaml = require('yamlparser'); // eslint-disable-line node/no-unpublished-require
|
|
6
|
-
|
|
7
|
-
fetch(
|
|
8
|
-
'https://raw.githubusercontent.com/ua-parser/uap-core/master/tests/test_ua.yaml'
|
|
9
|
-
)
|
|
10
|
-
.then((response) => response.text())
|
|
11
|
-
|
|
12
|
-
.then((uaYaml) => {
|
|
13
|
-
fs.writeFileSync(path.resolve(__dirname, '..', 'test', 'ua.yml'), uaYaml);
|
|
14
|
-
|
|
15
|
-
const ua = yaml.eval(uaYaml);
|
|
16
|
-
|
|
17
|
-
fs.writeFileSync(
|
|
18
|
-
path.resolve(__dirname, '..', 'test', 'ua.json'),
|
|
19
|
-
JSON.stringify(ua.test_cases, null, 2)
|
|
20
|
-
);
|
|
21
|
-
});
|
package/scripts/update-uas.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const { pick } = require('lodash');
|
|
5
|
-
|
|
6
|
-
const useragent = require('../src/lib/useragent');
|
|
7
|
-
|
|
8
|
-
const date = new Date().toISOString().slice(0, 10);
|
|
9
|
-
// const date = '2020-09-18';
|
|
10
|
-
|
|
11
|
-
const filename = path.join(__dirname, '../data/ua', `${date}.json`);
|
|
12
|
-
const parsedFilename = path.join(
|
|
13
|
-
__dirname,
|
|
14
|
-
'../data/ua',
|
|
15
|
-
`${date}-parsed.json`
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const uas = require(filename);
|
|
19
|
-
|
|
20
|
-
const fields = ['family', 'major', 'minor', 'patch', 'patch_minor'];
|
|
21
|
-
|
|
22
|
-
const parsedUas = {};
|
|
23
|
-
|
|
24
|
-
for (const ua of uas) {
|
|
25
|
-
const agent = useragent.parse(ua);
|
|
26
|
-
|
|
27
|
-
parsedUas[ua] = pick(agent.toJSON(), fields);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
fs.writeFileSync(parsedFilename, JSON.stringify(parsedUas, null, 2));
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const api = require('../app/api');
|
|
2
|
-
const { Aggregator } = require('../lib/aggregator');
|
|
3
|
-
const pipeline = require('../lib/pipeline');
|
|
4
|
-
|
|
5
|
-
const identifier = (log) => log.getIn(['address', 'value']);
|
|
6
|
-
|
|
7
|
-
function fill(log) {
|
|
8
|
-
if (!log.hasIn(['address', 'value'])) {
|
|
9
|
-
log = log.setIn(['address', 'value'], log.getIn(['request', 'address']));
|
|
10
|
-
}
|
|
11
|
-
return log;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function load() {
|
|
15
|
-
pipeline.getNode('main').map(fill).registerNode('main');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function beforeStart() {
|
|
19
|
-
const aggregator = new Aggregator();
|
|
20
|
-
|
|
21
|
-
aggregator.setIdentifier(identifier);
|
|
22
|
-
|
|
23
|
-
pipeline.getNode('main').map((log) => aggregator.processLog(log));
|
|
24
|
-
|
|
25
|
-
api.registerAggregator('userAgents', aggregator);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
module.exports = {
|
|
29
|
-
load,
|
|
30
|
-
beforeStart,
|
|
31
|
-
};
|
package/src/plugins/browser.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
const { fromJS } = require('immutable');
|
|
2
|
-
|
|
3
|
-
function augment(log) {
|
|
4
|
-
const browser = {};
|
|
5
|
-
|
|
6
|
-
if (log.hasIn(['request', 'headers', 'dnt'])) {
|
|
7
|
-
browser.dnt = true;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (log.hasIn(['request', 'headers', 'accept-language'])) {
|
|
11
|
-
browser.dnt = true;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const parser = require('accept-language-parser');
|
|
15
|
-
|
|
16
|
-
const languages = parser.parse('en-GB,en;q=0.8');
|
|
17
|
-
|
|
18
|
-
const agentFamily = log.getIn(['useragent', 'family']);
|
|
19
|
-
// console.log({ agentFamily });
|
|
20
|
-
|
|
21
|
-
if (agentFamily && browsers.includes(agentFamily)) {
|
|
22
|
-
const browser = {};
|
|
23
|
-
|
|
24
|
-
if (agentFamily === 'Chrome') {
|
|
25
|
-
browser.check = checkChrome(log);
|
|
26
|
-
}
|
|
27
|
-
log = log.set('browser', fromJS(browser));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return log;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
module.exports = {
|
|
34
|
-
augment,
|
|
35
|
-
};
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
const { fromJS } = require('immutable');
|
|
2
|
-
|
|
3
|
-
const browsers = [
|
|
4
|
-
'Firefox',
|
|
5
|
-
'Firefox Mobile',
|
|
6
|
-
'Firefox iOS',
|
|
7
|
-
'Chrome',
|
|
8
|
-
'Chrome Mobile',
|
|
9
|
-
'Chrome Mobile iOS',
|
|
10
|
-
'Chrome Mobile WebView',
|
|
11
|
-
'Edge',
|
|
12
|
-
'Safari',
|
|
13
|
-
'Mobile Safari',
|
|
14
|
-
'Opera',
|
|
15
|
-
'Opera Mobile',
|
|
16
|
-
'Chromium',
|
|
17
|
-
'Samsung Internet',
|
|
18
|
-
'Epiphany',
|
|
19
|
-
'Yandex Browser',
|
|
20
|
-
'MiuiBrowser',
|
|
21
|
-
'UC Browser',
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
function checkChrome(log) {
|
|
25
|
-
// console.log(log.getIn(['request', 'headers']).toJS());
|
|
26
|
-
|
|
27
|
-
const check = {
|
|
28
|
-
version: null,
|
|
29
|
-
accept: null,
|
|
30
|
-
language: null,
|
|
31
|
-
charset: null,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const accepts = {
|
|
35
|
-
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8':
|
|
36
|
-
'html',
|
|
37
|
-
'image/webp,image/apng,image/*,*/*;q=0.8': 'images',
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const major = log.getIn(['useragent', 'major']);
|
|
41
|
-
if (!major) {
|
|
42
|
-
// console.log('Missing Version');
|
|
43
|
-
check['version'] = false;
|
|
44
|
-
} else if (Number(major) >= 81) {
|
|
45
|
-
check['version'] = true;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// const agent = log.getIn(['agent']);
|
|
49
|
-
|
|
50
|
-
// console.log(agent.major);
|
|
51
|
-
|
|
52
|
-
const accept = log.getIn(['request', 'headers', 'accept']);
|
|
53
|
-
if (!accept) {
|
|
54
|
-
// console.log('Missing Accept');
|
|
55
|
-
check['accept'] = false;
|
|
56
|
-
} else if (!accepts[accept]) {
|
|
57
|
-
// console.log('Unnkown Accept', accept);
|
|
58
|
-
check['accept'] = false;
|
|
59
|
-
} else {
|
|
60
|
-
check['accept'] = true;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const acceptLanguage = log.getIn(['request', 'headers', 'accept-language']);
|
|
64
|
-
if (!acceptLanguage) {
|
|
65
|
-
// console.log('Missing Accept-Language');
|
|
66
|
-
check['language'] = false;
|
|
67
|
-
} else {
|
|
68
|
-
if (/^(.*);q=0.9$/i.test(acceptLanguage)) {
|
|
69
|
-
// console.log(
|
|
70
|
-
// 'Expected Accept-Language header: 1 language',
|
|
71
|
-
// acceptLanguage
|
|
72
|
-
// );
|
|
73
|
-
check['language'] = true;
|
|
74
|
-
} else if (/^(.*);q=0.9(.*);q=0.8$/i.test(acceptLanguage)) {
|
|
75
|
-
// console.log(
|
|
76
|
-
// 'Expected Accept-Language header: 2 languages',
|
|
77
|
-
// acceptLanguage
|
|
78
|
-
// );
|
|
79
|
-
check['language'] = true;
|
|
80
|
-
} else if (/^(.*);q=0.9(.*);q=0.8(.*);q=0.7$/i.test(acceptLanguage)) {
|
|
81
|
-
// console.log(
|
|
82
|
-
// 'Expected Accept-Language header: 3 languages',
|
|
83
|
-
// acceptLanguage
|
|
84
|
-
// );
|
|
85
|
-
check['language'] = true;
|
|
86
|
-
} else if (
|
|
87
|
-
/^(.*);q=0.9(.*);q=0.8(.*);q=0.7(.*);q=0.6/i.test(acceptLanguage)
|
|
88
|
-
) {
|
|
89
|
-
// console.log(
|
|
90
|
-
// 'Expected Accept-Language header: 4+ languages',
|
|
91
|
-
// acceptLanguage
|
|
92
|
-
// );
|
|
93
|
-
check['language'] = true;
|
|
94
|
-
} else {
|
|
95
|
-
// console.log('Other Accept-Language header', acceptLanguage);
|
|
96
|
-
check['language'] = false;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const acceptCharset = log.getIn(['request', 'headers', 'accept-charset']);
|
|
101
|
-
if (acceptCharset) {
|
|
102
|
-
// console.log('Accept-Charset detected', acceptCharset);
|
|
103
|
-
check['charset'] = false;
|
|
104
|
-
} else {
|
|
105
|
-
check['charset'] = true;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const secFetchDest = log.getIn(['request', 'headers', 'sec-fetch-dest']);
|
|
109
|
-
if (secFetchDest) {
|
|
110
|
-
// console.log('Accept-Charset detected', acceptCharset);
|
|
111
|
-
check['sec'] = true;
|
|
112
|
-
} else {
|
|
113
|
-
check['sec'] = false;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// 'sec-fetch-dest': 'image',
|
|
117
|
-
// 'sec-fetch-mode': 'no-cors',
|
|
118
|
-
// 'sec-fetch-site': 'cross-site',
|
|
119
|
-
|
|
120
|
-
// const acceptEncoding = log.getIn(['request', 'headers', 'accept-encoding']);
|
|
121
|
-
// if (acceptCharset) {
|
|
122
|
-
// console.log('Accept-Encoding detected');
|
|
123
|
-
// }
|
|
124
|
-
|
|
125
|
-
// console.log('Accept', log.getIn(['request', 'headers', 'accept']));
|
|
126
|
-
// console.log(
|
|
127
|
-
// 'Accept-Language',
|
|
128
|
-
// log.getIn(['request', 'headers', 'accept-language'])
|
|
129
|
-
// );
|
|
130
|
-
// console.log(
|
|
131
|
-
// 'Accept-Charset',
|
|
132
|
-
// log.getIn(['request', 'headers', 'accept-charset'])
|
|
133
|
-
// );
|
|
134
|
-
// console.log(
|
|
135
|
-
// 'Accept-Encoding',
|
|
136
|
-
// log.getIn(['request', 'headers', 'accept-encoding'])
|
|
137
|
-
// );
|
|
138
|
-
|
|
139
|
-
return check;
|
|
140
|
-
|
|
141
|
-
// console.log('DNT', log.getIn(['request', 'headers', 'dnt']));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function augment(log) {
|
|
145
|
-
// const agent = log.getIn(['agent']);
|
|
146
|
-
|
|
147
|
-
// console.log(agent);
|
|
148
|
-
|
|
149
|
-
const agentFamily = log.getIn(['useragent', 'family']);
|
|
150
|
-
// console.log({ agentFamily });
|
|
151
|
-
|
|
152
|
-
if (agentFamily && browsers.includes(agentFamily)) {
|
|
153
|
-
const browser = {};
|
|
154
|
-
if (log.hasIn(['request', 'headers', 'dnt'])) {
|
|
155
|
-
browser.dnt = true;
|
|
156
|
-
}
|
|
157
|
-
if (agentFamily === 'Chrome') {
|
|
158
|
-
browser.check = checkChrome(log);
|
|
159
|
-
}
|
|
160
|
-
log = log.set('browser', fromJS(browser));
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return log;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
module.exports = {
|
|
167
|
-
augment,
|
|
168
|
-
};
|