From 060a7c0cb1beafd103c5837ab0afa92b0d1a3ede Mon Sep 17 00:00:00 2001 From: G <52905881+giga-a@users.noreply.github.com> Date: Fri, 15 Jan 2021 13:30:08 -0800 Subject: [PATCH] [auto-b] 2021.V.2.14 Added detection levels (High & Extreme) - ref 67a63dbb --- README.md | 6 +- app.js | 40 +-- beautify_json_files.sh | 25 ++ info | 7 +- modules/external-apis.js | 153 +++++++++ modules/fast-scan.js | 113 +++++++ modules/helper.js | 48 ++- modules/name-analysis.js | 83 +++++ modules/slow-scan.js | 213 ++++++++++++ modules/special.js | 33 +- modules/string-analysis.js | 229 +++++++++++++ sites.json | 674 ++++++++++++++++++------------------- 12 files changed, 1230 insertions(+), 394 deletions(-) create mode 100644 beautify_json_files.sh create mode 100644 modules/external-apis.js create mode 100644 modules/fast-scan.js create mode 100644 modules/name-analysis.js create mode 100644 modules/slow-scan.js create mode 100644 modules/string-analysis.js diff --git a/README.md b/README.md index de8db5c..f310630 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,14 @@ API, CLI & Web App for analyzing & finding a person profile across +300 social m The detection modules utilize a rating mechanism based on different detection techniques, which produces a rate value that starts from 0 to 100 (No-Maybe-Yes) -This project *is currently used by some law enforcement agencies in countries where resources are limited*. It could help in investigating profiles related to suspicious or malicious activities such as [cyberbullying](https://en.wikipedia.org/wiki/Wikipedia:Cyberbullying), [cybergrooming](https://de.wikipedia.org/wiki/Cyber-Grooming) & [cyberstalking](https://en.wikipedia.org/wiki/Cyberstalking), [spreading misinformation](https://en.wikipedia.org/wiki/Misinformation) +This project *is currently used by some law enforcement agencies in countries where resources are limited*. + +The results from the analysis could help in investigating profiles related to suspicious or malicious activities such as [cyberbullying](https://en.wikipedia.org/wiki/Wikipedia:Cyberbullying), [cybergrooming](https://de.wikipedia.org/wiki/Cyber-Grooming) & [cyberstalking](https://en.wikipedia.org/wiki/Cyberstalking), [spreading misinformation](https://en.wikipedia.org/wiki/Misinformation) **All Pull Requests are welcomed!** ## Updates -- (Testing) high & extreme detection level (This checks if detection meets the requirement or not) +- Added detection levels (This checks if detection meets the requirement or not) - Added dynamic language detections for profiles - Added --websites "all" for python & NodeJS CLI (You can scan ALL the websites within 2~10 seconds) - Added a new refactored version diff --git a/app.js b/app.js index 8a355e7..56b8f7b 100644 --- a/app.js +++ b/app.js @@ -58,12 +58,12 @@ require('express-async-errors'); var _tokenizer = tokenizer(); var helper = require("./modules/helper.js") -var fastscan = require("./modules/fastscan.js") -var slowscan = require("./modules/slowscan.js") +var fastScan = require("./modules/fast-scan.js") +var slowScan = require("./modules/slow-scan.js") var special = require("./modules/special.js") -var externalapis = require("./modules/externalapis.js") -var stringanalysis = require("./modules/stringanalysis.js") -var nameanalysis = require("./modules/nameanalysis.js") +var externalApis = require("./modules/external-apis.js") +var stringAnalysis = require("./modules/string-analysis.js") +var nameAnalysis = require("./modules/name-analysis.js") if (!fs.existsSync('logs')) { fs.mkdirSync('logs'); @@ -230,7 +230,7 @@ app.post("/analyze_string", async function(req, res, next) { } if (req.body.option.includes("FindUserProfilesFast")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Checking user profiles normal") - user_info_advanced.data = await fastscan.find_username_normal(req); + user_info_advanced.data = await fastScan.find_username_normal(req); helper.log_to_file_queue(req.body.uuid, "[Done] Checking user profiles normal") } if (req.body.option.includes("FindUserProfilesSlow") || req.body.option.includes("ShowUserProfilesSlow")) { @@ -240,49 +240,49 @@ app.post("/analyze_string", async function(req, res, next) { user_info_normal.type = "noshow" } helper.log_to_file_queue(req.body.uuid, "[Starting] Checking user profiles advanced") - user_info_normal.data = await slowscan.find_username_advanced(req); + user_info_normal.data = await slowScan.find_username_advanced(req); helper.log_to_file_queue(req.body.uuid, "[Done] Checking user profiles advanced") } if (req.body.option.includes("LookUps")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Lookup") - await externalapis.check_engines(req, info); + await externalApis.check_engines(req, info); helper.log_to_file_queue(req.body.uuid, "[Done] Lookup") } if (req.body.option.includes("CustomSearch")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Custom Search") - custom_search = await externalapis.custom_search_ouputs(req); + custom_search = await externalApis.custom_search_ouputs(req); helper.log_to_file_queue(req.body.uuid, "[Done] Custom Search") } if (req.body.option.includes("FindOrigins")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Finding Origins") - names_origins = await nameanalysis.find_origins(req); + names_origins = await nameAnalysis.find_origins(req); helper.log_to_file_queue(req.body.uuid, "[Done] Finding Origins") } if (req.body.option.includes("SplitWordsByUpperCase")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Split by UpperCase") - await stringanalysis.split_upper_case(req,all_words) + await stringAnalysis.split_upper_case(req,all_words) helper.log_to_file_queue(req.body.uuid, "[Done] Split by UpperCase") } if (req.body.option.includes("SplitWordsByAlphabet")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Split by Alphabet") - await stringanalysis.split_alphabet_case(req,all_words) + await stringAnalysis.split_alphabet_case(req,all_words) helper.log_to_file_queue(req.body.uuid, "[Done] Split by Alphabet") } if (req.body.option.includes("FindSymbols")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Finding Symbols") - await stringanalysis.find_symbols(req,all_words) + await stringAnalysis.find_symbols(req,all_words) helper.log_to_file_queue(req.body.uuid, "[Done] Finding Symbols") } if (req.body.option.includes("FindNumbers")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Finding Numbers") - await stringanalysis.find_numbers(req,all_words) + await stringAnalysis.find_numbers(req,all_words) helper.log_to_file_queue(req.body.uuid, "[Done] Finding Numbers") } req.body.string = req.body.string.toLowerCase(); if (req.body.option.includes("ConvertNumbers")) { helper.log_to_file_queue(req.body.uuid, "[Starting] Convert Numbers") - await stringanalysis.convert_numbers(req,all_words) + await stringAnalysis.convert_numbers(req,all_words) helper.log_to_file_queue(req.body.uuid, "[Done] Convert Numbers") } @@ -295,16 +295,16 @@ app.post("/analyze_string", async function(req, res, next) { req.body.option.includes("FindNumbers") || req.body.option.includes("ConvertNumbers")) { - await stringanalysis.get_maybe_words(req, all_words) - await stringanalysis.analyze_string(req, all_words); + await stringAnalysis.get_maybe_words(req, all_words) + await stringAnalysis.analyze_string(req, all_words); Object.keys(all_words).forEach((key) => (all_words[key].length == 0) && delete all_words[key]); if (req.body.option.includes("MostCommon")) { - await stringanalysis.most_common(all_words, temp_words); + await stringAnalysis.most_common(all_words, temp_words); } if (req.body.option.includes("WordInfo")) { - await externalapis.get_words_info(all_words, words_info); + await externalApis.get_words_info(all_words, words_info); } } else if (req.body.option.includes("NormalAnalysis@@")) { //var maybe_words = WordsNinja.splitSentence(req.body.string); @@ -386,7 +386,7 @@ async function check_user_cli(argv) { }); } - ret = await fastscan.find_username_normal(req) + ret = await fastScan.find_username_normal(req) if (typeof ret === 'undefined' || ret === undefined || ret.length == 0) { helper.log_to_file_queue(req.body.uuid, 'User does not exist (try FindUserProfilesSlow or FindUserProfilesSpecial)'); } else { diff --git a/beautify_json_files.sh b/beautify_json_files.sh new file mode 100644 index 0000000..be5fce7 --- /dev/null +++ b/beautify_json_files.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +#qeeqbox/social-analyzer +#Please use this cleaner & formatter script after adding detections + +echo "[Cleaning] sites.json" +tmp_file=$(mktemp) +cat sites.json | jq 'sort_by(.url)' > $tmp_file +cat $tmp_file > sites.json +rm -f $tmp_file +echo "[Done] sites.json" + +echo "[Cleaning] names.json" +tmp_file=$(mktemp) +cat names.json | jq . > $tmp_file +cat $tmp_file > names.json +rm -f $tmp_file +echo "[Done] names.json" + +echo "[Cleaning] dict.json" +tmp_file=$(mktemp) +cat dict.json | jq . > $tmp_file +cat $tmp_file > dict.json +rm -f $tmp_file +echo "[Done] dict.json" diff --git a/info b/info index d2ef5f6..e4c3941 100644 --- a/info +++ b/info @@ -1,10 +1,11 @@ -{"version":"2021.V.2.13", +{"version":"2021.V.2.14", "build":"pass", "test":"pass", "grid_test":"pass", "websites":"346", "detections":"946", "special":"3", - "full_scan":"2-9s", + "levels":"High & Extreme", + "full_scan":"2-14s", "awaiting_verification":"22", - "auto_testing":"044fd42f-092c-4e43-9c6b-9ece092db947"} + "auto_testing":"8b75bdda-9021-423f-b046-badd744e785f"} diff --git a/modules/external-apis.js b/modules/external-apis.js new file mode 100644 index 0000000..51408ac --- /dev/null +++ b/modules/external-apis.js @@ -0,0 +1,153 @@ +var helper = require("./helper.js") +var async = require("async"); + +async function get_words_info(all_words, words_info) { + var temp_added = [] + for (let all_words_key of Object.keys(all_words)) { + for (let all_words_word of all_words[all_words_key]) { + if (!temp_added.includes(all_words_word)) { + temp_added.push(all_words_word); + var temp_words_info = { + "word": all_words_word, + "text": "", + "results": [] + } + try { + var url1 = "https://api.duckduckgo.com/?q={0}&format=json&pretty=1&no_html=1&skip_disambig=1".replace("{0}", all_words_word); + var url2 = "https://api.duckduckgo.com/?q={0}&format=json&pretty=1".replace("{0}", all_words_word); + var response1 = await helper.get_url_wrapper_json(url1); + var response2 = await helper.get_url_wrapper_json(url2); + if (response2.data != '') { + if ("RelatedTopics" in response2.data) { + if (response2.data.RelatedTopics.length > 0) { + if (response2.data != '') { + if ("AbstractText" in response1.data && response1.data.AbstractText != "") { + temp_words_info.text = response1.data.AbstractText; + } else if ("Abstract" in response1.data && response1.data.AbstractText != "") { + temp_words_info.text = response1.data.Abstract; + } else { + temp_words_info.text = "unknown"; + } + } + response2.data.RelatedTopics.forEach(function(item) { + if ("Name" in item) { + item.Topics.forEach(function(topic) { + temp_words_info.results.push({ + "type": item.Name, + "text": topic.Text, + "url": topic.FirstURL + }); + }); + } else { + temp_words_info.results.push({ + "type": "Related", + "text": item.Text, + "url": item.FirstURL + }); + } + }); + } + } + } + + if (temp_words_info.results.length > 0) { + words_info.push(temp_words_info); + } + } catch (error) { + helper.verbose && console.log(error); + } + } + } + } +} + +async function check_engines(req, info) { + try { + if (helper.google_api_key == "" || helper.google_api_cs == "") { + return + } + var url = "https://www.googleapis.com/customsearch/v1?key={0}&cx={1}&q={2}".replace("{0}", helper.google_api_key).replace("{1}", helper.google_api_cs).replace("{2}", req.body.string); + var response = await helper.get_url_wrapper_json(url); + if (response.data != '') { + try { + info.original = response.data.queries.request[0].searchTerms + } catch (e) {} + try { + info.corrected = response.data.spelling.correctedQuery + } catch (e) {} + try { + info.total = response.data.searchInformation.totalResults + } catch (e) {} + try { + response.data.items.forEach(function(item) { + info["items"].push({ + "title": item.title, + "snippet": item.snippet + }); + }); + } catch (e) {} + try { + if (info.total == 0 && info.corrected != "") { + info.checking = info.original + " [Error]
Try this: " + info.corrected; + } else if (info.total > 0 && info.corrected != "") { + info.checking = info.original + " [Good]
Suggested word: " + info.corrected + "
Total lookups: " + info.total; + } else if (info.total > 0 && info.corrected == "") { + info.checking = info.original + " [Good]
Total lookups: " + info.total; + } else { + info.checking = "Using " + info.original + " with no lookups"; + } + } catch (e) {} + } + } catch (error) { + helper.verbose && console.log(error); + } +} + +async function custom_search_ouputs(req) { + var possible_parameters = ['user', 'profile', 'account'] + const time = new Date(); + const functions = []; + possible_parameters.forEach((key) => { + functions.push(custom_search_ouputs_website.bind(null, req.body.uuid, req.body.string, key)); + }); + const results = await async.parallelLimit(functions, 6); + helper.verbose && console.log(`Total time ${new Date() - time}`); + var merged = [].concat.apply([], results.filter(item => item !== undefined)); + return merged +} + +async function custom_search_ouputs_website(uuid, name, key) { + + return new Promise(async (resolve, reject) => { + try { + var results = [] + helper.log_to_file_queue(uuid, "[Custom Search Using] " + key) + var url = "https://www.googleapis.com/customsearch/v1?key={0}&cx={1}&q={2}:{3}".replace("{0}", helper.google_api_key).replace("{1}", helper.google_api_cs).replace("{2}", key).replace("{3}", name); + var response = await helper.get_url_wrapper_json(url); + if (response.data != '') { + if ('items' in response.data) { + response.data.items.forEach((key) => { + results.push({ + site: helper.get_site_from_url(key.link), + link: key.link, + snippet: key.snippet + }) + }); + } + } + if (results.length > 0) { + resolve(results); + } else { + resolve(undefined) + } + } catch (err) { + resolve(undefined) + } + }); +} + +module.exports = { + check_engines, + get_words_info, + custom_search_ouputs +} diff --git a/modules/fast-scan.js b/modules/fast-scan.js new file mode 100644 index 0000000..5d50c12 --- /dev/null +++ b/modules/fast-scan.js @@ -0,0 +1,113 @@ +var helper = require("./helper.js") +var async = require("async"); +var sanitizeHtml = require("sanitize-html"); +var { + htmlToText +} = require('html-to-text'); +var cheerio = require('cheerio'); + +async function find_username_normal(req) { + const time = new Date(); + const functions = []; + await helper.parsed_sites.forEach(site => { + if ("status" in site) { + if (site.status == "bad") { + return Promise.resolve(); + } + } + if (site.selected == "true" && site.detections.length > 0) { + functions.push(find_username_site.bind(null, req.body.uuid, req.body.string, req.body.option, site)); + } + }); + const results = await async.parallelLimit(functions, 25); + helper.verbose && console.log(`Total time ${new Date() - time}`); + return results.filter(item => item !== undefined) +} + +async function find_username_site(uuid, username, options, site) { + return new Promise(async (resolve, reject) => { + try { + if (!options.includes('json')) { + helper.log_to_file_queue(uuid, "[Checking] " + helper.get_site_from_url(site.url)) + } + var body = await helper.get_url_wrapper_text(site.url.replace("{username}", username)); + var detections_count = 0; + var source = body; + var text_only = "unavailable"; + var title = "unavailable"; + var language = "unavailable" + var temp_profile = Object.assign({}, helper.profile_template); + var temp_detected = Object.assign({}, helper.detected_websites); + await Promise.all(site.detections.map(async detection => { + var temp_found = "false"; + if (detection.type == "normal" && options.includes("FindUserProfilesFast") && source != "" && helper.detection_level[helper.detection_level.current].types.includes(detection.type)) { + detections_count += 1 + temp_detected.count += 1 + if (source.toLowerCase().includes(detection.string.replace("{username}", username).toLowerCase())) { + temp_found = "true"; + } + if (detection.return == temp_found) { + temp_profile.found += 1 + temp_detected.normal += 1 + if (detection.return == 'true'){ + temp_detected.true += 1 + }else{ + temp_detected.false += 1 + } + } + } + //helper.verbose && console.log("[Requirement] " + site.url.replace("{username}", username)+ " Dosn't meet meet detection level"); + + })); + + helper.verbose && console.log({"Temp Profile":temp_profile,"Detected":temp_detected}) + + if (temp_profile.found >= helper.detection_level[helper.detection_level.current].found && detections_count >= helper.detection_level[helper.detection_level.current].count) { + temp_profile.text = sanitizeHtml(htmlToText(body, { + wordwrap: false, + hideLinkHrefIfSameAsText: true, + ignoreHref: true, + ignoreImage: true + })); + if (temp_profile.text == "") { + temp_profile.text = "unavailable" + } + + try { + var $ = cheerio.load(body); + title = sanitizeHtml($("title").text()) + if (title.length == 0) { + title = "unavailable" + } + } catch (err) { + helper.verbose && console.log(err); + } + + try{ + language = helper.get_language_by_parsing(body) + if (language == "unavailable"){ + language = helper.get_language_by_guessing(temp_profile.text) + } + } + catch(err){ + helper.verbose && console.log(err); + } + + temp_profile.title = title; + temp_profile.language = language; + temp_profile.rate = "%" + ((temp_profile["found"] / detections_count) * 100).toFixed(2); + temp_profile.link = site.url.replace("{username}", username); + temp_profile.type = site.type + resolve(temp_profile); + } else { + resolve(undefined) + } + } catch (err) { + resolve(undefined) + } + }); +} + +module.exports = { + find_username_normal +} diff --git a/modules/helper.js b/modules/helper.js index 81f1ee2..867ee0f 100644 --- a/modules/helper.js +++ b/modules/helper.js @@ -4,6 +4,42 @@ var google_api_cs = ""; var grid_url = ""; var proxy = "" +var detection_level = { + "extreme": { + "types": "normal,advanced,ocr", + "detections": "true", + "count":1, + "found":2 + }, + "high": { + "types": "normal,advanced,ocr", + "detections": "true,false", + "count":1, + "found":1 + }, + "current":"high" +} + +var profile_template = { + "found": 0, + "image": "", + "link": "", + "rate": "", + "title": "", + "language": "", + "text": "", + "type": "" +}; + +var detected_websites = { + "normal":0, + "advanced":0, + "ocr":0, + "true":0, + "false":0, + "count":0, +} + var header_options = { headers: { 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0', @@ -37,7 +73,9 @@ function get_language_by_parsing(body) { var $ = cheerio.load(body); var code = $("html").attr("lang") if (code != "") { - language = langs.where("1", code).name + if ('undefined' !== langs.where("1", code) && langs.where("1", code)){ + language = langs.where("1", code).name + } } } catch (err) { verbose && console.log(err); @@ -51,7 +89,10 @@ function get_language_by_guessing(text) { if (text != "unavailable" && text != "") { var code = franc(text); if (code !== 'und') { - language = langs.where("3", code).name + " (Maybe)" + if ('undefined' !== langs.where("3", code) && langs.where("3", code)) + { + language = langs.where("3", code).name + " (Maybe)" + } } } } catch (err) { @@ -131,6 +172,9 @@ async function get_url_wrapper_text(url, time = 5) { } module.exports = { + profile_template, + detection_level, + detected_websites, get_language_by_parsing, get_language_by_guessing, parsed_sites, diff --git a/modules/name-analysis.js b/modules/name-analysis.js new file mode 100644 index 0000000..bd0b4a9 --- /dev/null +++ b/modules/name-analysis.js @@ -0,0 +1,83 @@ +var helper = require("./helper.js") +var fs = require("fs"); +var stringSimilarity = require("string-similarity"); + +var parsed_names_origins = JSON.parse(fs.readFileSync("names.json")); + +async function find_origins(req) { + var found = [] + for (key in parsed_names_origins) { + for (name in parsed_names_origins[key]['boy']) { + if (req.body.string.includes(parsed_names_origins[key]['boy'][name])) { + found.push({ + "name": parsed_names_origins[key]['boy'][name], + "origin": key, + "gender": "boy", + "matched": parsed_names_origins[key]['boy'][name], + "similar": "" + }) + } else { + var similarity = stringSimilarity.compareTwoStrings(req.body.string, parsed_names_origins[key]['boy'][name]); + if (similarity > 0.7) { + found.push({ + "name": req.body.string, + "origin": key, + "gender": "boy", + "matched": "", + "similar": parsed_names_origins[key]['boy'][name] + }) + } + } + } + for (name in parsed_names_origins[key]['girl']) { + if (req.body.string.includes(parsed_names_origins[key]['girl'][name])) { + found.push({ + "name": parsed_names_origins[key]['girl'][name], + "origin": key, + "gender": "girl", + "matched": parsed_names_origins[key]['girl'][name], + "similar": "" + }) + } else { + var similarity = stringSimilarity.compareTwoStrings(req.body.string, parsed_names_origins[key]['girl'][name]); + if (similarity > 0.7) { + found.push({ + "name": req.body.string, + "origin": key, + "gender": "girl", + "matched": "", + "similar": parsed_names_origins[key]['girl'][name] + }) + } + } + } + for (name in parsed_names_origins[key]['uni']) { + if (req.body.string.includes(parsed_names_origins[key]['uni'][name])) { + found.push({ + "name": parsed_names_origins[key]['uni'][name], + "origin": key, + "gender": "uni", + "matched": parsed_names_origins[key]['uni'][name], + "similar": "" + }) + } else { + var similarity = stringSimilarity.compareTwoStrings(req.body.string, parsed_names_origins[key]['uni'][name]); + if (similarity > 0.7) { + found.push({ + "name": req.body.string, + "origin": key, + "gender": "uni", + "matched": "", + "similar": parsed_names_origins[key]['uni'][name] + }) + } + } + } + } + + return found +} + +module.exports = { + find_origins +} diff --git a/modules/slow-scan.js b/modules/slow-scan.js new file mode 100644 index 0000000..3a15b1b --- /dev/null +++ b/modules/slow-scan.js @@ -0,0 +1,213 @@ +var helper = require("./helper.js") +var async = require("async"); +var sanitizeHtml = require("sanitize-html"); +var tesseract = require("node-tesseract-ocr"); +var sanitizeHtml = require("sanitize-html"); +var firefox = require("selenium-webdriver/firefox"); +var { + Builder, + By, + Key +} = require("selenium-webdriver"); +var tmp = require("tmp"); +var fs = require("fs"); + +async function find_username_advanced(req) { + const time = new Date(); + const functions = []; + helper.parsed_sites.forEach((site) => { + if ("status" in site) { + if (site.status == "bad") { + return Promise.resolve(); + } + } + if (site.selected == "true" && site.detections.length > 0) { + functions.push(find_username_site.bind(null, req.body.uuid, req.body.string, req.body.option, site)); + } + }); + const results = await async.parallelLimit(functions, 8); + helper.verbose && console.log(`Total time ${new Date() - time}`); + return results.filter(item => item !== undefined) +} + +async function find_username_site(uuid, username, options, site) { + return new Promise(async (resolve, reject) => { + helper.log_to_file_queue(uuid, "[Checking] " + helper.get_site_from_url(site.url)) + let driver = undefined + if (helper.grid_url == "") { + driver = new Builder() + .forBrowser("firefox") + .setFirefoxOptions(new firefox.Options().headless().windowSize({ + width: 640, + height: 480 + })) + .build(); + } else { + driver = new Builder() + .forBrowser("firefox") + .setFirefoxOptions(new firefox.Options().headless().windowSize({ + width: 640, + height: 480 + })) + .usingServer(helper.grid_url) + .build(); + } + + try { + + var timeouts = { + implicit: 0, + pageLoad: 5000, + script: 5000 + }; + + var timeout = (site.timeout != 0) ? site.timeout * 1000 : 5000; + var implicit = (site.implicit != 0) ? site.implicit * 1000 : 0; + + timeouts = { + implicit: implicit, + pageLoad: timeout, + script: timeout + }; + + helper.verbose && console.log(timeouts) + + var source = ""; + var data = ""; + var language = "unavailable" + var text_only = "unavailable"; + var title = "unavailable"; + var detections_count = 0; + var temp_profile = Object.assign({}, helper.profile_template); + var temp_detected = Object.assign({}, helper.detected_websites); + var link = site.url.replace("{username}", username); + await driver.manage().setTimeouts(timeouts); + await driver.get(link);; + source = await driver.getPageSource(); + data = await driver.takeScreenshot(); + title = await driver.getTitle(); + text_only = await driver.findElement(By.tagName("body")).getText(); + await driver.quit() + if (options.includes("ShowUserProfilesSlow")) { + temp_profile["image"] = "data:image/png;base64,{image}".replace("{image}", data); + } + await Promise.all(site.detections.map(async detection => { + if (options.includes("FindUserProfilesSlow") && source != "" && helper.detection_level[helper.detection_level.current].types.includes(detection.type)) { + try { + detections_count += 1 + temp_detected.count += 1 + var temp_found = "false" + if (detection.type == "ocr" && data != "") { + tmpobj = tmp.fileSync(); + fs.writeFileSync(tmpobj.name, Buffer.from(data, "base64")); + await tesseract.recognize(tmpobj.name, { + lang: "eng", + oem: 1, + psm: 3, + }) + .then(text => { + text = text.replace(/[^A-Za-z0-9]/gi, ""); + detection.string = detection.string.replace(/[^A-Za-z0-9]/gi, ""); + if (text != "") { + if (text.toLowerCase().includes(detection.string.toLowerCase())) { + temp_found = "true"; + } + + if (detection.return == temp_found) { + temp_profile.found += 1 + temp_detected.ocr += 1 + if (detection.return == 'true'){ + temp_detected.true += 1 + }else{ + temp_detected.false += 1 + } + } + } + }) + .catch(error => { + helper.verbose && console.log(error.message); + }) + tmpobj.removeCallback(); + } else if (detection.type == "normal" && source != "") { + if (source.toLowerCase().includes(detection.string.replace("{username}", username).toLowerCase())) { + temp_found = "true"; + } + + if (detection.return == temp_found) { + temp_profile.found += 1 + temp_detected.normal += 1 + if (detection.return == 'true'){ + temp_detected.true += 1 + }else{ + temp_detected.false += 1 + } + } + } else if (detection.type == "advanced" && text_only != "") { + if (text_only.toLowerCase().includes(detection.string.replace("{username}", username).toLowerCase())) { + temp_found = "true"; + } + + if (detection.return == temp_found) { + temp_profile.found += 1 + temp_detected.advanced += 1 + if (detection.return == 'true'){ + temp_detected.true += 1 + }else{ + temp_detected.false += 1 + } + } + } + } catch (err) { + helper.verbose && console.log(err); + } + } + })); + + helper.verbose && console.log({"Temp Profile":temp_profile,"Detected":temp_detected}) + + if (temp_profile.found >= helper.detection_level[helper.detection_level.current].found && detections_count >= helper.detection_level[helper.detection_level.current].count){ + try { + language = helper.get_language_by_parsing(source) + if (language == "unavailable") { + language = helper.get_language_by_guessing(text_only) + } + } catch (err) { + helper.verbose && console.log(err); + } + + temp_profile.text = sanitizeHtml(text_only); + temp_profile.title = sanitizeHtml(title); + temp_profile.language = language + temp_profile.rate = "%" + ((temp_profile.found / site.detections.length) * 100).toFixed(2); + temp_profile.link = site.url.replace("{username}", username); + temp_profile.type = site.type + resolve(temp_profile); + } + else if (temp_profile.image != ""){ + temp_profile.text = "unavailable"; + temp_profile.title = "unavailable"; + temp_profile.language = "unavailable" + temp_profile.rate = "%00.0" + temp_profile.link = site.url.replace("{username}", username); + temp_profile.type = site.type + resolve(temp_profile); + } + else { + resolve(undefined) + } + } catch (err) { + if (driver !== undefined) { + try { + await driver.quit() + } catch (err) { + helper.verbose && console.log("Driver Session Issue") + } + } + resolve(undefined) + } + }); +} + +module.exports = { + find_username_advanced +} diff --git a/modules/special.js b/modules/special.js index 33a1cbf..88008f0 100644 --- a/modules/special.js +++ b/modules/special.js @@ -60,16 +60,7 @@ async function find_username_site_special_facebook_1(uuid, username, site) { var data = ""; var text_only = "unavailable"; var title = "unavailable"; - var temp_profile = { - "found": 0, - "image": "", - "link": "", - "rate": "", - "title": "", - "language": "", - "text": "", - "type": "" - }; + var temp_profile = Object.assign({}, helper.profile_template); var link = "https://mbasic.facebook.com/login/identify/?ctx=recoveqr"; await driver.manage().setTimeouts(timeouts); await driver.get(link);; @@ -127,16 +118,7 @@ async function find_username_site_special_gmail_1(uuid, username, site) { var data = ""; var text_only = "unavailable"; var title = "unavailable"; - var temp_profile = { - "found": 0, - "image": "", - "link": "", - "rate": "", - "title": "", - "language": "", - "text": "", - "type": "" - }; + var temp_profile = Object.assign({}, helper.profile_template); var link = "https://accounts.google.com/signup/v2/webcreateaccount?service=mail&continue=https%3A%2F%2Fmail.google.com%2Fmail%2F%3Fpc%3Dtopnav-about-n-en&flowName=GlifWebSignIn&flowEntry=SignUp"; await driver.manage().setTimeouts(timeouts); await driver.get(link);; @@ -194,16 +176,7 @@ async function find_username_site_special_google_1(uuid, username, site) { var data = ""; var text_only = "unavailable"; var title = "unavailable"; - var temp_profile = { - "found": 0, - "image": "", - "link": "", - "rate": "", - "title": "", - "language": "", - "text": "", - "type": "" - }; + var temp_profile = Object.assign({}, helper.profile_template); var link = "https://accounts.google.com/signin/v2/identifier?continue=https%3A%2F%2Fmail.google.com%2Fmail%2F&service=mail&sacu=1&rip=1&flowName=GlifWebSignIn&flowEntry=ServiceLogin"; await driver.manage().setTimeouts(timeouts); await driver.get(link);; diff --git a/modules/string-analysis.js b/modules/string-analysis.js new file mode 100644 index 0000000..17904ca --- /dev/null +++ b/modules/string-analysis.js @@ -0,0 +1,229 @@ +var helper = require("./helper.js") +var { + findWord +} = require("most-common-words-by-language"); +var fs = require("fs"); +var parsed_json = JSON.parse(fs.readFileSync("dict.json")); +var WordsNinjaPack = require("wordsninja"); +var WordsNinja = new WordsNinjaPack(); + +function most_common1(all_words, temp_words) { + var temp_list = [] + Object.keys(all_words).forEach(function(key) { + all_words[key].forEach(function(item) { + if (!temp_list.includes(item) && item.length > 1) { + temp_list.push(item); + var temp = findWord(item); + if (Object.keys(temp).length != 0) { + var languages = Object.keys(temp).map(function(key) { + return [key, temp[key]]; + }); + languages.sort(function(first, second) { + return second[1] - first[1] + }).reverse(); + temp_words.push({ + "word": item, + "languages": languages.map(e => e.join(":")).join(" ") + }); + } + } + }); + }); +} + +async function most_common(all_words, temp_words) { + var temp_list = [] + Object.keys(all_words).forEach(function(key) { + all_words[key].forEach(function(item) { + if (!temp_list.includes(item) && item.length > 1) { + temp_list.push(item); + var temp = findWord(item); + if (Object.keys(temp).length != 0) { + var languages = Object.keys(temp).map(function(key) { + return [key, temp[key]]; + }); + languages.sort(function(first, second) { + return second[1] - first[1] + }).reverse(); + temp_words.push({ + "word": item, + "languages": languages.map(e => e[0]).join(", ") + }); + } + } + }); + }); +} + +function find_other(all_words) { + var words = WordsNinja.splitSentence(req.body.string); + + words.forEach(function(word) { + var value = false + Object.keys(all_words).forEach(function(key) { + if (all_words[key].includes(word)) { + value = true + } + }); + + if (!value && !all_words.maybe.includes(word)) { + all_words.maybe.push(word); + } + }); +} + +function remove_word(str, sub_string) { + part1 = str.substring(0, str.indexOf(sub_string)); + part2 = str.substring(str.indexOf(sub_string) + sub_string.length, str.length); + temp = (part1 + part2).replace(/[ \[\]:"\\|,.<>\/?~`!@#$%^&*()_+\-={};"]/gi, ""); + return temp; +} + +async function analyze_string(req, all_words) { + helper.log_to_file_queue(req.body.uuid, "[Starting] String analysis") + temp_rr_names = [] + string_to_check = req.body.string + parsed_json.prefix.forEach(function(item, index) { + if (string_to_check.indexOf(item) == 0 && !all_words.prefix.includes(item)) { + all_words.prefix.push(item); + temp = remove_word(string_to_check, item); + if (temp !== null && temp !== "" && !all_words.unknown.includes(temp) && !all_words.maybe.includes(temp) && temp.length > 1) { + all_words.unknown.push(temp); + } + } + }); + parsed_json.m_names.forEach(function(item, index) { + if (string_to_check.indexOf(item) >= 0 && !all_words.name.includes(item)) { + all_words.name.push(item); + temp = remove_word(string_to_check, item); + if (temp !== null && temp !== "" && !all_words.unknown.includes(temp) && !all_words.maybe.includes(temp) && temp.length > 1) { + all_words.unknown.push(temp); + } + } + }); + parsed_json.f_names.forEach(function(item, index) { + if (string_to_check.indexOf(item) >= 0 && !all_words.name.includes(item)) { + all_words.name.push(item); + temp = remove_word(string_to_check, item); + if (temp !== null && temp !== "" && !all_words.unknown.includes(temp) && !all_words.maybe.includes(temp) && temp.length > 1) { + all_words.unknown.push(temp); + } + } + }); + + all_words.prefix.forEach(function(h_item, index) { + all_words.unknown.forEach(function(r_item, index) { + if (r_item.indexOf(h_item) == 0) { + temp = remove_word(r_item, h_item); + if (temp !== null && temp !== "" && !temp_rr_names.includes(temp) && !all_words.maybe.includes(temp) && temp.length > 1) { + temp_rr_names.push(temp); + } + } + }); + }); + + var temp_r_concat = all_words.unknown.concat(temp_rr_names.filter((item) => all_words.unknown.indexOf(item) < 0)); + + all_words.unknown = temp_r_concat + temp_rr_names = [] + + all_words.number.forEach(function(n_item, index) { + all_words.unknown.forEach(function(r_item, index) { + if (r_item.indexOf(n_item) >= 0) { + temp = remove_word(r_item, n_item); + if (temp !== null && temp !== "" && !temp_rr_names.includes(temp) && !all_words.maybe.includes(temp) && temp.length > 1) { + temp_rr_names.push(temp); + } + } + }); + }); + + var temp_r_concat = all_words.unknown.concat(temp_rr_names.filter((item) => all_words.unknown.indexOf(item) < 0)); + all_words.unknown = temp_r_concat + helper.log_to_file_queue(req.body.uuid, "[Done] String analysis") +} + +async function split_upper_case(req, all_words) { + try { + req.body.string.match(/[A-Z][a-z]+/g).forEach((item) => { + if (item.length > 1 && !all_words.unknown.includes(item) && !all_words.maybe.includes(item)) { + all_words.unknown.push(item.toLowerCase()); + } + }); + } catch (err) {} +} + +async function split_alphabet_case(req, all_words) { + try { + req.body.string.match(/[A-Za-z]+/g).forEach((item) => { + if (item.length > 1 && !all_words.unknown.includes(item) && !all_words.maybe.includes(item)) { + all_words.unknown.push(item.toLowerCase()); + } + }); + } catch (err) {} +} + +async function find_symbols(req, all_words) { + try { + req.body.string.match(/[ \[\]:"\\|,.<>\/?~`!@#$%^&*()_+\-={};']/gi).forEach((item) => { + if (item !== " " && !all_words.symbol.includes(item)) { + all_words.symbol.push(item); + } + }); + } catch (err) {} +} + +async function find_numbers(req, all_words) { + try { + req.body.string.match(/(\d+)/g).forEach((item) => { + if (!all_words.number.includes(item)) { + all_words.number.push(item); + } + }); + } catch (err) {} +} + +async function convert_numbers(req) { + try { + numbers_to_letters = { + "4": "a", + "8": "b", + "3": "e", + "1": "l", + "0": "o", + "5": "s", + "7": "t", + "2": "z" + } + + temp_value = "" + for (i = 0; i < req.body.string.length; i++) { + _temp = numbers_to_letters[req.body.string.charAt(i)] + if (_temp != undefined) { + temp_value += numbers_to_letters[req.body.string.charAt(i)]; + } else { + temp_value += req.body.string.charAt(i); + } + } + req.body.string = temp_value + } catch (err) {} +} + +async function get_maybe_words(req, all_words) { + await WordsNinja.loadDictionary(); + all_words.maybe = await WordsNinja.splitSentence(req.body.string).filter(function(elem, index, self) { + return index === self.indexOf(elem); + }).filter(word => word.length > 1); +} + +module.exports = { + get_maybe_words, + find_symbols, + find_numbers, + convert_numbers, + split_upper_case, + split_alphabet_case, + most_common, + find_other, + analyze_string +} diff --git a/sites.json b/sites.json index ed6b368..c323b7c 100644 --- a/sites.json +++ b/sites.json @@ -998,6 +998,25 @@ "implicit": 0, "type": "Internet and Telecom" }, + { + "url": "https://codeberg.com/{username}", + "detections": [ + { + "return": "false", + "string": "does not exist", + "type": "normal" + }, + { + "return": "true", + "string": "\"profile\"", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "Projects Archive" + }, { "url": "https://codechef.com/users/{username}", "detections": [ @@ -2274,38 +2293,6 @@ "implicit": 0, "type": "Social networking service" }, - { - "url": "https://gmail.com/{username}", - "detections": [ - { - "return": "true", - "string": "", - "function": "special_gmail_1", - "type": "special" - } - ], - "selected": "false", - "top": "top10", - "timeout": 0, - "implicit": 0, - "type": "Social networking service" - }, - { - "url": "https://google.com/{username}", - "detections": [ - { - "return": "true", - "string": "", - "function": "special_google_1", - "type": "special" - } - ], - "selected": "false", - "top": "top10", - "timeout": 0, - "implicit": 0, - "type": "Social networking service" - }, { "url": "https://facenama.com/{username}", "detections": [ @@ -2936,6 +2923,35 @@ "implicit": 0, "type": "Audio clip sharing" }, + { + "url": "https://gaiaonline.com/profiles/{username}", + "detections": [ + { + "return": "false", + "string": "General Error", + "type": "ocr" + }, + { + "return": "false", + "string": "General Error", + "type": "normal" + }, + { + "return": "true", + "string": "about_title", + "type": "normal" + }, + { + "return": "true", + "string": "\"username\">", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "unavailable" + }, { "url": "https://gamefaqs.gamespot.com/community/{username}", "detections": [ @@ -3221,6 +3237,41 @@ "implicit": 0, "type": "GitLab instance" }, + { + "url": "https://gitmemory.com/{username}", + "detections": [ + { + "return": "false", + "string": "404<", + "type": "normal" + }, + { + "return": "true", + "string": "user-name", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "Projects Archive" + }, + { + "url": "https://gmail.com/{username}", + "detections": [ + { + "return": "true", + "string": "", + "function": "special_gmail_1", + "type": "special" + } + ], + "selected": "false", + "top": "top10", + "timeout": 0, + "implicit": 0, + "type": "Social networking service" + }, { "url": "https://goodreads.com/{username}", "detections": [ @@ -3240,6 +3291,22 @@ "implicit": 0, "type": "Book" }, + { + "url": "https://google.com/{username}", + "detections": [ + { + "return": "true", + "string": "", + "function": "special_google_1", + "type": "special" + } + ], + "selected": "false", + "top": "top10", + "timeout": 0, + "implicit": 0, + "type": "Social networking service" + }, { "url": "https://gotinder.com/@{username}", "detections": [ @@ -3430,6 +3497,25 @@ "timeout": 0, "implicit": 0 }, + { + "url": "https://heavy-r.com/user/{username}", + "detections": [ + { + "return": "false", + "string": "Channel not found", + "type": "normal" + }, + { + "return": "true", + "string": "member-info", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "unavailable" + }, { "url": "https://hellboundhackers.org/user/{username}.html", "detections": [ @@ -3773,6 +3859,30 @@ "implicit": 0, "type": "unavailable" }, + { + "url": "https://influenster.com/{username}", + "detections": [ + { + "return": "false", + "string": "Page not found", + "type": "ocr" + }, + { + "return": "false", + "string": "Page not found", + "type": "normal" + }, + { + "return": "true", + "string": "@{username}", + "type": "advanced" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "unavailable" + }, { "url": "https://instagram.com/{username}", "detections": [ @@ -4569,6 +4679,20 @@ "implicit": 0, "type": "Review aggregator" }, + { + "url": "https://mix.com/{username}", + "detections": [ + { + "return": "true", + "string": "UserProfile", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "unavailable" + }, { "url": "https://mixcloud.com/{username}", "detections": [ @@ -6509,6 +6633,30 @@ "implicit": 0, "type": "unavailable" }, + { + "url": "https://steemit.com/@{username}", + "detections": [ + { + "return": "false", + "string": "This page doesn", + "type": "ocr" + }, + { + "return": "false", + "string": "This page doesn", + "type": "normal" + }, + { + "return": "true", + "string": "UserProfile", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "unavailable" + }, { "url": "https://strava.com/athletes/{username}", "detections": [ @@ -6668,6 +6816,25 @@ "implicit": 0, "type": "unavailable" }, + { + "url": "https://tnaflix.com/profile/{username}", + "detections": [ + { + "return": "false", + "string": "looking for is lost somewhere", + "type": "normal" + }, + { + "return": "true", + "string": "userProfileHeader", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "adult" + }, { "url": "https://tradingview.com/u/{username}", "detections": [ @@ -6830,6 +6997,25 @@ "implicit": 0, "type": "Live streaming" }, + { + "url": "https://udemy.com/user/{username}/", + "detections": [ + { + "return": "true", + "string": "-profile-", + "type": "normal" + }, + { + "return": "true", + "string": "about-me", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "unavailable" + }, { "url": "https://uid.me/{username}", "detections": [ @@ -6936,6 +7122,20 @@ "implicit": 0, "type": "unavailable" }, + { + "url": "https://v2ex.com/member/{username}", + "detections": [ + { + "return": "true", + "string": "号会员,加入于", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "Internet forum" + }, { "url": "https://venmo.com/{username}", "detections": [ @@ -7279,6 +7479,82 @@ "implicit": 0, "type": "unavailable" }, + { + "url": "https://xhamster.com/users/{username}", + "detections": [ + { + "return": "false", + "string": "User not found", + "type": "normal" + }, + { + "return": "true", + "string": "user-header", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "adult" + }, + { + "url": "https://xrares.com/user/{username}", + "detections": [ + { + "return": "false", + "string": "This user does not exist", + "type": "normal" + }, + { + "return": "true", + "string": "panel-body", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "unavailable" + }, + { + "url": "https://xvideos.com/profiles/{username}", + "detections": [ + { + "return": "false", + "string": "THIS PROFILE DOESN", + "type": "normal" + }, + { + "return": "true", + "string": "profile-title", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "adult" + }, + { + "url": "https://xxxbunker.com/users/{username}", + "detections": [ + { + "return": "false", + "string": "FILE NOT FOUND", + "type": "normal" + }, + { + "return": "true", + "string": "\"profile\"", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "adult" + }, { "url": "https://youpic.com/photographer/{username}", "detections": [ @@ -7626,6 +7902,35 @@ "implicit": 0, "type": "unavailable" }, + { + "url": "https://{username}.skyrock.com/profil", + "detections": [ + { + "return": "false", + "string": "Page not found", + "type": "ocr" + }, + { + "return": "false", + "string": "Page not found", + "type": "normal" + }, + { + "return": "true", + "string": "profil-zone", + "type": "normal" + }, + { + "return": "true", + "string": ":username", + "type": "normal" + } + ], + "selected": "false", + "timeout": 0, + "implicit": 0, + "type": "unavailable" + }, { "url": "https://{username}.slack.com", "detections": [], @@ -7754,310 +8059,5 @@ "timeout": 0, "implicit": 0, "type": "unavailable" - }, - { - "url": "https://udemy.com/user/{username}/", - "detections": [ - { - "return": "true", - "string": "-profile-", - "type": "normal" - }, - { - "return": "true", - "string": "about-me", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "unavailable" - }, - { - "url": "https://heavy-r.com/user/{username}", - "detections": [ - { - "return": "false", - "string": "Channel not found", - "type": "normal" - }, - { - "return": "true", - "string": "member-info", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "unavailable" - }, - { - "url": "https://xrares.com/user/{username}", - "detections": [ - { - "return": "false", - "string": "This user does not exist", - "type": "normal" - }, - { - "return": "true", - "string": "panel-body", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "unavailable" - }, - { - "url": "https://xvideos.com/profiles/{username}", - "detections": [ - { - "return": "false", - "string": "THIS PROFILE DOESN", - "type": "normal" - }, - { - "return": "true", - "string": "profile-title", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "adult" - }, - { - "url": "https://tnaflix.com/profile/{username}", - "detections": [ - { - "return": "false", - "string": "looking for is lost somewhere", - "type": "normal" - }, - { - "return": "true", - "string": "userProfileHeader", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "adult" - }, - { - "url": "https://xhamster.com/users/{username}", - "detections": [ - { - "return": "false", - "string": "User not found", - "type": "normal" - }, - { - "return": "true", - "string": "user-header", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "adult" - }, - { - "url": "https://xxxbunker.com/users/{username}", - "detections": [ - { - "return": "false", - "string": "FILE NOT FOUND", - "type": "normal" - }, - { - "return": "true", - "string": "\"profile\"", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "adult" - }, - { - "url": "https://mix.com/{username}", - "detections": [ - { - "return": "true", - "string": "UserProfile", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "unavailable" - }, - { - "url": "https://{username}.skyrock.com/profil", - "detections": [ - { - "return": "false", - "string": "Page not found", - "type": "ocr" - }, - { - "return": "false", - "string": "Page not found", - "type": "normal" - }, - { - "return": "true", - "string": "profil-zone", - "type": "normal" - }, - { - "return": "true", - "string": ":username", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "unavailable" - }, - { - "url": "https://gaiaonline.com/profiles/{username}", - "detections": [ - { - "return": "false", - "string": "General Error", - "type": "ocr" - }, - { - "return": "false", - "string": "General Error", - "type": "normal" - }, - { - "return": "true", - "string": "about_title", - "type": "normal" - }, - { - "return": "true", - "string": "\"username\">", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "unavailable" - }, - { - "url": "https://steemit.com/@{username}", - "detections": [ - { - "return": "false", - "string": "This page doesn", - "type": "ocr" - }, - { - "return": "false", - "string": "This page doesn", - "type": "normal" - }, - { - "return": "true", - "string": "UserProfile", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "unavailable" - }, - { - "url": "https://influenster.com/{username}", - "detections": [ - { - "return": "false", - "string": "Page not found", - "type": "ocr" - }, - { - "return": "false", - "string": "Page not found", - "type": "normal" - }, - { - "return": "true", - "string": "@{username}", - "type": "advanced" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "unavailable" - }, - { - "url": "https://v2ex.com/member/{username}", - "detections": [ - { - "return": "true", - "string": "号会员,加入于", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "Internet forum" - }, - { - "url": "https://gitmemory.com/{username}", - "detections": [ - { - "return": "false", - "string": "404<", - "type": "normal" - }, - { - "return": "true", - "string": "user-name", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "Projects Archive" - }, - { - "url": "https://codeberg.com/{username}", - "detections": [ - { - "return": "false", - "string": "does not exist", - "type": "normal" - }, - { - "return": "true", - "string": "\"profile\"", - "type": "normal" - } - ], - "selected": "false", - "timeout": 0, - "implicit": 0, - "type": "Projects Archive" } ]