返回 social-analyzer
app.js
根目录 / app.js
1 // -------------------------------------------------------------
2 // author Giga
3 // project qeeqbox/social-analyzer
4 // email gigaqeeq@gmail.com
5 // description app.py (CLI)
6 // licensee AGPL-3.0
7 // -------------------------------------------------------------
8 // contributors list qeeqbox/social-analyzer/graphs/contributors
9 // -------------------------------------------------------------
10
11 import yargs from 'yargs'
12 import { hideBin } from 'yargs/helpers'
13 const yarg_ = yargs(hideBin(process.argv))
14 const argv = yarg_.usage('Usage: $0 --username "johndoe" --websites "youtube tiktok"\nUsage: $0 "fast" --username "johndoe"')
15 .describe('gui', 'Reserved for a gui')
16 .default('gui', false)
17 .boolean('gui')
18 .describe('cli', 'Reserved for a cli (Not needed)')
19 .default('cli', false)
20 .boolean('cli')
21 .describe('username', 'E.g. johndoe, john_doe or johndoe9999')
22 .default('username', '')
23 .describe('websites', 'A website or websites separated by space E.g. youtube, tiktok or tumblr')
24 .default('websites', 'all')
25 .describe('mode', 'Analysis mode E.g.fast -> FindUserProfilesFast, slow -> FindUserProfilesSlow or special -> FindUserProfilesSpecial')
26 .default('mode', 'fast')
27 .describe('output', 'Show the output in the following format: json -> json output for integration or pretty -> prettify the output')
28 .default('output', 'pretty')
29 .describe('options', 'Show the following when a profile is found: link, rate, title or text')
30 .default('options', '')
31 .describe('list', 'List all available websites')
32 .default('list', false)
33 .boolean('list')
34 .describe('docker', 'allow docker')
35 .default('docker', false)
36 .boolean('docker')
37 .describe('method', 'find -> show detected profiles, get -> show all profiles regardless detected or not, all -> combine find & get')
38 .default('method', 'all')
39 .describe('grid', 'grid option, not for CLI')
40 .default('grid', '')
41 .describe('extract', 'Extract profiles, urls & patterns if possible')
42 .default('extract', false)
43 .boolean('extract')
44 .describe('metadata', 'Extract metadata if possible (pypi QeeqBox OSINT)')
45 .default('metadata', false)
46 .boolean('metadata')
47 .describe('trim', 'Trim long strings')
48 .default('trim', false)
49 .boolean('trim')
50 .describe('filter', 'filter detected profiles by good, maybe or bad, you can do combine them with comma (good,bad) or use all')
51 .default('filter', 'good')
52 .describe('profiles', 'filter profiles by detected, unknown or failed, you can do combine them with comma (detected,failed) or use all')
53 .default('profiles', 'detected')
54 .describe('top', 'select top websites as 10, 50 etc...[--websites is not needed]')
55 .default('top', '0')
56 .describe('type', 'Select websites by type (Adult, Music etc)')
57 .default('type', 'all')
58 .describe('countries', 'select websites by country or countries separated by space as: us br ru')
59 .default('countries', 'all')
60 .help('help')
61 .argv
62
63 if (argv.output !== 'json') {
64 console.log('[init] Detections are updated very often, make sure to get the most up-to-date ones')
65 }
66
67 import semver from 'semver'
68
69 if (semver.satisfies(process.version, '>13 || <13')) {
70 if (argv.output !== 'json') {
71 console.log('[init] NodeJS Version Check')
72 }
73 } else {
74 if (argv.output !== 'json') {
75 console.log('[Error] NodeJS Version Check')
76 }
77 process.exit(1)
78 }
79
80 import express from 'express'
81 import fs from 'fs'
82 import tokenizer from 'wink-tokenizer'
83 import generatorics from 'generatorics'
84 import HttpsProxyAgent from 'https-proxy-agent'
85 import PrettyError from 'pretty-error'
86
87 const pe = new PrettyError()
88 import 'express-async-errors'
89 //const _tokenizer = tokenizer()
90
91 if (!fs.existsSync('logs')) {
92 fs.mkdirSync('logs')
93 }
94
95 import helper from './modules/helper.js'
96 import fastScan from './modules/fast-scan.js'
97 import slowScan from './modules/slow-scan.js'
98 import specialScan from './modules/special-scan.js'
99 import externalApis from './modules/external-apis.js'
100 import stringAnalysis from './modules/string-analysis.js'
101 import nameAnalysis from './modules/name-analysis.js'
102 import visualize from './modules/visualize.js'
103 import stats from './modules/stats.js'
104
105 const app = express()
106 app.set('etag', false)
107 app.use(express.urlencoded({
108 extended: true
109 }))
110 app.use(express.json())
111 app.use(express.static('public'))
112
113 app.post('/get_logs', async function (req, res, next) {
114 let last_line = 'nothinghere'
115 if (req.body.uuid !== '') {
116 const temp_log_file = helper.get_log_file(req.body.uuid)
117 if (fs.existsSync(temp_log_file)) {
118 const data = fs.readFileSync(temp_log_file).toString()
119 if (typeof data !== 'undefined' && data) {
120 last_line = data.split('\n').slice(-2)[0]
121 }
122 } else {
123 last_line = 'nothing_here_error'
124 }
125 res.send(last_line)
126 }
127 })
128
129 app.get('/get_settings', async function (req, res, next) {
130 let temp_list = await Promise.all(helper.websites_entries.map(async (site, index) => {
131 let temp_url = ''
132 if ('status' in site) {
133 if (site.status === 'bad') {
134 return Promise.resolve()
135 }
136 }
137 if (site.detections.length > 0) {
138 temp_url = helper.get_site_from_url(site.url)
139 if (temp_url !== 'nothinghere') {
140 let temp_selected = 'false'
141 if ('selected' in site) {
142 if (site.selected === 'true') {
143 temp_selected = 'true'
144 }
145 }
146 return Promise.resolve({
147 index: index,
148 url: temp_url,
149 selected: temp_selected,
150 global_rank: site.global_rank
151 })
152 }
153 }
154
155 return Promise.resolve()
156 }))
157
158 temp_list = temp_list.filter(item => item !== undefined)
159 temp_list.sort(function (a, b) {
160 const keyA = a.url
161 const keyB = b.url
162 // Compare the 2 dates
163 if (keyA < keyB) return -1
164 if (keyA > keyB) return 1
165 return 0
166 })
167 res.json({
168 proxy: helper.proxy,
169 user_agent: helper.header_options.headers['User-Agent'],
170 google: [helper.google_api_key.substring(0, 10) + '******', helper.google_api_cs.substring(0, 10) + '******'],
171 websites: temp_list
172 })
173 })
174
175 app.post('/save_settings', async function (req, res, next) {
176 await helper.websites_entries.forEach(function (value, i) {
177 helper.websites_entries[i].selected = 'false'
178 })
179 if ('websites' in req.body) {
180 if (req.body.websites.length > 0) {
181 await req.body.websites.split(',').forEach(item => {
182 helper.websites_entries[Number(item)].selected = 'true'
183 })
184 }
185 }
186 if (req.body.google_key !== helper.google_api_key.substring(0, 10) + '******') {
187 helper.google_api_key = req.body.google_key
188 }
189 if (req.body.google_cv !== helper.google_api_cs.substring(0, 10) + '******') {
190 helper.google_api_cs = req.body.google_cv
191 }
192 if (req.body.user_agent !== helper.header_options.headers['User-Agent']) {
193 helper.header_options.headers['User-Agent'] = req.body.user_agent
194 }
195 if (req.body.proxy !== helper.proxy) {
196 helper.proxy = req.body.proxy
197 }
198
199 if (helper.proxy !== '') {
200 helper.header_options.agent = HttpsProxyAgent(helper.proxy)
201 } else {
202 if ('agent' in helper.header_options) {
203 delete helper.header_options.agent
204 }
205 }
206
207 res.json('Done')
208 })
209
210 app.get('/generate', async function (req, res, next) {
211 const list_of_combinations = []
212 if (req.body.option === 'Generate') {
213 if (req.body.words !== undefined && req.body.words.length > 1 && req.body.words.length < 8) {
214 for (const perm of generatorics.permutationCombination(req.body.words)) {
215 if (perm.join('') !== '') {
216 list_of_combinations.push(perm.join(''))
217 }
218 }
219 }
220 }
221 res.json({
222 combinations: list_of_combinations
223 })
224 })
225
226 app.post('/cancel', async function (req, res, next) {
227 if (req.body.option === 'on' && req.body.uuid !== '') {
228 const temp_uuid = req.body.uuid.replace(/[^a-zA-Z0-9\-]+/g, '')
229 if (!helper.global_lock.includes(temp_uuid)) {
230 helper.log_to_file_queue(req.body.uuid, '[Canceling] task: ' + req.body.uuid)
231 helper.global_lock.push(temp_uuid)
232 }
233 }
234 res.json('Done')
235 })
236
237 app.post('/analyze_string', async function (req, res, next) {
238 let username = ''
239 let temp_uuid = ''
240 const info = {
241 items: [],
242 original: '',
243 corrected: '',
244 total: 0,
245 checking: 'Using ' + req.body.string + ' with no lookups'
246 }
247 const user_info_normal = {
248 data: [],
249 type: 'all'
250 }
251 const user_info_advanced = {
252 data: [],
253 type: 'all'
254 }
255 const user_info_special = {
256 data: [],
257 type: 'all'
258 }
259 const all_words = {
260 prefix: [],
261 name: [],
262 number: [],
263 symbol: [],
264 unknown: [],
265 maybe: []
266 }
267 let ages = []
268 let names_origins = []
269 const words_info = []
270 const temp_words = []
271 let custom_search = []
272 let logs = ''
273 let fast = false
274 let graph = {
275 graph: {
276 nodes: [],
277 links: []
278 }
279 }
280
281 let stats_default = {
282 categories: {},
283 countries: {}
284 }
285
286 if (req.body.string === 'test_user_2021_2022_') {
287 if (fs.existsSync('test.json')) {
288 res.json(JSON.parse(fs.readFileSync('test.json', 'utf8')))
289 } else {
290 res.json('Error')
291 }
292 } else if (req.body.string === null || req.body.string === '') {
293 res.json('Error')
294 } else {
295 username = req.body.string
296 req.body.uuid = req.body.uuid.replace(/[^a-zA-Z0-9\-]+/g, '')
297 temp_uuid = req.body.uuid
298
299 helper.log_to_file_queue(req.body.uuid, '[Setting] Log file name: ' + req.body.uuid)
300
301 if (req.body.string.includes(',')) {
302 req.body.group = true
303 helper.log_to_file_queue(req.body.uuid, '[Setting] Multiple usernames: ' + req.body.string)
304 } else {
305 req.body.group = false
306 helper.log_to_file_queue(req.body.uuid, '[Setting] Username: ' + req.body.string)
307 }
308
309 if (req.body.option.includes('FindUserProfilesFast') || req.body.option.includes('GetUserProfilesFast')) {
310 fast = true
311 helper.log_to_file_queue(req.body.uuid, '[Starting] Checking user profiles normal')
312 if (req.body.group) {
313 const old_string_1 = req.body.string
314 const all_usernames = req.body.string.split(',').map(async item => {
315 req.body.string = item
316 let temp_arr = await fastScan.find_username_normal(req)
317 user_info_normal.data.push(...temp_arr)
318 })
319 await Promise.all(all_usernames)
320 req.body.string = old_string_1
321 } else {
322 user_info_normal.data = await fastScan.find_username_normal(req)
323 }
324
325 helper.log_to_file_queue(req.body.uuid, '[Done] Checking user profiles normal')
326 if (req.body.option.includes('CategoriesStats') || req.body.option.includes('MetadataStats')) {
327 helper.log_to_file_queue(req.body.uuid, '[Starting] Generate stats')
328 stats_default = await stats.get_stats(req,user_info_normal.data)
329 helper.log_to_file_queue(req.body.uuid, '[Done] Generate stats')
330 }
331 }
332
333 if (req.body.option.includes('FindUserProfilesSpecial')) {
334 if (!fast) {
335 helper.log_to_file_queue(req.body.uuid, '[Starting] Checking user profiles special')
336 user_info_special.data = await specialScan.find_username_special(req)
337 helper.log_to_file_queue(req.body.uuid, '[Done] Checking user profiles special')
338 } else {
339 helper.log_to_file_queue(req.body.uuid, '[Warning] FindUserProfilesFast with FindUserProfilesSpecial')
340 helper.log_to_file_queue(req.body.uuid, '[Skipping] FindUserProfilesSpecial')
341 }
342 }
343
344 if (req.body.option.includes('FindUserProfilesSlow') && fast) {
345 helper.log_to_file_queue(req.body.uuid, '[Warning] FindUserProfilesFast with FindUserProfilesSlow')
346 helper.log_to_file_queue(req.body.uuid, '[Skipping] FindUserProfilesSlow')
347 }
348
349 if (req.body.option.includes('ShowUserProfilesSlow') && fast) {
350 helper.log_to_file_queue(req.body.uuid, '[Warning] FindUserProfilesFast with ShowUserProfilesSlow')
351 helper.log_to_file_queue(req.body.uuid, '[Skipping] ShowUserProfilesSlow')
352 }
353
354 if ((req.body.option.includes('FindUserProfilesSlow') && !fast) || (req.body.option.includes('ShowUserProfilesSlow') && !fast)) {
355 if (!req.body.option.includes('FindUserProfilesSlow')) {
356 user_info_advanced.type = 'show'
357 } else if (!req.body.option.includes('ShowUserProfilesSlow')) {
358 user_info_advanced.type = 'noshow'
359 }
360 helper.log_to_file_queue(req.body.uuid, '[Starting] Checking user profiles advanced')
361
362 if (req.body.group) {
363 const old_string_2 = req.body.string
364 const all_usernames = req.body.string.split(',').map(async item => {
365 req.body.string = item
366 const temp_arr = await slowScan.find_username_advanced(req)
367 user_info_advanced.data.push(...temp_arr)
368 })
369 await Promise.all(all_usernames)
370 req.body.string = old_string_2
371 } else {
372 user_info_advanced.data = await slowScan.find_username_advanced(req)
373 }
374
375 helper.log_to_file_queue(req.body.uuid, '[Done] Checking user profiles advanced')
376 }
377
378 if (!req.body.group) {
379 if (req.body.option.includes('LookUps')) {
380 helper.log_to_file_queue(req.body.uuid, '[Starting] Lookup')
381 await externalApis.check_engines(req, info)
382 helper.log_to_file_queue(req.body.uuid, '[Done] Lookup')
383 }
384 if (req.body.option.includes('CustomSearch')) {
385 helper.log_to_file_queue(req.body.uuid, '[Starting] Custom Search')
386 custom_search = await externalApis.custom_search_ouputs(req)
387 helper.log_to_file_queue(req.body.uuid, '[Done] Custom Search')
388 }
389 if (req.body.option.includes("FindOrigins")) {
390 helper.log_to_file_queue(req.body.uuid, "[Starting] Finding Origins")
391 names_origins = await nameAnalysis.find_origins(req);
392 helper.log_to_file_queue(req.body.uuid, "[Done] Finding Origins")
393 }
394 } else {
395 if (req.body.option.includes('FindOrigins')) {
396 const old_string_2 = req.body.string
397 const all_usernames = req.body.string.split(',').map(async item => {
398 helper.log_to_file_queue(req.body.uuid, '[Starting] Finding Origins: ' + item)
399 req.body.string = item
400 const temp_arr = await nameAnalysis.find_origins(req)
401 names_origins.push(...temp_arr)
402 helper.log_to_file_queue(req.body.uuid, '[Done] Finding Origins: ' + item)
403 })
404 await Promise.all(all_usernames)
405 req.body.string = old_string_2
406 }
407
408 await stringAnalysis.split_comma(req, all_words)
409 }
410
411 if (req.body.option.includes('SplitWordsByUpperCase')) {
412 helper.log_to_file_queue(req.body.uuid, '[Starting] Split by UpperCase')
413 await stringAnalysis.split_upper_case(req, all_words)
414 helper.log_to_file_queue(req.body.uuid, '[Done] Split by UpperCase')
415 }
416 if (req.body.option.includes('SplitWordsByAlphabet')) {
417 helper.log_to_file_queue(req.body.uuid, '[Starting] Split by Alphabet')
418 await stringAnalysis.split_alphabet_case(req, all_words)
419 helper.log_to_file_queue(req.body.uuid, '[Done] Split by Alphabet')
420 }
421 if (req.body.option.includes('FindSymbols')) {
422 helper.log_to_file_queue(req.body.uuid, '[Starting] Finding Symbols')
423 await stringAnalysis.find_symbols(req, all_words)
424 helper.log_to_file_queue(req.body.uuid, '[Done] Finding Symbols')
425 }
426 if (req.body.option.includes('FindNumbers')) {
427 helper.log_to_file_queue(req.body.uuid, '[Starting] Finding Numbers')
428 await stringAnalysis.find_numbers(req, all_words)
429 helper.log_to_file_queue(req.body.uuid, '[Done] Finding Numbers')
430 }
431 if (req.body.option.includes('FindAges')) {
432 helper.log_to_file_queue(req.body.uuid, '[Starting] Finding Ages')
433 ages = await stringAnalysis.guess_age_from_string(req)
434 helper.log_to_file_queue(req.body.uuid, '[Done] Finding Ages')
435 }
436
437 req.body.string = req.body.string.toLowerCase()
438
439 if (req.body.option.includes('ConvertNumbers')) {
440 helper.log_to_file_queue(req.body.uuid, '[Starting] Convert Numbers')
441 await stringAnalysis.convert_numbers(req, all_words)
442 helper.log_to_file_queue(req.body.uuid, '[Done] Convert Numbers')
443 }
444
445 if (req.body.option.includes('LookUps') ||
446 req.body.option.includes('WordInfo') ||
447 req.body.option.includes('MostCommon') ||
448 req.body.option.includes('SplitWordsByUpperCase') ||
449 req.body.option.includes('SplitWordsByAlphabet') ||
450 req.body.option.includes('FindSymbols') ||
451 req.body.option.includes('FindNumbers') ||
452 req.body.option.includes('ConvertNumbers')) {
453 await stringAnalysis.get_maybe_words(req, all_words)
454 await stringAnalysis.analyze_string(req, all_words)
455
456 Object.keys(all_words).forEach((key) => (all_words[key].length === 0) && delete all_words[key])
457
458 if (req.body.option.includes('MostCommon')) {
459 await stringAnalysis.most_common(all_words, temp_words)
460 }
461 if (req.body.option.includes('WordInfo')) {
462 await externalApis.get_words_info(all_words, words_info)
463 }
464 } else if (req.body.option.includes('NormalAnalysis@@')) {
465 /*
466 // var maybe_words = WordsNinja.splitSentence(req.body.string);
467 all_words.maybe = maybe_words.filter(function (elem, index, self) {
468 return index === self.indexOf(elem)
469 })
470 list_of_tokens = _tokenizer.tokenize(req.body.string)
471 list_of_tokens.forEach(function (item, index) {
472 if (item.tag in all_words) {
473 all_words[item.tag].push(item.token)
474 } else {
475 all_words[item.tag] = []
476 all_words[item.tag].push(item.token)
477 }
478 })
479
480 Object.keys(all_words).forEach((key) => (all_words[key].length === 0) && delete all_words[key])
481 */
482 }
483
484 if (req.body.option.includes('NetworkGraph')) {
485 if ('data' in user_info_normal) {
486 if (user_info_normal.data.length > 0) {
487 if (req.body.option.includes('ExtractMetadata')) {
488 helper.log_to_file_queue(req.body.uuid, '[Starting] Network Graph')
489 graph = await visualize.visualize_force_graph(req, user_info_normal.data, 'fast')
490 helper.log_to_file_queue(req.body.uuid, '[Done] Network Graph')
491 } else {
492 helper.log_to_file_queue(req.body.uuid, '[Warning] NetworkGraph needs ExtractMetadata')
493 }
494 }
495 }
496 }
497
498 try {
499 logs = fs.readFileSync(helper.get_log_file(req.body.uuid), 'utf8')
500 } catch {
501
502 }
503
504 helper.log_to_file_queue(req.body.uuid, '[Finished] Analyzing: ' + req.body.string + ' Task: ' + req.body.uuid)
505
506 /*fs.writeFileSync('./test.json', JSON.stringify({
507 username: username,
508 uuid: temp_uuid,
509 info,
510 ages: ages,
511 table: all_words,
512 common: temp_words,
513 words_info: words_info,
514 user_info_normal: user_info_normal,
515 user_info_advanced: user_info_advanced,
516 user_info_special: user_info_special,
517 names_origins: names_origins,
518 custom_search: custom_search,
519 graph: graph,
520 stats: stats_default,
521 logs: logs
522 }, null, 2) , 'utf-8');*/
523
524 res.json({
525 username: username,
526 uuid: temp_uuid,
527 info,
528 ages: ages,
529 table: all_words,
530 common: temp_words,
531 words_info: words_info,
532 user_info_normal: user_info_normal,
533 user_info_advanced: user_info_advanced,
534 user_info_special: user_info_special,
535 names_origins: names_origins,
536 custom_search: custom_search,
537 graph: graph,
538 stats: stats_default,
539 logs: logs
540 })
541 }
542 })
543
544 app.use((err, req, res, next) => {
545 helper.verbose && console.log(' --- Global Error ---')
546 helper.verbose && console.log(pe.render(err))
547 res.json('Error')
548 })
549
550 app.use((req, res, next) => {
551 res.set('Cache-Control', 'no-store')
552 next()
553 })
554
555 process.on('uncaughtException', function (err) {
556 helper.verbose && console.log(' --- Uncaught Error ---')
557 helper.verbose && console.log(pe.render(err))
558 })
559
560 process.on('unhandledRejection', function (err) {
561 helper.verbose && console.log(' --- Uncaught Rejection ---')
562 helper.verbose && console.log(pe.render(err))
563 })
564
565 function delete_keys (object, temp_keys) {
566 temp_keys.forEach((key) => {
567 try {
568 delete object[key]
569 } catch (err) {}
570 })
571 return object
572 }
573
574 function clean_up_item (object, temp_keys_str) {
575 delete object.image
576 if (temp_keys_str === '') {} else {
577 Object.keys(object).forEach((key) => {
578 try {
579 if (!temp_keys_str.includes(key)) {
580 delete object[key]
581 }
582 } catch (err) {}
583 })
584 }
585 return object
586 }
587
588 function search_and_change (site, _dict) {
589 if (helper.websites_entries.includes(site)) {
590 const item = helper.websites_entries.indexOf(site)
591 if (item !== -1) {
592 helper.websites_entries[item] = Object.assign({}, helper.websites_entries[item], _dict)
593 }
594 }
595 }
596
597 async function check_user_cli (argv) {
598 let ret = []
599 const random_string = Math.random().toString(36).substring(2)
600 let temp_options = 'GetUserProfilesFast,FindUserProfilesFast'
601 if (argv.method !== '') {
602 if (argv.method === 'find') {
603 temp_options = ',FindUserProfilesFast,'
604 } else if (argv.method === 'get') {
605 temp_options = ',GetUserProfilesFast,'
606 }
607 }
608 if (argv.extract) {
609 temp_options += ',ExtractPatterns,'
610 }
611 if (argv.metadata) {
612 temp_options += ',ExtractMetadata,'
613 }
614 const req = {
615 body: {
616 uuid: random_string,
617 string: argv.username,
618 option: temp_options + argv.output
619 }
620 }
621
622 await helper.websites_entries.forEach(async function (value, i) {
623 helper.websites_entries[i].selected = 'false'
624 })
625
626 if (argv.websites === 'all') {
627 if (argv.countries != 'all') {
628 let list_of_countries = argv.countries.toLowerCase().split(' ')
629 await helper.websites_entries.forEach(async function (value, i) {
630 if (helper.websites_entries[i].country.toLowerCase() !== '' && list_of_countries.includes(helper.websites_entries[i].country.toLowerCase())) {
631 helper.websites_entries[i].selected = 'true'
632 } else {
633 helper.websites_entries[i].selected = 'false'
634 }
635 })
636 } else {
637 await helper.websites_entries.forEach(async function (value, i) {
638 helper.websites_entries[i].selected = 'true'
639 })
640 }
641
642 if (argv.type != 'all') {
643 let websites_entries_filtered = helper.websites_entries.filter((item) => item.selected === 'true')
644 websites_entries_filtered = websites_entries_filtered.filter((item) => item.type.toLowerCase().includes(argv.type.toLowerCase()))
645
646 await websites_entries_filtered.forEach(async function (value, i) {
647 await search_and_change(websites_entries_filtered[i], {
648 selected: 'pendding'
649 })
650 })
651 await helper.websites_entries.forEach(async function (value, i) {
652 if (helper.websites_entries[i].selected === 'pendding') {
653 helper.websites_entries[i].selected = 'true'
654 } else {
655 helper.websites_entries[i].selected = 'false'
656 }
657 })
658 }
659
660 if (argv.top != 0) {
661 let websites_entries_filtered = helper.websites_entries.filter((item) => item.selected === 'true')
662 websites_entries_filtered = websites_entries_filtered.filter((item) => item.global_rank !== 0)
663 websites_entries_filtered.sort(function (a, b) {
664 return a.global_rank - b.global_rank
665 })
666 for (let i = 0; i < argv.top; i++) {
667 await search_and_change(websites_entries_filtered[i], {
668 selected: 'pendding'
669 })
670 }
671 await helper.websites_entries.forEach(async function (value, i) {
672 if (helper.websites_entries[i].selected === 'pendding') {
673 helper.websites_entries[i].selected = 'true'
674 } else {
675 helper.websites_entries[i].selected = 'false'
676 }
677 })
678 }
679 } else {
680 await helper.websites_entries.forEach(async function (value, i) {
681 if (argv.websites.length > 0) {
682 await argv.websites.split(' ').forEach(item => {
683 if (helper.websites_entries[i].url.toLowerCase().includes(item.toLowerCase())) {
684 helper.websites_entries[i].selected = 'true'
685 }
686 })
687 }
688 })
689 }
690
691 if (req.body.string.includes(',')) {
692 req.body.group = true
693 helper.log_to_file_queue(req.body.uuid, '[Setting] Multiple usernames: ' + req.body.string)
694 } else {
695 req.body.group = false
696 helper.log_to_file_queue(req.body.uuid, '[Setting] Username: ' + req.body.string)
697 }
698
699 if (req.body.group) {
700 const old_string_1 = req.body.string
701 const all_usernames = req.body.string.split(',').map(async item => {
702 req.body.string = item
703 let temp_arr = await fastScan.find_username_normal(req)
704 ret.push(...temp_arr)
705 })
706 await Promise.all(all_usernames)
707 req.body.string = old_string_1
708 } else {
709 ret = await fastScan.find_username_normal(req)
710 }
711
712 if (typeof ret === 'undefined' || ret === undefined || ret.length === 0) {
713 helper.log_to_file_queue(req.body.uuid, 'User does not exist (try FindUserProfilesSlow or FindUserProfilesSpecial)')
714 } else {
715 const temp_detected = {
716 detected: [],
717 unknown: [],
718 failed: []
719 }
720 await ret.forEach(item => {
721 if (item.method === 'all') {
722 if (item.good === 'true') {
723 item = delete_keys(item, ['method', 'good'])
724 item = clean_up_item(item, argv.options)
725 temp_detected.detected.push(item)
726 } else {
727 item = delete_keys(item, ['found', 'rate', 'status', 'method', 'good', 'text', 'extracted', 'metadata'])
728 item = clean_up_item(item, argv.options)
729 temp_detected.unknown.push(item)
730 }
731 } else if (item.method === 'find') {
732 if (item.good === 'true') {
733 item = delete_keys(item, ['method', 'good'])
734 item = clean_up_item(item, argv.options)
735 temp_detected.detected.push(item)
736 }
737 } else if (item.method === 'get') {
738 item = delete_keys(item, ['found', 'rate', 'status', 'method', 'good', 'text', 'extracted', 'metadata'])
739 item = clean_up_item(item, argv.options)
740 temp_detected.unknown.push(item)
741 } else if (item.method === 'failed') {
742 item = delete_keys(item, ['found', 'rate', 'status', 'method', 'good', 'text', 'language', 'title', 'type', 'extracted', 'metadata'])
743 item = clean_up_item(item, argv.options)
744 temp_detected.failed.push(item)
745 }
746 })
747
748 if (temp_detected.detected.length === 0) {
749 delete temp_detected.detected
750 } else {
751 if (argv.profiles.includes('all') || argv.profiles.includes('detected')) {
752 if (argv.filter.includes('all')) {
753
754 } else {
755 temp_detected.detected = temp_detected.detected.filter(item => argv.filter.includes(item.status))
756 }
757
758 if (temp_detected.detected.length === 0) {
759 delete temp_detected.detected
760 }
761 } else {
762 delete temp_detected.detected
763 }
764 }
765
766 if (temp_detected.unknown.length === 0) {
767 delete temp_detected.unknown
768 } else {
769 if (argv.profiles.includes('all') || argv.profiles.includes('unknown')) {
770
771 } else {
772 delete temp_detected.unknown
773 }
774 }
775
776 if (temp_detected.failed.length === 0) {
777 delete temp_detected.failed
778 } else {
779 if (argv.profiles.includes('all') || argv.profiles.includes('failed')) {
780
781 } else {
782 delete temp_detected.failed
783 }
784 }
785
786 if (argv.output === 'pretty' || argv.output === '') {
787 if ('detected' in temp_detected) {
788 helper.log_to_file_queue(req.body.uuid, '[Detected] ' + temp_detected.detected.length + ' Profile[s]')
789 helper.log_to_file_queue(req.body.uuid, temp_detected.detected, true, argv)
790 }
791 if ('unknown' in temp_detected) {
792 helper.log_to_file_queue(req.body.uuid, '[Unknown] ' + temp_detected.unknown.length + ' Profile[s]')
793 helper.log_to_file_queue(req.body.uuid, temp_detected.unknown, true, argv)
794 }
795 if ('failed' in temp_detected) {
796 helper.log_to_file_queue(req.body.uuid, '[failed] ' + temp_detected.failed.length + ' Profile[s]')
797 helper.log_to_file_queue(req.body.uuid, temp_detected.failed, true, argv)
798 }
799 }
800
801 if (argv.output === 'json') {
802 console.log(JSON.stringify(temp_detected, null, 2))
803 }
804 }
805 };
806
807 async function list_all_websites () {
808 const temp_arr = []
809 await helper.websites_entries.forEach(item => {
810 temp_arr.push(helper.get_site_from_url(item.url))
811 })
812
813 console.log('[Listing] Available websites\n' + temp_arr.join('\n'))
814 }
815
816 let server_host = 'localhost'
817 const server_port = process.env.PORT || 9005
818
819 if (argv.grid !== '') {
820 helper.grid_url = argv.grid
821 }
822 if (argv.docker) {
823 server_host = '0.0.0.0'
824 }
825 if (argv.gui) {
826 app.listen(server_port, server_host, function () {
827 // helper.setup_tecert()
828 console.log('Server started at http://%s:%s/app.html', server_host, server_port)
829 })
830 } else {
831 if (argv.list) {
832 list_all_websites()
833 } else if (argv.mode === 'fast') {
834 if (argv.cli) {
835 console.log('[Warning] --cli is not needed and will be removed later on')
836 }
837 if (argv.username !== '' && argv.websites !== '') {
838 check_user_cli(argv)
839 }
840 }
841 }
842
842 lines JAVASCRIPT