diff --git a/src/drivers/npm/package.json b/src/drivers/npm/package.json index 9f7982aea..9f9e36f00 100644 --- a/src/drivers/npm/package.json +++ b/src/drivers/npm/package.json @@ -2,7 +2,7 @@ "name": "wappalyzer", "description": "Uncovers the technologies used on websites", "homepage": "https://github.com/AliasIO/Wappalyzer", - "version": "5.0.7", + "version": "5.1.0", "author": "Elbert Alias", "license": "GPL-3.0", "repository": { diff --git a/src/drivers/webextension/css/popup.css b/src/drivers/webextension/css/popup.css index 015a333bd..98c56c2de 100644 --- a/src/drivers/webextension/css/popup.css +++ b/src/drivers/webextension/css/popup.css @@ -1,31 +1,95 @@ body { background: #fff; - color: #4a4a4a; font-family: Helvetica, Arial, sans-serif; - font-size: 13px; - line-height: 16px; + font-size: .8rem; + height: 20.8rem; margin: 0; - min-width: 200px; - overflow-x: hidden; - padding: 15px; + overflow: hidden; + width: 30rem; } -a { - color: #4a4a4a; +.header { + align-items: center; + background: linear-gradient(160deg, #32067c, #150233); + height: 4rem; + display: flex; } -a:focus { - outline: 0; +.header__link:focus { + outline: none; } -img { +.header__logo { + display: inline-block; + margin: .2rem 0 0 1.5rem; + -webkit-backface-visibility: hidden; + -webkit-transform: translateZ(0) scale(1.0, 1.0); + transform: translateZ(0); + height: 2rem; +} + +.container { + height: 15.8rem; + overflow: scroll; + padding: 1rem 1.5rem 0rem 1.5rem; +} + +.detected { + columns: 2; + column-gap: 1.5rem; + line-height: 1.4rem; +} + +.detected__category { + break-inside: avoid-column; + padding-bottom: 1rem; +} + +.detected__category-link { + border-bottom: 1px solid #dbdbdb; + display: block; + margin-bottom: .5rem; + text-decoration: none; +} + +.detected__category-name { + color: #4608ad; + 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; +} + +.detected__app:focus { + display: block; + outline: 0; +} + +.detected__app-icon { display: inline-block; height: 16px; - margin-right: 8px; - vertical-align: top; + margin-right: .5rem; + vertical-align: -.2rem; width: 16px; } +.detected__app-name { + color: #4a4a4a; +} + +.detected__app:hover .detected__app-name { + border-bottom: 1px solid #4a4a4a; +} + .detected-app { padding: 7px 0; } @@ -39,40 +103,12 @@ img { padding-bottom: 0; } - .detected-app a { - color: #4608ad; - display: block; - text-decoration: none; - } - - .detected-app a .label .name { - border-bottom: 1px solid transparent; - } - - .detected-app a:hover .label .name { - border-bottom: 1px solid #4608ad; - } - - .detected-app a .category .name { - color: #4a4a4a; - border-bottom: 1px solid transparent; - } - - .detected-app a:hover .category .name { - border-bottom: 1px solid #4a4a4a; - } - -.label { - font-weight: bold; -} - -.category { - display: block; - margin: 5px 0 0 24px; +.empty { + display: flex; + height: 16rem; + align-items: center; + justify-content: center; } -.empty { - color: #999; - font-style: italic; - text-align: center; +.empty__text { } diff --git a/src/drivers/webextension/html/popup.html b/src/drivers/webextension/html/popup.html index 2f4e90ad2..1f17595cf 100644 --- a/src/drivers/webextension/html/popup.html +++ b/src/drivers/webextension/html/popup.html @@ -11,5 +11,12 @@ +
+ + + +
+ +
diff --git a/src/drivers/webextension/js/driver.js b/src/drivers/webextension/js/driver.js index ac26cb55c..e9c6c97a6 100644 --- a/src/drivers/webextension/js/driver.js +++ b/src/drivers/webextension/js/driver.js @@ -28,7 +28,7 @@ function getOption(name, defaultValue) { // Chrome, Firefox browser.storage.local.get(name) .then(callback) - .catch(console.error); + .catch(error => wappalyzer.log(error, 'driver', 'error')); } catch ( e ) { // Edge browser.storage.local.get(name, callback); @@ -125,7 +125,7 @@ var callback = tabs => { try { browser.tabs.query({}) .then(callback) - .catch(console.error); + .catch(error => wappalyzer.log(error, 'driver', 'error')); } catch ( e ) { browser.tabs.query({}, callback); } @@ -281,10 +281,10 @@ wappalyzer.driver.getRobotsTxt = (host, secure = false) => { fetch('http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt') .then(response => { if ( !response.ok ) { - if (response.status === 404) { - return ''; + if ( response.status === 404 ) { + return ''; } else { - throw 'GET ' + response.url + ' was not ok'; + throw 'GET ' + response.url + ' was not ok'; } } diff --git a/src/drivers/webextension/js/iframe.js b/src/drivers/webextension/js/iframe.js index ea3e2a990..0dd339d58 100644 --- a/src/drivers/webextension/js/iframe.js +++ b/src/drivers/webextension/js/iframe.js @@ -181,7 +181,7 @@ var exports = {}; video_assets: opt_video_assets, assets: opt_assets, version: '3', - mrev: '082d7cb-d', + mrev: '4d79384-d', msgNum: this.msgNum, timestamp: new Date().getTime(), pageVis: document.visibilityState, @@ -890,7 +890,7 @@ var exports = {}; var _pageTags; var INIT_MS_BW_SEARCHES = 2000; 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)'); 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) { if ( exports.utils.SCRIPT_IN_FRIENDLY_IFRAME ) { @@ -1137,6 +1154,8 @@ if ( exports.utils.SCRIPT_IN_WINDOW_TOP ) { init: exports.coordinator.init, addPostMessageListener: exports.coordinator.addPostMessageListener, askIfTrackingEnabled: exports.utils.askIfTrackingEnabled, + blockedRobotsMsgGen: exports.coordinator.blockedRobotsMsgGen, + inWindowTop: exports.utils.SCRIPT_IN_WINDOW_TOP, sendToBackground: exports.utils.sendToBackground }; } else { @@ -1149,18 +1168,18 @@ if ( exports.utils.SCRIPT_IN_WINDOW_TOP ) { ); } })(window); -(function(adparser) { +(function(adparser, pageUrl) { function onAdFound(log) { adparser.sendToBackground({ id: 'ad_log', subject: log }, 'ad_log', '', function(){}); } - if ( window === window.top ) { + if ( adparser && adparser.inWindowTop ) { adparser.addPostMessageListener(); adparser.askIfTrackingEnabled( function() { adparser.init(onAdFound); }, - function() {} + adparser.blockedRobotsMsgGen(onAdFound, pageUrl) ) } -})(window.adparser); +})(window.adparser, window.location.href); diff --git a/src/drivers/webextension/js/network.js b/src/drivers/webextension/js/network.js index 8a0421b88..d5bc4458c 100644 --- a/src/drivers/webextension/js/network.js +++ b/src/drivers/webextension/js/network.js @@ -66,6 +66,7 @@ 'washingtonpost.com' ]; + var robotsTxtAllows = wappalyzer.robotsTxtAllows; if ( !String.prototype.endsWith ) { String.prototype.endsWith = function(searchString, position) { var subjectString = this.toString(); @@ -114,10 +115,10 @@ } } - function ifTrackingEnabled(url, ifCallback, elseCallback) { + function ifTrackingEnabled(details, ifCallback, elseCallback) { var fullIfCallback = function() { - allowedByRobotsTxt(url, ifCallback, elseCallback); + allowedByRobotsTxt(details, ifCallback, elseCallback); }; browser.storage.local.get('tracking').then(function(item) { @@ -135,9 +136,9 @@ } - function allowedByRobotsTxt(url, ifCallback, elseCallback) { - if ( ! url.startsWith('chrome://') ) { - wappalyzer.robotsTxtAllows(url).then(ifCallback, elseCallback); + function allowedByRobotsTxt(details, ifCallback, elseCallback) { + if ( details.url && !details.url.startsWith('chrome://') ) { + robotsTxtAllows(details.url).then(ifCallback, elseCallback); } else { elseCallback(); } @@ -219,7 +220,7 @@ this.cleanupCollector(tabId); ifTrackingEnabled( - details.url, + details, function() { if ( !areListenersRegistered ) { @@ -279,18 +280,20 @@ browserProxy.tabs.sendMessage(this.tabId, message); }; - PageNetworkTrafficCollector.prototype.sendToTab = function(assetReq, reqs, curPageUrl, isValidAd) { + PageNetworkTrafficCollector.prototype.sendToTab = function(assetReq, reqs, curPageUrl, nonAdTrackingEvent) { var msg = {}; msg.assets = []; + msg.requests = []; msg.event_data = {}; - if ( isValidAd ) { + if ( !nonAdTrackingEvent ) { msg.event = 'new-video-ad'; msg.requests = reqs; msg.requests.sort(function(reqA, reqB) {return reqA.requestTimestamp - reqB.requestTimestamp;}); if ( assetReq ) { msg.assets = [assetReq]; } - } else { + } else if ( nonAdTrackingEvent === 'new-invalid-video-ad' ) { + msg.event = nonAdTrackingEvent; msg.requests = reqs.map(function(request) { return parseHostnameFromUrl(request.url); }); @@ -301,7 +304,8 @@ contentType: assetReq.contentType, size: assetReq.size }]; - msg.event = 'new-invalid-video-ad'; + } else if ( nonAdTrackingEvent === 'robots-txt-no-scraping' ) { + msg.event = nonAdTrackingEvent; } msg.origUrl = curPageUrl; msg.displayAdFound = this.displayAdFound; @@ -805,7 +809,7 @@ browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) { if ( request === 'is_tracking_enabled' ) { ifTrackingEnabled( - sender.tab.url, + sender.tab, function() { try {sendResponse({'tracking_enabled': true});} catch(err) {} }, diff --git a/src/drivers/webextension/js/popup.js b/src/drivers/webextension/js/popup.js index 94be5f258..95184f8ea 100644 --- a/src/drivers/webextension/js/popup.js +++ b/src/drivers/webextension/js/popup.js @@ -32,26 +32,16 @@ function replaceDomWhenReady(dom) { } function replaceDom(domTemplate) { - var body = document.body; + var container = document.getElementsByClassName('container')[0]; - while ( body.firstChild ) { - body.removeChild(body.firstChild); + while ( container.firstChild ) { + container.removeChild(container.firstChild); } - body.appendChild(jsonToDOM(domTemplate, document, {})); + container.appendChild(jsonToDOM(domTemplate, document, {})); 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 => { node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n); }); @@ -63,65 +53,87 @@ function appsToDomTemplate(response) { template = []; if ( response.tabCache && Object.keys(response.tabCache.detected).length > 0 ) { - for ( appName in response.tabCache.detected ) { - confidence = response.tabCache.detected[appName].confidenceTotal; - version = response.tabCache.detected[appName].version; - categories = []; + const categories = {}; + // Group apps by category + for ( appName in response.tabCache.detected ) { response.apps[appName].cats.forEach(cat => { - categories.push( + 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; + version = response.tabCache.detected[appName].version; + + apps.push( [ 'a', { + class: 'detected__app', target: '_blank', - href: 'https://wappalyzer.com/categories/' + slugify(response.categories[cat].name) + href: 'https://wappalyzer.com/applications/' + slugify(appName) }, [ + 'img', { + class: 'detected__app-icon', + src: '../images/icons/' + ( response.apps[appName].icon || 'default.svg' ) + }, + ], [ 'span', { - class: 'category' - }, [ - 'span', { - class: 'name' - }, - browser.i18n.getMessage('categoryName' + cat) - ] + class: 'detected__app-name' + }, + appName + ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) ] ] ); - }); + } template.push( [ 'div', { - class: 'detected-app' + class: 'detected__category' }, [ 'a', { + class: 'detected__category-link', 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', { - class: 'name' - }, - appName - ], - ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) + class: 'detected__category-name' + }, + browser.i18n.getMessage('categoryName' + cat) ] - ], - categories + ], [ + 'div', { + class: 'detected__apps' + }, + apps + ] ] ); } + + template = [ + 'div', { + class: 'detected' + }, + template + ]; } else { template = [ 'div', { class: 'empty' }, - browser.i18n.getMessage('noAppsDetected') + [ + 'span', { + class: 'empty__text' + }, + browser.i18n.getMessage('noAppsDetected') + ], ]; } diff --git a/src/drivers/webextension/manifest.edge.json b/src/drivers/webextension/manifest.edge.json index b2a544023..f00a16d05 100644 --- a/src/drivers/webextension/manifest.edge.json +++ b/src/drivers/webextension/manifest.edge.json @@ -4,7 +4,7 @@ "author": "Elbert Alias", "homepage_url": "https://wappalyzer.com/", "description": "Identify web technologies", - "version": "5.0.7", + "version": "5.1.0", "default_locale": "en", "manifest_version": 2, "icons": { diff --git a/src/drivers/webextension/manifest.json b/src/drivers/webextension/manifest.json index 8d821774b..0d0c48123 100644 --- a/src/drivers/webextension/manifest.json +++ b/src/drivers/webextension/manifest.json @@ -4,7 +4,7 @@ "author": "Elbert Alias", "homepage_url": "https://wappalyzer.com/", "description": "Identify web technologies", - "version": "5.0.7", + "version": "5.1.0", "default_locale": "en", "manifest_version": 2, "icons": {