diff --git a/.travis.yml b/.travis.yml index d9370dba1..1b59f9ea0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ before_install: - export WAPPALYZER_NODE_PATH=$TRAVIS_BUILD_DIR - export PATH=$PATH:$TRAVIS_BUILD_DIR/bin - ln -s docker/node/package.json package.json +before_script: npm i -g manifoldjs after_success: - sha256sum build/* > build/SHA256SUMS - cat build/SHA256SUMS diff --git a/bin/wappalyzer-build b/bin/wappalyzer-build index b526af24b..a07a85b59 100755 --- a/bin/wappalyzer-build +++ b/bin/wappalyzer-build @@ -55,13 +55,42 @@ wappalyzer links # WebExtension echo "Building WebExtension driver..." -pushd $WAPPALYZER_ROOT/src/drivers/webextension > /dev/null +webextension_dir=$WAPPALYZER_ROOT/src/drivers/webextension -zip -qr $WAPPALYZER_ROOT/build/wappalyzer_webextension.zip . -x manifest.edge.json +pushd $webextension_dir > /dev/null -zip -qr $WAPPALYZER_ROOT/build/wappalyzer_webextension.edge.zip . -x manifest.json +zip -qr $WAPPALYZER_ROOT/build/wappalyzer_webextension.zip . -printf "@ manifest.edge.json\n@=manifest.json\n" | zipnote -w $WAPPALYZER_ROOT/build/wappalyzer_webextension.edge.zip +popd > /dev/null + +# Edge + +pushd $WAPPALYZER_ROOT/build > /dev/null + +mv $webextension_dir/manifest.json $webextension_dir/manifest.webextension.json +mv $webextension_dir/manifest.edge.json $webextension_dir/manifest.json + +manifoldjs -l debug -p edgeextension -f edgeextension -m $webextension_dir/manifest.json + +mv $webextension_dir/manifest.json $webextension_dir/manifest.edge.json +mv $webextension_dir/manifest.webextension.json $webextension_dir/manifest.json + +manifest_dir="Wappalyzer/edgeextension/manifest" + +sed -i 's/INSERT-YOUR-PACKAGE-IDENTITY-NAME-HERE/Wappalyzer/' $manifest_dir/appxmanifest.xml +sed -i 's/INSERT-YOUR-PACKAGE-IDENTITY-PUBLISHER-HERE/Wappalyzer/' $manifest_dir/appxmanifest.xml +sed -i 's/INSERT-YOUR-PACKAGE-PROPERTIES-PUBLISHERDISPLAYNAME-HERE/Wappalyzer/' $manifest_dir/appxmanifest.xml +sed -i 's/Version="0.\([^"]\+\)/Version="\1.0/' $manifest_dir/appxmanifest.xml + +cp $webextension_dir/images/icon_44.png $manifest_dir/Assets/Square44x44Logo.png +cp $webextension_dir/images/icon_150.png $manifest_dir/Assets/Square150x150Logo.png +cp $webextension_dir/images/icon_50.png $manifest_dir/Assets/StoreLogo.png + +manifoldjs -l debug -p edgeextension package $manifest_dir + +mv Wappalyzer/edgeextension/package/edgeExtension.appx wappalyzer_edge.appx + +rm -rf Wappalyzer popd > /dev/null diff --git a/docker/Dockerfile b/docker/Dockerfile index c4e7806c0..c35776024 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -12,15 +12,15 @@ RUN sed -i 's/^deb-src\ /\#deb-src\ /g' /etc/apt/sources.list RUN sed -i 's/archive\.ubuntu\.com/au.archive.ubuntu.com/g' /etc/apt/sources.list RUN sed -i 's/security\.ubuntu\.com/au.archive.ubuntu.com/g' /etc/apt/sources.list RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - && \ - apt-get install -y \ - nodejs \ - bzip2 \ - zip \ - libfreetype6 \ - libfontconfig \ - rsync && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + apt-get install -y \ + nodejs \ + bzip2 \ + zip \ + libfreetype6 \ + libfontconfig \ + rsync && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Add user @@ -50,6 +50,8 @@ ADD node/package.json $WAPPALYZER_NODE_PATH/package.json RUN su wappalyzer -c "cd $WAPPALYZER_NODE_PATH && npm i" +RUN npm i -g manifoldjs + # SSH RUN rm -f /etc/service/sshd/down diff --git a/src/apps.json b/src/apps.json index eca8e667e..8bbc56a63 100755 --- a/src/apps.json +++ b/src/apps.json @@ -9,7 +9,6 @@ "url": "/shop/catalog/browse\\?sessid=", "website": "http://1and1.com" }, - "1C-Bitrix": { "cats": [ "1" @@ -3188,18 +3187,6 @@ }, "website": "http://www.greenvalley.nl/Public/Producten/Content_Management/CMS" }, - "Homeland": { - "cats": [ - "1", - "2" - ], - "headers": { - "Set-Cookie:": "_homeland_" - }, - "icon": "Homeland.png", - "implies": "Ruby on Rails", - "website": "https://gethomeland.com" - }, "HERE": { "cats": [ "35" @@ -3430,6 +3417,18 @@ ], "website": "http://twitter.github.com/hogan.js" }, + "Homeland": { + "cats": [ + "1", + "2" + ], + "headers": { + "Set-Cookie:": "_homeland_" + }, + "icon": "Homeland.png", + "implies": "Ruby on Rails", + "website": "https://gethomeland.com" + }, "Hotaru CMS": { "cats": [ "1" @@ -5467,7 +5466,6 @@ "script": "^/nodebb\\.min\\.js\\?", "website": "https://nodebb.org" }, - "OWL Carousel": { "cats": [ "5", @@ -6249,6 +6247,10 @@ "^priceDisplayMethod$\\;confidence:25", "^priceDisplayPrecision$\\;confidence:25" ], + "headers": { + "Powered-By": "^Prestashop$", + "Set-Cookie": "^PrestaShop" + }, "html": [ "Powered by ]+>PrestaShop", "", @@ -6259,10 +6261,6 @@ "meta": { "generator": "PrestaShop" }, - "headers": { - "Set-Cookie": "^PrestaShop", - "Powered-By": "^Prestashop$" - }, "website": "http://www.prestashop.com" }, "Project Wonderful": { @@ -7782,15 +7780,6 @@ "url": "/typo3/", "website": "http://www.typo3.org" }, - "Typecho": { - "cats": [ - "11" - ], - "icon": "typecho.svg", - "implies": "PHP", - "url": "/admin/login\\.php?referer=http%3A%2F%2F", - "website": "http://typecho.org/" - }, "Taiga": { "cats": [ "13" @@ -8135,6 +8124,15 @@ "url": "typepad\\.com", "website": "http://www.typepad.com" }, + "Typecho": { + "cats": [ + "11" + ], + "icon": "typecho.svg", + "implies": "PHP", + "url": "/admin/login\\.php?referer=http%3A%2F%2F", + "website": "http://typecho.org/" + }, "Typekit": { "cats": [ "17" @@ -10376,4 +10374,4 @@ "priority": "9" } } -} +} \ No newline at end of file diff --git a/src/drivers/webextension/images/icon_150.png b/src/drivers/webextension/images/icon_150.png new file mode 100644 index 000000000..7028f9c5e Binary files /dev/null and b/src/drivers/webextension/images/icon_150.png differ diff --git a/src/drivers/webextension/images/icon_44.png b/src/drivers/webextension/images/icon_44.png new file mode 100644 index 000000000..9a6321eaa Binary files /dev/null and b/src/drivers/webextension/images/icon_44.png differ diff --git a/src/drivers/webextension/images/icon_50.png b/src/drivers/webextension/images/icon_50.png new file mode 100644 index 000000000..935b35b72 Binary files /dev/null and b/src/drivers/webextension/images/icon_50.png differ diff --git a/src/drivers/webextension/js/driver.js b/src/drivers/webextension/js/driver.js index cf4ae7b9f..709094e38 100644 --- a/src/drivers/webextension/js/driver.js +++ b/src/drivers/webextension/js/driver.js @@ -1,5 +1,5 @@ /** - * Chrome driver + * WebExtension driver */ (function() { @@ -74,13 +74,19 @@ chrome.runtime.onMessage.addListener(w.driver.onMessage); } - browser.tabs.query({}).then(function(tabs) { + var callback = function(tabs) { tabs.forEach(function(tab) { if ( tab.url.match(/^https?:\/\//) ) { browser.tabs.executeScript(tab.id, { file: 'js/content.js' }); } }) - }); + }; + + try { + browser.tabs.query({}).then(callback); + } catch ( e ) { + browser.tabs.query({}, callback); + } browser.tabs.onRemoved.addListener(function(tabId) { w.log('remove tab'); diff --git a/src/drivers/webextension/js/ms_background_scripts_api_bridge.js b/src/drivers/webextension/js/ms_background_scripts_api_bridge.js new file mode 100644 index 000000000..d023cf1b0 --- /dev/null +++ b/src/drivers/webextension/js/ms_background_scripts_api_bridge.js @@ -0,0 +1,846 @@ +if (!Range.prototype["intersectsNode"]) { + Range.prototype["intersectsNode"] = function (node) { + let range = document.createRange(); + range.selectNode(node); + return 0 > this.compareBoundaryPoints(Range.END_TO_START, range) + && 0 < this.compareBoundaryPoints(Range.START_TO_END, range); + }; +} +var getExtensionProtocol = function () { + if (typeof browser == "undefined") { + if (typeof chrome !== "undefined") + return "chrome-extension://"; + } + else { + return "ms-browser-extension://"; + } +}; +class FakeEvent { + addListener(callback) { } + addRules(rules, callback) { } + getRules(ruleIdentifiers, callback) { } + hasListener(callback) { return false; } + hasListeners() { return false; } + removeRules(ruleIdentifiers, callback) { } + removeListener(callback) { } +} +class EdgeBridgeHelper { + constructor() { + this.fakeEvent = new FakeEvent(); + } + toAbsolutePath(relativePath) { + if (relativePath.indexOf("ms-browser-extension://") == 0) { + return relativePath.replace(myBrowser.runtime.getURL(""), ""); + } + else if (relativePath.indexOf("/") != 0) { + var absolutePath = ""; + var documentPath = document.location.pathname; + absolutePath = documentPath.substring(0, documentPath.lastIndexOf("/") + 1); + absolutePath += relativePath; + return absolutePath; + } + return relativePath; + } +} +var bridgeHelper = new EdgeBridgeHelper(); +class EdgeBridgeDebugLog { + constructor() { + this.CatchOnException = true; + this.VerboseLogging = true; + this.FailedCalls = {}; + this.SuccededCalls = {}; + this.DeprecatedCalls = {}; + this.BridgedCalls = {}; + this.UnavailableApis = {}; + this.EdgeIssues = {}; + } + log(message) { + try { + if (this.VerboseLogging) { + console.log(message); + } + } + catch (e) { + } + } + info(message) { + try { + if (this.VerboseLogging) { + console.info(message); + } + } + catch (e) { + } + } + warn(message) { + try { + if (this.VerboseLogging) { + console.warn(message); + } + } + catch (e) { + } + } + error(message) { + try { + if (this.VerboseLogging) { + console.error(message); + } + } + catch (e) { + } + } + DoActionAndLog(action, name, deprecatedTo, bridgedTo) { + var result; + try { + result = action(); + this.AddToCalledDictionary(this.SuccededCalls, name); + if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") { + this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!"); + this.AddToCalledDictionary(this.DeprecatedCalls, name); + } + if (typeof bridgedTo !== "undefined" && typeof bridgedTo !== "null") { + this.info("API Call '" + name + "' has been bridged to another Edge API: " + bridgedTo); + this.AddToCalledDictionary(this.BridgedCalls, name); + } + return result; + } + catch (ex) { + this.AddToCalledDictionary(this.FailedCalls, name); + if (this.CatchOnException) + this.error("API Call Failed: " + name + " - " + ex); + else + throw ex; + } + } + LogEdgeIssue(name, message) { + this.warn(message); + this.AddToCalledDictionary(this.EdgeIssues, name); + } + LogUnavailbleApi(name, deprecatedTo) { + this.warn("API Call '" + name + "' is not supported in Edge"); + this.AddToCalledDictionary(this.UnavailableApis, name); + if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") { + this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!"); + this.AddToCalledDictionary(this.DeprecatedCalls, name); + } + } + AddToCalledDictionary(dictionary, name) { + if (typeof dictionary[name] !== "undefined") { + dictionary[name]++; + } + else { + dictionary[name] = 1; + } + } +} +var bridgeLog = new EdgeBridgeDebugLog(); +class EdgeChromeAppBridge { + getDetails() { + return bridgeLog.DoActionAndLog(() => { + return EdgeChromeRuntimeBridge.prototype.getManifest(); + }, "app.getManifest", undefined, "runtime.getManifest"); + } + get isInstalled() { return bridgeLog.DoActionAndLog(() => { throw "app.isInstalled is not available in Edge"; }, "app.isInstalled"); } + getIsInstalled() { return bridgeLog.DoActionAndLog(() => { throw "app.getIsInstalled is not available in the Edge"; }, "app.getIsInstalled"); } + installState() { return bridgeLog.DoActionAndLog(() => { throw "app.installState is not available in Edge"; }, "app.installState"); } + runningState() { return bridgeLog.DoActionAndLog(() => { throw "app.runningState is not available in Edge"; }, "app.runningState"); } +} +class EdgeBrowserActionBridge { + get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.browserAction.onClicked; }, "browserAction.onClicked"); } + disable(tabId) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.disable(tabId); + }, "browserAction.disable"); + } + enable(tabId) { + bridgeLog.DoActionAndLog(() => { + if (typeof tabId !== "undefined" && typeof tabId !== "null") { + myBrowser.browserAction.enable(tabId); + } + else { + myBrowser.browserAction.enable(); + } + }, "browserAction.Enable"); + } + getBadgeBackgroundColor(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.getBadgeBackgroundColor(details, callback); + }, "browserAction.getBadgeBackgroundColor"); + } + getBadgeText(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.getBadgeText(details, callback); + }, "browserAction.getBadgeText"); + } + setBadgeBackgroundColor(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.setBadgeBackgroundColor(details); + }, "browserAction.setBadgeBackgroundColor"); + } + setBadgeText(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.setBadgeText(details); + }, "browserAction.setBadgeText"); + } + setIcon(details, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof details.path !== "undefined") { + if (typeof details.path === "object") { + for (var key in details.path) { + if (details.path.hasOwnProperty(key)) { + details.path[key] = bridgeHelper.toAbsolutePath(details.path[key]); + } + } + } + else { + details.path = bridgeHelper.toAbsolutePath(details.path); + } + } + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.browserAction.setIcon(details, callback); + } + else { + myBrowser.browserAction.setIcon(details); + } + }, "browserAction.setIcon", undefined, "browserAction.setIcon with absolute path"); + } + setPopup(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.setPopup(details); + }, "browserAction.setPopup"); + } +} +class EdgeChromeBrowserActionBridge extends EdgeBrowserActionBridge { + getPopup(details, callback) { + bridgeLog.LogUnavailbleApi("browserAction.getPopup"); + } + getTitle(details, callback) { + bridgeLog.LogUnavailbleApi("browserAction.getTitle"); + } + setTitle(details) { + bridgeLog.LogUnavailbleApi("browserAction.setTitle"); + } +} +class EdgeContextMenusBridge { + get ACTION_MENU_TOP_LEVEL_LIMIT() { return bridgeLog.DoActionAndLog(() => { return myBrowser.contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT; }, "contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT"); } + get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.contextMenus.onClicked; }, "contextMenus.onClicked"); } + create(createProperties, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.contextMenus.create(createProperties, callback); + } + else { + myBrowser.contextMenus.create(createProperties); + } + }, "contextMenus.create"); + } + remove(menuItemId, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.contextMenus.remove(menuItemId, callback); + } + else { + myBrowser.contextMenus.remove(menuItemId); + } + }, "contextMenus.remove"); + } + removeAll(callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.contextMenus.removeAll(callback); + } + else { + myBrowser.contextMenus.removeAll(); + } + }, "contextMenus.removeAll"); + } + update(id, updateProperties, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.contextMenus.update(id, updateProperties, callback); + } + else { + myBrowser.contextMenus.update(id, updateProperties); + } + }, "contextMenus.update"); + } +} +class EdgeCookiesBridge { + get(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.cookies.get(details, callback); + }, "cookies.get"); + } + getAll(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.cookies.getAll(details, callback); + }, "cookies.getAll"); + } + remove(details, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.cookies.remove(details, callback); + } + else { + myBrowser.cookies.remove(details); + } + }, "cookies.remove"); + } + set(details, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.cookies.set(details, callback); + } + else { + myBrowser.cookies.set(details); + } + }, "cookies.set"); + } +} +class EdgeChromeCookiesBridge extends EdgeCookiesBridge { + get onChanged() { bridgeLog.LogUnavailbleApi("cookies.onChanged"); return bridgeHelper.fakeEvent; } +} +class EdgeExtensionBridge { + getBackgroundPage() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getBackgroundPage(); + }, "extension.getBackgroundPage"); + } + getURL(path) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getURL(path); + }, "extension.getURL"); + } + getViews(fetchProperties) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getViews(fetchProperties); + }, "extension.getViews"); + } +} +class EdgeChromeExtensionBridge extends EdgeExtensionBridge { + get onConnect() { return bridgeLog.DoActionAndLog(() => { return EdgeRuntimeBridge.prototype.onConnect; }, "extension.onConnect", "runtime.onConnect", "runtime.onConnect"); } + get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onMessage", "runtime.onMessage", "runtime.onMessage"); } + get onRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onRequest", "runtime.onMessage", "runtime.onMessage"); } + get onRequestExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "extension.onRequestExternal", "runtime.onMessageExternal", "runtime.onMessageExternal"); } + get inIncognitoContext() { return bridgeLog.DoActionAndLog(() => { return myBrowser.extension["inPrivateContext"]; }, "extension.inIncognitoContext", undefined, "extension.inPrivateContext"); } + get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "extension.lastError", undefined, "runtime.lastError"); } + connect(extensionId, connectInfo) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.connect(extensionId, connectInfo); + }, "extension.connect", "runtime.connect", "runtime.connect"); + } + sendMessage(message, responseCallback) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.sendMessage(message, responseCallback, undefined, undefined); + }, "extension.sendMessage", "runtime.sendMessage", "runtime.sendMessage"); + } + sendRequest(extensionId, message, options, responseCallback) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.sendMessage(extensionId, message, options, responseCallback); + }, "extension.sendRequest", "runtime.sendMessage", "runtime.sendMessage"); + } + isAllowedFileSchemeAccess(callback) { + bridgeLog.LogUnavailbleApi("extension.isAllowedFileSchemeAccess"); + } + isAllowedIncognitoAccess(callback) { + bridgeLog.LogUnavailbleApi("extension.isAllowedIncognitoAccess"); + } + setUpdateUrlData(data) { + bridgeLog.LogUnavailbleApi("extension.setUpdateUrlData"); + } +} +class EdgeHistoryBridge { + get onVisited() { bridgeLog.LogUnavailbleApi("history.onVisited"); return bridgeHelper.fakeEvent; } + get onVisitRemoved() { bridgeLog.LogUnavailbleApi("history.onVisitRemoved"); return bridgeHelper.fakeEvent; } + addUrl(details, callback) { + bridgeLog.LogUnavailbleApi("history.addUrl"); + } + deleteAll(callback) { + bridgeLog.LogUnavailbleApi("history.deleteAll"); + } + deleteRange(range, callback) { + bridgeLog.LogUnavailbleApi("history.deleteRange"); + } + deleteUrl(details, callback) { + bridgeLog.LogUnavailbleApi("history.deleteUrl"); + } + getVisits(details, callback) { + bridgeLog.LogUnavailbleApi("history.getVisits"); + } + search(query, callback) { + bridgeLog.LogUnavailbleApi("history.search"); + } +} +class EdgeI18nBridge { + getAcceptLanguages(callback) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.i18n.getAcceptLanguages(callback); + }, "i18n.getAcceptLanguages"); + } + getMessage(messageName, substitutions) { + return bridgeLog.DoActionAndLog(() => { + if (messageName.indexOf("@@extension_id") > -1) { + return myBrowser.runtime.id; + } + if (typeof substitutions !== "undefined" && typeof substitutions !== "null") { + return myBrowser.i18n.getMessage(messageName, substitutions); + } + else { + return myBrowser.i18n.getMessage(messageName); + } + }, "i18n.getMessage"); + } + getUILanguage() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.i18n.getUILanguage(); + }, "i18n.getUILanguage"); + } +} +class EdgeNotificationBridge { + get onButtonClicked() { bridgeLog.LogUnavailbleApi("notifications.onButtonClicked"); return bridgeHelper.fakeEvent; } + get onClicked() { bridgeLog.LogUnavailbleApi("notifications.onClicked"); return bridgeHelper.fakeEvent; } + get onClosed() { bridgeLog.LogUnavailbleApi("notifications.onClosed"); return bridgeHelper.fakeEvent; } + get onPermissionLevelChanged() { bridgeLog.LogUnavailbleApi("notifications.onPermissionLevelChanged"); return bridgeHelper.fakeEvent; } + get onShowSettings() { bridgeLog.LogUnavailbleApi("notifications.onShowSettings"); return bridgeHelper.fakeEvent; } + clear(notificationId, callback) { + bridgeLog.LogUnavailbleApi("notifications.clear"); + } + create(notificationId, options, callback) { + bridgeLog.LogUnavailbleApi("notifications.create"); + } + getAll(callback) { + bridgeLog.LogUnavailbleApi("notifications.getAll"); + } + getPermissionLevel(callback) { + bridgeLog.LogUnavailbleApi("notifications.getPermissionLevel"); + } + update(notificationId, options, callback) { + bridgeLog.LogUnavailbleApi("notifications.update"); + } +} +class EdgePageActionBridge { + get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.pageAction.onClicked; }, "pageAction.onClicked"); } + getPopup(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.getPopup(details, callback); + }, "pageAction.getPopup"); + } + getTitle(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.getTitle(details, callback); + }, "pageAction.getTitle"); + } + hide(tabId) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.hide(tabId); + }, "pageAction.hide"); + } + setTitle(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.setTitle(details); + }, "pageAction.setTitle"); + } + setIcon(details, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.pageAction.setIcon(details, callback); + } + else { + myBrowser.pageAction.setIcon(details, callback); + } + }, "pageAction.setIcon"); + } + setPopup(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.setPopup(details); + }, "pageAction.setPopup"); + } + show(tabId) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.show(tabId); + }, "pageAction.show"); + } +} +class EdgePermissionsBridge { + get onAdded() { bridgeLog.LogUnavailbleApi("permissions.onAdded"); return bridgeHelper.fakeEvent; } + get onRemoved() { bridgeLog.LogUnavailbleApi("permissions.onRemoved"); return bridgeHelper.fakeEvent; } + contains(permissions, callback) { + bridgeLog.LogUnavailbleApi("permissions.contains"); + } + getAll(callback) { + bridgeLog.LogUnavailbleApi("permissions.getAll"); + } + remove(permissions, callback) { + bridgeLog.LogUnavailbleApi("permissions.remove"); + } + request(permissions, callback) { + bridgeLog.LogUnavailbleApi("permissions.request"); + } +} +class EdgeRuntimeBridge { + get id() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.id; }, "runtime.id"); } + get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "runtime.lastError"); } + get onConnect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onConnect; }, "runtime.onConnect"); } + get onInstalled() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onInstalled; }, "runtime.onInstalled"); } + get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "runtime.onMessage"); } + get onMessageExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "runtime.onMessageExternal"); } + connect(extensionId, connectInfo) { + return bridgeLog.DoActionAndLog(() => { + if (typeof connectInfo !== "undefined" && typeof connectInfo !== "null") { + return myBrowser.runtime.connect(extensionId, connectInfo); + } + else { + return myBrowser.runtime.connect(extensionId); + } + }, "runtime.connect"); + } + getBackgroundPage(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.getBackgroundPage(callback); + }, "runtime.getBackgroundPage"); + } + getManifest() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.getManifest(); + }, "runtime.getManifest"); + } + getURL(path) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.getURL(path); + }, "runtime.getURL"); + } + sendMessage(extensionId, message, options, responseCallback) { + bridgeLog.DoActionAndLog(() => { + if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") { + myBrowser.runtime.sendMessage(extensionId, message, options, responseCallback); + } + else if (typeof options !== "undefined" && typeof options !== "null") { + myBrowser.runtime.sendMessage(extensionId, message, options); + } + else if (typeof message !== "undefined" && typeof message !== "null") { + myBrowser.runtime.sendMessage(extensionId, message); + } + else { + myBrowser.runtime.sendMessage(undefined, extensionId); + } + }, "runtime.sendMessage"); + } +} +class EdgeChromeRuntimeBridge extends EdgeRuntimeBridge { + get onConnectExternal() { bridgeLog.LogUnavailbleApi("runtime.onConnectExternal"); return bridgeHelper.fakeEvent; } + get onRestartRequired() { bridgeLog.LogUnavailbleApi("runtime.onRestartRequired"); return bridgeHelper.fakeEvent; } + get onStartup() { bridgeLog.LogUnavailbleApi("runtime.onStartup"); return bridgeHelper.fakeEvent; } + get onSuspend() { bridgeLog.LogUnavailbleApi("runtime.onSuspend"); return bridgeHelper.fakeEvent; } + get onSuspendCanceled() { bridgeLog.LogUnavailbleApi("runtime.onSuspendCanceled"); return bridgeHelper.fakeEvent; } + get onUpdateAvailable() { bridgeLog.LogUnavailbleApi("runtime.onUpdateAvailable"); return bridgeHelper.fakeEvent; } + openOptionsPage(callback) { + bridgeLog.DoActionAndLog(() => { + var optionsPage = myBrowser.runtime.getManifest()["options_page"]; + var optionsPageUrl = myBrowser.runtime.getURL(optionsPage); + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.tabs.create({ url: optionsPageUrl }, callback); + } + else { + myBrowser.tabs.create({ url: optionsPageUrl }); + } + }, "runtime.openOptionsPage", undefined, "tabs.create({ url: optionsPageUrl })"); + } + connectNative(application) { + bridgeLog.LogUnavailbleApi("runtime.connectNative"); + return null; + } + getPackageDirectoryEntry(callback) { + bridgeLog.LogUnavailbleApi("runtime.getPackageDirectoryEntry"); + } + getPlatformInfo(callback) { + bridgeLog.LogUnavailbleApi("runtime.getPlatformInfo"); + } + reload() { + bridgeLog.LogUnavailbleApi("runtime.reload"); + } + requestUpdateCheck(callback) { + bridgeLog.LogUnavailbleApi("runtime.requestUpdateCheck"); + } + restart() { + bridgeLog.LogUnavailbleApi("runtime.restart"); + } + setUninstallURL(url, callback) { + bridgeLog.LogUnavailbleApi("runtime.setUninstallURL"); + } + sendNativeMessage(application, message, responseCallback) { + bridgeLog.LogUnavailbleApi("runtime.sendNativeMessage"); + } +} +class EdgeStorageBridge { + get local() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.local"); } + get onChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.onChanged; }, "storage.onChanged"); } +} +class EdgeChromeStorageBridge extends EdgeStorageBridge { + get managed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.managed", undefined, "storage.local"); } + get sync() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.sync", undefined, "storage.local"); } +} +class EdgeTabsBridge { + get onActivated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onActivated; }, "tabs.onActivated"); } + get onCreated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onCreated; }, "tabs.onCreated"); } + get onRemoved() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onRemoved; }, "tabs.onRemoved"); } + get onReplaced() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onReplaced; }, "tabs.onReplaced"); } + get onUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onUpdated; }, "tabs.onUpdated"); } + create(createProperties, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.tabs.create(createProperties, callback); + } + else { + myBrowser.tabs.create(createProperties); + } + }, "tabs.create"); + } + detectLanguage(tabId, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.detectLanguage(tabId, callback); + }, "tabs.detectLanguage"); + } + executeScript(tabId, details, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.tabs.executeScript(tabId, details, callback); + } + else { + myBrowser.tabs.executeScript(tabId, details); + } + }, "tabs.executeScript"); + } + get(tabId, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.get(tabId, callback); + }, "tabs.get"); + } + getCurrent(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.getCurrent(callback); + }, "tabs.getCurrent"); + } + insertCSS(tabId, details, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.tabs.insertCSS(tabId, details, callback); + } + else { + myBrowser.tabs.insertCSS(tabId, details); + } + }, "tabs.insertCSS"); + } + query(queryInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.query(queryInfo, callback); + }, "tabs.query"); + } + remove(tabId, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.tabs.remove(tabId, callback); + } + else { + myBrowser.tabs.remove(tabId); + } + }, "tabs.remove"); + } + sendMessage(tabId, message, responseCallback) { + bridgeLog.DoActionAndLog(() => { + if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") { + myBrowser.tabs.sendMessage(tabId, message, responseCallback); + } + else { + myBrowser.tabs.sendMessage(tabId, message); + } + }, "tabs.sendMessage"); + } + update(tabId, updateProperties, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.tabs.update(tabId, updateProperties, callback); + } + else { + myBrowser.tabs.update(tabId, updateProperties); + } + }, "tabs.update"); + } +} +class EdgeChromeTabsBridge extends EdgeTabsBridge { + get onAttached() { bridgeLog.LogUnavailbleApi("tabs.onAttached"); return bridgeHelper.fakeEvent; } + get onDetached() { bridgeLog.LogUnavailbleApi("tabs.onDetached"); return bridgeHelper.fakeEvent; } + get onHighlighted() { bridgeLog.LogUnavailbleApi("tabs.onHighlighted"); return bridgeHelper.fakeEvent; } + get onMoved() { bridgeLog.LogUnavailbleApi("tabs.onMoved"); return bridgeHelper.fakeEvent; } + get onSelectionChanged() { + return bridgeLog.DoActionAndLog(() => { + var fakeEvent = bridgeHelper.fakeEvent; + fakeEvent.addListener = (callback) => { + myBrowser.tabs.onActivated.addListener((activeInfo) => { + callback(activeInfo.tabId, { windowId: activeInfo.windowId }); + }); + }; + return fakeEvent; + }, "tabs.onSelectionChanged", "tabs.onActivated", "tabs.onActivated"); + } + duplicate(tabId, callback) { + bridgeLog.DoActionAndLog(() => { + this.get(tabId, function (tab) { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.tabs.create({ url: tab.url }, callback); + } + else { + myBrowser.tabs.create({ url: tab.url }); + } + }); + }, "tabs.duplicate", undefined, "tabs.create"); + } + getAllInWindow(windowId, callback) { + bridgeLog.DoActionAndLog(() => { + this.query({ windowId: windowId }, callback); + }, "tabs.getAllInWindow", "tabs.query", "tabs.query"); + } + getSelected(windowId, callback) { + bridgeLog.DoActionAndLog(() => { + this.query({ active: true }, (tabs) => callback(tabs[0])); + }, "tabs.getSelected", "tabs.query", "tabs.query"); + } + sendRequest(tabId, request, responseCallback) { + bridgeLog.DoActionAndLog(() => { + this.sendMessage(tabId, request, responseCallback); + }, "tabs.sendRequest", "tabs.sendMessage", "tabs.sendMessage"); + } + captureVisibleTab(windowId, options, callback) { + bridgeLog.LogUnavailbleApi("tabs.captureVisibleTab"); + } + connect(tabId, connectInfo) { + bridgeLog.LogUnavailbleApi("tabs.connect"); + return null; + } + highlight(highlightInfo, callback) { + bridgeLog.LogUnavailbleApi("tabs.highlight"); + } + move(tabId, moveProperties, callback) { + bridgeLog.LogUnavailbleApi("tabs.move"); + } + reload(tabId, reloadProperties, callback) { + bridgeLog.LogUnavailbleApi("tabs.reload"); + } +} +class EdgeWebNavigationBridge { + get onBeforeNavigate() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onBeforeNavigate; }, "webNavigation.onBeforeNavigate"); } + get onCommitted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCommitted; }, "webNavigation.onCommitted"); } + get onCompleted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCompleted; }, "webNavigation.onCompleted"); } + get onCreatedNavigationTarget() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCreatedNavigationTarget; }, "webNavigation.onCreatedNavigationTarget"); } + get onDOMContentLoaded() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onDOMContentLoaded; }, "webNavigation.onDOMContentLoaded"); } + get onErrorOccurred() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onErrorOccurred; }, "webNavigation.onErrorOccurred"); } + get onHistoryStateUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onHistoryStateUpdated; }, "webNavigation.onHistoryStateUpdated"); } + get onReferenceFragmentUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onReferenceFragmentUpdated; }, "webNavigation.onReferenceFragmentUpdated"); } + get onTabReplaced() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onTabReplaced; }, "webNavigation.onTabReplaced"); } + getAllFrames(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.webNavigation.getAllFrames(details, callback); + }, "webNavigation.getAllFrames"); + } + getFrame(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.webNavigation.getFrame(details, callback); + }, "webNavigation.getFrame"); + } +} +class EdgeWebRequestBridge { + get MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES; }, "webNavigation.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES"); } + get onAuthRequired() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onAuthRequired; }, "webNavigation.onAuthRequired"); } + get onBeforeRedirect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeRedirect; }, "webNavigation.onBeforeRedirect"); } + get onBeforeRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeRequest; }, "webNavigation.onBeforeRequest"); } + get onBeforeSendHeaders() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeSendHeaders; }, "webNavigation.onBeforeSendHeaders"); } + get onCompleted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onCompleted; }, "webNavigation.onCompleted"); } + get onErrorOccurred() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onErrorOccurred; }, "webNavigation.onErrorOccurred"); } + get onHeadersReceived() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onHeadersReceived; }, "webNavigation.onHeadersReceived"); } + get onResponseStarted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onResponseStarted; }, "webNavigation.onResponseStarted"); } + get onSendHeaders() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onSendHeaders; }, "webNavigation.onSendHeaders"); } + handlerBehaviorChanged(callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.webRequest.handlerBehaviorChanged(callback); + } + else { + myBrowser.webRequest.handlerBehaviorChanged(); + } + }, "webRequest.handlerBehaviorChanged"); + } +} +class EdgeWindowsBridge { + get WINDOW_ID_CURRENT() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.WINDOW_ID_CURRENT; }, "windows.WINDOW_ID_CURRENT"); } + get WINDOW_ID_NONE() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.WINDOW_ID_NONE; }, "windows.WINDOW_ID_NONE"); } + get onCreated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onCreated; }, "windows.onCreated"); } + get onFocusChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onFocusChanged; }, "windows.onFocusChanged"); } + get onRemoved() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onRemoved; }, "windows.onRemoved"); } + create(createData, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.windows.create(createData, callback); + } + else { + myBrowser.windows.create(createData); + } + }, "windows.create"); + } + get(windowId, getInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.get(windowId, getInfo, callback); + }, "windows.get"); + } + getAll(getInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.getAll(getInfo, callback); + }, "windows.getAll"); + } + getCurrent(getInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.getCurrent(getInfo, callback); + }, "windows.getCurrent"); + } + getLastFocused(getInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.getLastFocused(getInfo, callback); + }, "windows.getLastFocused"); + } + update(windowId, updateInfo, callback) { + bridgeLog.DoActionAndLog(() => { + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.windows.update(windowId, updateInfo, callback); + } + else { + myBrowser.windows.update(windowId, updateInfo); + } + }, "windows.update"); + } +} +class EdgeChromeWindowsBridge extends EdgeWindowsBridge { + remove(windowId, callback) { + bridgeLog.LogUnavailbleApi("windows.remove"); + } +} +class EdgeBackgroundBridge { + constructor() { + this.app = new EdgeChromeAppBridge(); + this.browserAction = typeof browser.browserAction !== "undefined" ? new EdgeChromeBrowserActionBridge() : undefined; + this.contextMenus = typeof browser.contextMenus !== "undefined" ? new EdgeContextMenusBridge() : undefined; + this.cookies = typeof browser.cookies !== "undefined" ? new EdgeChromeCookiesBridge() : undefined; + this.extension = typeof browser.extension !== "undefined" ? new EdgeChromeExtensionBridge() : undefined; + this.history = typeof browser.history !== "undefined" ? new EdgeHistoryBridge() : undefined; + this.i18n = typeof browser.i18n !== "undefined" ? new EdgeI18nBridge() : undefined; + this.notifications = typeof browser.notifications !== "undefined" ? new EdgeNotificationBridge() : undefined; + this.pageAction = typeof browser.pageAction !== "undefined" ? new EdgePageActionBridge() : undefined; + this.permissions = typeof browser.permissions !== "undefined" ? new EdgePermissionsBridge() : undefined; + this.runtime = typeof browser.runtime !== "undefined" ? new EdgeChromeRuntimeBridge() : undefined; + this.storage = typeof browser.storage !== "undefined" ? new EdgeChromeStorageBridge() : undefined; + this.tabs = typeof browser.tabs !== "undefined" ? new EdgeChromeTabsBridge() : undefined; + this.webNavigation = typeof browser.webNavigation !== "undefined" ? new EdgeWebNavigationBridge() : undefined; + this.webRequest = typeof browser.webRequest !== "undefined" ? new EdgeWebRequestBridge() : undefined; + this.windows = typeof browser.windows !== "undefined" ? new EdgeChromeWindowsBridge() : undefined; + } +} +var myBrowser = browser; +var chrome = new EdgeBackgroundBridge(); diff --git a/src/drivers/webextension/js/ms_content_scripts_api_bridge.js b/src/drivers/webextension/js/ms_content_scripts_api_bridge.js new file mode 100644 index 000000000..183aafc02 --- /dev/null +++ b/src/drivers/webextension/js/ms_content_scripts_api_bridge.js @@ -0,0 +1,323 @@ +if (!Range.prototype["intersectsNode"]) { + Range.prototype["intersectsNode"] = function (node) { + let range = document.createRange(); + range.selectNode(node); + return 0 > this.compareBoundaryPoints(Range.END_TO_START, range) + && 0 < this.compareBoundaryPoints(Range.START_TO_END, range); + }; +} +var getExtensionProtocol = function () { + if (typeof browser == "undefined") { + if (typeof chrome !== "undefined") + return "chrome-extension://"; + } + else { + return "ms-browser-extension://"; + } +}; +class FakeEvent { + addListener(callback) { } + addRules(rules, callback) { } + getRules(ruleIdentifiers, callback) { } + hasListener(callback) { return false; } + hasListeners() { return false; } + removeRules(ruleIdentifiers, callback) { } + removeListener(callback) { } +} +class EdgeBridgeHelper { + constructor() { + this.fakeEvent = new FakeEvent(); + } + toAbsolutePath(relativePath) { + if (relativePath.indexOf("ms-browser-extension://") == 0) { + return relativePath.replace(myBrowser.runtime.getURL(""), ""); + } + else if (relativePath.indexOf("/") != 0) { + var absolutePath = ""; + var documentPath = document.location.pathname; + absolutePath = documentPath.substring(0, documentPath.lastIndexOf("/") + 1); + absolutePath += relativePath; + return absolutePath; + } + return relativePath; + } +} +var bridgeHelper = new EdgeBridgeHelper(); +class EdgeBridgeDebugLog { + constructor() { + this.CatchOnException = true; + this.VerboseLogging = true; + this.FailedCalls = {}; + this.SuccededCalls = {}; + this.DeprecatedCalls = {}; + this.BridgedCalls = {}; + this.UnavailableApis = {}; + this.EdgeIssues = {}; + } + log(message) { + try { + if (this.VerboseLogging) { + console.log(message); + } + } + catch (e) { + } + } + info(message) { + try { + if (this.VerboseLogging) { + console.info(message); + } + } + catch (e) { + } + } + warn(message) { + try { + if (this.VerboseLogging) { + console.warn(message); + } + } + catch (e) { + } + } + error(message) { + try { + if (this.VerboseLogging) { + console.error(message); + } + } + catch (e) { + } + } + DoActionAndLog(action, name, deprecatedTo, bridgedTo) { + var result; + try { + result = action(); + this.AddToCalledDictionary(this.SuccededCalls, name); + if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") { + this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!"); + this.AddToCalledDictionary(this.DeprecatedCalls, name); + } + if (typeof bridgedTo !== "undefined" && typeof bridgedTo !== "null") { + this.info("API Call '" + name + "' has been bridged to another Edge API: " + bridgedTo); + this.AddToCalledDictionary(this.BridgedCalls, name); + } + return result; + } + catch (ex) { + this.AddToCalledDictionary(this.FailedCalls, name); + if (this.CatchOnException) + this.error("API Call Failed: " + name + " - " + ex); + else + throw ex; + } + } + LogEdgeIssue(name, message) { + this.warn(message); + this.AddToCalledDictionary(this.EdgeIssues, name); + } + LogUnavailbleApi(name, deprecatedTo) { + this.warn("API Call '" + name + "' is not supported in Edge"); + this.AddToCalledDictionary(this.UnavailableApis, name); + if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") { + this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!"); + this.AddToCalledDictionary(this.DeprecatedCalls, name); + } + } + AddToCalledDictionary(dictionary, name) { + if (typeof dictionary[name] !== "undefined") { + dictionary[name]++; + } + else { + dictionary[name] = 1; + } + } +} +var bridgeLog = new EdgeBridgeDebugLog(); +class EdgeExtensionBridge { + getBackgroundPage() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getBackgroundPage(); + }, "extension.getBackgroundPage"); + } + getURL(path) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getURL(path); + }, "extension.getURL"); + } + getViews(fetchProperties) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getViews(fetchProperties); + }, "extension.getViews"); + } +} +class EdgeChromeExtensionBridge extends EdgeExtensionBridge { + get onConnect() { return bridgeLog.DoActionAndLog(() => { return EdgeRuntimeBridge.prototype.onConnect; }, "extension.onConnect", "runtime.onConnect", "runtime.onConnect"); } + get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onMessage", "runtime.onMessage", "runtime.onMessage"); } + get onRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onRequest", "runtime.onMessage", "runtime.onMessage"); } + get onRequestExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "extension.onRequestExternal", "runtime.onMessageExternal", "runtime.onMessageExternal"); } + get inIncognitoContext() { return bridgeLog.DoActionAndLog(() => { return myBrowser.extension["inPrivateContext"]; }, "extension.inIncognitoContext", undefined, "extension.inPrivateContext"); } + get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "extension.lastError", undefined, "runtime.lastError"); } + connect(extensionId, connectInfo) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.connect(extensionId, connectInfo); + }, "extension.connect", "runtime.connect", "runtime.connect"); + } + sendMessage(message, responseCallback) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.sendMessage(message, responseCallback, undefined, undefined); + }, "extension.sendMessage", "runtime.sendMessage", "runtime.sendMessage"); + } + sendRequest(extensionId, message, options, responseCallback) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.sendMessage(extensionId, message, options, responseCallback); + }, "extension.sendRequest", "runtime.sendMessage", "runtime.sendMessage"); + } + isAllowedFileSchemeAccess(callback) { + bridgeLog.LogUnavailbleApi("extension.isAllowedFileSchemeAccess"); + } + isAllowedIncognitoAccess(callback) { + bridgeLog.LogUnavailbleApi("extension.isAllowedIncognitoAccess"); + } + setUpdateUrlData(data) { + bridgeLog.LogUnavailbleApi("extension.setUpdateUrlData"); + } +} +class EdgeI18nBridge { + getAcceptLanguages(callback) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.i18n.getAcceptLanguages(callback); + }, "i18n.getAcceptLanguages"); + } + getMessage(messageName, substitutions) { + return bridgeLog.DoActionAndLog(() => { + if (messageName.indexOf("@@extension_id") > -1) { + return myBrowser.runtime.id; + } + if (typeof substitutions !== "undefined" && typeof substitutions !== "null") { + return myBrowser.i18n.getMessage(messageName, substitutions); + } + else { + return myBrowser.i18n.getMessage(messageName); + } + }, "i18n.getMessage"); + } + getUILanguage() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.i18n.getUILanguage(); + }, "i18n.getUILanguage"); + } +} +class EdgeRuntimeBridge { + get id() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.id; }, "runtime.id"); } + get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "runtime.lastError"); } + get onConnect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onConnect; }, "runtime.onConnect"); } + get onInstalled() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onInstalled; }, "runtime.onInstalled"); } + get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "runtime.onMessage"); } + get onMessageExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "runtime.onMessageExternal"); } + connect(extensionId, connectInfo) { + return bridgeLog.DoActionAndLog(() => { + if (typeof connectInfo !== "undefined" && typeof connectInfo !== "null") { + return myBrowser.runtime.connect(extensionId, connectInfo); + } + else { + return myBrowser.runtime.connect(extensionId); + } + }, "runtime.connect"); + } + getBackgroundPage(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.getBackgroundPage(callback); + }, "runtime.getBackgroundPage"); + } + getManifest() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.getManifest(); + }, "runtime.getManifest"); + } + getURL(path) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.getURL(path); + }, "runtime.getURL"); + } + sendMessage(extensionId, message, options, responseCallback) { + bridgeLog.DoActionAndLog(() => { + if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") { + myBrowser.runtime.sendMessage(extensionId, message, options, responseCallback); + } + else if (typeof options !== "undefined" && typeof options !== "null") { + myBrowser.runtime.sendMessage(extensionId, message, options); + } + else if (typeof message !== "undefined" && typeof message !== "null") { + myBrowser.runtime.sendMessage(extensionId, message); + } + else { + myBrowser.runtime.sendMessage(undefined, extensionId); + } + }, "runtime.sendMessage"); + } +} +class EdgeChromeRuntimeBridge extends EdgeRuntimeBridge { + get onConnectExternal() { bridgeLog.LogUnavailbleApi("runtime.onConnectExternal"); return bridgeHelper.fakeEvent; } + get onRestartRequired() { bridgeLog.LogUnavailbleApi("runtime.onRestartRequired"); return bridgeHelper.fakeEvent; } + get onStartup() { bridgeLog.LogUnavailbleApi("runtime.onStartup"); return bridgeHelper.fakeEvent; } + get onSuspend() { bridgeLog.LogUnavailbleApi("runtime.onSuspend"); return bridgeHelper.fakeEvent; } + get onSuspendCanceled() { bridgeLog.LogUnavailbleApi("runtime.onSuspendCanceled"); return bridgeHelper.fakeEvent; } + get onUpdateAvailable() { bridgeLog.LogUnavailbleApi("runtime.onUpdateAvailable"); return bridgeHelper.fakeEvent; } + openOptionsPage(callback) { + bridgeLog.DoActionAndLog(() => { + var optionsPage = myBrowser.runtime.getManifest()["options_page"]; + var optionsPageUrl = myBrowser.runtime.getURL(optionsPage); + if (typeof callback !== "undefined" && typeof callback !== "null") { + myBrowser.tabs.create({ url: optionsPageUrl }, callback); + } + else { + myBrowser.tabs.create({ url: optionsPageUrl }); + } + }, "runtime.openOptionsPage", undefined, "tabs.create({ url: optionsPageUrl })"); + } + connectNative(application) { + bridgeLog.LogUnavailbleApi("runtime.connectNative"); + return null; + } + getPackageDirectoryEntry(callback) { + bridgeLog.LogUnavailbleApi("runtime.getPackageDirectoryEntry"); + } + getPlatformInfo(callback) { + bridgeLog.LogUnavailbleApi("runtime.getPlatformInfo"); + } + reload() { + bridgeLog.LogUnavailbleApi("runtime.reload"); + } + requestUpdateCheck(callback) { + bridgeLog.LogUnavailbleApi("runtime.requestUpdateCheck"); + } + restart() { + bridgeLog.LogUnavailbleApi("runtime.restart"); + } + setUninstallURL(url, callback) { + bridgeLog.LogUnavailbleApi("runtime.setUninstallURL"); + } + sendNativeMessage(application, message, responseCallback) { + bridgeLog.LogUnavailbleApi("runtime.sendNativeMessage"); + } +} +class EdgeStorageBridge { + get local() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.local"); } + get onChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.onChanged; }, "storage.onChanged"); } +} +class EdgeChromeStorageBridge extends EdgeStorageBridge { + get managed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.managed", undefined, "storage.local"); } + get sync() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.sync", undefined, "storage.local"); } +} +class EdgeContentBridge { + constructor() { + this.extension = typeof browser.extension !== "undefined" ? new EdgeChromeExtensionBridge() : undefined; + this.i18n = typeof browser.i18n !== "undefined" ? new EdgeI18nBridge() : undefined; + this.runtime = typeof browser.runtime !== "undefined" ? new EdgeChromeRuntimeBridge() : undefined; + this.storage = typeof browser.storage !== "undefined" ? new EdgeChromeStorageBridge() : undefined; + } +} +var myBrowser = browser; +var chrome = new EdgeContentBridge(); diff --git a/src/drivers/webextension/js/popup.js b/src/drivers/webextension/js/popup.js index dbb4444e0..4b959e954 100644 --- a/src/drivers/webextension/js/popup.js +++ b/src/drivers/webextension/js/popup.js @@ -10,13 +10,21 @@ document.addEventListener('DOMContentLoaded', function() { popup = { init: function() { - browser.tabs.query({ active: true, currentWindow: true }).then(function(tabs) { + var callback = function(tabs) { if ( tabs[0].url.match(/https?:\/\//) ) { detectedApps.innerHTML = '
' + browser.i18n.getMessage('noAppsDetected') + '
'; } else { detectedApps.innerHTML = '
' + browser.i18n.getMessage('nothingToDo') + '
'; } - }); + }; + + try { + // Chrome, Firefox + browser.tabs.query({ active: true, currentWindow: true }).then(callback); + } catch ( e ) { + // Edge + browser.tabs.query({ active: true, currentWindow: true }, callback); + } popup.displayApps(); }, @@ -24,7 +32,7 @@ document.addEventListener('DOMContentLoaded', function() { displayApps: function() { var appName, confidence, version; - browser.tabs.query({ active: true, currentWindow: true }).then(function(tabs) { + var callback = function(tabs) { function sendGetApps(response) { if ( response.tabCache && response.tabCache.count > 0 ) { detectedApps.innerHTML = ''; @@ -60,7 +68,15 @@ document.addEventListener('DOMContentLoaded', function() { } else { chrome.runtime.sendMessage({ id: 'get_apps', tab: tabs[0] }, sendGetApps); } - }); + }; + + try { + // Chrome, Firefox + browser.tabs.query({ active: true, currentWindow: true }).then(callback); + } catch ( e ) { + // Edge + browser.tabs.query({ active: true, currentWindow: true }, callback); + } } }; diff --git a/src/drivers/webextension/manifest.edge.json b/src/drivers/webextension/manifest.edge.json index 4c94099f2..9e9faf3a6 100644 --- a/src/drivers/webextension/manifest.edge.json +++ b/src/drivers/webextension/manifest.edge.json @@ -1,44 +1,51 @@ { "name": "Wappalyzer", - "short_name": "Wappalyzer", - "author": "Elbert Alias", + "short_name": "Wappalyzer", + "author": "Elbert Alias", "homepage_url": "https://wappalyzer.com/", "description": "Identify web technologies", - "version": "4", + "version": "4.0.1", "default_locale": "en", "manifest_version": 2, "icons": { - "16": "images/icon_16.png", - "19": "images/icon_19.png", - "32": "images/icon_32.png", - "38": "images/icon_38.png", + "16": "images/icon_16.png", + "19": "images/icon_19.png", + "32": "images/icon_32.png", + "38": "images/icon_38.png", "128": "images/icon_128.png" }, "page_action": { "default_icon": { - "16": "images/icon_16.png", - "19": "images/icon_19.png", - "32": "images/icon_32.png", - "38": "images/icon_38.png", - "128": "images/icon_128.png" - }, + "16": "images/icon_16.png", + "19": "images/icon_19.png", + "32": "images/icon_32.png", + "38": "images/icon_38.png", + "128": "images/icon_128.png" + }, "default_title": "Wappalyzer", "default_popup": "popup.html" }, "background": { "page": "background.html", - "persistent": true + "persistent": true }, "content_scripts": [ { - "matches": [ "http://*/*", "https://*/*" ], + "matches": [ + "http://*/*", + "https://*/*" + ], "js": [ "js/browser-polyfill.js", "js/content.js" ], "run_at": "document_idle" - }, { - "matches": [ "http://*/*", "https://*/*" ], + }, + { + "matches": [ + "http://*/*", + "https://*/*" + ], "js": [ "js/browser-polyfill.js", "js/iframe.js" @@ -50,7 +57,7 @@ "web_accessible_resources": [ "js/inject.js" ], - "options_page": "options.html", + "options_page": "options.html", "permissions": [ "tabs", "webRequest", @@ -58,5 +65,9 @@ "http://*/*", "https://*/*" ], - "content_security_policy": "script-src 'self'; object-src 'self'" + "content_security_policy": "script-src 'self'; object-src 'self'", + "-ms-preload": { + "backgroundScript": "js/ms_background_scripts_api_bridge.js", + "contentScript": "js/ms_content_scripts_api_bridge.js" + } } diff --git a/src/drivers/webextension/manifest.json b/src/drivers/webextension/manifest.json index 54d2a07e4..38b9f5abb 100644 --- a/src/drivers/webextension/manifest.json +++ b/src/drivers/webextension/manifest.json @@ -1,47 +1,53 @@ { "name": "Wappalyzer", - "short_name": "Wappalyzer", - "author": "Elbert Alias", + "short_name": "Wappalyzer", + "author": "Elbert Alias", "homepage_url": "https://wappalyzer.com/", "description": "Identify web technologies", "version": "4.0.1", "default_locale": "en", "manifest_version": 2, "icons": { - "16": "images/icon_16.png", - "19": "images/icon_19.png", - "32": "images/icon_32.png", - "38": "images/icon_38.png", + "16": "images/icon_16.png", + "19": "images/icon_19.png", + "32": "images/icon_32.png", + "38": "images/icon_38.png", "128": "images/icon_128.png" }, "page_action": { "default_icon": { - "16": "images/icon_16.png", - "19": "images/icon_19.png", - "32": "images/icon_32.png", - "38": "images/icon_38.png", - "128": "images/icon_128.png" - }, + "16": "images/icon_16.png", + "19": "images/icon_19.png", + "32": "images/icon_32.png", + "38": "images/icon_38.png", + "128": "images/icon_128.png" + }, "default_title": "Wappalyzer", "default_popup": "popup.html" }, "background": { - "page": "background.html" - + "page": "background.html", + "persistent": true }, "content_scripts": [ { - "matches": [ "http://*/*", "https://*/*" ], + "matches": [ + "http://*/*", + "https://*/*" + ], "js": [ "js/browser-polyfill.js", "js/content.js" ], "run_at": "document_idle" - }, { - "matches": [ "http://*/*", "https://*/*" ], + }, + { + "matches": [ + "http://*/*", + "https://*/*" + ], "js": [ - "js/browser-polyfill.js", - "js/iframe.js" + "js/browser-polyfill.js" ], "run_at": "document_start", "all_frames": true @@ -50,11 +56,7 @@ "web_accessible_resources": [ "js/inject.js" ], - "options_page": "options.html", - "options_ui": { - "page": "options.html", - "open_in_tab": false - }, + "options_page": "options.html", "permissions": [ "tabs", "webRequest", @@ -62,5 +64,9 @@ "http://*/*", "https://*/*" ], - "content_security_policy": "script-src 'self'; object-src 'self'" + "content_security_policy": "script-src 'self'; object-src 'self'", + "-ms-preload": { + "backgroundScript": "js/ms_background_scripts_api_bridge.js", + "contentScript": "js/ms_content_scripts_api_bridge.js" + } } diff --git a/src/wappalyzer.js b/src/wappalyzer.js index 8eb4f289f..6b13f0c88 100644 --- a/src/wappalyzer.js +++ b/src/wappalyzer.js @@ -1,5 +1,5 @@ /** - * Wappalyzer v2 + * Wappalyzer v4 * * Created by Elbert Alias *