Implemented ternary operator for version detection

Fixed detected application data being overwritten
Added version detection for Magento
Fixed typo in README
Track versions, new ping destination
Other minor improvements
main
Elbert Alias 13 years ago
parent 7b2124a02f
commit d8764f27db

@ -74,7 +74,7 @@ script | string | `src` attribute of HTML script tags, e.g. `jquery.js`.
Except `cats`, all fields are optional. Except `cats`, all fields are optional.
Except `cats` and `implied` all fields except one or more patterns (either a string or an array of regular expressions). Except `cats` and `implied` all fields accept one or more patterns (either a string or an array of regular expressions).
### Patterns ### Patterns

@ -81,10 +81,20 @@ var wappalyzer = (function() {
if ( matches ) { if ( matches ) {
matches.map(function(match, i) { matches.map(function(match, i) {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.+)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace('\\' + i, match ? match : ''); version = version.replace('\\' + i, match ? match : '');
}); });
if ( version ) {
self.versions.push(version); self.versions.push(version);
}
self.getVersion(); self.getVersion();
} }
@ -129,8 +139,8 @@ var wappalyzer = (function() {
// Key value pairs // Key value pairs
attr = attr.split(':'); attr = attr.split(':');
if ( attr.length === 2 ) { if ( attr.length > 1 ) {
attrs[attr[0]] = attr[1]; attrs[attr.shift()] = attr.join(':');
} }
} else { } else {
attrs.string = attr; attrs.string = attr;
@ -237,7 +247,7 @@ var wappalyzer = (function() {
data.url = url = url.split('#')[0]; data.url = url = url.split('#')[0];
if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) { if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) {
w.log('apps.json not loaded'); w.log('apps.json not loaded, check for syntax errors');
return; return;
} }
@ -247,7 +257,7 @@ var wappalyzer = (function() {
} }
for ( app in w.apps ) { for ( app in w.apps ) {
apps[app] = new Application(app); apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
switch ( type ) { switch ( type ) {
@ -289,7 +299,7 @@ var wappalyzer = (function() {
profiler.regexCount ++; profiler.regexCount ++;
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
apps[app].setDetected(pattern, type, data[type]); apps[app].setDetected(pattern, type, match[2]);
} }
} }
}); });
@ -383,13 +393,13 @@ var wappalyzer = (function() {
implied = parse(implied)[0]; implied = parse(implied)[0];
if ( !w.apps[implied.string] ) { if ( !w.apps[implied.string] ) {
w.log('Implied application ' + implied.string + ' does not exist'); w.log('Implied application ' + implied.string + ' does not exist', 'warn');
return; return;
} }
if ( !apps.hasOwnProperty(implied.string) ) { if ( !apps.hasOwnProperty(implied.string) ) {
apps[implied.string] = new Application(implied.string, true); apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
} }
// Apply app confidence to implied app // Apply app confidence to implied app
@ -406,6 +416,7 @@ var wappalyzer = (function() {
// Keep history of detected apps // Keep history of detected apps
for ( app in apps ) { for ( app in apps ) {
confidence = apps[app].confidence; confidence = apps[app].confidence;
version = apps[app].version;
// Per URL // Per URL
w.detected[url][app] = apps[app]; w.detected[url][app] = apps[app];
@ -422,18 +433,20 @@ var wappalyzer = (function() {
} }
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) { if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
w.ping.hostnames[hostname].applications[app] = 1; w.ping.hostnames[hostname].applications[app] = { hits: 0 };
} }
w.ping.hostnames[hostname].applications[app] ++; w.ping.hostnames[hostname].applications[app].hits ++;
if ( version ) {
w.ping.hostnames[hostname].applications[app].version = version;
}
} else { } else {
w.log('Ignoring hostname "' + hostname + '"'); w.log('Ignoring hostname "' + hostname + '"');
} }
} }
} }
w.log(JSON.stringify(w.detected));
// Additional information // Additional information
if ( w.ping.hostnames.hasOwnProperty(hostname) ) { if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
if ( typeof data.html === 'string' && data.html ) { if ( typeof data.html === 'string' && data.html ) {
@ -456,7 +469,7 @@ var wappalyzer = (function() {
} }
} }
w.log(hostname + ': ' + JSON.stringify(w.ping.hostnames[hostname])); w.log({ hostname: hostname, ping: w.ping.hostnames[hostname] });
} }
if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); }

@ -106,7 +106,7 @@
}, },
"AMPcms": { "AMPcms": {
"cats": [ 1 ], "cats": [ 1 ],
"headers": { "X-AMP-Version": "([\\d\\.]+)\\;version=\\1", "Set-Cookie": "^AMP=" }, "headers": { "X-AMP-Version": "([\\d\\.]+)\\;version:\\1", "Set-Cookie": "^AMP=" },
"env": "^amp_js_init$", "env": "^amp_js_init$",
"implies": "PHP" "implies": "PHP"
}, },
@ -1006,7 +1006,7 @@
}, },
"Locomotive": { "Locomotive": {
"cats": [ 1 ], "cats": [ 1 ],
"html": "<link[^>]*\/sites\/[a-zA-Z0-9]{24}\/theme\/stylesheets\/.*>", "html": "<link[^>]*/sites/[a-zA-Z0-9]{24}/theme/stylesheets/.*>",
"implies": [ "Ruby on Rails", "MongoDB" ] "implies": [ "Ruby on Rails", "MongoDB" ]
}, },
"Lotus Domino": { "Lotus Domino": {
@ -1015,7 +1015,7 @@
}, },
"Magento": { "Magento": {
"cats": [ 6 ], "cats": [ 6 ],
"script": "(js/mage|skin/frontend/(default|enterprise))", "script": "(js/mage|skin/frontend/(default|(enterprise)))\\;version:\\3?Enterprise:Community",
"headers": { "Set-Cookie": "frontend=\\;confidence:50" }, "headers": { "Set-Cookie": "frontend=\\;confidence:50" },
"env": "^(Mage|VarienForm)$", "env": "^(Mage|VarienForm)$",
"implies": "PHP" "implies": "PHP"
@ -1323,7 +1323,7 @@
}, },
"PHP": { "PHP": {
"cats": [ 27 ], "cats": [ 27 ],
"headers": { "Server": "php/?([\\d\\.]+)?\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" }, "headers": { "Server": "php/?([\\d\\.]+)?\\;confidence:50\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" },
"url": "\\.php$" "url": "\\.php$"
}, },
"phpAlbum": { "phpAlbum": {

@ -106,7 +106,7 @@
}, },
"AMPcms": { "AMPcms": {
"cats": [ 1 ], "cats": [ 1 ],
"headers": { "X-AMP-Version": "([\\d\\.]+)\\;version=\\1", "Set-Cookie": "^AMP=" }, "headers": { "X-AMP-Version": "([\\d\\.]+)\\;version:\\1", "Set-Cookie": "^AMP=" },
"env": "^amp_js_init$", "env": "^amp_js_init$",
"implies": "PHP" "implies": "PHP"
}, },
@ -1006,7 +1006,7 @@
}, },
"Locomotive": { "Locomotive": {
"cats": [ 1 ], "cats": [ 1 ],
"html": "<link[^>]*\/sites\/[a-zA-Z0-9]{24}\/theme\/stylesheets\/.*>", "html": "<link[^>]*/sites/[a-zA-Z0-9]{24}/theme/stylesheets/.*>",
"implies": [ "Ruby on Rails", "MongoDB" ] "implies": [ "Ruby on Rails", "MongoDB" ]
}, },
"Lotus Domino": { "Lotus Domino": {
@ -1015,7 +1015,7 @@
}, },
"Magento": { "Magento": {
"cats": [ 6 ], "cats": [ 6 ],
"script": "(js/mage|skin/frontend/(default|enterprise))", "script": "(js/mage|skin/frontend/(default|(enterprise)))\\;version:\\3?Enterprise:Community",
"headers": { "Set-Cookie": "frontend=\\;confidence:50" }, "headers": { "Set-Cookie": "frontend=\\;confidence:50" },
"env": "^(Mage|VarienForm)$", "env": "^(Mage|VarienForm)$",
"implies": "PHP" "implies": "PHP"
@ -1323,7 +1323,7 @@
}, },
"PHP": { "PHP": {
"cats": [ 27 ], "cats": [ 27 ],
"headers": { "Server": "php/?([\\d\\.]+)?\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" }, "headers": { "Server": "php/?([\\d\\.]+)?\\;confidence:50\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" },
"url": "\\.php$" "url": "\\.php$"
}, },
"phpAlbum": { "phpAlbum": {

@ -166,7 +166,7 @@
// Make POST request // Make POST request
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open('POST', w.config.websiteURL + 'ping/', true); xhr.open('POST', w.config.websiteURL + 'ping/v2/', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

@ -81,10 +81,20 @@ var wappalyzer = (function() {
if ( matches ) { if ( matches ) {
matches.map(function(match, i) { matches.map(function(match, i) {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.+)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace('\\' + i, match ? match : ''); version = version.replace('\\' + i, match ? match : '');
}); });
if ( version ) {
self.versions.push(version); self.versions.push(version);
}
self.getVersion(); self.getVersion();
} }
@ -129,8 +139,8 @@ var wappalyzer = (function() {
// Key value pairs // Key value pairs
attr = attr.split(':'); attr = attr.split(':');
if ( attr.length === 2 ) { if ( attr.length > 1 ) {
attrs[attr[0]] = attr[1]; attrs[attr.shift()] = attr.join(':');
} }
} else { } else {
attrs.string = attr; attrs.string = attr;
@ -237,7 +247,7 @@ var wappalyzer = (function() {
data.url = url = url.split('#')[0]; data.url = url = url.split('#')[0];
if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) { if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) {
w.log('apps.json not loaded'); w.log('apps.json not loaded, check for syntax errors');
return; return;
} }
@ -247,7 +257,7 @@ var wappalyzer = (function() {
} }
for ( app in w.apps ) { for ( app in w.apps ) {
apps[app] = new Application(app); apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
switch ( type ) { switch ( type ) {
@ -289,7 +299,7 @@ var wappalyzer = (function() {
profiler.regexCount ++; profiler.regexCount ++;
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
apps[app].setDetected(pattern, type, data[type]); apps[app].setDetected(pattern, type, match[2]);
} }
} }
}); });
@ -383,13 +393,13 @@ var wappalyzer = (function() {
implied = parse(implied)[0]; implied = parse(implied)[0];
if ( !w.apps[implied.string] ) { if ( !w.apps[implied.string] ) {
w.log('Implied application ' + implied.string + ' does not exist'); w.log('Implied application ' + implied.string + ' does not exist', 'warn');
return; return;
} }
if ( !apps.hasOwnProperty(implied.string) ) { if ( !apps.hasOwnProperty(implied.string) ) {
apps[implied.string] = new Application(implied.string, true); apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
} }
// Apply app confidence to implied app // Apply app confidence to implied app
@ -406,6 +416,7 @@ var wappalyzer = (function() {
// Keep history of detected apps // Keep history of detected apps
for ( app in apps ) { for ( app in apps ) {
confidence = apps[app].confidence; confidence = apps[app].confidence;
version = apps[app].version;
// Per URL // Per URL
w.detected[url][app] = apps[app]; w.detected[url][app] = apps[app];
@ -422,18 +433,20 @@ var wappalyzer = (function() {
} }
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) { if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
w.ping.hostnames[hostname].applications[app] = 1; w.ping.hostnames[hostname].applications[app] = { hits: 0 };
} }
w.ping.hostnames[hostname].applications[app] ++; w.ping.hostnames[hostname].applications[app].hits ++;
if ( version ) {
w.ping.hostnames[hostname].applications[app].version = version;
}
} else { } else {
w.log('Ignoring hostname "' + hostname + '"'); w.log('Ignoring hostname "' + hostname + '"');
} }
} }
} }
w.log(JSON.stringify(w.detected));
// Additional information // Additional information
if ( w.ping.hostnames.hasOwnProperty(hostname) ) { if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
if ( typeof data.html === 'string' && data.html ) { if ( typeof data.html === 'string' && data.html ) {
@ -456,7 +469,7 @@ var wappalyzer = (function() {
} }
} }
w.log(hostname + ': ' + JSON.stringify(w.ping.hostnames[hostname])); w.log({ hostname: hostname, ping: w.ping.hostnames[hostname] });
} }
if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); }

@ -106,7 +106,7 @@
}, },
"AMPcms": { "AMPcms": {
"cats": [ 1 ], "cats": [ 1 ],
"headers": { "X-AMP-Version": "([\\d\\.]+)\\;version=\\1", "Set-Cookie": "^AMP=" }, "headers": { "X-AMP-Version": "([\\d\\.]+)\\;version:\\1", "Set-Cookie": "^AMP=" },
"env": "^amp_js_init$", "env": "^amp_js_init$",
"implies": "PHP" "implies": "PHP"
}, },
@ -1006,7 +1006,7 @@
}, },
"Locomotive": { "Locomotive": {
"cats": [ 1 ], "cats": [ 1 ],
"html": "<link[^>]*\/sites\/[a-zA-Z0-9]{24}\/theme\/stylesheets\/.*>", "html": "<link[^>]*/sites/[a-zA-Z0-9]{24}/theme/stylesheets/.*>",
"implies": [ "Ruby on Rails", "MongoDB" ] "implies": [ "Ruby on Rails", "MongoDB" ]
}, },
"Lotus Domino": { "Lotus Domino": {
@ -1015,7 +1015,7 @@
}, },
"Magento": { "Magento": {
"cats": [ 6 ], "cats": [ 6 ],
"script": "(js/mage|skin/frontend/(default|enterprise))", "script": "(js/mage|skin/frontend/(default|(enterprise)))\\;version:\\3?Enterprise:Community",
"headers": { "Set-Cookie": "frontend=\\;confidence:50" }, "headers": { "Set-Cookie": "frontend=\\;confidence:50" },
"env": "^(Mage|VarienForm)$", "env": "^(Mage|VarienForm)$",
"implies": "PHP" "implies": "PHP"
@ -1323,7 +1323,7 @@
}, },
"PHP": { "PHP": {
"cats": [ 27 ], "cats": [ 27 ],
"headers": { "Server": "php/?([\\d\\.]+)?\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" }, "headers": { "Server": "php/?([\\d\\.]+)?\\;confidence:50\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" },
"url": "\\.php$" "url": "\\.php$"
}, },
"phpAlbum": { "phpAlbum": {

@ -81,10 +81,20 @@ var wappalyzer = (function() {
if ( matches ) { if ( matches ) {
matches.map(function(match, i) { matches.map(function(match, i) {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.+)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace('\\' + i, match ? match : ''); version = version.replace('\\' + i, match ? match : '');
}); });
if ( version ) {
self.versions.push(version); self.versions.push(version);
}
self.getVersion(); self.getVersion();
} }
@ -129,8 +139,8 @@ var wappalyzer = (function() {
// Key value pairs // Key value pairs
attr = attr.split(':'); attr = attr.split(':');
if ( attr.length === 2 ) { if ( attr.length > 1 ) {
attrs[attr[0]] = attr[1]; attrs[attr.shift()] = attr.join(':');
} }
} else { } else {
attrs.string = attr; attrs.string = attr;
@ -237,7 +247,7 @@ var wappalyzer = (function() {
data.url = url = url.split('#')[0]; data.url = url = url.split('#')[0];
if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) { if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) {
w.log('apps.json not loaded'); w.log('apps.json not loaded, check for syntax errors');
return; return;
} }
@ -247,7 +257,7 @@ var wappalyzer = (function() {
} }
for ( app in w.apps ) { for ( app in w.apps ) {
apps[app] = new Application(app); apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
switch ( type ) { switch ( type ) {
@ -289,7 +299,7 @@ var wappalyzer = (function() {
profiler.regexCount ++; profiler.regexCount ++;
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
apps[app].setDetected(pattern, type, data[type]); apps[app].setDetected(pattern, type, match[2]);
} }
} }
}); });
@ -383,13 +393,13 @@ var wappalyzer = (function() {
implied = parse(implied)[0]; implied = parse(implied)[0];
if ( !w.apps[implied.string] ) { if ( !w.apps[implied.string] ) {
w.log('Implied application ' + implied.string + ' does not exist'); w.log('Implied application ' + implied.string + ' does not exist', 'warn');
return; return;
} }
if ( !apps.hasOwnProperty(implied.string) ) { if ( !apps.hasOwnProperty(implied.string) ) {
apps[implied.string] = new Application(implied.string, true); apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
} }
// Apply app confidence to implied app // Apply app confidence to implied app
@ -406,6 +416,7 @@ var wappalyzer = (function() {
// Keep history of detected apps // Keep history of detected apps
for ( app in apps ) { for ( app in apps ) {
confidence = apps[app].confidence; confidence = apps[app].confidence;
version = apps[app].version;
// Per URL // Per URL
w.detected[url][app] = apps[app]; w.detected[url][app] = apps[app];
@ -422,18 +433,20 @@ var wappalyzer = (function() {
} }
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) { if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
w.ping.hostnames[hostname].applications[app] = 1; w.ping.hostnames[hostname].applications[app] = { hits: 0 };
} }
w.ping.hostnames[hostname].applications[app] ++; w.ping.hostnames[hostname].applications[app].hits ++;
if ( version ) {
w.ping.hostnames[hostname].applications[app].version = version;
}
} else { } else {
w.log('Ignoring hostname "' + hostname + '"'); w.log('Ignoring hostname "' + hostname + '"');
} }
} }
} }
w.log(JSON.stringify(w.detected));
// Additional information // Additional information
if ( w.ping.hostnames.hasOwnProperty(hostname) ) { if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
if ( typeof data.html === 'string' && data.html ) { if ( typeof data.html === 'string' && data.html ) {
@ -456,7 +469,7 @@ var wappalyzer = (function() {
} }
} }
w.log(hostname + ': ' + JSON.stringify(w.ping.hostnames[hostname])); w.log({ hostname: hostname, ping: w.ping.hostnames[hostname] });
} }
if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); }

@ -106,7 +106,7 @@
}, },
"AMPcms": { "AMPcms": {
"cats": [ 1 ], "cats": [ 1 ],
"headers": { "X-AMP-Version": "([\\d\\.]+)\\;version=\\1", "Set-Cookie": "^AMP=" }, "headers": { "X-AMP-Version": "([\\d\\.]+)\\;version:\\1", "Set-Cookie": "^AMP=" },
"env": "^amp_js_init$", "env": "^amp_js_init$",
"implies": "PHP" "implies": "PHP"
}, },
@ -1006,7 +1006,7 @@
}, },
"Locomotive": { "Locomotive": {
"cats": [ 1 ], "cats": [ 1 ],
"html": "<link[^>]*\/sites\/[a-zA-Z0-9]{24}\/theme\/stylesheets\/.*>", "html": "<link[^>]*/sites/[a-zA-Z0-9]{24}/theme/stylesheets/.*>",
"implies": [ "Ruby on Rails", "MongoDB" ] "implies": [ "Ruby on Rails", "MongoDB" ]
}, },
"Lotus Domino": { "Lotus Domino": {
@ -1015,7 +1015,7 @@
}, },
"Magento": { "Magento": {
"cats": [ 6 ], "cats": [ 6 ],
"script": "(js/mage|skin/frontend/(default|enterprise))", "script": "(js/mage|skin/frontend/(default|(enterprise)))\\;version:\\3?Enterprise:Community",
"headers": { "Set-Cookie": "frontend=\\;confidence:50" }, "headers": { "Set-Cookie": "frontend=\\;confidence:50" },
"env": "^(Mage|VarienForm)$", "env": "^(Mage|VarienForm)$",
"implies": "PHP" "implies": "PHP"
@ -1323,7 +1323,7 @@
}, },
"PHP": { "PHP": {
"cats": [ 27 ], "cats": [ 27 ],
"headers": { "Server": "php/?([\\d\\.]+)?\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" }, "headers": { "Server": "php/?([\\d\\.]+)?\\;confidence:50\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" },
"url": "\\.php$" "url": "\\.php$"
}, },
"phpAlbum": { "phpAlbum": {

@ -275,7 +275,7 @@
// Make POST request // Make POST request
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
request.open('POST', w.config.websiteURL + 'ping/', true); request.open('POST', w.config.websiteURL + 'ping/v2/', true);
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

@ -81,10 +81,20 @@ var wappalyzer = (function() {
if ( matches ) { if ( matches ) {
matches.map(function(match, i) { matches.map(function(match, i) {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.+)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace('\\' + i, match ? match : ''); version = version.replace('\\' + i, match ? match : '');
}); });
if ( version ) {
self.versions.push(version); self.versions.push(version);
}
self.getVersion(); self.getVersion();
} }
@ -129,8 +139,8 @@ var wappalyzer = (function() {
// Key value pairs // Key value pairs
attr = attr.split(':'); attr = attr.split(':');
if ( attr.length === 2 ) { if ( attr.length > 1 ) {
attrs[attr[0]] = attr[1]; attrs[attr.shift()] = attr.join(':');
} }
} else { } else {
attrs.string = attr; attrs.string = attr;
@ -237,7 +247,7 @@ var wappalyzer = (function() {
data.url = url = url.split('#')[0]; data.url = url = url.split('#')[0];
if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) { if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) {
w.log('apps.json not loaded'); w.log('apps.json not loaded, check for syntax errors');
return; return;
} }
@ -247,7 +257,7 @@ var wappalyzer = (function() {
} }
for ( app in w.apps ) { for ( app in w.apps ) {
apps[app] = new Application(app); apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
switch ( type ) { switch ( type ) {
@ -289,7 +299,7 @@ var wappalyzer = (function() {
profiler.regexCount ++; profiler.regexCount ++;
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
apps[app].setDetected(pattern, type, data[type]); apps[app].setDetected(pattern, type, match[2]);
} }
} }
}); });
@ -383,13 +393,13 @@ var wappalyzer = (function() {
implied = parse(implied)[0]; implied = parse(implied)[0];
if ( !w.apps[implied.string] ) { if ( !w.apps[implied.string] ) {
w.log('Implied application ' + implied.string + ' does not exist'); w.log('Implied application ' + implied.string + ' does not exist', 'warn');
return; return;
} }
if ( !apps.hasOwnProperty(implied.string) ) { if ( !apps.hasOwnProperty(implied.string) ) {
apps[implied.string] = new Application(implied.string, true); apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
} }
// Apply app confidence to implied app // Apply app confidence to implied app
@ -406,6 +416,7 @@ var wappalyzer = (function() {
// Keep history of detected apps // Keep history of detected apps
for ( app in apps ) { for ( app in apps ) {
confidence = apps[app].confidence; confidence = apps[app].confidence;
version = apps[app].version;
// Per URL // Per URL
w.detected[url][app] = apps[app]; w.detected[url][app] = apps[app];
@ -422,18 +433,20 @@ var wappalyzer = (function() {
} }
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) { if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
w.ping.hostnames[hostname].applications[app] = 1; w.ping.hostnames[hostname].applications[app] = { hits: 0 };
} }
w.ping.hostnames[hostname].applications[app] ++; w.ping.hostnames[hostname].applications[app].hits ++;
if ( version ) {
w.ping.hostnames[hostname].applications[app].version = version;
}
} else { } else {
w.log('Ignoring hostname "' + hostname + '"'); w.log('Ignoring hostname "' + hostname + '"');
} }
} }
} }
w.log(JSON.stringify(w.detected));
// Additional information // Additional information
if ( w.ping.hostnames.hasOwnProperty(hostname) ) { if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
if ( typeof data.html === 'string' && data.html ) { if ( typeof data.html === 'string' && data.html ) {
@ -456,7 +469,7 @@ var wappalyzer = (function() {
} }
} }
w.log(hostname + ': ' + JSON.stringify(w.ping.hostnames[hostname])); w.log({ hostname: hostname, ping: w.ping.hostnames[hostname] });
} }
if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); }

@ -106,7 +106,7 @@
}, },
"AMPcms": { "AMPcms": {
"cats": [ 1 ], "cats": [ 1 ],
"headers": { "X-AMP-Version": "([\\d\\.]+)\\;version=\\1", "Set-Cookie": "^AMP=" }, "headers": { "X-AMP-Version": "([\\d\\.]+)\\;version:\\1", "Set-Cookie": "^AMP=" },
"env": "^amp_js_init$", "env": "^amp_js_init$",
"implies": "PHP" "implies": "PHP"
}, },
@ -1006,7 +1006,7 @@
}, },
"Locomotive": { "Locomotive": {
"cats": [ 1 ], "cats": [ 1 ],
"html": "<link[^>]*\/sites\/[a-zA-Z0-9]{24}\/theme\/stylesheets\/.*>", "html": "<link[^>]*/sites/[a-zA-Z0-9]{24}/theme/stylesheets/.*>",
"implies": [ "Ruby on Rails", "MongoDB" ] "implies": [ "Ruby on Rails", "MongoDB" ]
}, },
"Lotus Domino": { "Lotus Domino": {
@ -1015,7 +1015,7 @@
}, },
"Magento": { "Magento": {
"cats": [ 6 ], "cats": [ 6 ],
"script": "(js/mage|skin/frontend/(default|enterprise))", "script": "(js/mage|skin/frontend/(default|(enterprise)))\\;version:\\3?Enterprise:Community",
"headers": { "Set-Cookie": "frontend=\\;confidence:50" }, "headers": { "Set-Cookie": "frontend=\\;confidence:50" },
"env": "^(Mage|VarienForm)$", "env": "^(Mage|VarienForm)$",
"implies": "PHP" "implies": "PHP"
@ -1323,7 +1323,7 @@
}, },
"PHP": { "PHP": {
"cats": [ 27 ], "cats": [ 27 ],
"headers": { "Server": "php/?([\\d\\.]+)?\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" }, "headers": { "Server": "php/?([\\d\\.]+)?\\;confidence:50\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" },
"url": "\\.php$" "url": "\\.php$"
}, },
"phpAlbum": { "phpAlbum": {

@ -81,10 +81,20 @@ var wappalyzer = (function() {
if ( matches ) { if ( matches ) {
matches.map(function(match, i) { matches.map(function(match, i) {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.+)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace('\\' + i, match ? match : ''); version = version.replace('\\' + i, match ? match : '');
}); });
if ( version ) {
self.versions.push(version); self.versions.push(version);
}
self.getVersion(); self.getVersion();
} }
@ -129,8 +139,8 @@ var wappalyzer = (function() {
// Key value pairs // Key value pairs
attr = attr.split(':'); attr = attr.split(':');
if ( attr.length === 2 ) { if ( attr.length > 1 ) {
attrs[attr[0]] = attr[1]; attrs[attr.shift()] = attr.join(':');
} }
} else { } else {
attrs.string = attr; attrs.string = attr;
@ -237,7 +247,7 @@ var wappalyzer = (function() {
data.url = url = url.split('#')[0]; data.url = url = url.split('#')[0];
if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) { if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) {
w.log('apps.json not loaded'); w.log('apps.json not loaded, check for syntax errors');
return; return;
} }
@ -247,7 +257,7 @@ var wappalyzer = (function() {
} }
for ( app in w.apps ) { for ( app in w.apps ) {
apps[app] = new Application(app); apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
switch ( type ) { switch ( type ) {
@ -289,7 +299,7 @@ var wappalyzer = (function() {
profiler.regexCount ++; profiler.regexCount ++;
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
apps[app].setDetected(pattern, type, data[type]); apps[app].setDetected(pattern, type, match[2]);
} }
} }
}); });
@ -383,13 +393,13 @@ var wappalyzer = (function() {
implied = parse(implied)[0]; implied = parse(implied)[0];
if ( !w.apps[implied.string] ) { if ( !w.apps[implied.string] ) {
w.log('Implied application ' + implied.string + ' does not exist'); w.log('Implied application ' + implied.string + ' does not exist', 'warn');
return; return;
} }
if ( !apps.hasOwnProperty(implied.string) ) { if ( !apps.hasOwnProperty(implied.string) ) {
apps[implied.string] = new Application(implied.string, true); apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
} }
// Apply app confidence to implied app // Apply app confidence to implied app
@ -406,6 +416,7 @@ var wappalyzer = (function() {
// Keep history of detected apps // Keep history of detected apps
for ( app in apps ) { for ( app in apps ) {
confidence = apps[app].confidence; confidence = apps[app].confidence;
version = apps[app].version;
// Per URL // Per URL
w.detected[url][app] = apps[app]; w.detected[url][app] = apps[app];
@ -422,18 +433,20 @@ var wappalyzer = (function() {
} }
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) { if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
w.ping.hostnames[hostname].applications[app] = 1; w.ping.hostnames[hostname].applications[app] = { hits: 0 };
} }
w.ping.hostnames[hostname].applications[app] ++; w.ping.hostnames[hostname].applications[app].hits ++;
if ( version ) {
w.ping.hostnames[hostname].applications[app].version = version;
}
} else { } else {
w.log('Ignoring hostname "' + hostname + '"'); w.log('Ignoring hostname "' + hostname + '"');
} }
} }
} }
w.log(JSON.stringify(w.detected));
// Additional information // Additional information
if ( w.ping.hostnames.hasOwnProperty(hostname) ) { if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
if ( typeof data.html === 'string' && data.html ) { if ( typeof data.html === 'string' && data.html ) {
@ -456,7 +469,7 @@ var wappalyzer = (function() {
} }
} }
w.log(hostname + ': ' + JSON.stringify(w.ping.hostnames[hostname])); w.log({ hostname: hostname, ping: w.ping.hostnames[hostname] });
} }
if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); }

@ -106,7 +106,7 @@
}, },
"AMPcms": { "AMPcms": {
"cats": [ 1 ], "cats": [ 1 ],
"headers": { "X-AMP-Version": "([\\d\\.]+)\\;version=\\1", "Set-Cookie": "^AMP=" }, "headers": { "X-AMP-Version": "([\\d\\.]+)\\;version:\\1", "Set-Cookie": "^AMP=" },
"env": "^amp_js_init$", "env": "^amp_js_init$",
"implies": "PHP" "implies": "PHP"
}, },
@ -1006,7 +1006,7 @@
}, },
"Locomotive": { "Locomotive": {
"cats": [ 1 ], "cats": [ 1 ],
"html": "<link[^>]*\/sites\/[a-zA-Z0-9]{24}\/theme\/stylesheets\/.*>", "html": "<link[^>]*/sites/[a-zA-Z0-9]{24}/theme/stylesheets/.*>",
"implies": [ "Ruby on Rails", "MongoDB" ] "implies": [ "Ruby on Rails", "MongoDB" ]
}, },
"Lotus Domino": { "Lotus Domino": {
@ -1015,7 +1015,7 @@
}, },
"Magento": { "Magento": {
"cats": [ 6 ], "cats": [ 6 ],
"script": "(js/mage|skin/frontend/(default|enterprise))", "script": "(js/mage|skin/frontend/(default|(enterprise)))\\;version:\\3?Enterprise:Community",
"headers": { "Set-Cookie": "frontend=\\;confidence:50" }, "headers": { "Set-Cookie": "frontend=\\;confidence:50" },
"env": "^(Mage|VarienForm)$", "env": "^(Mage|VarienForm)$",
"implies": "PHP" "implies": "PHP"
@ -1323,7 +1323,7 @@
}, },
"PHP": { "PHP": {
"cats": [ 27 ], "cats": [ 27 ],
"headers": { "Server": "php/?([\\d\\.]+)?\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" }, "headers": { "Server": "php/?([\\d\\.]+)?\\;confidence:50\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" },
"url": "\\.php$" "url": "\\.php$"
}, },
"phpAlbum": { "phpAlbum": {

@ -81,10 +81,20 @@ var wappalyzer = (function() {
if ( matches ) { if ( matches ) {
matches.map(function(match, i) { matches.map(function(match, i) {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.+)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace('\\' + i, match ? match : ''); version = version.replace('\\' + i, match ? match : '');
}); });
if ( version ) {
self.versions.push(version); self.versions.push(version);
}
self.getVersion(); self.getVersion();
} }
@ -129,8 +139,8 @@ var wappalyzer = (function() {
// Key value pairs // Key value pairs
attr = attr.split(':'); attr = attr.split(':');
if ( attr.length === 2 ) { if ( attr.length > 1 ) {
attrs[attr[0]] = attr[1]; attrs[attr.shift()] = attr.join(':');
} }
} else { } else {
attrs.string = attr; attrs.string = attr;
@ -237,7 +247,7 @@ var wappalyzer = (function() {
data.url = url = url.split('#')[0]; data.url = url = url.split('#')[0];
if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) { if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) {
w.log('apps.json not loaded'); w.log('apps.json not loaded, check for syntax errors');
return; return;
} }
@ -247,7 +257,7 @@ var wappalyzer = (function() {
} }
for ( app in w.apps ) { for ( app in w.apps ) {
apps[app] = new Application(app); apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
switch ( type ) { switch ( type ) {
@ -289,7 +299,7 @@ var wappalyzer = (function() {
profiler.regexCount ++; profiler.regexCount ++;
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
apps[app].setDetected(pattern, type, data[type]); apps[app].setDetected(pattern, type, match[2]);
} }
} }
}); });
@ -383,13 +393,13 @@ var wappalyzer = (function() {
implied = parse(implied)[0]; implied = parse(implied)[0];
if ( !w.apps[implied.string] ) { if ( !w.apps[implied.string] ) {
w.log('Implied application ' + implied.string + ' does not exist'); w.log('Implied application ' + implied.string + ' does not exist', 'warn');
return; return;
} }
if ( !apps.hasOwnProperty(implied.string) ) { if ( !apps.hasOwnProperty(implied.string) ) {
apps[implied.string] = new Application(implied.string, true); apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
} }
// Apply app confidence to implied app // Apply app confidence to implied app
@ -406,6 +416,7 @@ var wappalyzer = (function() {
// Keep history of detected apps // Keep history of detected apps
for ( app in apps ) { for ( app in apps ) {
confidence = apps[app].confidence; confidence = apps[app].confidence;
version = apps[app].version;
// Per URL // Per URL
w.detected[url][app] = apps[app]; w.detected[url][app] = apps[app];
@ -422,18 +433,20 @@ var wappalyzer = (function() {
} }
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) { if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
w.ping.hostnames[hostname].applications[app] = 1; w.ping.hostnames[hostname].applications[app] = { hits: 0 };
} }
w.ping.hostnames[hostname].applications[app] ++; w.ping.hostnames[hostname].applications[app].hits ++;
if ( version ) {
w.ping.hostnames[hostname].applications[app].version = version;
}
} else { } else {
w.log('Ignoring hostname "' + hostname + '"'); w.log('Ignoring hostname "' + hostname + '"');
} }
} }
} }
w.log(JSON.stringify(w.detected));
// Additional information // Additional information
if ( w.ping.hostnames.hasOwnProperty(hostname) ) { if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
if ( typeof data.html === 'string' && data.html ) { if ( typeof data.html === 'string' && data.html ) {
@ -456,7 +469,7 @@ var wappalyzer = (function() {
} }
} }
w.log(hostname + ': ' + JSON.stringify(w.ping.hostnames[hostname])); w.log({ hostname: hostname, ping: w.ping.hostnames[hostname] });
} }
if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); }

@ -106,7 +106,7 @@
}, },
"AMPcms": { "AMPcms": {
"cats": [ 1 ], "cats": [ 1 ],
"headers": { "X-AMP-Version": "([\\d\\.]+)\\;version=\\1", "Set-Cookie": "^AMP=" }, "headers": { "X-AMP-Version": "([\\d\\.]+)\\;version:\\1", "Set-Cookie": "^AMP=" },
"env": "^amp_js_init$", "env": "^amp_js_init$",
"implies": "PHP" "implies": "PHP"
}, },
@ -1006,7 +1006,7 @@
}, },
"Locomotive": { "Locomotive": {
"cats": [ 1 ], "cats": [ 1 ],
"html": "<link[^>]*\/sites\/[a-zA-Z0-9]{24}\/theme\/stylesheets\/.*>", "html": "<link[^>]*/sites/[a-zA-Z0-9]{24}/theme/stylesheets/.*>",
"implies": [ "Ruby on Rails", "MongoDB" ] "implies": [ "Ruby on Rails", "MongoDB" ]
}, },
"Lotus Domino": { "Lotus Domino": {
@ -1015,7 +1015,7 @@
}, },
"Magento": { "Magento": {
"cats": [ 6 ], "cats": [ 6 ],
"script": "(js/mage|skin/frontend/(default|enterprise))", "script": "(js/mage|skin/frontend/(default|(enterprise)))\\;version:\\3?Enterprise:Community",
"headers": { "Set-Cookie": "frontend=\\;confidence:50" }, "headers": { "Set-Cookie": "frontend=\\;confidence:50" },
"env": "^(Mage|VarienForm)$", "env": "^(Mage|VarienForm)$",
"implies": "PHP" "implies": "PHP"
@ -1323,7 +1323,7 @@
}, },
"PHP": { "PHP": {
"cats": [ 27 ], "cats": [ 27 ],
"headers": { "Server": "php/?([\\d\\.]+)?\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" }, "headers": { "Server": "php/?([\\d\\.]+)?\\;confidence:50\\;version:\\1", "X-Powered-By": "php/?([\\d\\.]+)?\\;version:\\1", "Set-Cookie": "PHPSESSID" },
"url": "\\.php$" "url": "\\.php$"
}, },
"phpAlbum": { "phpAlbum": {

@ -81,10 +81,20 @@ var wappalyzer = (function() {
if ( matches ) { if ( matches ) {
matches.map(function(match, i) { matches.map(function(match, i) {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.+)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace('\\' + i, match ? match : ''); version = version.replace('\\' + i, match ? match : '');
}); });
if ( version ) {
self.versions.push(version); self.versions.push(version);
}
self.getVersion(); self.getVersion();
} }
@ -129,8 +139,8 @@ var wappalyzer = (function() {
// Key value pairs // Key value pairs
attr = attr.split(':'); attr = attr.split(':');
if ( attr.length === 2 ) { if ( attr.length > 1 ) {
attrs[attr[0]] = attr[1]; attrs[attr.shift()] = attr.join(':');
} }
} else { } else {
attrs.string = attr; attrs.string = attr;
@ -237,7 +247,7 @@ var wappalyzer = (function() {
data.url = url = url.split('#')[0]; data.url = url = url.split('#')[0];
if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) { if ( typeof w.apps === 'undefined' || typeof w.categories === 'undefined' ) {
w.log('apps.json not loaded'); w.log('apps.json not loaded, check for syntax errors');
return; return;
} }
@ -247,7 +257,7 @@ var wappalyzer = (function() {
} }
for ( app in w.apps ) { for ( app in w.apps ) {
apps[app] = new Application(app); apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
for ( type in w.apps[app] ) { for ( type in w.apps[app] ) {
switch ( type ) { switch ( type ) {
@ -289,7 +299,7 @@ var wappalyzer = (function() {
profiler.regexCount ++; profiler.regexCount ++;
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
apps[app].setDetected(pattern, type, data[type]); apps[app].setDetected(pattern, type, match[2]);
} }
} }
}); });
@ -383,13 +393,13 @@ var wappalyzer = (function() {
implied = parse(implied)[0]; implied = parse(implied)[0];
if ( !w.apps[implied.string] ) { if ( !w.apps[implied.string] ) {
w.log('Implied application ' + implied.string + ' does not exist'); w.log('Implied application ' + implied.string + ' does not exist', 'warn');
return; return;
} }
if ( !apps.hasOwnProperty(implied.string) ) { if ( !apps.hasOwnProperty(implied.string) ) {
apps[implied.string] = new Application(implied.string, true); apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
} }
// Apply app confidence to implied app // Apply app confidence to implied app
@ -406,6 +416,7 @@ var wappalyzer = (function() {
// Keep history of detected apps // Keep history of detected apps
for ( app in apps ) { for ( app in apps ) {
confidence = apps[app].confidence; confidence = apps[app].confidence;
version = apps[app].version;
// Per URL // Per URL
w.detected[url][app] = apps[app]; w.detected[url][app] = apps[app];
@ -422,18 +433,20 @@ var wappalyzer = (function() {
} }
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) { if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
w.ping.hostnames[hostname].applications[app] = 1; w.ping.hostnames[hostname].applications[app] = { hits: 0 };
} }
w.ping.hostnames[hostname].applications[app] ++; w.ping.hostnames[hostname].applications[app].hits ++;
if ( version ) {
w.ping.hostnames[hostname].applications[app].version = version;
}
} else { } else {
w.log('Ignoring hostname "' + hostname + '"'); w.log('Ignoring hostname "' + hostname + '"');
} }
} }
} }
w.log(JSON.stringify(w.detected));
// Additional information // Additional information
if ( w.ping.hostnames.hasOwnProperty(hostname) ) { if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
if ( typeof data.html === 'string' && data.html ) { if ( typeof data.html === 'string' && data.html ) {
@ -456,7 +469,7 @@ var wappalyzer = (function() {
} }
} }
w.log(hostname + ': ' + JSON.stringify(w.ping.hostnames[hostname])); w.log({ hostname: hostname, ping: w.ping.hostnames[hostname] });
} }
if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } if ( Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); }