forked from 7c/fakefilter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
193 lines (162 loc) · 6.13 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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
Basic Javascript Interface to lookup by Email or Domain
Important: you need to auto update npm package daily to make continious feed
*/
const assert = require('assert');
const static_json_v1 = require('./json/data.json')
const https = require('https')
const http = require('http')
const apiserver = "https://fakefilter.net"
// const apiserver = "http://127.0.0.1:5520" -- local tests
const scheme = apiserver.search(/^https/) === 0 ? "https" : "http"
function hostnameFromEmailAddress(email) {
if (email && typeof email === 'string' && email.search(/@/) > 0)
return email.split(/@/)[1]
return null
}
function isFakeDomain(domain, json = false) {
if (!json) json = static_json_v1
for (let dom of Object.keys(json.domains)) {
// exact match
if (dom === domain.toLowerCase().trim()) return dom
// subdomain match
if (domain.search(new RegExp(`.+\\.${dom}`)) === 0) return dom
}
return false
}
function fetch(url, timeout = 5000, json = true) {
return new Promise(async function (resolve, reject) {
try {
let proto = apiserver.search(/^https/) === 0 ? https : http
let request = proto.get(url, (res) => {
if (res.statusCode !== 200) {
res.resume()
return reject('STATUSCODE')
}
let data = ''
res.on('data', (chunk) => { data += chunk })
res.on('close', () => {
if (json) {
try {
return resolve(JSON.parse(data))
} catch (err) {
return resolve(false)
}
}
return resolve(data)
})
})
request.setTimeout(timeout, () => {
request.destroy()
return reject('TIMEOUT')
})
request.end()
request.on('error', (err) => {
return reject(err)
})
} catch (err3) {
// errors like ERR_INVALID_PROTOCOL is thrown here
reject(err3)
}
})
}
function isFakeEmail(email, json = false) {
return isFakeDomain(hostnameFromEmailAddress(email), json)
}
function isFakeEmailOnline(email, timeout = 5000) {
return isFakeDomainOnline(hostnameFromEmailAddress(email), timeout)
}
function isFakeDomainOnline(domain, timeout = 5000) {
// we intentionally do not reject because we do not want to hold
// the process too long, null indicates error
return new Promise(async function (resolve, reject) {
try {
let answer = await fetch(`${apiserver}/api/is/fakedomain/${domain}`, timeout, true)
if (answer && answer.hasOwnProperty('retcode') && answer.retcode === 200)
return resolve(answer)
} catch (err) {
// error returns null
return resolve(null)
}
})
}
async function runTests() {
// fetch tests
// not existing domain
try {
await fetch(`${scheme}://nonexisting${Date.now()}.com`)
assert.equal(false, true) // we should never reach this position
} catch (err) {
assert.equal(err.code, 'ENOTFOUND')
}
// not existing url on existing domain
try {
await fetch(`${apiserver}/notexisting`)
assert.equal(false, true) // we should never reach this position
} catch (err) {
assert.equal(err, 'STATUSCODE')
}
// invalid protocoll
try {
await fetch(`htps://fakefilter.net/notexisting`)
assert.equal(false, true) // we should never reach this position
} catch (err) {
assert.equal(err.code, 'ERR_INVALID_PROTOCOL')
}
// invalid url
try {
await fetch(`://fakefilter.net/notexisting`)
assert.equal(false, true) // we should never reach this position
} catch (err) {
assert.equal(err.code, 'ERR_INVALID_URL')
}
// 404
try {
await fetch(`${apiserver}/api/is/fakedomain/`)
assert.equal(false, true) // we should never reach this position
} catch (err) {
assert.equal(err, 'STATUSCODE')
}
// non FakeDomain
assert.equal((await fetch(`${apiserver}/api/is/fakedomain/fakefilter.net`)).retcode, 200)
// FakeDomain
assert.equal((await fetch(`${apiserver}/api/is/fakedomain/fakefilte r.net`)).retcode, -50)
let json = static_json_v1
console.log(`Running tests`)
let all_domains = Object.keys(json.domains)
// all domains we know must be detected as FakeDomain
for (let domain of all_domains) {
// if (domain!=='www.barryogorman.com') continue
// console.log((domain),isFakeDomain(domain)===domain.toLowerCase())
// exact match
// console.log(`>> ${domain}`)
assert.notEqual(isFakeDomain(domain), false)
// subdomain match for example [email protected] should match if test.com is part of the filter
assert.notEqual(isFakeDomain(`sub.${domain}`), false)
assert.notEqual(isFakeDomain(`sub.sub.${domain}`), false)
assert.notEqual(isFakeDomain(`another.sub.sub.${domain}`), false)
// sub$hostname should not be detected as fakedomain - if we have test.com in the filter, subtest.com should not be detected as fake
if (domain.search(/^[^.]+\.[^.]+$/) == 0) {
assert.equal(isFakeEmail(`any@sub${domain}`), false)
assert.equal(isFakeDomain(`sub${domain}`), false)
}
assert.notEqual(isFakeEmail(`any@${domain}`), false)
assert.notEqual(isFakeEmail(`any@sub.${domain}`), false)
// RESTFul API query
assert.equal((await isFakeDomainOnline(domain)).isFakeDomain, domain)
assert.equal((await isFakeEmailOnline(`any@${domain}`)).isFakeDomain, domain)
assert.equal((await isFakeEmailOnline(`any@sub.${domain}`)).isFakeDomain, "sub." + domain)
}
console.log(`OK`)
process.exit(0)
}
// basic tests
if (require.main == module) runTests()
module.exports = {
// offline version
isFakeDomain,
isFakeEmail,
// online version
isFakeDomainOnline,
isFakeEmailOnline
}