diff --git a/.gitignore b/.gitignore index 1bbe41985..28a39b701 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,4 @@ tags.* /nbproject/private/ src/out.json -keys.json \ No newline at end of file +keys.json diff --git a/bin/build.js b/bin/build.js index 5f1017b25..1c7dd8b20 100755 --- a/bin/build.js +++ b/bin/build.js @@ -17,7 +17,8 @@ if (!version) { ;[ './src/package.json', './src/drivers/npm/package.json', - './src/drivers/webextension/manifest.json', + './src/drivers/webextension/manifest-v2.json', + './src/drivers/webextension/manifest-v3.json', ].forEach((file) => { const json = JSON.parse(fs.readFileSync(file)) @@ -26,8 +27,34 @@ if (!version) { fs.writeFileSync(file, JSON.stringify(json, null, 2)) }) -const zip = new Zip() +fs.copyFileSync( + `./src/drivers/webextension/manifest.json`, + './src/drivers/webextension/manifest.bak.json' +) + +fs.copyFileSync( + `./src/drivers/webextension/manifest-v2.json`, + './src/drivers/webextension/manifest.json' +) + +let zip = new Zip() + +zip.addLocalFolder('./src/drivers/webextension', '') + +zip.writeZip('./build/webextension-v2.zip') + +fs.copyFileSync( + `./src/drivers/webextension/manifest-v3.json`, + './src/drivers/webextension/manifest.json' +) + +zip = new Zip() zip.addLocalFolder('./src/drivers/webextension', '') -zip.writeZip('./build/webextension.zip') +zip.writeZip('./build/webextension-v3.zip') + +fs.copyFileSync( + `./src/drivers/webextension/manifest.bak.json`, + './src/drivers/webextension/manifest.json' +) diff --git a/bin/manifest.js b/bin/manifest.js new file mode 100755 index 000000000..d6260c664 --- /dev/null +++ b/bin/manifest.js @@ -0,0 +1,15 @@ +const fs = require('fs') + +const version = process.argv[2] + +if (!version) { + // eslint-disable-next-line no-console + console.error(`No manifest version specified.`) + + process.exit(1) +} + +fs.copyFileSync( + `./src/drivers/webextension/manifest-${version}.json`, + './src/drivers/webextension/manifest.json' +) diff --git a/package.json b/package.json index ff4ca5aab..c90b5af94 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,14 @@ "terminal-overwrite": "^2.0.1" }, "scripts": { - "link": "node ./bin/link.js", + "link": "node ./bin/link.js; node ./bin/manifest.js v3", "lint": "eslint src/**/*.{js,json}", "lint:fix": "eslint --fix src/**/*.{js,json}", "validate": "yarn run lint && jsonlint -qV ./schema.json ./src/technologies/ && node ./bin/validate.js", "convert": "node --no-warnings ./bin/convert.js", "prettify": "jsonlint -si --trim-trailing-commas --enforce-double-quotes ./src/categories.json ./src/technologies/*.json", "build": "yarn run link && yarn run validate && yarn run prettify && yarn run convert && node ./bin/build.js", - "build:safari": "xcrun safari-web-extension-converter --swift --project-location build --force src/drivers/webextension" + "build:safari": "xcrun safari-web-extension-converter --swift --project-location build --force src/drivers/webextension", + "manifest": "node ./bin/manifest.js" } } diff --git a/src/drivers/webextension/css/styles.css b/src/drivers/webextension/css/styles.css index 1575211ba..52cdd97f5 100644 --- a/src/drivers/webextension/css/styles.css +++ b/src/drivers/webextension/css/styles.css @@ -740,6 +740,12 @@ body.dynamic-icon .category__heading:hover .category__pin { margin-top: 1.5rem; } +.body__options { + background: var(--color-secondary); + max-width: 600px; + margin: 0 auto; +} + .options { background: var(--color-secondary); color: var(--color-text); diff --git a/src/drivers/webextension/js/background.js b/src/drivers/webextension/js/background.js new file mode 100644 index 000000000..1743427fc --- /dev/null +++ b/src/drivers/webextension/js/background.js @@ -0,0 +1,6 @@ +/* globals chrome, importScripts */ + +importScripts(chrome.runtime.getURL('js/wappalyzer.js')) +importScripts(chrome.runtime.getURL('js/utils.js')) +importScripts(chrome.runtime.getURL('js/driver.js')) +importScripts(chrome.runtime.getURL('js/lib/network.js')) diff --git a/src/drivers/webextension/js/driver.js b/src/drivers/webextension/js/driver.js index 9a2ef1901..9a426c192 100644 --- a/src/drivers/webextension/js/driver.js +++ b/src/drivers/webextension/js/driver.js @@ -71,7 +71,7 @@ const Driver = { ads: [], } - chrome.browserAction.setBadgeBackgroundColor({ color: '#6B39BD' }, () => {}) + chrome.action.setBadgeBackgroundColor({ color: '#6B39BD' }, () => {}) chrome.webRequest.onCompleted.addListener( Driver.onWebRequestComplete, @@ -742,7 +742,7 @@ const Driver = { } tabs.forEach(({ id: tabId }) => { - chrome.browserAction.setBadgeText( + chrome.action.setBadgeText( { tabId, text: @@ -753,7 +753,7 @@ const Driver = { () => {} ) - chrome.browserAction.setIcon( + chrome.action.setIcon( { tabId, path: chrome.runtime.getURL( @@ -823,11 +823,7 @@ const Driver = { // eslint-disable-next-line no-async-promise-executor new Promise(async (resolve) => { const response = await fetch( - `http${secure ? 's' : ''}://${hostname}/robots.txt`, - { - redirect: 'follow', - mode: 'no-cors', - } + `http${secure ? 's' : ''}://${hostname}/robots.txt` ) if (!response.ok) { diff --git a/src/drivers/webextension/js/lib/network.js b/src/drivers/webextension/js/lib/network.js index 7b0573205..258d821ef 100644 --- a/src/drivers/webextension/js/lib/network.js +++ b/src/drivers/webextension/js/lib/network.js @@ -148,9 +148,13 @@ } function parseHostnameFromUrl(url) { - const parser = document.createElement('a') - parser.href = url - return parser.hostname + try { + const { hostname } = new URL(url) + + return hostname + } catch { + return '' + } } function hasDomain(url, domain) { diff --git a/src/drivers/webextension/js/popup.js b/src/drivers/webextension/js/popup.js index 3be6e76a3..d45212de4 100644 --- a/src/drivers/webextension/js/popup.js +++ b/src/drivers/webextension/js/popup.js @@ -170,11 +170,12 @@ function getCsv() { } function csvEscape(value = '') { + console.log(value) if (Array.isArray(value)) { value = value .flat() .slice(0, 10) - .map((value) => csvEscape(value.replace(/ ; /g, ' : '))) + .map((value) => csvEscape(String(value).replace(/ ; /g, ' : '))) .join(' ; ') } diff --git a/src/drivers/webextension/js/utils.js b/src/drivers/webextension/js/utils.js index e58d96158..53eb779d0 100644 --- a/src/drivers/webextension/js/utils.js +++ b/src/drivers/webextension/js/utils.js @@ -2,6 +2,18 @@ /* eslint-env browser */ /* globals chrome */ +// Manifest v2 polyfill +if (chrome.runtime.getManifest().manifest_version === 2) { + chrome.action = chrome.browserAction + + chrome.storage.sync = { + get: (...args) => + new Promise((resolve) => chrome.storage.local.get(...args, resolve)), + set: (...args) => + new Promise((resolve) => chrome.storage.local.set(...args, resolve)), + } +} + const Utils = { agent: chrome.runtime.getURL('/').startsWith('moz-') ? 'firefox' @@ -43,7 +55,7 @@ const Utils = { */ async getOption(name, defaultValue = null) { try { - const option = await Utils.promisify(chrome.storage.local, 'get', name) + const option = await Utils.promisify(chrome.storage.sync, 'get', name) if (option[name] !== undefined) { return option[name] @@ -63,7 +75,7 @@ const Utils = { */ async setOption(name, value) { try { - await Utils.promisify(chrome.storage.local, 'set', { + await Utils.promisify(chrome.storage.sync, 'set', { [name]: value, }) } catch (error) { diff --git a/src/drivers/webextension/manifest.json b/src/drivers/webextension/manifest-v2.json similarity index 100% rename from src/drivers/webextension/manifest.json rename to src/drivers/webextension/manifest-v2.json diff --git a/src/drivers/webextension/manifest-v3.json b/src/drivers/webextension/manifest-v3.json new file mode 100644 index 000000000..972f45c79 --- /dev/null +++ b/src/drivers/webextension/manifest-v3.json @@ -0,0 +1,93 @@ +{ + "name": "Wappalyzer - Technology profiler", + "short_name": "Wappalyzer", + "author": "Wappalyzer", + "homepage_url": "https://www.wappalyzer.com/", + "description": "Identify web technologies", + "version": "6.10.40", + "default_locale": "en", + "manifest_version": 3, + "icons": { + "16": "images/icon_16.png", + "19": "images/icon_19.png", + "32": "images/icon_32.png", + "38": "images/icon_38.png", + "64": "images/icon_64.png", + "128": "images/icon_128.png", + "256": "images/icon_256.png", + "512": "images/icon_512.png", + "1024": "images/icon_1024.png" + }, + "action": { + "default_icon": { + "16": "images/icon_16.png", + "19": "images/icon_19.png", + "32": "images/icon_32.png", + "38": "images/icon_38.png", + "64": "images/icon_64.png", + "128": "images/icon_128.png", + "256": "images/icon_256.png", + "512": "images/icon_512.png", + "1024": "images/icon_1024.png" + }, + "default_title": "Wappalyzer", + "default_popup": "html/popup.html" + }, + "background": { + "service_worker": "js/background.js" + }, + "content_scripts": [ + { + "matches": [ + "http://*/*", + "https://*/*" + ], + "js": [ + "js/content.js" + ], + "run_at": "document_idle" + }, + { + "matches": [ + "http://*/*", + "https://*/*" + ], + "js": [ + "js/lib/iframe.js" + ], + "run_at": "document_start", + "all_frames": true + } + ], + "web_accessible_resources": [ + { + "resources": [ + "js/js.js", + "js/dom.js" + ], + "matches": [ + "http://*/*", + "https://*/*" + ] + } + ], + "options_page": "html/options.html", + "permissions": [ + "cookies", + "storage", + "scripting", + "tabs", + "webRequest", + "webNavigation" + ], + "host_permissions": [ + "http://*/*", + "https://*/*" + ], + "optional_permissions": [ + "downloads" + ], + "content_security_policy": { + "extension_pages": "script-src 'self'; object-src 'self'" + } +} \ No newline at end of file