fakefilter 0.1.650 → 1.1.10
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 +16 -64
- package/apiserver/api/ext_result.js +51 -0
- package/apiserver/api/ext_tasks.js +151 -0
- package/apiserver/api/is_fakedomain.js +39 -0
- package/apiserver/api/is_fakeemail.js +17 -0
- package/apiserver/api/ping.js +12 -0
- package/apiserver/docs/README.md +41 -0
- package/apiserver/docs/babel.config.js +3 -0
- package/apiserver/docs/blog/2019-05-28-first-blog-post.md +12 -0
- package/apiserver/docs/blog/2019-05-29-long-blog-post.md +44 -0
- package/apiserver/docs/blog/2021-08-01-mdx-blog-post.mdx +20 -0
- package/apiserver/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
- package/apiserver/docs/blog/2021-08-26-welcome/index.md +25 -0
- package/apiserver/docs/blog/authors.yml +17 -0
- package/apiserver/docs/docs/intro.md +16 -0
- package/apiserver/docs/docs/nodejs/_category_.json +4 -0
- package/apiserver/docs/docs/nodejs/index.md +30 -0
- package/apiserver/docs/docs/restful/_category_.json +4 -0
- package/apiserver/docs/docs/restful/index.md +59 -0
- package/apiserver/docs/docusaurus.config.js +118 -0
- package/apiserver/docs/package.json +37 -0
- package/apiserver/docs/sidebars.js +31 -0
- package/apiserver/docs/src/components/HomepageFeatures/index.js +64 -0
- package/apiserver/docs/src/components/HomepageFeatures/styles.module.css +11 -0
- package/apiserver/docs/src/css/custom.css +39 -0
- package/apiserver/docs/src/pages/index.js +45 -0
- package/apiserver/docs/src/pages/index.module.css +23 -0
- package/apiserver/docs/src/pages/markdown-page.md +7 -0
- package/apiserver/docs/src/theme/IconArrow/index.js +10 -0
- package/apiserver/docs/static/.nojekyll +0 -0
- package/apiserver/docs/static/img/docusaurus.png +0 -0
- package/apiserver/docs/static/img/favicon.ico +0 -0
- package/apiserver/docs/static/img/logo.svg +1 -0
- package/apiserver/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
- package/apiserver/docs/static/img/tutorial/localeDropdown.png +0 -0
- package/apiserver/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/apiserver/docs/static/img/undraw_docusaurus_react.svg +170 -0
- package/apiserver/docs/static/img/undraw_docusaurus_tree.svg +40 -0
- package/apiserver/inc/middleware_client.js +37 -0
- package/apiserver/inc/middleware_logging.js +17 -0
- package/apiserver/inc/shared.js +45 -0
- package/apiserver/inc/worker_fakefilter.js +53 -0
- package/apiserver/index.js +62 -0
- package/apiserver/public/10minemail.com.js +27 -0
- package/apiserver/public/10minuteemails.com.js +46 -0
- package/apiserver/public/10minutemail.com.js +29 -0
- package/apiserver/public/crazymailing.com.js +27 -0
- package/apiserver/public/gettempmail.com.js +39 -0
- package/apiserver/public/img/dynamic/README.md +0 -0
- package/apiserver/public/onetempmail.com.js +35 -0
- package/apiserver/public/shared.js +54 -0
- package/apiserver/public/temp-mail.org.js +28 -0
- package/apiserver/public/tempmail.com.tr.js +36 -0
- package/apiserver/public/tempmail.net.js +28 -0
- package/apiserver/public/tempmailid.com.js +40 -0
- package/apiserver/public/tempmailo.org.js +36 -0
- package/apiserver/public/throwawaymail.com.js +27 -0
- package/burner/README.md +1 -0
- package/burner/burner-check.js +57 -0
- package/burner/emails.txt +57106 -0
- package/chart-update.js +179 -0
- package/cleanup.js +58 -0
- package/config.js +126 -0
- package/events.js +59 -0
- package/fetch.js +177 -0
- package/models/events.js +37 -0
- package/models/harvested.js +45 -0
- package/models/harvested_clone.js +44 -0
- package/package.json +41 -23
- package/providers/10-minute-mail.com.js +38 -0
- package/providers/10-minuten-mail.de.js +38 -0
- package/providers/10mails.net.js +40 -0
- package/providers/10minut.com.pl.js +38 -0
- package/providers/10minut.xyz.js +40 -0
- package/providers/10minuteemails.com.js +39 -0
- package/providers/10minutemail.co.za.js +38 -0
- package/providers/10minutemail.com.js +39 -0
- package/providers/10minutemail.info.js +38 -0
- package/providers/10minutemail.net.js +38 -0
- package/providers/10minutemail.org.js +38 -0
- package/providers/10minutesemail.net.js +36 -0
- package/providers/10minutesmail.us.js +38 -0
- package/providers/1secmail.com.js +39 -0
- package/providers/20minutemail.com.js +36 -0
- package/providers/24hour.email.js +37 -0
- package/providers/___emailondeck.com.js +76 -0
- package/providers/abandonmail.com.js +38 -0
- package/providers/airmailbox.website.js +38 -0
- package/providers/akmail.in.js +37 -0
- package/providers/altmails.com.js +37 -0
- package/providers/anonbox.net.js +42 -0
- package/providers/anonmails.de.js +25 -0
- package/providers/another-temp-mail.com.js +40 -0
- package/providers/brodilla.email.js +44 -0
- package/providers/byom.de.js +42 -0
- package/providers/cryptogmail.com.js +40 -0
- package/providers/default.tmail.thehp.in.js +41 -0
- package/providers/developermail.com.js +39 -0
- package/providers/dispemail.com.js +37 -0
- package/providers/disposableemail.co.js +37 -0
- package/providers/disposableemail.us.js +36 -0
- package/providers/disposablemail.com.js +38 -0
- package/providers/disposeamail.com.js +43 -0
- package/providers/dispostable.com.js +38 -0
- package/providers/dodsi.com.js +38 -0
- package/providers/dropmail.me.js +37 -0
- package/providers/easytrashmail.com.js +33 -0
- package/providers/edumail.icu.js +36 -0
- package/providers/email-fake.com.js +35 -0
- package/providers/emailfake.com.js +35 -0
- package/providers/etempmail.net.js +37 -0
- package/providers/eyepaste.com.js +39 -0
- package/providers/fakemail.io.js +35 -0
- package/providers/fakemail.net.js +35 -0
- package/providers/fakemailgenerator.com.js +35 -0
- package/providers/fakermail.com.js +37 -0
- package/providers/fex.plus.js +38 -0
- package/providers/findtempmail.com.js +38 -0
- package/providers/foxiomail.com.js +41 -0
- package/providers/fyii.de.js +42 -0
- package/providers/gecicimail.co.js +14 -0
- package/providers/gecicimail.com.tr.js +15 -0
- package/providers/generator.email.js +37 -0
- package/providers/getnada.com.js +37 -0
- package/providers/gpa.lu.js +37 -0
- package/providers/guerrillamail.com.js +38 -0
- package/providers/harakirimail.com.js +38 -0
- package/providers/haribu.net.js +39 -0
- package/providers/hizli.email.js +40 -0
- package/providers/hottempmail.com.js +51 -0
- package/providers/instant-email.org.js +39 -0
- package/providers/instantemailaddress.com.js +39 -0
- package/providers/jooko.info.js +36 -0
- package/providers/kopeechka.store.js +53 -0
- package/providers/linshi-email.com.js +38 -0
- package/providers/lroid.com.js +35 -0
- package/providers/luxusmail.org.js +39 -0
- package/providers/mail-temp.com.js +37 -0
- package/providers/mail-tester.com.js +37 -0
- package/providers/mail.gen.tr.js +14 -0
- package/providers/mail.gw.js +35 -0
- package/providers/mail.td.js +42 -0
- package/providers/mail.tm.js +35 -0
- package/providers/mail1a.de.js +42 -0
- package/providers/mail7.io.js +41 -0
- package/providers/mailcatch.com.js +38 -0
- package/providers/maildim.com.js +38 -0
- package/providers/maildrop.cc.js +38 -0
- package/providers/mailinator.com.js +27 -0
- package/providers/mailnesia.com.js +41 -0
- package/providers/mailpoof.com.js +71 -0
- package/providers/mailsac.com.js +27 -0
- package/providers/mailswipe.net.js +37 -0
- package/providers/minimail.eu.org.js +27 -0
- package/providers/mintemail.com.js +49 -0
- package/providers/minuteinbox.com.js +35 -0
- package/providers/moakt.com.js +37 -0
- package/providers/mohmal.com.js +39 -0
- package/providers/muellmail.com.js +41 -0
- package/providers/mytemp.email.js +35 -0
- package/providers/mytrashmailer.com.js +38 -0
- package/providers/niepodam.pl.js +53 -0
- package/providers/nolog.email.js +38 -0
- package/providers/onetempmail.com.js +37 -0
- package/providers/open.js +41 -0
- package/providers/oxyemail.com.js +38 -0
- package/providers/phaantm.de.js +42 -0
- package/providers/poo.email.js +27 -0
- package/providers/sandvpn.com.js +49 -0
- package/providers/shitmail.me.js +38 -0
- package/providers/shitmail.org.js +38 -0
- package/providers/spamdecoy.net.js +38 -0
- package/providers/spamgourmet.com.js +29 -0
- package/providers/spoofmail.de.js +47 -0
- package/providers/t-mail.org.js +42 -0
- package/providers/temp-email.info.js +39 -0
- package/providers/temp-inbox.com.js +38 -0
- package/providers/temp-mail.io.js +36 -0
- package/providers/temp-mails.com.js +45 -0
- package/providers/temp.cab.js +39 -0
- package/providers/tempail.com.js +36 -0
- package/providers/tempinbox.xyz.js +38 -0
- package/providers/tempmail.altmails.com.js +37 -0
- package/providers/tempmail.cn.js +38 -0
- package/providers/tempmail.co.js +38 -0
- package/providers/tempmail.dev.js +35 -0
- package/providers/tempmail.ninja.js +35 -0
- package/providers/tempmail.plus.js +47 -0
- package/providers/tempmail.run.js +37 -0
- package/providers/tempmail.tel.js +38 -0
- package/providers/tempmailed.com.js +43 -0
- package/providers/tempmailo.com.js +35 -0
- package/providers/tempo-email.com.js +38 -0
- package/providers/tempo-mail.xyz.js +40 -0
- package/providers/temporary-email.com.js +35 -0
- package/providers/temporary-mail.net.js +42 -0
- package/providers/temporarymail.com.js +39 -0
- package/providers/tempos.email.js +38 -0
- package/providers/tempr.email.js +45 -0
- package/providers/temprmail.com.js +38 -0
- package/providers/tenmail.org.js +40 -0
- package/providers/thnen.com.js +25 -0
- package/providers/throwaway.io.js +39 -0
- package/providers/tmail.gg.js +36 -0
- package/providers/tmail.mmomekong.com.js +38 -0
- package/providers/tmailor.com.js +37 -0
- package/providers/tmailweb.com.js +39 -0
- package/providers/trash-mail.com.js +42 -0
- package/providers/trashmail.com.js +39 -0
- package/providers/trashmail.de.js +36 -0
- package/providers/trashmail.live.js +36 -0
- package/providers/trashmail.org.js +39 -0
- package/providers/trashmail.ws.js +42 -0
- package/providers/trashmails.com.js +38 -0
- package/providers/txen.de.js +48 -0
- package/providers/wegwerfemailadresse.com.js +43 -0
- package/providers/yopmail.com.js +37 -0
- package/providers/yopmail.fr.js +37 -0
- package/providers/yopmail.net.js +37 -0
- package/providers/yourmail.online.js +39 -0
- package/release.sh +26 -0
- package/repo-update.js +121 -0
- package/shared.js +559 -0
- package/test/doRequest.js +47 -0
- package/test/is_domain_banned.js +53 -0
- package/test/is_fakedomain.js +136 -0
- package/test/is_fakeemail.js +136 -0
- package/test/psl.js +58 -0
- package/test/repo_json_v1.js +30 -0
- package/test/repo_json_v2.js +41 -0
- package/test1.js +36 -0
- package/update-repo.sh +44 -0
- package/vars.js +16 -0
- package/CHARTS.md +0 -492
- package/LICENSE.md +0 -29
- package/examples/online.js +0 -16
- package/index.d.ts +0 -23
- package/index.js +0 -193
- package/json/data.json +0 -1
- package/json/data_version2.json +0 -1
- package/markdown/README.md +0 -16316
- package/txt/data.txt +0 -16316
package/repo-update.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
var Table = require('easy-table')
|
|
3
|
+
const winston = require('winston')
|
|
4
|
+
const { getConfig, Sentry } = require('./config')
|
|
5
|
+
const chalk = require('chalk')
|
|
6
|
+
const vars = require('./vars')
|
|
7
|
+
const argv = require('minimist')(process.argv.slice(2))
|
|
8
|
+
|
|
9
|
+
// load all providers/*.js
|
|
10
|
+
var glob = require('glob'), path = require('path')
|
|
11
|
+
const { pullDomains, combineDomains, getProviderDetails, obfuscatedTime } = require('./shared')
|
|
12
|
+
const { isLocal } = require('mybase')
|
|
13
|
+
const { perDomain } = require('./apiserver/inc/shared')
|
|
14
|
+
glob.sync('./providers/*.js').forEach(function (file) {
|
|
15
|
+
require(path.resolve(file));
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
this file is designed to deploy repo/ folder with data taken from mysql
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const logger = winston.createLogger({
|
|
24
|
+
level: 'info',
|
|
25
|
+
format: winston.format.json(),
|
|
26
|
+
defaultMeta: { service: 'user-service' },
|
|
27
|
+
transports: [
|
|
28
|
+
//
|
|
29
|
+
// - Write all logs with importance level of `error` or less to `error.log`
|
|
30
|
+
// - Write all logs with importance level of `info` or less to `combined.log`
|
|
31
|
+
//
|
|
32
|
+
new winston.transports.File({ filename: 'logs/repo-markdown-error.log', level: 'error' }),
|
|
33
|
+
new winston.transports.File({ filename: 'logs/repo-markdown-combined.log' }),
|
|
34
|
+
// log to Console too
|
|
35
|
+
new winston.transports.Console()
|
|
36
|
+
],
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
function writeToFile(fn, content) {
|
|
42
|
+
// let fn = 'repo/markdown/README.md'
|
|
43
|
+
fs.writeFileSync(fn, content)
|
|
44
|
+
console.log(chalk.green(`+ file ${fn}`))
|
|
45
|
+
return true
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function start() {
|
|
49
|
+
try {
|
|
50
|
+
await getConfig()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
let rows = await pullDomains(isLocal() ? 10 : 1000, logger)
|
|
54
|
+
let combined = await combineDomains(rows, true)
|
|
55
|
+
let json2domains = perDomain(combined)
|
|
56
|
+
let markdown = `# Providers\n\n`
|
|
57
|
+
let now = Math.round(Date.now() / 1000)
|
|
58
|
+
let json = {
|
|
59
|
+
version: 1,
|
|
60
|
+
t: now,
|
|
61
|
+
domains: {},
|
|
62
|
+
// flat:[]
|
|
63
|
+
}
|
|
64
|
+
let json2 = {
|
|
65
|
+
version: 2,
|
|
66
|
+
t: now,
|
|
67
|
+
domains: json2domains,
|
|
68
|
+
}
|
|
69
|
+
let updated = `Last Update: ${new Date().toISOString()}`
|
|
70
|
+
let txt = `# Fake and Temp Mail Providers\n# https://github.com/7c/fakefilter\n# ${updated}\n\n\n`
|
|
71
|
+
|
|
72
|
+
for (let provider of Object.keys(combined)) {
|
|
73
|
+
let domains = combined[provider]
|
|
74
|
+
var t = new Table()
|
|
75
|
+
console.log(chalk.bold.yellow(provider))
|
|
76
|
+
markdown += `## ${provider}\n`
|
|
77
|
+
txt += `## ${provider}\n`
|
|
78
|
+
|
|
79
|
+
for (let domain of Object.keys(domains)) {
|
|
80
|
+
let data = domains[domain]
|
|
81
|
+
domain = domain.toLowerCase()
|
|
82
|
+
|
|
83
|
+
for (let host of Object.keys(data.hosts)) {
|
|
84
|
+
// 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,
|
|
89
|
+
}
|
|
90
|
+
t.cell('domain', host)
|
|
91
|
+
markdown += `- ${host}\n`
|
|
92
|
+
txt += `${host}\n`
|
|
93
|
+
t.newRow()
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
markdown += `\n`
|
|
97
|
+
txt += `\n`
|
|
98
|
+
// console.log(t.toString())
|
|
99
|
+
}
|
|
100
|
+
markdown += `\n\n${updated}\n`
|
|
101
|
+
// deploy to file
|
|
102
|
+
if (!argv.dry) {
|
|
103
|
+
// markdown
|
|
104
|
+
writeToFile(path.join(__dirname, 'repo/markdown/README.md'), markdown)
|
|
105
|
+
// json v1
|
|
106
|
+
writeToFile(path.join(__dirname, 'repo/json/data.json'), JSON.stringify(json))
|
|
107
|
+
// json v2
|
|
108
|
+
writeToFile(path.join(__dirname, 'repo/json/data_version2.json'), JSON.stringify(json2))
|
|
109
|
+
// txt
|
|
110
|
+
writeToFile(path.join(__dirname, 'repo/txt/data.txt'), txt)
|
|
111
|
+
} else console.log(chalk.yellow(`dry flag: did not deploy to files`))
|
|
112
|
+
// console.log(json)
|
|
113
|
+
|
|
114
|
+
// console.log(markdown)
|
|
115
|
+
process.exit(0)
|
|
116
|
+
} catch (err) {
|
|
117
|
+
console.log(chalk.red(err))
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
start()
|
package/shared.js
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
const punycode = require('punycode/')
|
|
2
|
+
const { Op } = require("sequelize")
|
|
3
|
+
const { parseDomain, ParseResultType } = require("parse-domain")
|
|
4
|
+
const argv = require('minimist')(process.argv.slice(2))
|
|
5
|
+
const chalk = require('chalk')
|
|
6
|
+
var dns = require('dns')
|
|
7
|
+
const vars = require('./vars')
|
|
8
|
+
const { wait, validEmail } = require('mybase');
|
|
9
|
+
const puppeteer = require('puppeteer-extra')
|
|
10
|
+
const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha')
|
|
11
|
+
var { randomUseragent, UseragentByFamily } = require('useragentsdata');
|
|
12
|
+
const { Sentry, config } = require('./config');
|
|
13
|
+
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
|
|
14
|
+
const { default: isEmail } = require("validator/lib/isEmail")
|
|
15
|
+
const UA = UseragentByFamily('chrome', 'Mac OS X').ua
|
|
16
|
+
const psl = require('psl')
|
|
17
|
+
const { hostnameFromEmailAddress } = require("./apiserver/inc/shared")
|
|
18
|
+
// console.log(chalk.bold(`Useragent:${UA}`))
|
|
19
|
+
|
|
20
|
+
function getDomainPart(hostname) {
|
|
21
|
+
const parseResult = parseDomain(hostname)
|
|
22
|
+
const domain = parseResult.domain + '.' + parseResult.topLevelDomains.join('.')
|
|
23
|
+
if (hostname !== domain) {
|
|
24
|
+
// console.log(chalk.red(`Is this a subdomain ? `),parseResult,domain,hostname)
|
|
25
|
+
// collect+=`${chalk.yellow(domain)} <> ${chalk.green(hostname)}\n`
|
|
26
|
+
// process.exit(0)
|
|
27
|
+
return domain
|
|
28
|
+
}
|
|
29
|
+
return hostname
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async function initiateEmpty() {
|
|
34
|
+
return new Promise(async function (resolve, reject) {
|
|
35
|
+
return resolve(true)
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const promiseTimeout = function (ms, promise) {
|
|
40
|
+
// Create a promise that rejects in <ms> milliseconds
|
|
41
|
+
let timeout = new Promise((resolve, reject) => {
|
|
42
|
+
let id = setTimeout(() => {
|
|
43
|
+
clearTimeout(id);
|
|
44
|
+
reject('TIMEDOUT')
|
|
45
|
+
}, ms)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
// Returns a race between our timeout and the passed in promise
|
|
49
|
+
return Promise.race([
|
|
50
|
+
promise,
|
|
51
|
+
timeout
|
|
52
|
+
])
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function launch(headless, url, waitTime = 3, CLICK_SELECTOR = false, captchaPlugin = false, waitUntil = 'load') {
|
|
56
|
+
return new Promise(async function (resolve, reject) {
|
|
57
|
+
try {
|
|
58
|
+
if (captchaPlugin) puppeteer.use(
|
|
59
|
+
RecaptchaPlugin({
|
|
60
|
+
provider: {
|
|
61
|
+
id: '2captcha',
|
|
62
|
+
token: config.captcha_resolver_api
|
|
63
|
+
},
|
|
64
|
+
visualFeedback: true // colorize reCAPTCHAs (violet = detected, green = solved)
|
|
65
|
+
})
|
|
66
|
+
)
|
|
67
|
+
puppeteer.use(StealthPlugin())
|
|
68
|
+
const browser = await puppeteer.launch({
|
|
69
|
+
args: ['--no-sandbox'],
|
|
70
|
+
// args: [
|
|
71
|
+
// // '--disable-features=IsolateOrigins,site-per-process',
|
|
72
|
+
// // '--flag-switches-begin --disable-site-isolation-trials --flag-switches-end',
|
|
73
|
+
// '--disable-web-security',
|
|
74
|
+
// '--no-sandbox'
|
|
75
|
+
// ],
|
|
76
|
+
defaultViewport: null,
|
|
77
|
+
headless: headless ? true : false
|
|
78
|
+
})
|
|
79
|
+
vars.browsers.push(browser)
|
|
80
|
+
const page = await browser.newPage()
|
|
81
|
+
await page.setUserAgent(UA)
|
|
82
|
+
await page.goto(url, { waitUntil });
|
|
83
|
+
if (argv.ss) await page.screenshot({ path: 'screenshots/goto.png', fullPage: true })
|
|
84
|
+
|
|
85
|
+
await wait(waitTime)
|
|
86
|
+
if (CLICK_SELECTOR) {
|
|
87
|
+
|
|
88
|
+
// await page.waitForNavigation()
|
|
89
|
+
try {
|
|
90
|
+
// we use puppeeter click function
|
|
91
|
+
await page.click(CLICK_SELECTOR)
|
|
92
|
+
} catch (err3) {
|
|
93
|
+
// if it fails we click via javascript
|
|
94
|
+
await page.evaluate((CLICK_SELECTOR) => {
|
|
95
|
+
let btn = document.querySelector(CLICK_SELECTOR)
|
|
96
|
+
if (btn) {
|
|
97
|
+
btn.click()
|
|
98
|
+
return true
|
|
99
|
+
}
|
|
100
|
+
return false
|
|
101
|
+
}, CLICK_SELECTOR)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// await page.waitForNavigation()
|
|
105
|
+
await wait(waitTime)
|
|
106
|
+
if (argv.ss) await page.screenshot({ path: 'screenshots/afterclick.png', fullPage: true })
|
|
107
|
+
}
|
|
108
|
+
return resolve({ page, browser })
|
|
109
|
+
} catch (err) {
|
|
110
|
+
console.log(err)
|
|
111
|
+
console.log(`Browser handels:${vars.browsers.length} UA:${UA}`)
|
|
112
|
+
Sentry.captureException(err)
|
|
113
|
+
resolve(false)
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function resolveMx(host) {
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
dns.resolveMx(host, (err, addresses) => {
|
|
121
|
+
if (err) return resolve(false)
|
|
122
|
+
resolve(addresses)
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
async function emailBy_querySelector_innerText(page, Selector, raw = false) {
|
|
129
|
+
if (!page) return false
|
|
130
|
+
let got = await page.evaluate((Selector) => {
|
|
131
|
+
let response = []
|
|
132
|
+
for (let item of document.querySelectorAll(Selector))
|
|
133
|
+
response.push(item.innerText)
|
|
134
|
+
return response
|
|
135
|
+
}, Selector)
|
|
136
|
+
// await page.screenshot({path: 'screenshots/after.png', fullPage: true})
|
|
137
|
+
if (raw) return got
|
|
138
|
+
// console.log(got)
|
|
139
|
+
for (let item of got)
|
|
140
|
+
if (validEmail(item.trim())) return item.toLowerCase().trim()
|
|
141
|
+
return false
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function emailBy_querySelector_innerHTML(page, Selector, raw = false) {
|
|
145
|
+
if (!page) return false
|
|
146
|
+
let got = await page.evaluate((Selector) => {
|
|
147
|
+
let response = []
|
|
148
|
+
for (let item of document.querySelectorAll(Selector))
|
|
149
|
+
response.push(item.innerHTML)
|
|
150
|
+
return response
|
|
151
|
+
}, Selector)
|
|
152
|
+
// await page.screenshot({path: 'screenshots/after.png', fullPage: true})
|
|
153
|
+
if (raw) return got
|
|
154
|
+
// console.log(got)
|
|
155
|
+
for (let item of got)
|
|
156
|
+
if (validEmail(item.trim())) return item.toLowerCase().trim()
|
|
157
|
+
return false
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
async function emailBy_querySelector_placeholder(page, Selector, raw = false) {
|
|
162
|
+
if (!page) return false
|
|
163
|
+
let got = await page.evaluate((Selector) => {
|
|
164
|
+
let response = []
|
|
165
|
+
for (let item of document.querySelectorAll(Selector))
|
|
166
|
+
response.push(item.placeholder)
|
|
167
|
+
return response
|
|
168
|
+
}, Selector)
|
|
169
|
+
if (raw) return got
|
|
170
|
+
for (let item of got)
|
|
171
|
+
if (validEmail(item.trim())) return item.toLowerCase().trim()
|
|
172
|
+
return false
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function emailBy_querySelector_value(page, Selector, raw = false) {
|
|
176
|
+
if (!page) return false
|
|
177
|
+
let got = await page.evaluate((Selector) => {
|
|
178
|
+
let response = []
|
|
179
|
+
for (let item of document.querySelectorAll(Selector))
|
|
180
|
+
response.push(item.value)
|
|
181
|
+
return response
|
|
182
|
+
}, Selector)
|
|
183
|
+
if (raw) return got
|
|
184
|
+
for (let item of got)
|
|
185
|
+
if (validEmail(item.trim())) return item.toLowerCase().trim()
|
|
186
|
+
return false
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function emailBy_id_value(page, tagId) {
|
|
190
|
+
if (!page) return false
|
|
191
|
+
let got = await page.evaluate((tagId) => {
|
|
192
|
+
return document.getElementById(tagId).value
|
|
193
|
+
}, tagId)
|
|
194
|
+
|
|
195
|
+
if (validEmail(got.trim())) return got.toLowerCase().trim()
|
|
196
|
+
return false
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function emailBy_id_innerText(page, tagId, raw = false) {
|
|
200
|
+
if (!page) return false
|
|
201
|
+
let got = await page.evaluate((tagId) => {
|
|
202
|
+
console.log(`>`, tagId)
|
|
203
|
+
return document.getElementById(tagId).innerText
|
|
204
|
+
}, tagId)
|
|
205
|
+
// console.log(`emailBy_id_innerText`,got)
|
|
206
|
+
if (raw) return got
|
|
207
|
+
if (validEmail(got.trim())) return got.toLowerCase().trim()
|
|
208
|
+
return false
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
function findByIdValue(headless, url, tagId, waitTime = 3) {
|
|
213
|
+
async function pull(page, theid) {
|
|
214
|
+
|
|
215
|
+
let got = await page.evaluate((theid) => {
|
|
216
|
+
|
|
217
|
+
return document.getElementById(theid).value
|
|
218
|
+
}, tagId)
|
|
219
|
+
|
|
220
|
+
if (validEmail(got.trim())) return got.trim()
|
|
221
|
+
|
|
222
|
+
return false
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return new Promise(async function (resolve, reject) {
|
|
226
|
+
try {
|
|
227
|
+
let { page, browser } = await launch(headless, url, waitTime)
|
|
228
|
+
let emailAddr = await pull(page, tagId)
|
|
229
|
+
await browser.close()
|
|
230
|
+
if (emailAddr) return resolve({
|
|
231
|
+
email: emailAddr,
|
|
232
|
+
url,
|
|
233
|
+
t: Date.now()
|
|
234
|
+
})
|
|
235
|
+
return resolve(null)
|
|
236
|
+
} catch (err) {
|
|
237
|
+
console.log(err)
|
|
238
|
+
Sentry.captureException(err)
|
|
239
|
+
resolve(false)
|
|
240
|
+
}
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function emailFrom_combobox_selector(page, Selector, replaceRX = false) {
|
|
245
|
+
return new Promise(async function (resolve, reject) {
|
|
246
|
+
if (!page) return resolve(false)
|
|
247
|
+
let got = await page.evaluate((Selector) => {
|
|
248
|
+
let response = []
|
|
249
|
+
// console.log(`>>`,Selector)
|
|
250
|
+
// console.log(document.querySelectorAll(Selector))
|
|
251
|
+
for (let option of document.querySelectorAll(Selector)[0].children) {
|
|
252
|
+
console.log(`option`, option)
|
|
253
|
+
let txt = option.innerText.toLowerCase().trim()
|
|
254
|
+
response.push(`any@` + txt)
|
|
255
|
+
}
|
|
256
|
+
return response
|
|
257
|
+
}, Selector)
|
|
258
|
+
let email = []
|
|
259
|
+
for (let item of got) {
|
|
260
|
+
if (replaceRX) item = item.replace(replaceRX, '').toLowerCase().trim()
|
|
261
|
+
if (item && validEmail(item.toLowerCase().trim())) email.push(item.toLowerCase().trim())
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (email.length > 0) return resolve(email)
|
|
265
|
+
return resolve(false)
|
|
266
|
+
})
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function emailFrom_combobox_id(page, elementID, replaceRX = false) {
|
|
270
|
+
return new Promise(async function (resolve, reject) {
|
|
271
|
+
if (!page) return resolve(false) // in case page could not be loaded
|
|
272
|
+
let got = await page.evaluate((elementID) => {
|
|
273
|
+
// console.log(`emailendID`, elementID)
|
|
274
|
+
|
|
275
|
+
let response = []
|
|
276
|
+
for (let option of document.getElementById(elementID).children) {
|
|
277
|
+
// console.log(`option`,option)
|
|
278
|
+
let txt = option.innerText.toLowerCase().trim()
|
|
279
|
+
if (txt.search(/^@/) == 0) response.push(`any` + txt); else
|
|
280
|
+
response.push(`any@` + txt)
|
|
281
|
+
}
|
|
282
|
+
return response
|
|
283
|
+
}, elementID)
|
|
284
|
+
// console.log(got)
|
|
285
|
+
let email = []
|
|
286
|
+
for (let item of got) {
|
|
287
|
+
if (validEmail(item)) {
|
|
288
|
+
email.push(item)
|
|
289
|
+
continue
|
|
290
|
+
}
|
|
291
|
+
if (replaceRX) item = item.replace(replaceRX, '').toLowerCase().trim()
|
|
292
|
+
if (item && validEmail(item.toLowerCase().trim())) email.push(item.toLowerCase().trim())
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (email.length > 0) return resolve(email)
|
|
296
|
+
return resolve(false)
|
|
297
|
+
})
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
function email_from_raw(rawArray) {
|
|
303
|
+
let email = []
|
|
304
|
+
if (Array.isArray(rawArray))
|
|
305
|
+
for (let i of rawArray) {
|
|
306
|
+
i = i.trim()
|
|
307
|
+
if (validEmail(`any@${i}`) && !email.includes(`any@${i}`)) email.push(`any@${i}`);
|
|
308
|
+
else
|
|
309
|
+
if (validEmail(`any${i}`) && !email.includes(`any${i}`)) email.push(`any${i}`);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (email.length > 0) return email
|
|
313
|
+
return null
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
function pullEventsByProvider(providerName, daysago = 60) {
|
|
319
|
+
return new Promise(async function (resolve, reject) {
|
|
320
|
+
let since = Date.now() - daysago * 24 * 60 * 60 * 1000
|
|
321
|
+
try {
|
|
322
|
+
let rows = await vars.models.Events.findAll({
|
|
323
|
+
// attributes:['provider'],
|
|
324
|
+
where: { t: { [Op.gt]: since }, provider: providerName },
|
|
325
|
+
raw: true
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
return resolve(rows)
|
|
329
|
+
} catch (err) {
|
|
330
|
+
console.log(err)
|
|
331
|
+
if (logger) logger.error(err)
|
|
332
|
+
Sentry.captureException(err)
|
|
333
|
+
}
|
|
334
|
+
return resolve(false)
|
|
335
|
+
})
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
function pullEventsProviders(logger, daysago = 60) {
|
|
340
|
+
return new Promise(async function (resolve, reject) {
|
|
341
|
+
let since = Date.now() - daysago * 24 * 60 * 60 * 1000
|
|
342
|
+
try {
|
|
343
|
+
let rows = await vars.models.Events.findAll({
|
|
344
|
+
attributes: ['provider'],
|
|
345
|
+
where: { t: { [Op.gt]: since } },
|
|
346
|
+
raw: true
|
|
347
|
+
})
|
|
348
|
+
let providers = []
|
|
349
|
+
rows.map(r => !providers.includes(r.provider) && providers.push(r.provider))
|
|
350
|
+
|
|
351
|
+
return resolve(providers.sort())
|
|
352
|
+
} catch (err) {
|
|
353
|
+
console.log(err)
|
|
354
|
+
if (logger) logger.error(err)
|
|
355
|
+
Sentry.captureException(err)
|
|
356
|
+
}
|
|
357
|
+
return resolve(false)
|
|
358
|
+
})
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
function pullDomains(days = 600, logger) {
|
|
363
|
+
return new Promise(async function (resolve, reject) {
|
|
364
|
+
let yearago = Date.now() - days * 24 * 60 * 60 * 1000
|
|
365
|
+
try {
|
|
366
|
+
let rows = await vars.models.Harvested.findAll({
|
|
367
|
+
where: { t: { [Op.gt]: yearago } },
|
|
368
|
+
order: [["t", "DESC"]],
|
|
369
|
+
raw: true
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
return resolve(rows)
|
|
373
|
+
} catch (err) {
|
|
374
|
+
console.log(err)
|
|
375
|
+
if (logger) logger.error(err)
|
|
376
|
+
Sentry.captureException(err)
|
|
377
|
+
}
|
|
378
|
+
return resolve(false)
|
|
379
|
+
})
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function getProviderDetails(name) {
|
|
383
|
+
for (let provider of vars.providers) {
|
|
384
|
+
if (provider.name === name) return provider
|
|
385
|
+
}
|
|
386
|
+
return null
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function combineDomains(rows,obfuscateTime=true) {
|
|
390
|
+
return new Promise(async function (resolve, reject) {
|
|
391
|
+
let result = {} // provider/domain
|
|
392
|
+
const progress = require('progressbar').create().step('combining')
|
|
393
|
+
progress.setTotal(rows.length)
|
|
394
|
+
for (let row of rows) {
|
|
395
|
+
// detect IDN domains
|
|
396
|
+
let pc = punycode.toASCII(row.domain)
|
|
397
|
+
if (pc!==row.domain) {
|
|
398
|
+
console.log(`IDN Domain found: ${row.domain} provider: ${row.provider}`)
|
|
399
|
+
row.unicodeDomain = row.domain
|
|
400
|
+
row.domain = pc
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
await wait(1 / 1000)
|
|
404
|
+
progress.addTick()
|
|
405
|
+
let hostname = row.domain.toLowerCase()
|
|
406
|
+
// 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}`)
|
|
410
|
+
continue
|
|
411
|
+
}
|
|
412
|
+
// lets take the domain of the hostname
|
|
413
|
+
let domain = domainparse.domain
|
|
414
|
+
let domain_pc = punycode.toASCII(domain)
|
|
415
|
+
|
|
416
|
+
// not listed tld found, not listed tlds are made up ones
|
|
417
|
+
if (!domainparse.listed) {
|
|
418
|
+
console.log(`Not listed TLD: ${domain} - detected id: ${row.id} - provider: ${row.provider} `)
|
|
419
|
+
// what to do with those
|
|
420
|
+
}
|
|
421
|
+
// ignore whitelisted domains
|
|
422
|
+
if (vars.config.ignore_domains.includes(domain)) {
|
|
423
|
+
try { await vars.models.Harvested.destroy({ where: { id: row.id } }) } catch (_) { } // DELETE
|
|
424
|
+
console.log(chalk.red(`Ignoring whitelisted domain:${domain} at row: ${row.id} provider:${row.provider} - DELETED`))
|
|
425
|
+
continue
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// make sure email address is valid by validator library
|
|
429
|
+
if (!isEmail(`any@${domain}`)) {
|
|
430
|
+
try { await vars.models.Harvested.destroy({ where: { id: row.id } }) } catch (_) { } // DELETE
|
|
431
|
+
console.log(`Invalid domain: ${domain} - detected id: ${row.id} - DELETED`)
|
|
432
|
+
continue
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// create the provider
|
|
436
|
+
if (!result.hasOwnProperty(row.provider)) result[row.provider] = {}
|
|
437
|
+
|
|
438
|
+
// create the domain inside provider
|
|
439
|
+
if (!result[row.provider].hasOwnProperty(domain))
|
|
440
|
+
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]={
|
|
449
|
+
firstseen: 5645821813648,
|
|
450
|
+
lastseen: 0,
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
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
|
+
let t = obfuscateTime ? obfuscatedTime(row.t) : row.t
|
|
467
|
+
// firstseen of host
|
|
468
|
+
if (t < result[row.provider][domain].hosts[hostname].firstseen) result[row.provider][domain].hosts[hostname].firstseen = t
|
|
469
|
+
// lastseen
|
|
470
|
+
if (t > result[row.provider][domain].hosts[hostname].lastseen) result[row.provider][domain].hosts[hostname].lastseen = t
|
|
471
|
+
}
|
|
472
|
+
return resolve(result)
|
|
473
|
+
})
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function obfuscatedTime(dt) {
|
|
477
|
+
return Math.round(dt / 10000000) * 10000
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function domainFromEmail(email) {
|
|
481
|
+
let domPart = email.split(/@/)[1]
|
|
482
|
+
return domPart
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
function eventsOfProvider(providerName, days = 7) {
|
|
487
|
+
const { Op } = require("sequelize")
|
|
488
|
+
return new Promise(async function (resolve, reject) {
|
|
489
|
+
try {
|
|
490
|
+
let got = await vars.models.Events.findAll({
|
|
491
|
+
where: {
|
|
492
|
+
provider: providerName,
|
|
493
|
+
createdAt: {
|
|
494
|
+
[Op.gt]: new Date(new Date() - days * 24 * 60 * 60 * 1000)
|
|
495
|
+
}
|
|
496
|
+
}, raw: true
|
|
497
|
+
})
|
|
498
|
+
return resolve(got)
|
|
499
|
+
} catch (err) {
|
|
500
|
+
console.log(err)
|
|
501
|
+
Sentry.captureException(err)
|
|
502
|
+
return resolve(false)
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
})
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function is_domain_banned(hostname_or_email, current_filter = {}) {
|
|
509
|
+
// determins if the main domain of this hostname is banned
|
|
510
|
+
let hostname
|
|
511
|
+
// lets parse the hostname from email address
|
|
512
|
+
if (hostname_or_email && typeof hostname_or_email === 'string' && hostname_or_email.search(/^.*@.+$/) === 0)
|
|
513
|
+
hostname = hostnameFromEmailAddress(hostname_or_email);
|
|
514
|
+
else hostname = hostname_or_email
|
|
515
|
+
|
|
516
|
+
// lets work with the hostname
|
|
517
|
+
if (hostname && typeof hostname === 'string') {
|
|
518
|
+
hostname = hostname.toLowerCase().trim()
|
|
519
|
+
let domainparse = psl.parse(hostname)
|
|
520
|
+
if (domainparse && typeof domainparse.domain === 'string' && domainparse.domain.length > 0) {
|
|
521
|
+
return current_filter.hasOwnProperty(domainparse.domain) ? current_filter[domainparse.domain] : false
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return null
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
module.exports = {
|
|
529
|
+
findByIdValue,
|
|
530
|
+
initiateEmpty,
|
|
531
|
+
launch,
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
emailBy_id_innerText,
|
|
535
|
+
emailBy_querySelector_innerHTML,
|
|
536
|
+
emailBy_querySelector_innerText,
|
|
537
|
+
emailBy_querySelector_placeholder,
|
|
538
|
+
emailBy_querySelector_value,
|
|
539
|
+
emailBy_id_value,
|
|
540
|
+
|
|
541
|
+
emailFrom_combobox_id,
|
|
542
|
+
emailFrom_combobox_selector,
|
|
543
|
+
|
|
544
|
+
email_from_raw,
|
|
545
|
+
|
|
546
|
+
resolveMx,
|
|
547
|
+
promiseTimeout,
|
|
548
|
+
getDomainPart,
|
|
549
|
+
|
|
550
|
+
combineDomains,
|
|
551
|
+
getProviderDetails,
|
|
552
|
+
pullDomains,
|
|
553
|
+
pullEventsProviders,
|
|
554
|
+
pullEventsByProvider,
|
|
555
|
+
obfuscatedTime,
|
|
556
|
+
domainFromEmail,
|
|
557
|
+
eventsOfProvider,
|
|
558
|
+
is_domain_banned
|
|
559
|
+
}
|