Merge pull request #5 from AliasIO/master

Sync no.5
main
Daniel Zdziebko 7 years ago committed by GitHub
commit 7cdfe916ea

8
run

@ -10,13 +10,7 @@ fi
cmd="docker run --rm -v "$(pwd):/opt/wappalyzer" -it wappalyzer/dev" cmd="docker run --rm -v "$(pwd):/opt/wappalyzer" -it wappalyzer/dev"
$cmd yarn install $cmd sh -c "yarn install; cd src/drivers/webextension; yarn install"
pushd src/drivers/webextension
$cmd yarn install
popd
$cmd ./bin/run links $cmd ./bin/run links
$cmd ./bin/run $@ $cmd ./bin/run $@

@ -401,7 +401,7 @@
"headers": { "headers": {
"X-Akamai-Transformed": "" "X-Akamai-Transformed": ""
}, },
"icon": "Akamai.png", "icon": "akamai.svg",
"website": "http://akamai.com" "website": "http://akamai.com"
}, },
"Akka HTTP": { "Akka HTTP": {
@ -939,6 +939,14 @@
"script": "bittads\\.com/js/bitt\\.js$", "script": "bittads\\.com/js/bitt\\.js$",
"website": "http://bittads.com" "website": "http://bittads.com"
}, },
"Bizweb":{
"cats": [
"6"
],
"env": "^Bizweb$",
"icon": "bizweb.png",
"website": "https://www.bizweb.vn"
},
"Blesta": { "Blesta": {
"cats": [ "cats": [
"6" "6"
@ -5331,7 +5339,7 @@
"cats": [ "cats": [
"12" "12"
], ],
"icon": "moon.png", "icon": "moon.svg",
"script": "/moon(?:\\.min)?\\.js$", "script": "/moon(?:\\.min)?\\.js$",
"website": "http://moonjs.ga/" "website": "http://moonjs.ga/"
}, },
@ -5585,6 +5593,24 @@
"icon": "New Relic.png", "icon": "New Relic.png",
"website": "http://newrelic.com" "website": "http://newrelic.com"
}, },
"Next.js": {
"cats": [
"18",
"22"
],
"headers": {
"x-powered-by": "^Next.js ?([0-9.]+)?\\;version:\\1"
},
"html": "<[^>]+__next",
"env": "^__NEXT_DATA__$",
"icon": "zeit.svg",
"implies": [
"React",
"webpack",
"Node.js"
],
"website": "https://zeit.co/next"
},
"Nginx": { "Nginx": {
"cats": [ "cats": [
"22" "22"
@ -5614,6 +5640,16 @@
"script": "^/nodebb\\.min\\.js\\?", "script": "^/nodebb\\.min\\.js\\?",
"website": "https://nodebb.org" "website": "https://nodebb.org"
}, },
"Now": {
"cats": [
"22"
],
"headers": {
"server": "now"
},
"icon": "zeit.svg",
"website": "https://zeit.co/now"
},
"OWL Carousel": { "OWL Carousel": {
"cats": [ "cats": [
"5" "5"
@ -8430,6 +8466,10 @@
], ],
"icon": "typecho.svg", "icon": "typecho.svg",
"implies": "PHP", "implies": "PHP",
"env": "^TypechoComment$",
"meta": {
"generator": "Typecho( [\\d.]+)?\\;version:\\1"
},
"url": "/admin/login\\.php?referer=http%3A%2F%2F", "url": "/admin/login\\.php?referer=http%3A%2F%2F",
"website": "http://typecho.org/" "website": "http://typecho.org/"
}, },
@ -8521,7 +8561,7 @@
}, },
"UMI.CMS": { "UMI.CMS": {
"cats": [ "cats": [
1 "1"
], ],
"headers": { "headers": {
"X-Generated-By": "UMI.CMS" "X-Generated-By": "UMI.CMS"

@ -105,9 +105,9 @@
'</a>' + '</a>' +
'<div id="wappalyzer-apps">'; '<div id="wappalyzer-apps">';
if ( w.detected[url] != null && Object.keys(w.detected[url]).length ) { if ( detected[url] != null && Object.keys(detected[url]).length ) {
for ( app in w.detected[url] ) { for ( app in detected[url] ) {
if ( !hasOwn.call(w.detected[url], app) ) { if ( !hasOwn.call(detected[url], app) ) {
continue; continue;
} }
@ -154,5 +154,5 @@
} }
}; };
w.init(); w.driver.init();
})(); })();

@ -1,19 +1,21 @@
'use strict'; 'use strict';
const wappalyzer = require('./wappalyzer'); const Wappalyzer = require('./wappalyzer');
const request = require('request'); const request = require('request');
const fs = require('fs'); const fs = require('fs');
const Browser = require('zombie'); const Browser = require('zombie');
const json = JSON.parse(fs.readFileSync(__dirname + '/apps.json')); const json = JSON.parse(fs.readFileSync(__dirname + '/apps.json'));
wappalyzer.apps = json.apps;
wappalyzer.categories = json.categories;
const driver = { const driver = {
quiet: true, quiet: true,
analyze: url => { analyze: url => {
const wappalyzer = new Wappalyzer();
wappalyzer.apps = json.apps;
wappalyzer.categories = json.categories;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
wappalyzer.driver.log = (message, source, type) => { wappalyzer.driver.log = (message, source, type) => {
if ( type === 'error' ) { if ( type === 'error' ) {

@ -2,7 +2,7 @@
"name": "wappalyzer", "name": "wappalyzer",
"description": "Uncovers the technologies used on websites", "description": "Uncovers the technologies used on websites",
"homepage": "https://github.com/AliasIO/Wappalyzer", "homepage": "https://github.com/AliasIO/Wappalyzer",
"version": "5.0.5", "version": "5.1.0",
"author": "Elbert Alias", "author": "Elbert Alias",
"license": "GPL-3.0", "license": "GPL-3.0",
"repository": { "repository": {

@ -1,78 +1,114 @@
body { body {
background: #fff; background: #fff;
color: #4a4a4a;
font-family: Helvetica, Arial, sans-serif; font-family: Helvetica, Arial, sans-serif;
font-size: 13px; font-size: .8rem;
line-height: 16px; height: 20.8rem;
margin: 0; margin: 0;
min-width: 200px; overflow: hidden;
overflow-x: hidden; width: 30rem;
padding: 15px;
} }
a { .header {
color: #4a4a4a; align-items: center;
background: linear-gradient(160deg, #32067c, #150233);
height: 4rem;
display: flex;
} }
a:focus { .header__link:focus {
outline: 0; outline: none;
} }
img { .header__logo {
display: inline-block; display: inline-block;
height: 16px; margin: .2rem 0 0 1.5rem;
margin-right: 8px; -webkit-backface-visibility: hidden;
vertical-align: top; -webkit-transform: translateZ(0) scale(1.0, 1.0);
width: 16px; transform: translateZ(0);
height: 2rem;
} }
.detected-app { .container {
padding: 7px 0; height: 15.8rem;
overflow: scroll;
padding: 1rem 1.5rem 0rem 1.5rem;
} }
.detected-app:first-child { .detected {
padding-top: 0; columns: 2;
column-gap: 1.5rem;
line-height: 1.4rem;
} }
.detected-app:last-child { .detected__category {
border: none; break-inside: avoid-column;
padding-bottom: 0; padding-bottom: 1rem;
}
.detected__category-link {
border-bottom: 1px solid #dbdbdb;
display: block;
margin-bottom: .5rem;
text-decoration: none;
} }
.detected-app a { .detected__category-name {
color: #4608ad; color: #4608ad;
display: block; display: block;
font-weight: bold;
line-height: 2rem;
}
.detected__category-link:hover .detected__category-name {
color: #4a4a4a;
}
.detected__app {
display: block;
line-height: 1.7rem;
text-decoration: none; text-decoration: none;
} }
.detected-app a .label .name { .detected__app:focus {
border-bottom: 1px solid transparent; display: block;
outline: 0;
} }
.detected-app a:hover .label .name { .detected__app-icon {
border-bottom: 1px solid #4608ad; display: inline-block;
height: 16px;
margin-right: .5rem;
vertical-align: -.2rem;
width: 16px;
} }
.detected-app a .category .name { .detected__app-name {
color: #4a4a4a; color: #4a4a4a;
border-bottom: 1px solid transparent;
} }
.detected-app a:hover .category .name { .detected__app:hover .detected__app-name {
border-bottom: 1px solid #4a4a4a; border-bottom: 1px solid #4a4a4a;
} }
.label { .detected-app {
font-weight: bold; padding: 7px 0;
} }
.category { .detected-app:first-child {
display: block; padding-top: 0;
margin: 5px 0 0 24px; }
.detected-app:last-child {
border: none;
padding-bottom: 0;
} }
.empty { .empty {
color: #999; display: flex;
font-style: italic; height: 16rem;
text-align: center; align-items: center;
justify-content: center;
}
.empty__text {
} }

@ -11,5 +11,12 @@
<script src="../js/popup.js"></script> <script src="../js/popup.js"></script>
</head> </head>
<body> <body>
<div class="header">
<a href="https://wappalyzer.com/" class="header__link" target="_blank">
<img class="header__logo" src="../images/logo-white.svg">
</a>
</div>
<div class="container"></div>
</body> </body>
</html> </html>

@ -3,7 +3,9 @@
*/ */
/** global: browser */ /** global: browser */
/** global: wappalyzer */ /** global: Wappalyzer */
const wappalyzer = new Wappalyzer();
var tabCache = {}; var tabCache = {};
var headersCache = {}; var headersCache = {};
@ -26,7 +28,7 @@ function getOption(name, defaultValue) {
// Chrome, Firefox // Chrome, Firefox
browser.storage.local.get(name) browser.storage.local.get(name)
.then(callback) .then(callback)
.catch(console.error); .catch(error => wappalyzer.log(error, 'driver', 'error'));
} catch ( e ) { } catch ( e ) {
// Edge // Edge
browser.storage.local.get(name, callback); browser.storage.local.get(name, callback);
@ -123,7 +125,7 @@ var callback = tabs => {
try { try {
browser.tabs.query({}) browser.tabs.query({})
.then(callback) .then(callback)
.catch(console.error); .catch(error => wappalyzer.log(error, 'driver', 'error'));
} catch ( e ) { } catch ( e ) {
browser.tabs.query({}, callback); browser.tabs.query({}, callback);
} }

@ -181,7 +181,7 @@ var exports = {};
video_assets: opt_video_assets, video_assets: opt_video_assets,
assets: opt_assets, assets: opt_assets,
version: '3', version: '3',
mrev: '082d7cb-d', mrev: '4d79384-d',
msgNum: this.msgNum, msgNum: this.msgNum,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
pageVis: document.visibilityState, pageVis: document.visibilityState,
@ -890,7 +890,7 @@ var exports = {};
var _pageTags; var _pageTags;
var INIT_MS_BW_SEARCHES = 2000; var INIT_MS_BW_SEARCHES = 2000;
var PAGE_TAG_RE = new RegExp('gpt|oascentral'); var PAGE_TAG_RE = new RegExp('gpt|oascentral');
var POST_MSG_ID = '1501281986-4236-27733-5465-12184'; var POST_MSG_ID = '1503096304-372-12333-31563-11152';
var AD_SERVER_RE = new RegExp('^(google_ads_iframe|oas_frame|atwAdFrame)'); var AD_SERVER_RE = new RegExp('^(google_ads_iframe|oas_frame|atwAdFrame)');
function getPageTags(doc) { function getPageTags(doc) {
@ -1104,6 +1104,23 @@ var exports = {};
} }
}, },
blockedRobotsMsgGen: function(sendFcn, origUrl) {
if ( origUrl.indexOf('google.com/_/chrome/newtab') === -1 ) {
var onBlockedRobotsMessage = function() {
var log;
log = _logGen.log('invalid-robotstxt', []);
log.doc.finalPageUrl = log.doc.url;
log.doc.url = exports.utils.normalizeUrl(origUrl);
sendFcn(log);
};
return onBlockedRobotsMessage;
} else {
return function() {};
}
},
init: function(onAdFound) { init: function(onAdFound) {
if ( exports.utils.SCRIPT_IN_FRIENDLY_IFRAME ) { if ( exports.utils.SCRIPT_IN_FRIENDLY_IFRAME ) {
@ -1137,6 +1154,8 @@ if ( exports.utils.SCRIPT_IN_WINDOW_TOP ) {
init: exports.coordinator.init, init: exports.coordinator.init,
addPostMessageListener: exports.coordinator.addPostMessageListener, addPostMessageListener: exports.coordinator.addPostMessageListener,
askIfTrackingEnabled: exports.utils.askIfTrackingEnabled, askIfTrackingEnabled: exports.utils.askIfTrackingEnabled,
blockedRobotsMsgGen: exports.coordinator.blockedRobotsMsgGen,
inWindowTop: exports.utils.SCRIPT_IN_WINDOW_TOP,
sendToBackground: exports.utils.sendToBackground sendToBackground: exports.utils.sendToBackground
}; };
} else { } else {
@ -1149,18 +1168,18 @@ if ( exports.utils.SCRIPT_IN_WINDOW_TOP ) {
); );
} }
})(window); })(window);
(function(adparser) { (function(adparser, pageUrl) {
function onAdFound(log) { function onAdFound(log) {
adparser.sendToBackground({ id: 'ad_log', subject: log }, 'ad_log', '', function(){}); adparser.sendToBackground({ id: 'ad_log', subject: log }, 'ad_log', '', function(){});
} }
if ( window === window.top ) { if ( adparser && adparser.inWindowTop ) {
adparser.addPostMessageListener(); adparser.addPostMessageListener();
adparser.askIfTrackingEnabled( adparser.askIfTrackingEnabled(
function() { function() {
adparser.init(onAdFound); adparser.init(onAdFound);
}, },
function() {} adparser.blockedRobotsMsgGen(onAdFound, pageUrl)
) )
} }
})(window.adparser); })(window.adparser, window.location.href);

@ -66,6 +66,7 @@
'washingtonpost.com' 'washingtonpost.com'
]; ];
var robotsTxtAllows = wappalyzer.robotsTxtAllows;
if ( !String.prototype.endsWith ) { if ( !String.prototype.endsWith ) {
String.prototype.endsWith = function(searchString, position) { String.prototype.endsWith = function(searchString, position) {
var subjectString = this.toString(); var subjectString = this.toString();
@ -114,10 +115,10 @@
} }
} }
function ifTrackingEnabled(url, ifCallback, elseCallback) { function ifTrackingEnabled(details, ifCallback, elseCallback) {
var fullIfCallback = function() { var fullIfCallback = function() {
allowedByRobotsTxt(url, ifCallback, elseCallback); allowedByRobotsTxt(details, ifCallback, elseCallback);
}; };
browser.storage.local.get('tracking').then(function(item) { browser.storage.local.get('tracking').then(function(item) {
@ -135,9 +136,9 @@
} }
function allowedByRobotsTxt(url, ifCallback, elseCallback) { function allowedByRobotsTxt(details, ifCallback, elseCallback) {
if ( ! url.startsWith('chrome://') ) { if ( details.url && !details.url.startsWith('chrome://') ) {
wappalyzer.robotsTxtAllows(url).then(ifCallback, elseCallback); robotsTxtAllows(details.url).then(ifCallback, elseCallback);
} else { } else {
elseCallback(); elseCallback();
} }
@ -219,7 +220,7 @@
this.cleanupCollector(tabId); this.cleanupCollector(tabId);
ifTrackingEnabled( ifTrackingEnabled(
details.url, details,
function() { function() {
if ( !areListenersRegistered ) { if ( !areListenersRegistered ) {
@ -279,18 +280,20 @@
browserProxy.tabs.sendMessage(this.tabId, message); browserProxy.tabs.sendMessage(this.tabId, message);
}; };
PageNetworkTrafficCollector.prototype.sendToTab = function(assetReq, reqs, curPageUrl, isValidAd) { PageNetworkTrafficCollector.prototype.sendToTab = function(assetReq, reqs, curPageUrl, nonAdTrackingEvent) {
var msg = {}; var msg = {};
msg.assets = []; msg.assets = [];
msg.requests = [];
msg.event_data = {}; msg.event_data = {};
if ( isValidAd ) { if ( !nonAdTrackingEvent ) {
msg.event = 'new-video-ad'; msg.event = 'new-video-ad';
msg.requests = reqs; msg.requests = reqs;
msg.requests.sort(function(reqA, reqB) {return reqA.requestTimestamp - reqB.requestTimestamp;}); msg.requests.sort(function(reqA, reqB) {return reqA.requestTimestamp - reqB.requestTimestamp;});
if ( assetReq ) { if ( assetReq ) {
msg.assets = [assetReq]; msg.assets = [assetReq];
} }
} else { } else if ( nonAdTrackingEvent === 'new-invalid-video-ad' ) {
msg.event = nonAdTrackingEvent;
msg.requests = reqs.map(function(request) { msg.requests = reqs.map(function(request) {
return parseHostnameFromUrl(request.url); return parseHostnameFromUrl(request.url);
}); });
@ -301,7 +304,8 @@
contentType: assetReq.contentType, contentType: assetReq.contentType,
size: assetReq.size size: assetReq.size
}]; }];
msg.event = 'new-invalid-video-ad'; } else if ( nonAdTrackingEvent === 'robots-txt-no-scraping' ) {
msg.event = nonAdTrackingEvent;
} }
msg.origUrl = curPageUrl; msg.origUrl = curPageUrl;
msg.displayAdFound = this.displayAdFound; msg.displayAdFound = this.displayAdFound;
@ -805,7 +809,7 @@
browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) { browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if ( request === 'is_tracking_enabled' ) { if ( request === 'is_tracking_enabled' ) {
ifTrackingEnabled( ifTrackingEnabled(
sender.tab.url, sender.tab,
function() { function() {
try {sendResponse({'tracking_enabled': true});} try {sendResponse({'tracking_enabled': true});}
catch(err) {} }, catch(err) {} },

@ -32,26 +32,16 @@ function replaceDomWhenReady(dom) {
} }
function replaceDom(domTemplate) { function replaceDom(domTemplate) {
var body = document.body; var container = document.getElementsByClassName('container')[0];
while ( body.firstChild ) { while ( container.firstChild ) {
body.removeChild(body.firstChild); container.removeChild(container.firstChild);
} }
body.appendChild(jsonToDOM(domTemplate, document, {})); container.appendChild(jsonToDOM(domTemplate, document, {}));
var nodes = document.querySelectorAll('[data-i18n]'); var nodes = document.querySelectorAll('[data-i18n]');
for ( let ms = 200; ms < 500; ms += 50 ) {
setTimeout(() => {
let div = document.createElement('div');
div.style.display = 'none';
body.appendChild(div);
}, ms);
};
Array.prototype.forEach.call(nodes, node => { Array.prototype.forEach.call(nodes, node => {
node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n); node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n);
}); });
@ -63,65 +53,87 @@ function appsToDomTemplate(response) {
template = []; template = [];
if ( response.tabCache && Object.keys(response.tabCache.detected).length > 0 ) { if ( response.tabCache && Object.keys(response.tabCache.detected).length > 0 ) {
const categories = {};
// Group apps by category
for ( appName in response.tabCache.detected ) { for ( appName in response.tabCache.detected ) {
response.apps[appName].cats.forEach(cat => {
categories[cat] = categories[cat] || { apps: [] };
categories[cat].apps[appName] = appName;
});
}
for ( cat in categories ) {
const apps = [];
for ( appName in categories[cat].apps ) {
confidence = response.tabCache.detected[appName].confidenceTotal; confidence = response.tabCache.detected[appName].confidenceTotal;
version = response.tabCache.detected[appName].version; version = response.tabCache.detected[appName].version;
categories = [];
response.apps[appName].cats.forEach(cat => { apps.push(
categories.push(
[ [
'a', { 'a', {
class: 'detected__app',
target: '_blank', target: '_blank',
href: 'https://wappalyzer.com/categories/' + slugify(response.categories[cat].name) href: 'https://wappalyzer.com/applications/' + slugify(appName)
}, [
'span', {
class: 'category'
}, [ }, [
'img', {
class: 'detected__app-icon',
src: '../images/icons/' + ( response.apps[appName].icon || 'default.svg' )
},
], [
'span', { 'span', {
class: 'name' class: 'detected__app-name'
}, },
browser.i18n.getMessage('categoryName' + cat) appName + ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' )
]
] ]
] ]
); );
}); }
template.push( template.push(
[ [
'div', { 'div', {
class: 'detected-app' class: 'detected__category'
}, [ }, [
'a', { 'a', {
class: 'detected__category-link',
target: '_blank', target: '_blank',
href: 'https://wappalyzer.com/applications/' + slugify(appName) href: 'https://wappalyzer.com/categories/' + slugify(response.categories[cat].name)
}, [
'img', {
src: '../images/icons/' + ( response.apps[appName].icon || 'default.svg' )
}
], [
'span', {
class: 'label'
}, [ }, [
'span', { 'span', {
class: 'name' class: 'detected__category-name'
}, },
appName browser.i18n.getMessage('categoryName' + cat)
], ]
( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) ], [
'div', {
class: 'detected__apps'
},
apps
] ]
],
categories
] ]
); );
} }
template = [
'div', {
class: 'detected'
},
template
];
} else { } else {
template = [ template = [
'div', { 'div', {
class: 'empty' class: 'empty'
}, },
[
'span', {
class: 'empty__text'
},
browser.i18n.getMessage('noAppsDetected') browser.i18n.getMessage('noAppsDetected')
],
]; ];
} }

@ -4,7 +4,7 @@
"author": "Elbert Alias", "author": "Elbert Alias",
"homepage_url": "https://wappalyzer.com/", "homepage_url": "https://wappalyzer.com/",
"description": "Identify web technologies", "description": "Identify web technologies",
"version": "5.0.5", "version": "5.1.0",
"default_locale": "en", "default_locale": "en",
"manifest_version": 2, "manifest_version": 2,
"icons": { "icons": {

@ -4,7 +4,7 @@
"author": "Elbert Alias", "author": "Elbert Alias",
"homepage_url": "https://wappalyzer.com/", "homepage_url": "https://wappalyzer.com/",
"description": "Identify web technologies", "description": "Identify web technologies",
"version": "5.0.5", "version": "5.1.0",
"default_locale": "en", "default_locale": "en",
"manifest_version": 2, "manifest_version": 2,
"icons": { "icons": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 845 B

@ -1 +1,4 @@
<svg width="59" height="61" viewBox="0 0 59 61" xmlns="http://www.w3.org/2000/svg"><title>rock-logo</title><path d="M57.705 60.063L41.387 40.936s11.83-.026 11.928-.028a5.456 5.456 0 0 0 3.736-1.259 5.504 5.504 0 0 0 .693-7.752L32.396 2.151a5.562 5.562 0 0 0-.836-.891c-.039-.029-.084-.051-.121-.082-.012-.01-.027-.018-.039-.025a5.887 5.887 0 0 0-.867-.563c-.018-.009-.039-.014-.059-.021a5.377 5.377 0 0 0-.922-.366c-.057-.013-.119-.025-.178-.039-.277-.063-.557-.129-.84-.15-.172-.021-.346-.008-.516-.008-.172 0-.34-.014-.514.008-.281.021-.559.087-.84.15l-.174.039a5.18 5.18 0 0 0-.924.366c-.021.009-.039.014-.057.021a5.204 5.204 0 0 0-.869.563c-.018.009-.025.017-.037.025-.039.031-.084.053-.123.082-.32.271-.594.57-.84.885L0 29.86h14.461l13.557-15.891 13.604 15.967-12.104.008c-.045 0-.088.013-.133.017-.287 0-.578.026-.865.071a7.39 7.39 0 0 0-.244.054 5 5 0 0 0-.775.229 2 2 0 0 0-.266.117 4.44 4.44 0 0 0-.957.549c-.117.081-.238.143-.346.229-.076.067-.137.147-.211.221a4.613 4.613 0 0 0-.258.264 5.523 5.523 0 0 0-.453.531c-.068.105-.131.205-.195.308a5.154 5.154 0 0 0-.332.601c-.059.126-.107.255-.156.384-.072.199-.145.398-.191.605a4.218 4.218 0 0 0-.084.451 5.182 5.182 0 0 0-.07.606c-.006.074-.023.137-.023.209 0 .101.023.189.027.294.012.188.023.368.051.557a5.735 5.735 0 0 0 .246 1.012c.072.199.154.397.248.588.061.119.119.234.188.35.123.215.26.414.408.605.045.057.068.115.115.168l18.004 21.104h14.459v-.005z" fill="#EE7624" fill-rule="evenodd"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#ED7726;}
</style><circle class="st0" cx="203" cy="208.1" r="184.8"/><path class="st1" d="M200 0C89.5 0 0 89.5 0 200s89.5 200 200 200 200-89.5 200-200S310.5 0 200 0zM327 338.3h-72.6l-90.3-105.9c-0.2-0.3-0.4-0.6-0.6-0.8 -0.7-1-1.4-2-2-3 -0.3-0.6-0.6-1.2-0.9-1.8 -0.5-0.9-0.9-2-1.2-2.9 -0.3-0.8-0.5-1.5-0.7-2.3 -0.2-0.9-0.4-1.8-0.6-2.8 -0.1-0.9-0.2-1.9-0.3-2.8 0-0.5-0.1-1-0.1-1.5 0-0.4 0.1-0.7 0.1-1.1 0.1-1 0.2-2 0.4-3 0.1-0.8 0.2-1.5 0.4-2.3 0.2-1 0.6-2 1-3 0.2-0.6 0.5-1.3 0.8-1.9 0.5-1 1-2 1.7-3 0.3-0.5 0.6-1 1-1.5 0.7-0.9 1.4-1.8 2.3-2.7 0.4-0.5 0.9-0.9 1.3-1.3 0.4-0.4 0.7-0.8 1.1-1.1 0.5-0.4 1.1-0.7 1.7-1.1 0.5-0.3 1-0.7 1.4-1 1.1-0.7 2.2-1.3 3.4-1.8 0.4-0.2 0.9-0.4 1.3-0.6 1.3-0.5 2.6-0.9 3.9-1.1 0.4-0.1 0.8-0.2 1.2-0.3 1.4-0.2 2.9-0.4 4.3-0.4 0.2 0 0.4-0.1 0.7-0.1l60.7 0L178 107.1l-68 79.7H37.5l118.6-139c1.2-1.6 2.6-3.1 4.2-4.4 0.2-0.1 0.4-0.3 0.6-0.4 0.1-0.1 0.1-0.1 0.2-0.1 1.4-1.1 2.8-2 4.4-2.8 0.1 0 0.2-0.1 0.3-0.1 1.5-0.8 3-1.4 4.6-1.8 0.3-0.1 0.6-0.1 0.9-0.2 1.4-0.3 2.8-0.6 4.2-0.8 0.9-0.1 1.7 0 2.6 0 0.9 0 1.7-0.1 2.6 0 1.4 0.1 2.8 0.4 4.2 0.8 0.3 0.1 0.6 0.1 0.9 0.2 1.6 0.5 3.1 1.1 4.6 1.8 0.1 0 0.2 0.1 0.3 0.1 1.5 0.8 2.9 1.7 4.4 2.8 0.1 0 0.1 0.1 0.2 0.1 0.2 0.2 0.4 0.3 0.6 0.4 1.6 1.4 3 2.9 4.2 4.5L327.2 197c9.8 11.7 8.2 29.1-3.5 38.9 -5.4 4.6-12.2 6.6-18.7 6.3 -0.5 0-59.8 0.1-59.8 0.1L327 338.3z"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><g fill="#008cdb"><path d="M273.971 437.617c-78.241-23.9-135.099-96.163-135.099-181.622 0-86.376 58.091-159.287 137.634-182.373 8.13-2.355 5.994-7.622-3.799-7.622C166.942 66 81.22 151.063 81.22 255.995 81.22 360.937 166.942 446 272.708 446c9.797 0 10.192-5.652 1.263-8.383z"/><path d="M175.135 300.485c-5.643-54.204 20.877-162.662 150.07-166.31 78.744-2.224 102.435 35.2 105.355 32.898 3.214-2.531-28.582-72.253-121.088-72.253-83.323 0-150.859 67.547-150.859 150.869 0 19.243 3.613 37.629 10.192 54.551 2.77 7.112 7.042 7.136 6.33.245z"/><path d="M238.342 191.77c39.194-17.083 88.473-17.561 136.878-.668 32.503 11.348 51.371 27.538 52.902 26.895 2.565-1.111-18.921-35.132-57.686-49.83-46.943-17.814-97.543-8.495-134.376 20.385-4.073 3.178-2.527 5.319 2.282 3.218z"/></g></svg>

After

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="145.61mm" height="168.42mm" version="1.1" viewBox="0 0 550.32981 636.55663" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title>Moon Logo</dc:title></cc:Work></rdf:RDF></metadata><title>Moon Logo</title><g transform="matrix(1.1168 0 0 1.0609 -223.35 -212.19)"><g transform="translate(-3102,-6459)"><clipPath id="f" clip-rule="evenodd"><path d="m3102 6459h1e3v1e3h-1e3z" fill="#fff"/></clipPath><g clip-path="url(#f)"><use transform="translate(3302,6659)" width="100%" height="100%" fill="url(#d)" xlink:href="#e"/></g></g></g><defs><linearGradient id="d" x2="1" gradientTransform="matrix(348 600 -195.66 352.44 97.83 -176.22)" gradientUnits="userSpaceOnUse"><stop stop-color="#007EFF" offset="0"/><stop stop-color="#B22BFF" offset=".97238"/></linearGradient><path id="e" d="m491.47 530.96c6.198-5.145 3.529-15.01-4.221-17.208-125.37-35.561-217.25-151.37-217.25-288.75 0-79.162 30.508-151.16 80.353-204.78 5.473-5.886 2.646-15.667-5.301-16.864-14.695-2.2131-29.74-3.3603-45.052-3.3603-165.69 0-300 134.31-300 300s134.31 300 300 300c72.788 0 139.52-25.923 191.47-69.039z" fill-rule="evenodd"/></defs></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1 @@
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><title>Zeit</title><desc>Created with Sketch.</desc><defs><linearGradient x1="100.686%" y1="181.283%" x2="41.808%" y2="100%" id="a"><stop stop-color="#fff" offset="0%"/><stop offset="100%"/></linearGradient></defs><path d="M15.766 3l14.766 26.134h-29.531z" fill-rule="nonzero" fill="url(#a)"/></svg>

After

Width:  |  Height:  |  Size: 382 B

@ -13,30 +13,31 @@ const validation = {
hostnameBlacklist: /((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/ hostnameBlacklist: /((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/
}; };
var wappalyzer = { class Wappalyzer {
apps: {}, constructor() {
categories: {}, this.apps = {};
driver: {} this.categories = {};
}; this.driver = {};
var detected = {}; this.detected = {};
var hostnameCache = {}; this.hostnameCache = {};
var adCache = []; this.adCache = [];
wappalyzer.config = { this.config = {
websiteURL: 'https://wappalyzer.com/', websiteURL: 'https://wappalyzer.com/',
twitterURL: 'https://twitter.com/Wappalyzer', twitterURL: 'https://twitter.com/Wappalyzer',
githubURL: 'https://github.com/AliasIO/Wappalyzer', githubURL: 'https://github.com/AliasIO/Wappalyzer',
}; };
}
/** /**
* Log messages to console * Log messages to console
*/ */
wappalyzer.log = (message, source, type) => { log(message, source, type) {
wappalyzer.driver.log(message, source || '', type || 'debug'); this.driver.log(message, source || '', type || 'debug');
}; }
wappalyzer.analyze = (hostname, url, data, context) => { analyze(hostname, url, data, context) {
var apps = {}; var apps = {};
// Remove hash from URL // Remove hash from URL
@ -46,35 +47,35 @@ wappalyzer.analyze = (hostname, url, data, context) => {
data.html = ''; data.html = '';
} }
if ( detected[url] === undefined ) { if ( this.detected[url] === undefined ) {
detected[url] = {}; this.detected[url] = {};
} }
Object.keys(wappalyzer.apps).forEach(appName => { Object.keys(this.apps).forEach(appName => {
apps[appName] = detected[url] && detected[url][appName] ? detected[url][appName] : new Application(appName, wappalyzer.apps[appName]); apps[appName] = this.detected[url] && this.detected[url][appName] ? this.detected[url][appName] : new Application(appName, this.apps[appName]);
var app = apps[appName]; var app = apps[appName];
if ( url ) { if ( url ) {
analyzeUrl(app, url); this.analyzeUrl(app, url);
} }
if ( data.html ) { if ( data.html ) {
analyzeHtml(app, data.html); this.analyzeHtml(app, data.html);
analyzeScript(app, data.html); this.analyzeScript(app, data.html);
analyzeMeta(app, data.html); this.analyzeMeta(app, data.html);
} }
if ( data.headers ) { if ( data.headers ) {
analyzeHeaders(app, data.headers); this.analyzeHeaders(app, data.headers);
} }
if ( data.env ) { if ( data.env ) {
analyzeEnv(app, data.env); this.analyzeEnv(app, data.env);
} }
if ( data.robotsTxt ) { if ( data.robotsTxt ) {
analyzeRobotsTxt(app, data.robotsTxt); this.analyzeRobotsTxt(app, data.robotsTxt);
} }
}) })
@ -86,34 +87,34 @@ wappalyzer.analyze = (hostname, url, data, context) => {
} }
}); });
resolveExcludes(apps); this.resolveExcludes(apps);
resolveImplies(apps, url); this.resolveImplies(apps, url);
cacheDetectedApps(apps, url); this.cacheDetectedApps(apps, url);
trackDetectedApps(apps, url, hostname, data.html); this.trackDetectedApps(apps, url, hostname, data.html);
if ( Object.keys(apps).length ) { if ( Object.keys(apps).length ) {
wappalyzer.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url, 'core'); this.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url, 'core');
} }
wappalyzer.driver.displayApps(detected[url], context); this.driver.displayApps(this.detected[url], context);
} }
/** /**
* Cache detected ads * Cache detected ads
*/ */
wappalyzer.cacheDetectedAds = ad => { cacheDetectedAds(ad) {
adCache.push(ad); this.adCache.push(ad);
} }
/** /**
* *
*/ */
wappalyzer.robotsTxtAllows = url => { robotsTxtAllows(url) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var parsed = wappalyzer.parseUrl(url); var parsed = this.parseUrl(url);
wappalyzer.driver.getRobotsTxt(parsed.host, parsed.protocol === 'https:') this.driver.getRobotsTxt(parsed.host, parsed.protocol === 'https:')
.then(robotsTxt => { .then(robotsTxt => {
robotsTxt.forEach(disallow => { robotsTxt.forEach(disallow => {
if ( parsed.pathname.indexOf(disallow) === 0 ) { if ( parsed.pathname.indexOf(disallow) === 0 ) {
@ -129,8 +130,8 @@ wappalyzer.robotsTxtAllows = url => {
/** /**
* Parse a URL * Parse a URL
*/ */
wappalyzer.parseUrl = url => { parseUrl(url) {
var a = wappalyzer.driver.document.createElement('a'); var a = this.driver.document.createElement('a');
a.href = url; a.href = url;
@ -142,7 +143,7 @@ wappalyzer.parseUrl = url => {
/** /**
* *
*/ */
wappalyzer.parseRobotsTxt = robotsTxt => { parseRobotsTxt(robotsTxt) {
var userAgent; var userAgent;
var disallow = []; var disallow = [];
@ -168,39 +169,39 @@ wappalyzer.parseRobotsTxt = robotsTxt => {
/** /**
* *
*/ */
wappalyzer.ping = () => { ping() {
if ( Object.keys(hostnameCache).length >= 50 || adCache.length >= 50 ) { if ( Object.keys(this.hostnameCache).length >= 50 || this.adCache.length >= 50 ) {
wappalyzer.driver.ping(hostnameCache, adCache); this.driver.ping(this.hostnameCache, this.adCache);
hostnameCache = {}; this.hostnameCache = {};
adCache = []; this.adCache = [];
} }
} }
/** /**
* Enclose string in array * Enclose string in array
*/ */
function asArray(value) { asArray(value) {
return typeof value === 'string' ? [ value ] : value; return typeof value === 'string' ? [ value ] : value;
} }
/** /**
* Parse apps.json patterns * Parse apps.json patterns
*/ */
function parsePatterns(patterns) { parsePatterns(patterns) {
var parsed = {}; var parsed = {};
// Convert string to object containing array containing string // Convert string to object containing array containing string
if ( typeof patterns === 'string' || patterns instanceof Array ) { if ( typeof patterns === 'string' || patterns instanceof Array ) {
patterns = { patterns = {
main: asArray(patterns) main: this.asArray(patterns)
}; };
} }
for ( var key in patterns ) { for ( var key in patterns ) {
parsed[key] = []; parsed[key] = [];
asArray(patterns[key]).forEach(pattern => { this.asArray(patterns[key]).forEach(pattern => {
var attrs = {}; var attrs = {};
pattern.split('\\;').forEach((attr, i) => { pattern.split('\\;').forEach((attr, i) => {
@ -219,7 +220,7 @@ function parsePatterns(patterns) {
} catch (e) { } catch (e) {
attrs.regex = new RegExp(); attrs.regex = new RegExp();
wappalyzer.log(e + ': ' + attr, 'error', 'core'); this.log(e + ': ' + attr, 'error', 'core');
} }
} }
}); });
@ -236,7 +237,7 @@ function parsePatterns(patterns) {
return parsed; return parsed;
} }
function resolveExcludes(apps) { resolveExcludes(apps) {
var excludes = []; var excludes = [];
// Exclude app in detected apps only // Exclude app in detected apps only
@ -244,7 +245,7 @@ function resolveExcludes(apps) {
var app = apps[appName]; var app = apps[appName];
if ( app.props.excludes ) { if ( app.props.excludes ) {
asArray(app.props.excludes).forEach(excluded => { this.asArray(app.props.excludes).forEach(excluded => {
excludes.push(excluded); excludes.push(excluded);
}); });
} }
@ -258,7 +259,7 @@ function resolveExcludes(apps) {
}) })
} }
function resolveImplies(apps, url) { resolveImplies(apps, url) {
var checkImplies = true; var checkImplies = true;
// Implied applications // Implied applications
@ -270,17 +271,17 @@ function resolveImplies(apps, url) {
var app = apps[appName]; var app = apps[appName];
if ( app && app.implies ) { if ( app && app.implies ) {
asArray(app.props.implies).forEach(implied => { this.asArray(app.props.implies).forEach(implied => {
implied = parsePatterns(implied)[0]; implied = this.parsePatterns(implied)[0];
if ( !wappalyzer.apps[implied.string] ) { if ( !this.apps[implied.string] ) {
wappalyzer.log('Implied application ' + implied.string + ' does not exist', 'core', 'warn'); this.log('Implied application ' + implied.string + ' does not exist', 'core', 'warn');
return; return;
} }
if ( !( implied.string in apps ) ) { if ( !( implied.string in apps ) ) {
apps[implied.string] = detected[url] && detected[url][implied.string] ? detected[url][implied.string] : new Application(implied.string, true); apps[implied.string] = this.detected[url] && this.detected[url][implied.string] ? this.detected[url][implied.string] : new Application(implied.string, true);
checkImplies = true; checkImplies = true;
} }
@ -298,53 +299,57 @@ function resolveImplies(apps, url) {
/** /**
* Cache detected applications * Cache detected applications
*/ */
function cacheDetectedApps(apps, url) { cacheDetectedApps(apps, url) {
if (!wappalyzer.driver.ping instanceof Function) return; if ( !( this.driver.ping instanceof Function ) ) {
return;
}
Object.keys(apps).forEach(appName => { Object.keys(apps).forEach(appName => {
var app = apps[appName]; var app = apps[appName];
// Per URL // Per URL
detected[url][appName] = app; this.detected[url][appName] = app;
Object.keys(app.confidence).forEach(id => { Object.keys(app.confidence).forEach(id => {
detected[url][appName].confidence[id] = app.confidence[id]; this.detected[url][appName].confidence[id] = app.confidence[id];
}); });
}) })
wappalyzer.ping(); this.ping();
} }
/** /**
* Track detected applications * Track detected applications
*/ */
function trackDetectedApps(apps, url, hostname, html) { trackDetectedApps(apps, url, hostname, html) {
if (!wappalyzer.driver.ping instanceof Function) return; if ( !( this.driver.ping instanceof Function ) ) {
return;
}
Object.keys(apps).forEach(appName => { Object.keys(apps).forEach(appName => {
var app = apps[appName]; var app = apps[appName];
if ( detected[url][appName].getConfidence() >= 100 ) { if ( this.detected[url][appName].getConfidence() >= 100 ) {
if ( validation.hostname.test(hostname) && !validation.hostnameBlacklist.test(url) ) { if ( validation.hostname.test(hostname) && !validation.hostnameBlacklist.test(url) ) {
wappalyzer.robotsTxtAllows(url) this.robotsTxtAllows(url)
.then(() => { .then(() => {
if ( !( hostname in hostnameCache ) ) { if ( !( hostname in this.hostnameCache ) ) {
hostnameCache[hostname] = { this.hostnameCache[hostname] = {
applications: {}, applications: {},
meta: {} meta: {}
}; };
} }
if ( !( appName in hostnameCache[hostname].applications ) ) { if ( !( appName in this.hostnameCache[hostname].applications ) ) {
hostnameCache[hostname].applications[appName] = { this.hostnameCache[hostname].applications[appName] = {
hits: 0 hits: 0
}; };
} }
hostnameCache[hostname].applications[appName].hits ++; this.hostnameCache[hostname].applications[appName].hits ++;
if ( apps[appName].version ) { if ( apps[appName].version ) {
hostnameCache[hostname].applications[appName].version = app.version; this.hostnameCache[hostname].applications[appName].version = app.version;
} }
}) })
.catch(() => console.log('Disallowed in robots.txt: ' + url)) .catch(() => console.log('Disallowed in robots.txt: ' + url))
@ -353,27 +358,27 @@ function trackDetectedApps(apps, url, hostname, html) {
}); });
// Additional information // Additional information
if ( hostname in hostnameCache ) { if ( hostname in this.hostnameCache ) {
var match = html.match(/<html[^>]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i); var match = html.match(/<html[^>]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i);
if ( match && match.length ) { if ( match && match.length ) {
hostnameCache[hostname].meta['language'] = match[1]; this.hostnameCache[hostname].meta['language'] = match[1];
} }
} }
wappalyzer.ping(); this.ping();
} }
/** /**
* Analyze URL * Analyze URL
*/ */
function analyzeUrl(app, url) { analyzeUrl(app, url) {
var patterns = parsePatterns(app.props.url); var patterns = this.parsePatterns(app.props.url);
if ( patterns.length ) { if ( patterns.length ) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
if ( pattern.regex.test(url) ) { if ( pattern.regex.test(url) ) {
addDetected(app, pattern, 'url', url); this.addDetected(app, pattern, 'url', url);
} }
}); });
} }
@ -382,13 +387,13 @@ function analyzeUrl(app, url) {
/** /**
* Analyze HTML * Analyze HTML
*/ */
function analyzeHtml(app, html) { analyzeHtml(app, html) {
var patterns = parsePatterns(app.props.html); var patterns = this.parsePatterns(app.props.html);
if ( patterns.length ) { if ( patterns.length ) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
if ( pattern.regex.test(html) ) { if ( pattern.regex.test(html) ) {
addDetected(app, pattern, 'html', html); this.addDetected(app, pattern, 'html', html);
} }
}); });
} }
@ -397,9 +402,9 @@ function analyzeHtml(app, html) {
/** /**
* Analyze script tag * Analyze script tag
*/ */
function analyzeScript(app, html) { analyzeScript(app, html) {
var regex = new RegExp('<script[^>]+src=("|\')([^"\']+)', 'ig'); var regex = new RegExp('<script[^>]+src=("|\')([^"\']+)', 'ig');
var patterns = parsePatterns(app.props.script); var patterns = this.parsePatterns(app.props.script);
if ( patterns.length ) { if ( patterns.length ) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
@ -407,7 +412,7 @@ function analyzeScript(app, html) {
while ( ( match = regex.exec(html) ) ) { while ( ( match = regex.exec(html) ) ) {
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
addDetected(app, pattern, 'script', match[2]); this.addDetected(app, pattern, 'script', match[2]);
} }
} }
}); });
@ -417,9 +422,9 @@ function analyzeScript(app, html) {
/** /**
* Analyze meta tag * Analyze meta tag
*/ */
function analyzeMeta(app, html) { analyzeMeta(app, html) {
var regex = /<meta[^>]+>/ig; var regex = /<meta[^>]+>/ig;
var patterns = parsePatterns(app.props.meta); var patterns = this.parsePatterns(app.props.meta);
var content; var content;
var match; var match;
@ -430,7 +435,7 @@ function analyzeMeta(app, html) {
patterns[meta].forEach(pattern => { patterns[meta].forEach(pattern => {
if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { if ( content && content.length === 4 && pattern.regex.test(content[2]) ) {
addDetected(app, pattern, 'meta', content[2], meta); this.addDetected(app, pattern, 'meta', content[2], meta);
} }
}); });
} }
@ -441,8 +446,8 @@ function analyzeMeta(app, html) {
/** /**
* analyze response headers * analyze response headers
*/ */
function analyzeHeaders(app, headers) { analyzeHeaders(app, headers) {
var patterns = parsePatterns(app.props.headers); var patterns = this.parsePatterns(app.props.headers);
if ( headers ) { if ( headers ) {
Object.keys(patterns).forEach(header => { Object.keys(patterns).forEach(header => {
@ -450,7 +455,7 @@ function analyzeHeaders(app, headers) {
header = header.toLowerCase(); header = header.toLowerCase();
if ( header in headers && pattern.regex.test(headers[header]) ) { if ( header in headers && pattern.regex.test(headers[header]) ) {
addDetected(app, pattern, 'headers', headers[header], header); this.addDetected(app, pattern, 'headers', headers[header], header);
} }
}); });
}); });
@ -460,14 +465,14 @@ function analyzeHeaders(app, headers) {
/** /**
* Analyze environment variables * Analyze environment variables
*/ */
function analyzeEnv(app, envs) { analyzeEnv(app, envs) {
var patterns = parsePatterns(app.props.env); var patterns = this.parsePatterns(app.props.env);
if ( patterns.length ) { if ( patterns.length ) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
Object.keys(envs).forEach(env => { Object.keys(envs).forEach(env => {
if ( pattern.regex.test(envs[env]) ) { if ( pattern.regex.test(envs[env]) ) {
addDetected(app, pattern, 'env', envs[env]); this.addDetected(app, pattern, 'env', envs[env]);
} }
}) })
}); });
@ -477,13 +482,13 @@ function analyzeEnv(app, envs) {
/** /**
* Analyze robots.txt * Analyze robots.txt
*/ */
function analyzeRobotsTxt(app, robotsTxt) { analyzeRobotsTxt(app, robotsTxt) {
var patterns = parsePatterns(app.props.robotsTxt); var patterns = this.parsePatterns(app.props.robotsTxt);
if ( patterns.length ) { if ( patterns.length ) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
if ( pattern.regex.test(robotsTxt) ) { if ( pattern.regex.test(robotsTxt) ) {
addDetected(app, pattern, 'robotsTxt', robotsTxt); this.addDetected(app, pattern, 'robotsTxt', robotsTxt);
} }
}); });
} }
@ -492,7 +497,7 @@ function analyzeRobotsTxt(app, robotsTxt) {
/** /**
* Mark application as detected, set confidence and version * Mark application as detected, set confidence and version
*/ */
function addDetected(app, pattern, type, value, key) { addDetected(app, pattern, type, value, key) {
app.detected = true; app.detected = true;
// Set confidence level // Set confidence level
@ -528,6 +533,7 @@ function addDetected(app, pattern, type, value, key) {
} }
} }
} }
}
/** /**
* Application class * Application class
@ -558,5 +564,5 @@ class Application {
} }
if ( typeof module === 'object' ) { if ( typeof module === 'object' ) {
module.exports = wappalyzer; module.exports = Wappalyzer;
} }