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/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/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 5138214a5..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 @@ -79,10 +80,10 @@ const Driver = { 'https://www.wappalyzer.com/installed/?utm_source=installed&utm_medium=extension&utm_campaign=wappalyzer' ) } else if (version !== previous && upgradeMessage) { - // open( - // `https://www.wappalyzer.com/upgraded/?utm_source=upgraded&utm_medium=extension&utm_campaign=wappalyzer`, - // false - // ) + open( + `https://www.wappalyzer.com/upgraded/?utm_source=upgraded&utm_medium=extension&utm_campaign=wappalyzer`, + false + ) } await setOption('version', version) @@ -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/technologies.json b/src/technologies.json index 01a1de10b..74afadccc 100644 --- a/src/technologies.json +++ b/src/technologies.json @@ -6997,6 +6997,26 @@ "scripts": "js/gogs\\.js", "website": "http://gogs.io" }, + "Microsoft Advertising": { + "cats": [ + 36 + ], + "description": "Microsoft Advertising is an online advertising platform developed by Microsoft.", + "icon": "Microsoft.svg", + "saas": true, + "pricing": ["payg"], + "website": "https://ads.microsoft.com" + }, + "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 @@ -21094,4 +21114,4 @@ "website": "https://www.xt-commerce.com" } } -} \ No newline at end of file +}