diff --git a/README.md b/README.md index 6a9731763..0c0b6fb43 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ Patterns (regular expressions) are kept in [`src/technologies.json`](https://git "url": ".+\\.example\\.com", "oss": true, "saas": true, - "pricing": ["low", "medium", "high", "freemium", "onetime", "recurring", "poa"], + "pricing": ["medium", "freemium", "recurring"], "website": "https://example.com", } ``` diff --git a/src/drivers/npm/package.json b/src/drivers/npm/package.json index 6cc04a54c..4d1cff085 100644 --- a/src/drivers/npm/package.json +++ b/src/drivers/npm/package.json @@ -13,7 +13,7 @@ "software" ], "homepage": "https://www.wappalyzer.com/", - "version": "6.5.25", + "version": "6.5.26", "author": "Wappalyzer", "license": "MIT", "repository": { diff --git a/src/drivers/webextension/_locales/fr/messages.json b/src/drivers/webextension/_locales/fr/messages.json index f7d6ab9b6..829ec5814 100644 --- a/src/drivers/webextension/_locales/fr/messages.json +++ b/src/drivers/webextension/_locales/fr/messages.json @@ -1,5 +1,5 @@ { - "github": { "message": "Forker Wappalyzer sur GitHub!" }, + "github": { "message": "Forker Wappalyzer sur GitHub !" }, "noAppsDetected": { "message": "Pas d'applications détectées." }, "nothingToDo": { "message": "Rien à faire ici." }, "optionTracking": { "message": "Envoyer anonymement des rapports sur les applications détectées à wappalyzer.com pour la recherche" }, @@ -15,11 +15,11 @@ "twitter": { "message": "Suivre Wappalyzer sur Twitter" }, "website": { "message": "Aller sur wappalyzer.com" }, "categoryPin": { "message": " Toujours afficher l'icône" }, - "termsAccept": { "message": "I'm ok with that" }, + "termsAccept": { "message": "Je suis OK avec ça" }, "termsDecline": { "message": "Disable" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, - "privacyPolicy": { "message": "Privacy policy" }, - "createAlert": { "message": "Create an alert for this website" }, + "privacyPolicy": { "message": "Politique de confidentialité" }, + "createAlert": { "message": "Créer un alerte pour ce site web" }, "leadLists": { "message": "Lead generation tools" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Forum" }, @@ -80,18 +80,18 @@ "categoryName57": { "message": "Générateur de site statique" }, "categoryName58": { "message": "User Onboarding" }, "categoryName59": { "message": "Librairies JavaScript" }, - "categoryName60": { "message": "Contenus" }, + "categoryName60": { "message": "Conteneurs" }, "categoryName61": { "message": "SaaS" }, "categoryName62": { "message": "PaaS" }, "categoryName63": { "message": "IaaS" }, - "categoryName64": { "message": "Reverse Proxy" }, + "categoryName64": { "message": "Proxy inversé" }, "categoryName65": { "message": "Load Balancer" }, "categoryName66": { "message": "Frameworks UI" }, "categoryName67": { "message": "Cookie compliance" }, "categoryName68": { "message": "Accessibilité" }, "categoryName69": { "message": "Connexion avec les réseaux sociaux" }, "categoryName70": { "message": "SSL/TLS certificate authorities" }, - "categoryName71": { "message": "Affiliate programs" }, + "categoryName71": { "message": "Programmes affiliés" }, "categoryName72": { "message": "Appointment scheduling" }, "categoryName73": { "message": "Surveys" }, "categoryName74": { "message": "A/B testing" }, diff --git a/src/drivers/webextension/images/icons/Etracker.png b/src/drivers/webextension/images/icons/Etracker.png new file mode 100644 index 000000000..26318cbd6 Binary files /dev/null and b/src/drivers/webextension/images/icons/Etracker.png differ diff --git a/src/drivers/webextension/images/icons/Frosmo.png b/src/drivers/webextension/images/icons/Frosmo.png new file mode 100644 index 000000000..6c2e57d57 Binary files /dev/null and b/src/drivers/webextension/images/icons/Frosmo.png differ diff --git a/src/drivers/webextension/images/icons/Google Ads.svg b/src/drivers/webextension/images/icons/Google Ads.svg new file mode 100644 index 000000000..ea4bc17e3 --- /dev/null +++ b/src/drivers/webextension/images/icons/Google Ads.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/drivers/webextension/images/icons/Helpscout.svg b/src/drivers/webextension/images/icons/Helpscout.svg new file mode 100644 index 000000000..88bde6fc8 --- /dev/null +++ b/src/drivers/webextension/images/icons/Helpscout.svg @@ -0,0 +1 @@ + diff --git a/src/drivers/webextension/images/icons/boomerang.svg b/src/drivers/webextension/images/icons/boomerang.svg new file mode 100644 index 000000000..ff809f823 --- /dev/null +++ b/src/drivers/webextension/images/icons/boomerang.svg @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/drivers/webextension/images/icons/lede.png b/src/drivers/webextension/images/icons/lede.png new file mode 100644 index 000000000..8528429e8 Binary files /dev/null and b/src/drivers/webextension/images/icons/lede.png differ diff --git a/src/drivers/webextension/images/icons/pico.svg b/src/drivers/webextension/images/icons/pico.svg new file mode 100644 index 000000000..b9e533d6f --- /dev/null +++ b/src/drivers/webextension/images/icons/pico.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/drivers/webextension/js/content.js b/src/drivers/webextension/js/content.js index 883b38247..ccaa7e6d3 100644 --- a/src/drivers/webextension/js/content.js +++ b/src/drivers/webextension/js/content.js @@ -231,6 +231,29 @@ const Content = { return technologies }, []) + // Detect Google Ads + if (/^(www\.)?google(\.[a-z]{2,3}){1,2}$/.test(location.hostname)) { + const ads = document.querySelectorAll('#tads [data-text-ad] a[data-pcu]') + + for (const ad of ads) { + Content.driver('detectTechnology', [ad.href, 'Google Ads']) + } + } + + // Detect Microsoft Ads + if (/^(www\.)?bing\.com$/.test(location.hostname)) { + const ads = document.querySelectorAll('.b_ad .b_adurl cite') + + for (const ad of ads) { + const url = ad.textContent.split(' ')[0].trim() + + Content.driver('detectTechnology', [ + url.startsWith('http') ? url : `http://${url}`, + 'Microsoft Advertising', + ]) + } + } + Content.driver('analyzeDom', [location.href, dom]) }, } diff --git a/src/drivers/webextension/js/driver.js b/src/drivers/webextension/js/driver.js index 2ece03254..57498579f 100644 --- a/src/drivers/webextension/js/driver.js +++ b/src/drivers/webextension/js/driver.js @@ -8,6 +8,7 @@ const { analyze, analyzeManyToMany, resolve, + getTechnology, } = Wappalyzer const { agent, promisify, getOption, setOption, open } = Utils @@ -211,6 +212,19 @@ const Driver = { ) }, + /** + * Force a technology detection by URL and technology name + * @param {String} url + * @param {String} name + */ + detectTechnology(url, name) { + const technology = getTechnology(name) + + return Driver.onDetect(url, [ + { technology, pattern: { regex: '', confidence: 100 }, version: '' }, + ]) + }, + /** * Enable scripts to call Driver functions through messaging * @param {Object} message @@ -411,7 +425,13 @@ const Driver = { await Driver.setIcon(url, resolved) if (url) { - const tabs = await promisify(chrome.tabs, 'query', { url }) + let tabs = [] + + try { + tabs = await promisify(chrome.tabs, 'query', { url }) + } catch (error) { + // Continue + } tabs.forEach(({ id }) => (Driver.cache.tabs[id] = resolved)) } @@ -454,34 +474,38 @@ const Driver = { return } - ;(await promisify(chrome.tabs, 'query', { url })).forEach( - ({ id: tabId }) => { - chrome.browserAction.setBadgeText( - { - tabId, - text: - badge && technologies.length - ? technologies.length.toString() - : '', - }, - () => {} - ) + let tabs = [] - chrome.browserAction.setIcon( - { - tabId, - path: chrome.extension.getURL( - `../images/icons/${ - /\.svg$/i.test(icon) - ? `converted/${icon.replace(/\.svg$/, '.png')}` - : icon - }` - ), - }, - () => {} - ) - } - ) + try { + tabs = await promisify(chrome.tabs, 'query', { url }) + } catch (error) { + // Continue + } + + tabs.forEach(({ id: tabId }) => { + chrome.browserAction.setBadgeText( + { + tabId, + text: + badge && technologies.length ? technologies.length.toString() : '', + }, + () => {} + ) + + chrome.browserAction.setIcon( + { + tabId, + path: chrome.extension.getURL( + `../images/icons/${ + /\.svg$/i.test(icon) + ? `converted/${icon.replace(/\.svg$/, '.png')}` + : icon + }` + ), + }, + () => {} + ) + }) }, /** diff --git a/src/drivers/webextension/js/inject.js b/src/drivers/webextension/js/inject.js index f47088d7e..63d81ec45 100644 --- a/src/drivers/webextension/js/inject.js +++ b/src/drivers/webextension/js/inject.js @@ -3,11 +3,11 @@ ;(function () { try { const onMessage = ({ data }) => { - if (!data.wappalyzer) { + if (!data.wappalyzer || !data.wappalyzer.technologies) { return } - const { technologies } = data.wappalyzer || {} + const { technologies } = data.wappalyzer removeEventListener('message', onMessage) diff --git a/src/drivers/webextension/js/popup.js b/src/drivers/webextension/js/popup.js index 537e6014c..b18db25aa 100644 --- a/src/drivers/webextension/js/popup.js +++ b/src/drivers/webextension/js/popup.js @@ -55,7 +55,6 @@ const Popup = { if (themeMode) { document.querySelector('body').classList.add('theme-mode') } - document.querySelector('body').classList.add('theme-mode') // Terms const termsAccepted = diff --git a/src/drivers/webextension/manifest.json b/src/drivers/webextension/manifest.json index 6c049956c..c9565a08a 100644 --- a/src/drivers/webextension/manifest.json +++ b/src/drivers/webextension/manifest.json @@ -4,7 +4,7 @@ "author": "Wappalyzer", "homepage_url": "https://www.wappalyzer.com/", "description": "Identify web technologies", - "version": "6.5.25", + "version": "6.5.26", "default_locale": "en", "manifest_version": 2, "icons": { diff --git a/src/package.json b/src/package.json index 6db181d22..f0f16fcd3 100644 --- a/src/package.json +++ b/src/package.json @@ -13,7 +13,7 @@ "software" ], "homepage": "https://www.wappalyzer.com/", - "version": "6.5.25", + "version": "6.5.26", "author": "Wappalyzer", "license": "MIT", "repository": { diff --git a/src/technologies.json b/src/technologies.json index 6c557a6b1..d82122b53 100644 --- a/src/technologies.json +++ b/src/technologies.json @@ -1169,7 +1169,9 @@ ], "description": "Akamai is global content delivery network (CDN) services provider for media and software delivery, and cloud security solutions.", "headers": { - "X-Akamai-Transformed": "" + "X-Akamai-Transformed": "", + "X-EdgeConnect-MidMile-RTT": "", + "X-EdgeConnect-Origin-MEX-Latency": "" }, "icon": "akamai.svg", "pricing": [ @@ -1218,26 +1220,28 @@ }, "Akamai mPulse": { "cats": [ - 13, - 10 + 10, + 47 ], "cookies": { "akaas_AB-Testing": "" }, "description": "Akamai mPulse is a real user monitoring (RUM) solution that enables companies to monitor, find, and fix website and application performance issues.", + "html": [ + "" + ], "icon": "akamai.svg", - "implies": "Akamai", + "implies": [ + "Boomerang" + ], "js": { - "BOOMR": "", - "BOOMR_API_key": "", - "BOOMR_lstart": "", - "BOOMR_mq": "" + "BOOMR_API_key": "" }, "pricing": [ "poa" ], "saas": true, - "website": "https://www.akamai.com/uk/en/products/performance/mpulse-real-user-monitoring.jsp" + "website": "https://developer.akamai.com/akamai-mpulse-real-user-monitoring-solution" }, "Akaunting": { "cats": [ @@ -1381,22 +1385,6 @@ "saas": true, "website": "https://affiliate-program.amazon.com.au/" }, - "Azion": { - "cats": [ - 31 - ], - "description": "", - "headers": { - "Server": "^Azion " - }, - "dns": { - "CNAME": "azioncdn\\.net\\.?$" - }, - "icon": "Azion.svg", - "saas": true, - "pricing": ["poa", "payg"], - "website": "https://www.azion.com/" - }, "Amazon Cloudfront": { "cats": [ 31 @@ -2282,6 +2270,25 @@ ], "website": "https://github.com/axios/axios" }, + "Azion": { + "cats": [ + 31 + ], + "description": "", + "dns": { + "CNAME": "azioncdn\\.net\\.?$" + }, + "headers": { + "Server": "^Azion " + }, + "icon": "Azion.svg", + "pricing": [ + "poa", + "payg" + ], + "saas": true, + "website": "https://www.azion.com/" + }, "Azure": { "cats": [ 62 @@ -2830,6 +2837,20 @@ "scripts": "booksy\\.com/widget/code\\.js", "website": "https://booksy.com/" }, + "Boomerang": { + "cats": [ + 59 + ], + "description": "boomerang is a JavaScript library that measures the page load time experienced by real users, commonly called RUM (Real User Measurement).", + "icon": "boomerang.svg", + "js": { + "BOOMR": "", + "BOOMR_lstart": "", + "BOOMR_mq": "" + }, + "oss": true, + "website": "https://akamai.github.io/boomerang" + }, "Bootstrap": { "cats": [ 66 @@ -5200,9 +5221,28 @@ 6 ], "cpe": "cpe:/a:commerceguys:commerce", - "html": "<[^>]+(?:id=\"block[_-]commerce[_-]cart[_-]cart|class=\"commerce[_-]product[_-]field)", "icon": "Drupal Commerce.png", + "description": "Drupal Commerce is open-source ecommerce software that augments the content management system Drupal.", + "html": "<[^>]+(?:id=\"block[_-]commerce[_-]cart[_-]cart|class=\"commerce[_-]product[_-]field)", + "dom": { + "form.commerce-order-item-add-to-cart-form,form.commerce-add-to-cart": { + "attributes": { + "class": "" + } + }, + "aside#cart-offcanvas": { + "attributes": { + "id": "" + } + } + }, + "scripts": [ + "/modules/(?:contrib/)?commerce/js/conditions\\.js\\;confidence:50", + "/profiles/commerce_kickstart/modules/contrib/commerce/modules/checkout/commerce_checkout\\.js\\;confidence:50", + "/sites/(?:all|default)/modules/(?:contrib/)?commerce/modules/checkout/commerce_checkout\\.js\\;confidence:50" + ], "implies": "Drupal", + "oss": true, "website": "http://drupalcommerce.org" }, "Duda": { @@ -5699,6 +5739,21 @@ ], "website": "https://etherpad.org" }, + "Etracker": { + "cats": [ + 10, + 74 + ], + "description": "Etracker is a web optimization solution.", + "icon": "Etracker.png", + "js": { + "_etracker": "" + }, + "scripts": "\\.etracker\\.com", + "saas": true, + "pricing": ["low","recurring"], + "website": "https://www.etracker.com" + }, "Eveve": { "cats": [ 5, @@ -5733,8 +5788,13 @@ ], "description": "ExpertRec is a collaborative Web search engine, which allows users share search histories through a web browser.", "icon": "ExpertRec.png", - "scripts": "cse\\.expertrec\\.com/api/js/ci_common\\.js\\?id=.*$", - "website": "https://expertrec.com" + "pricing": [ + "low", + "recurring" + ], + "saas": true, + "scripts": "expertrec\\.com/api/js/ci_common\\.js\\?id=.*", + "website": "https://www.expertrec.com" }, "Express": { "cats": [ @@ -6453,7 +6513,23 @@ "meta": { "generator": "^Frontity(.*)" }, - "website": "https://frontity.org/" + "website": "https://frontity.org + }, + "Frosmo": { + "cats": [ + 32, + 74 + ], + "description": "Frosmo is a SaaS company wich provides AI-driven personalization products.", + "icon": "Frosmo.png", + "js": { + "frosmo": "", + "_frosmo": "" + }, + "scripts": "frosmo\\.easy\\.js", + "saas": true, + "pricing": ["poa"], + "website": "https://frosmo.com" }, "FrontPage": { "cats": [ @@ -7011,6 +7087,16 @@ "scripts": "js/gogs\\.js", "website": "http://gogs.io" }, + "Google Ads": { + "cats": [ + 36 + ], + "description": "Google Ads is an online advertising platform developed by Google.", + "icon": "Google Ads.svg", + "saas": true, + "pricing": ["payg"], + "website": "https://ads.google.com" + }, "Google AdSense": { "cats": [ 36 @@ -7646,6 +7732,20 @@ "scripts": "hellobar\\.js", "website": "http://hellobar.com" }, + "Helpscout": { + "cats": [ + 52 + ], + "description": "Simple Customer Service Software and Education.", + "icon": "Helpscout.svg", + "js": { + "Beacon": "\\;confidence:25" + }, + "saas": true, + "pricing": ["low", "recurring"], + "scripts": "beacon-v2\\.helpscout\\.net", + "website": "https://www.helpscout.com/" + }, "Heroku": { "cats": [ 62 @@ -9356,6 +9456,30 @@ "scripts": "npm/leanplum-sdk\\@([\\d.]+)\\;version:\\1", "website": "https://www.leanplum.com" }, + "Lede": { + "cats": [ + 1 + ], + "description": "Lede is a publishing platform and growth program designed to support journalism startups and news media.", + "html": [ + "]*href=\"[^\"]+joinlede.com" + ], + "icon": "lede.png", + "implies": [ + "WordPress", + "WordPress VIP" + ], + "js": { + "ledeChartbeatViews": "", + "ledeEngagement": "", + "ledeEngagementReset": "" + }, + "meta": { + "og:image": "https?\\:\\/\\/lede-admin" + }, + "saas": true, + "website": "https://joinlede.com/" + }, "Less": { "cats": [ 19 @@ -10602,14 +10726,13 @@ }, "Microsoft Advertising": { "cats": [ - 10, 36 ], "cookies": { "_uetsid": "\\w+", "_uetvid": "\\w+" }, - "description": "Microsoft Advertising is a service that provides pay per click advertising on both the Bing and Yahoo! search engines.", + "description": "Microsoft Advertising is an online advertising platform developed by Microsoft.", "icon": "Microsoft.png", "js": { "UET": "", @@ -10620,7 +10743,7 @@ ], "saas": true, "scripts": "bat\\.bing\\.com/bat\\.js", - "website": "https://about.ads.microsoft.com" + "website": "https://ads.microsoft.com" }, "Microsoft Excel": { "cats": [ @@ -12911,6 +13034,24 @@ "icon": "Phusion Passenger.png", "website": "https://phusionpassenger.com" }, + "Pico": { + "cats": [ + 53 + ], + "icon": "pico.svg", + "js": { + "Pico": "" + }, + "scripts": [ + "widget\\.pico\\.tools" + ], + "pricing": [ + "low", + "recurring" + ], + "saas": true, + "website": "https://trypico.com" + }, "Pimcore": { "cats": [ 1, @@ -18947,7 +19088,10 @@ "x-powered-by": "^WordPress\\.com VIP" }, "icon": "wpvip.svg", - "implies": "WordPress", + "implies": [ + "WordPress", + "Automattic" + ], "website": "https://wpvip.com" }, "Wowza Media Server": {