fakefilter 1.1.10 → 1.1.12

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.
Files changed (67) hide show
  1. package/apiserver/inc/shared.js +3 -1
  2. package/apiserver/inc/worker_fakefilter.js +3 -3
  3. package/apiserver/public/img/test.html +48 -0
  4. package/chart-update.js +156 -74
  5. package/config.js +2 -2
  6. package/demos/visitor0/index.js +41 -0
  7. package/demos/visitor0/renderedDOM.html +8 -0
  8. package/elements/demo.js +78 -0
  9. package/elements/renderedDOM.html +6459 -0
  10. package/elements/screenshots/afterclick.png +0 -0
  11. package/elements/screenshots/goto.png +0 -0
  12. package/fetch.js +4 -1
  13. package/package.json +6 -3
  14. package/providers/10-minute-mail.com.js +2 -1
  15. package/providers/10-minuten-mail.de.js +2 -1
  16. package/providers/10mails.net.js +2 -1
  17. package/providers/10minut.com.pl.js +2 -1
  18. package/providers/10minutemail.co.za.js +2 -1
  19. package/providers/10minutesemail.net.js +2 -2
  20. package/providers/10minutesmail.us.js +2 -1
  21. package/providers/22.do.js +25 -0
  22. package/providers/abandonmail.com.js +2 -1
  23. package/providers/akmail.in.js +3 -3
  24. package/providers/altaddress.org.js +50 -0
  25. package/providers/anonymmail.net.js +47 -0
  26. package/providers/awgarstone.com.js +15 -0
  27. package/providers/brodilla.email.js +3 -2
  28. package/providers/chacuo.net.js +38 -0
  29. package/providers/dispemail.com.js +3 -2
  30. package/providers/disposableemail.us.js +2 -1
  31. package/providers/dispostable.com.js +2 -1
  32. package/providers/emailnator.com.js +37 -0
  33. package/providers/etempmail.com.js +36 -0
  34. package/providers/fakemail.io.js +2 -1
  35. package/providers/faxmail.co.js +47 -0
  36. package/providers/findtempmail.com.js +3 -2
  37. package/providers/foxiomail.com.js +3 -2
  38. package/providers/getnada.cc.js +37 -0
  39. package/providers/gmailcity.com.js +37 -0
  40. package/providers/hottempmail.com.js +3 -2
  41. package/providers/instantemailaddress.com.js +3 -2
  42. package/providers/internxt.com.js +47 -0
  43. package/providers/jooko.info.js +2 -1
  44. package/providers/kopeechka.store.js +0 -10
  45. package/providers/kuku.lu.js +37 -0
  46. package/providers/linshiyou.com.js +25 -0
  47. package/providers/linshiyouxiang.net.js +36 -0
  48. package/providers/mail.td.js +13 -13
  49. package/providers/mail.tm.js +1 -1
  50. package/providers/mail1.js +44 -0
  51. package/providers/mail4qa.com.js +37 -0
  52. package/providers/muellmail.com.js +7 -8
  53. package/providers/snapmail.cc.js +42 -0
  54. package/providers/static.js +32 -0
  55. package/providers/temp-inbox.me.js +47 -0
  56. package/providers/temp-mail.org.2.js +60 -0
  57. package/providers/temp-mail.org.js +36 -0
  58. package/providers/temp-mailbox.com.js +35 -0
  59. package/providers/tempmail.adguard.com.js +31 -0
  60. package/providers/tempmail.io.js +38 -0
  61. package/providers/tempmail.quest.js +45 -0
  62. package/providers/temporary-email.org.js +36 -0
  63. package/providers/tuamaeaquelaursa.com.js +25 -0
  64. package/providers/youxiang.dev.js +25 -0
  65. package/repo-update.js +26 -13
  66. package/shared.js +225 -48
  67. package/update-repo.sh +6 -19
@@ -0,0 +1,36 @@
1
+
2
+ const { Sentry } = require('../config')
3
+ const { initiateEmpty, launch, emailBy_id_innerText, emailBy_querySelector_innerHTML, emailBy_id_value } = require('../shared')
4
+ const vars = require('./../vars')
5
+ const URL = 'https://temporary-email.org'
6
+
7
+ function start(headless=true,waitTime=3) {
8
+ return new Promise(async function (resolve,reject) {
9
+ try {
10
+ let {page,browser} = await launch(headless,URL,waitTime)
11
+ let email = await emailBy_id_value(page,'trsh_mail')
12
+ if (browser) await browser.close()
13
+ if (email) return resolve({
14
+ email,
15
+ URL,
16
+ t:Date.now()
17
+ })
18
+ return resolve(null)
19
+ } catch (err) {
20
+ console.log(err)
21
+ Sentry.captureException(err)
22
+ resolve(false)
23
+ }
24
+ })
25
+ }
26
+
27
+ // for cli usage - development
28
+ if (require.main==module) {
29
+ start(false).then(res=>console.log(res))
30
+ }
31
+
32
+ vars.providers.push({
33
+ name:'temporary-email.org',
34
+ init:initiateEmpty,
35
+ start:start
36
+ })
@@ -0,0 +1,25 @@
1
+ const { findByIdValue, initiateEmpty } = require('../shared')
2
+ const vars = require('./../vars')
3
+ const URL = 'https://tuamaeaquelaursa.com/'
4
+
5
+ function start(headless = true, waitTime = 3) {
6
+ return new Promise(async function (resolve, reject) {
7
+ return resolve({
8
+ email: [`any@tuamaeaquelaursa.com`],
9
+ URL,
10
+ t: Date.now()
11
+ })
12
+ })
13
+ }
14
+
15
+
16
+ // for cli usage - development
17
+ if (require.main == module) {
18
+ start(false).then(res => console.log(res))
19
+ }
20
+
21
+ vars.providers.push({
22
+ name: 'tuamaeaquelaursa.com',
23
+ init: initiateEmpty,
24
+ start: start
25
+ })
@@ -0,0 +1,25 @@
1
+ const { findByIdValue, initiateEmpty } = require('../shared')
2
+ const vars = require('./../vars')
3
+ const URL = 'https://youxiang.dev/'
4
+
5
+ function start(headless = true, waitTime = 3) {
6
+ return new Promise(async function (resolve, reject) {
7
+ return resolve({
8
+ email: [`any@youxiang.dev`],
9
+ URL,
10
+ t: Date.now()
11
+ })
12
+ })
13
+ }
14
+
15
+
16
+ // for cli usage - development
17
+ if (require.main == module) {
18
+ start(false).then(res => console.log(res))
19
+ }
20
+
21
+ vars.providers.push({
22
+ name: 'youxiang.dev',
23
+ init: initiateEmpty,
24
+ start: start
25
+ })
package/repo-update.js CHANGED
@@ -49,11 +49,13 @@ async function start() {
49
49
  try {
50
50
  await getConfig()
51
51
 
52
+ // we only pull domains harvested last 365 days, so domains
53
+ let rows = await pullDomains(isLocal() ? 10 : 600, logger)
54
+ let [ combined,expiredDomains ] = await combineDomains(rows, true, 365)
52
55
 
53
- let rows = await pullDomains(isLocal() ? 10 : 1000, logger)
54
- let combined = await combineDomains(rows, true)
55
- let json2domains = perDomain(combined)
56
+ let json2domains = perDomain(combined,true)
56
57
  let markdown = `# Providers\n\n`
58
+ let markdownExpired = `# Providers Expired Domains\nOur service removes domains from fakefilter after a year of inactivity. If these domains reappear, they are reinstated in our database for a minimum of 365 days.\n\n`
57
59
  let now = Math.round(Date.now() / 1000)
58
60
  let json = {
59
61
  version: 1,
@@ -69,39 +71,50 @@ async function start() {
69
71
  let updated = `Last Update: ${new Date().toISOString()}`
70
72
  let txt = `# Fake and Temp Mail Providers\n# https://github.com/7c/fakefilter\n# ${updated}\n\n\n`
71
73
 
74
+ // generate json v1 & markdown
72
75
  for (let provider of Object.keys(combined)) {
73
76
  let domains = combined[provider]
74
- var t = new Table()
77
+ // var t = new Table()
75
78
  console.log(chalk.bold.yellow(provider))
76
79
  markdown += `## ${provider}\n`
80
+ markdownExpired += `## ${provider}\n`
77
81
  txt += `## ${provider}\n`
78
82
 
79
83
  for (let domain of Object.keys(domains)) {
80
84
  let data = domains[domain]
81
85
  domain = domain.toLowerCase()
86
+ let lastSeenAgo = Math.floor((now - data.lastseen)/60/60/24) // days
82
87
 
83
88
  for (let host of Object.keys(data.hosts)) {
84
89
  // json v1 format - which is host based format
85
- json.domains[host] = {
86
- provider,
87
- firstseen: data.hosts[host].firstseen,
88
- lastseen: data.hosts[host].lastseen,
90
+ if (!data.expired) {
91
+ json.domains[host] = {
92
+ provider,
93
+ firstseen: data.hosts[host].firstseen,
94
+ lastseen: data.hosts[host].lastseen,
95
+ }
96
+ markdown += `- ${host} (lastseen ${lastSeenAgo} days ago)\n`
97
+ txt += `${host}\n`
98
+ } else {
99
+ markdownExpired += `- ${host} (expired ${lastSeenAgo} days ago)\n`
89
100
  }
90
- t.cell('domain', host)
91
- markdown += `- ${host}\n`
92
- txt += `${host}\n`
93
- t.newRow()
101
+
102
+
103
+ // t.newRow()
94
104
  }
95
105
  }
96
106
  markdown += `\n`
107
+ markdownExpired += `\n`
97
108
  txt += `\n`
98
109
  // console.log(t.toString())
99
110
  }
100
111
  markdown += `\n\n${updated}\n`
101
112
  // deploy to file
102
113
  if (!argv.dry) {
103
- // markdown
114
+ // markdown not expired
104
115
  writeToFile(path.join(__dirname, 'repo/markdown/README.md'), markdown)
116
+ // markdown expired
117
+ writeToFile(path.join(__dirname, 'repo/markdown/EXPIRED.md'),markdownExpired)
105
118
  // json v1
106
119
  writeToFile(path.join(__dirname, 'repo/json/data.json'), JSON.stringify(json))
107
120
  // json v2
package/shared.js CHANGED
@@ -1,3 +1,4 @@
1
+ const debug = require('debug')('_shared')
1
2
  const punycode = require('punycode/')
2
3
  const { Op } = require("sequelize")
3
4
  const { parseDomain, ParseResultType } = require("parse-domain")
@@ -5,7 +6,7 @@ const argv = require('minimist')(process.argv.slice(2))
5
6
  const chalk = require('chalk')
6
7
  var dns = require('dns')
7
8
  const vars = require('./vars')
8
- const { wait, validEmail } = require('mybase');
9
+ const { wait, validEmail, isLocal, utcnow } = require('mybase');
9
10
  const puppeteer = require('puppeteer-extra')
10
11
  const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha')
11
12
  var { randomUseragent, UseragentByFamily } = require('useragentsdata');
@@ -52,7 +53,8 @@ const promiseTimeout = function (ms, promise) {
52
53
  ])
53
54
  }
54
55
 
55
- function launch(headless, url, waitTime = 3, CLICK_SELECTOR = false, captchaPlugin = false, waitUntil = 'load') {
56
+ function launch(headless, url, waitTime = 3, CLICK_SELECTOR = false, captchaPlugin = false, waitUntil = 'load', socks5 = '') {
57
+ debug(`launching ${url}`)
56
58
  return new Promise(async function (resolve, reject) {
57
59
  try {
58
60
  if (captchaPlugin) puppeteer.use(
@@ -65,8 +67,18 @@ function launch(headless, url, waitTime = 3, CLICK_SELECTOR = false, captchaPlug
65
67
  })
66
68
  )
67
69
  puppeteer.use(StealthPlugin())
70
+ debug(`launching browser`)
71
+
72
+ const args = ['--no-sandbox']
73
+ if (argv.socks5 || socks5 !== '') {
74
+ argv.socks5 = argv.socks5 || socks5
75
+ debug(`using socks5 proxy ${argv.socks5}`)
76
+ args.push(`--proxy-server=socks5://${argv.socks5}`)
77
+ }
78
+
68
79
  const browser = await puppeteer.launch({
69
- args: ['--no-sandbox'],
80
+ args,
81
+ devtools: isLocal(), // This line opens the DevTools
70
82
  // args: [
71
83
  // // '--disable-features=IsolateOrigins,site-per-process',
72
84
  // // '--flag-switches-begin --disable-site-isolation-trials --flag-switches-end',
@@ -77,14 +89,23 @@ function launch(headless, url, waitTime = 3, CLICK_SELECTOR = false, captchaPlug
77
89
  headless: headless ? true : false
78
90
  })
79
91
  vars.browsers.push(browser)
92
+ debug(`opening new page`)
80
93
  const page = await browser.newPage()
94
+ debug(`setting useragent`)
81
95
  await page.setUserAgent(UA)
96
+ debug(`going to ${url} waituntil: ${waitUntil}`)
82
97
  await page.goto(url, { waitUntil });
83
- if (argv.ss) await page.screenshot({ path: 'screenshots/goto.png', fullPage: true })
84
98
 
99
+ if (argv.ss) {
100
+ debug(`taking screenshot as goto.png`)
101
+ await page.screenshot({ path: 'screenshots/goto.png', fullPage: true })
102
+ }
103
+
104
+ debug(`waiting ${waitTime} seconds`)
85
105
  await wait(waitTime)
106
+ debug(`waiting ended`)
86
107
  if (CLICK_SELECTOR) {
87
-
108
+ debug(`clicking ${CLICK_SELECTOR}`)
88
109
  // await page.waitForNavigation()
89
110
  try {
90
111
  // we use puppeeter click function
@@ -103,8 +124,13 @@ function launch(headless, url, waitTime = 3, CLICK_SELECTOR = false, captchaPlug
103
124
 
104
125
  // await page.waitForNavigation()
105
126
  await wait(waitTime)
106
- if (argv.ss) await page.screenshot({ path: 'screenshots/afterclick.png', fullPage: true })
127
+
128
+ }
129
+ if (argv.ss) {
130
+ debug(`taking screenshot as afterclick.png`)
131
+ await page.screenshot({ path: 'screenshots/afterclick.png', fullPage: true })
107
132
  }
133
+ debug(`finished launching`)
108
134
  return resolve({ page, browser })
109
135
  } catch (err) {
110
136
  console.log(err)
@@ -126,6 +152,7 @@ function resolveMx(host) {
126
152
 
127
153
 
128
154
  async function emailBy_querySelector_innerText(page, Selector, raw = false) {
155
+ debug(`emailBy_querySelector_innerText '${Selector}'`)
129
156
  if (!page) return false
130
157
  let got = await page.evaluate((Selector) => {
131
158
  let response = []
@@ -133,6 +160,7 @@ async function emailBy_querySelector_innerText(page, Selector, raw = false) {
133
160
  response.push(item.innerText)
134
161
  return response
135
162
  }, Selector)
163
+ debug(`got ${got}`)
136
164
  // await page.screenshot({path: 'screenshots/after.png', fullPage: true})
137
165
  if (raw) return got
138
166
  // console.log(got)
@@ -141,7 +169,21 @@ async function emailBy_querySelector_innerText(page, Selector, raw = false) {
141
169
  return false
142
170
  }
143
171
 
172
+ async function clickto_element_withText(page, element, text) {
173
+ debug(`clickto_element_withText ${element} ${text}`)
174
+ if (argv.ss) await page.screenshot({ path: 'screenshots/clickto_element_withText.png', fullPage: true })
175
+ const got = await page.evaluate((element, text) => {
176
+ const spanElement = Array.from(document.querySelectorAll(element))
177
+ .find(span => span.textContent.trim() === text);
178
+
179
+ if (spanElement) spanElement.click()
180
+ return spanElement
181
+ }, element, text)
182
+ debug(`clickto_element_withText ${got}`)
183
+ }
184
+
144
185
  async function emailBy_querySelector_innerHTML(page, Selector, raw = false) {
186
+ debug(`emailBy_querySelector_innerHTML '${Selector}'`)
145
187
  if (!page) return false
146
188
  let got = await page.evaluate((Selector) => {
147
189
  let response = []
@@ -173,6 +215,7 @@ async function emailBy_querySelector_placeholder(page, Selector, raw = false) {
173
215
  }
174
216
 
175
217
  async function emailBy_querySelector_value(page, Selector, raw = false) {
218
+ debug(`emailBy_querySelector_value '${Selector}'`)
176
219
  if (!page) return false
177
220
  let got = await page.evaluate((Selector) => {
178
221
  let response = []
@@ -180,22 +223,58 @@ async function emailBy_querySelector_value(page, Selector, raw = false) {
180
223
  response.push(item.value)
181
224
  return response
182
225
  }, Selector)
226
+ debug(`got '${got}'`)
183
227
  if (raw) return got
184
228
  for (let item of got)
185
- if (validEmail(item.trim())) return item.toLowerCase().trim()
229
+ if (item && validEmail(item.trim())) return item.toLowerCase().trim()
186
230
  return false
187
231
  }
188
232
 
189
233
  async function emailBy_id_value(page, tagId) {
190
- if (!page) return false
234
+ debug(`emailBy_id_value ${tagId} ${page}`)
235
+ if (!page) {
236
+ debug(`no page found`)
237
+ return false
238
+ }
239
+ debug(`page.evaluate '${tagId}'`)
191
240
  let got = await page.evaluate((tagId) => {
192
- return document.getElementById(tagId).value
241
+ return document.getElementById(tagId)?.value
193
242
  }, tagId)
194
-
195
- if (validEmail(got.trim())) return got.toLowerCase().trim()
243
+ debug(`got ${got}`)
244
+ if (validEmail(got?.trim())) return got.toLowerCase().trim()
196
245
  return false
197
246
  }
198
247
 
248
+ async function email_recursive_search(page, selector) {
249
+ if (!page) return false
250
+ let emails = await page.evaluate((selector) => {
251
+ function findAllEmails(element, regex, emails = []) {
252
+ // Check the current element
253
+ if (regex.test(element.innerText)) {
254
+ if (!emails.includes(element.innerText)) emails.push(element.innerText);
255
+ }
256
+
257
+ // Recursively search in each child
258
+ for (let child of element.children) {
259
+ findAllEmails(child, regex, emails);
260
+ }
261
+
262
+ return emails;
263
+ }
264
+
265
+ let emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
266
+ // https://stackoverflow.com/questions/46155/how-can-i-validate-an-email-address-in-javascript
267
+ let emails = []
268
+ for (let item of document.querySelectorAll(selector)) {
269
+ findAllEmails(item, emailRegex, emails);
270
+ }
271
+ return emails
272
+ }, selector)
273
+ emails = emails.filter(e => validEmail(e))
274
+ return emails
275
+ }
276
+
277
+
199
278
  async function emailBy_id_innerText(page, tagId, raw = false) {
200
279
  if (!page) return false
201
280
  let got = await page.evaluate((tagId) => {
@@ -241,7 +320,8 @@ function findByIdValue(headless, url, tagId, waitTime = 3) {
241
320
  })
242
321
  }
243
322
 
244
- function emailFrom_combobox_selector(page, Selector, replaceRX = false) {
323
+ function emailFrom_combobox_selector(page, Selector, replaceRX = false, raw = false) {
324
+ debug(`emailFrom_combobox_selector ${Selector}`)
245
325
  return new Promise(async function (resolve, reject) {
246
326
  if (!page) return resolve(false)
247
327
  let got = await page.evaluate((Selector) => {
@@ -249,12 +329,15 @@ function emailFrom_combobox_selector(page, Selector, replaceRX = false) {
249
329
  // console.log(`>>`,Selector)
250
330
  // console.log(document.querySelectorAll(Selector))
251
331
  for (let option of document.querySelectorAll(Selector)[0].children) {
252
- console.log(`option`, option)
253
332
  let txt = option.innerText.toLowerCase().trim()
254
- response.push(`any@` + txt)
333
+ if (txt.search(/^@/) == 0) response.push(`any` + txt); else
334
+ response.push(`any@` + txt)
335
+ console.log(`option`, option, response)
255
336
  }
256
337
  return response
257
338
  }, Selector)
339
+ debug(`got ${got}`)
340
+ // if (raw) return got
258
341
  let email = []
259
342
  for (let item of got) {
260
343
  if (replaceRX) item = item.replace(replaceRX, '').toLowerCase().trim()
@@ -386,90 +469,180 @@ function getProviderDetails(name) {
386
469
  return null
387
470
  }
388
471
 
389
- function combineDomains(rows,obfuscateTime=true) {
472
+ function combineDomains(rows, obfuscateTime = true, expiration_days = 2 * 365) {
473
+ let profile = {
474
+ punycode: 0,
475
+ domainparse: 0,
476
+ progressbar: 0,
477
+ whitelistcheck: 0,
478
+ emailvalidation: 0,
479
+ total: 0
480
+ }
481
+ let domainparse_cache = {
482
+
483
+ }
390
484
  return new Promise(async function (resolve, reject) {
391
485
  let result = {} // provider/domain
392
486
  const progress = require('progressbar').create().step('combining')
393
487
  progress.setTotal(rows.length)
488
+ const started = Date.now()
489
+ let cnt = 0
394
490
  for (let row of rows) {
491
+ // if (row.domain!=='maitrimony.com') continue
492
+ cnt++
493
+
494
+
395
495
  // detect IDN domains
496
+ let time0 = Date.now()
396
497
  let pc = punycode.toASCII(row.domain)
397
- if (pc!==row.domain) {
498
+ if (pc !== row.domain) {
398
499
  console.log(`IDN Domain found: ${row.domain} provider: ${row.provider}`)
399
500
  row.unicodeDomain = row.domain
400
501
  row.domain = pc
401
502
  }
503
+ profile.punycode += Date.now() - time0
402
504
 
403
- await wait(1 / 1000)
404
- progress.addTick()
505
+ time0 = Date.now()
506
+ if (Math.random() * 500 < 1) {
507
+ await wait(1 / 10000)
508
+ progress.setTick(cnt)
509
+ // if (cnt>100000) break
510
+ }
511
+ profile.progressbar += Date.now() - time0
512
+
513
+
514
+ // parse domains with psl
515
+ time0 = Date.now()
405
516
  let hostname = row.domain.toLowerCase()
517
+ let domainparse
406
518
  // parse domains with psl
407
- let domainparse = psl.parse(hostname)
408
- if (!domainparse) {
409
- console.log(`Not parseable hostname : ${hostname} - detected id: ${row.id} - provider: ${row.provider}`)
519
+ if (domainparse_cache.hasOwnProperty(hostname)) {
520
+ domainparse = domainparse_cache[hostname]
521
+ } else {
522
+ domainparse = psl.parse(hostname)
523
+ }
524
+
525
+ if (!domainparse || !domainparse?.domain) {
526
+ console.log(`Not parseable hostname : ${hostname} - detected id: ${row.id} - provider: ${row.provider} - ${chalk.red('deleting')}`)
527
+ try { await vars.models.Harvested.destroy({ where: { id: row.id } }) } catch (_) { } // DELETE
410
528
  continue
411
529
  }
530
+ domainparse_cache[hostname] = domainparse
531
+
532
+
533
+
412
534
  // lets take the domain of the hostname
413
535
  let domain = domainparse.domain
414
- let domain_pc = punycode.toASCII(domain)
536
+ // let domain_pc = punycode.toASCII(domain)
537
+ profile.domainparse += Date.now() - time0
415
538
 
416
539
  // not listed tld found, not listed tlds are made up ones
417
540
  if (!domainparse.listed) {
418
541
  console.log(`Not listed TLD: ${domain} - detected id: ${row.id} - provider: ${row.provider} `)
419
542
  // what to do with those
420
543
  }
544
+
545
+
546
+
421
547
  // ignore whitelisted domains
548
+ time0 = Date.now()
422
549
  if (vars.config.ignore_domains.includes(domain)) {
423
550
  try { await vars.models.Harvested.destroy({ where: { id: row.id } }) } catch (_) { } // DELETE
424
551
  console.log(chalk.red(`Ignoring whitelisted domain:${domain} at row: ${row.id} provider:${row.provider} - DELETED`))
425
552
  continue
426
553
  }
554
+ profile.whitelistcheck += Date.now() - time0
555
+
427
556
 
428
557
  // make sure email address is valid by validator library
558
+ time0 = Date.now()
429
559
  if (!isEmail(`any@${domain}`)) {
430
560
  try { await vars.models.Harvested.destroy({ where: { id: row.id } }) } catch (_) { } // DELETE
431
561
  console.log(`Invalid domain: ${domain} - detected id: ${row.id} - DELETED`)
432
562
  continue
433
563
  }
564
+ profile.emailvalidation += Date.now() - time0
434
565
 
435
566
  // create the provider
436
567
  if (!result.hasOwnProperty(row.provider)) result[row.provider] = {}
437
-
568
+
438
569
  // create the domain inside provider
439
570
  if (!result[row.provider].hasOwnProperty(domain))
440
571
  result[row.provider][domain] = {
441
- hosts:{[hostname]:{
442
- firstseen: 5645821813648,
443
- lastseen: 0,
444
- }}
445
- }
446
- else {
447
- if (!result[row.provider][domain].hosts.hasOwnProperty(hostname))
448
- result[row.provider][domain].hosts[hostname]={
572
+ // domain level firstseen & lastseen
573
+ firstseen: 5645821813648,
574
+ lastseen: 0,
575
+
576
+ hosts: {
577
+ [hostname]: {
449
578
  firstseen: 5645821813648,
450
579
  lastseen: 0,
451
580
  }
581
+ }
452
582
  }
583
+ else {
584
+ if (!result[row.provider][domain].hosts.hasOwnProperty(hostname))
585
+ result[row.provider][domain].hosts[hostname] = {
586
+ firstseen: 5645821813648,
587
+ lastseen: 0,
588
+ }
589
+ }
590
+
591
+ if (row.unicodeDomain)
592
+ result[row.provider][domain].unicodeDomain = punycode.toUnicode(domain)
453
593
 
454
- if (row.unicodeDomain)
455
- result[row.provider][domain].unicodeDomain = punycode.toUnicode(domain)
456
-
457
- // result[row.provider][domain].isSubdomain = domainparse.domain !== hostname ? true : false
458
- // if (result[row.provider][domain].isSubdomain) {
459
- // result[row.provider][domain].domain = domainparse.domain
460
- // result[row.provider][domain].tld = domainparse.tld
461
- // // console.log(`provider: ${row.provider} hostname:${hostname} - domain:${domainparse.domain}`)
462
- // }
463
-
464
- // let providerDetails = getProviderDetails(row.provider)
465
- // if (providerDetails && providerDetails.randomSubdomain === true) result[row.provider][domain].randomSubdomain = true
466
594
  let t = obfuscateTime ? obfuscatedTime(row.t) : row.t
467
- // firstseen of host
595
+
596
+ // firstseen of domain
597
+ if (t < result[row.provider][domain].firstseen) result[row.provider][domain].firstseen = t
598
+ // lastseen update of domain
599
+ if (t > result[row.provider][domain].lastseen) result[row.provider][domain].lastseen = t
600
+
601
+ // firstseen of hostname
468
602
  if (t < result[row.provider][domain].hosts[hostname].firstseen) result[row.provider][domain].hosts[hostname].firstseen = t
469
- // lastseen
603
+
604
+ // lastseen update of hostname
470
605
  if (t > result[row.provider][domain].hosts[hostname].lastseen) result[row.provider][domain].hosts[hostname].lastseen = t
471
606
  }
472
- return resolve(result)
607
+ profile.total = Date.now() - started
608
+ console.log(profile)
609
+
610
+ // routine to detect and remove expired domains from the results
611
+ // based on lastseen property
612
+ let expiredDomains = {
613
+
614
+ }
615
+ if (expiration_days > 0) {
616
+ for (let provider of Object.keys(result)) {
617
+ let inner = result[provider]
618
+ for (let domain of Object.keys(inner)) {
619
+ let inner2 = inner[domain]
620
+ if (!inner2?.lastseen || !inner2?.firstseen) {
621
+ console.log(chalk.red(`📌 domain without lastseen or firstseen: ${domain} - provider: ${provider}`))
622
+ continue
623
+ }
624
+ // we check domain level expiration
625
+ // for now expiration implementation rudimentary
626
+ let lastseenDaysAgo = Math.round((utcnow() - inner2.lastseen) / 60 / 60 / 24)
627
+ if (lastseenDaysAgo > expiration_days) {
628
+ if (!expiredDomains.hasOwnProperty(domain)) expiredDomains[domain] = {}
629
+ if (!expiredDomains[domain].hasOwnProperty(provider)) expiredDomains[domain][provider] = {
630
+ firstseen: inner2.firstseen,
631
+ lastseen: inner2.lastseen,
632
+ }
633
+ result[provider][domain].expired = true
634
+
635
+ // console.log(`expired domain: ${chalk.yellow(domain)} @ ${chalk.blue(provider)} - firstseen: ${new Date(inner2.firstseen * 1000).toISOString()} - lastseen: ${new Date(inner2.lastseen * 1000).toISOString()} (${lastseenDaysAgo} days ago)`)
636
+ }
637
+
638
+ }
639
+ }
640
+ }
641
+
642
+ progress.finish()
643
+ console.log(`✅ finished ${rows.length} rows, took ${(Math.floor(Date.now() - started) / 1000)} seconds`)
644
+ console.log(`✅ expired domains: ${Object.keys(expiredDomains).length}`)
645
+ return resolve([result, expiredDomains])
473
646
  })
474
647
  }
475
648
 
@@ -532,11 +705,13 @@ module.exports = {
532
705
 
533
706
 
534
707
  emailBy_id_innerText,
708
+ emailBy_id_value,
709
+
535
710
  emailBy_querySelector_innerHTML,
536
711
  emailBy_querySelector_innerText,
537
712
  emailBy_querySelector_placeholder,
538
713
  emailBy_querySelector_value,
539
- emailBy_id_value,
714
+
540
715
 
541
716
  emailFrom_combobox_id,
542
717
  emailFrom_combobox_selector,
@@ -555,5 +730,7 @@ module.exports = {
555
730
  obfuscatedTime,
556
731
  domainFromEmail,
557
732
  eventsOfProvider,
558
- is_domain_banned
733
+ is_domain_banned,
734
+ email_recursive_search,
735
+ clickto_element_withText
559
736
  }
package/update-repo.sh CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/bin/bash
2
+ source /opt/coadmin-peer/inc/shared.sh
2
3
  optstring=":v"
3
4
  verbose=
4
5
  while getopts ${optstring} arg; do
@@ -7,25 +8,11 @@ while getopts ${optstring} arg; do
7
8
  esac
8
9
  done
9
10
 
10
- report_test_ok() {
11
- local id="$1"
12
- local details="$2"
13
- test -z $2 && details="-"
14
- test -e /opt/coadmin-peer/tools/report_test.js && {
15
- test -z $verbose || echo "✅ $id"
16
- node /opt/coadmin-peer/tools/report_test.js --project 'fakefilter' --group 'update-repo.sh' --id "$id" --result "ok" --details "$details"
17
- }
18
- }
11
+ pkill -f repo-update.js
12
+ pkill -f chart-update.js
13
+ pkill -f repo-update.js
14
+ pkill -f chart-update.js
19
15
 
20
- report_test_error() {
21
- local id="$1"
22
- local details="$2"
23
- test -z $2 && details="-"
24
- test -e /opt/coadmin-peer/tools/report_test.js && {
25
- test -z $verbose || echo "❌ $id"
26
- node /opt/coadmin-peer/tools/report_test.js --project 'fakefilter' --group 'update-repo.sh' --id "$id" --result "error" --details "$details"
27
- }
28
- }
29
16
 
30
17
  cd /opt/fakefilter && {
31
18
  node chart-update.js
@@ -33,7 +20,7 @@ cd /opt/fakefilter && {
33
20
  if cd repo/; then
34
21
  # git add assets/img/*.png
35
22
  report_test_ok "repo folder exists"
36
- if ./release.sh 'auto update' && npm publish; then
23
+ if ./release.sh 'auto update'; then
37
24
  report_test_ok "npm published"
38
25
  else
39
26
  report_test_error "npm published"