diff --git a/bin/build b/bin/build index ea7ad0cc8..2bdd89fa1 100755 --- a/bin/build +++ b/bin/build @@ -54,7 +54,6 @@ zip -qr ../../../build/wappalyzer_webextension.zip . \ -x images/icon_50.png \ -x images/icon_150.png \ -x js/ms_\*.js \ - -x manifest.edge.json \ -x \*.log \ -x \*.lock \ -x \*.gitignore \ @@ -68,46 +67,4 @@ zip -qr ../../../build/wappalyzer_webextension.zip . \ popd > /dev/null -# Edge -#echo "Building Edge application..." -# -#pushd build > /dev/null -# -#webextension_dir="../$webextension_dir" -#manifest_dir="Wappalyzer/edgeextension/manifest" -# -#mv $webextension_dir/manifest.json $webextension_dir/manifest.webextension.json -#mv $webextension_dir/manifest.edge.json $webextension_dir/manifest.json -# -#sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"$version\"/" $webextension_dir/manifest.json -# -#manifoldjs -l debug -p edgeextension -f edgeextension -m $webextension_dir/manifest.json -# -## Replace symlinks with actual files -#rm $manifest_dir/Extension/images/icons -# -#cp ../src/apps.json $manifest_dir/Extension -#cp ../src/wappalyzer.js $manifest_dir/Extension/js -#cp -r ../src/icons $manifest_dir/Extension/images -# -#mv $webextension_dir/manifest.json $webextension_dir/manifest.edge.json -#mv $webextension_dir/manifest.webextension.json $webextension_dir/manifest.json -# -#sed -i 's/INSERT-YOUR-PACKAGE-IDENTITY-NAME-HERE/1591Wappalyzer.Wappalyzer/' $manifest_dir/appxmanifest.xml -#sed -i 's/INSERT-YOUR-PACKAGE-IDENTITY-PUBLISHER-HERE/D240C22F-A6C1-45DF-BF7B-4C835064DF51/' $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 - echo "Done (v$version)." diff --git a/bin/validate b/bin/validate index 1d6587600..dd9b12729 100755 --- a/bin/validate +++ b/bin/validate @@ -6,7 +6,7 @@ set -eu echo "Validating apps.json..." -jsonlint-cli -s schema.json src/apps.json +jsonlint-cli -tps schema.json src/apps.json > /tmp/apps.json && mv /tmp/apps.json src/apps.json echo "Validating regular expressions..." diff --git a/package.json b/package.json index 2148f0f67..cdb767828 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "dependencies": { - "file-type": "3.8.*", - "is-svg": "2.0.*", - "read-chunk": "2.0.*" + "file-type": "7.4.*", + "is-svg": "2.1.*", + "read-chunk": "2.1.*" } } diff --git a/schema.json b/schema.json index ac366218f..e66f71303 100644 --- a/schema.json +++ b/schema.json @@ -3,6 +3,9 @@ "type": "object", "additionalProperties": false, "properties": { + "$schema": { + "type": "string" + }, "categories": { "type": "object", "required": true, @@ -13,7 +16,7 @@ "required": true, "properties": { "priority": { - "type": "string" + "type": "number" }, "name": { "type": "string" @@ -31,13 +34,13 @@ "cats": { "type": "array", "items": { - "type": "string" + "type": "number" }, "required": true }, - "env": { - "type": [ "string", "array" ], - "items": { + "js": { + "type": "object", + "additionalProperties": { "type": "string" } }, @@ -48,19 +51,28 @@ } }, "html": { - "type": [ "string", "array" ], + "type": [ + "string", + "array" + ], "items": { "type": "string" } }, "excludes": { - "type": [ "string", "array" ], + "type": [ + "string", + "array" + ], "items": { "type": "string" } }, "implies": { - "type": [ "string", "array" ], + "type": [ + "string", + "array" + ], "items": { "type": "string" } @@ -72,7 +84,10 @@ } }, "script": { - "type": [ "string", "array" ], + "type": [ + "string", + "array" + ], "items": { "type": "string" } diff --git a/src/apps.json b/src/apps.json index 349376559..2dcff4fba 100644 --- a/src/apps.json +++ b/src/apps.json @@ -1,11291 +1,12468 @@ { - "apps": { - "1&1": { - "cats": [ - "6" - ], - "icon": "1and1.svg", - "implies": "PHP", - "url": "/shop/catalog/browse\\?sessid=", - "website": "http://1and1.com" - }, - "1C-Bitrix": { - "cats": [ - "1" - ], - "headers": { - "Set-Cookie": "^BITRIX_", - "X-Powered-CMS": "^Bitrix Site Manager" - }, - "html": "(?:]+components/bitrix|(?:src|href)=\"/bitrix/(?:js|templates))", - "icon": "1C-Bitrix.png", - "implies": "PHP", - "script": "1c-bitrix", - "website": "http://www.1c-bitrix.ru" - }, - "2z Project": { - "cats": [ - "1" - ], - "icon": "2z Project.png", - "meta": { - "generator": "2z project ([\\d.]+)\\;version:\\1" - }, - "website": "http://2zproject-cms.ru" - }, - "3DM": { - "cats": [ - "19" - ], - "html": "3ware 3DM([\\d\\.]+)?\\;version:\\1", - "icon": "3DM.png", - "implies": "3ware", - "website": "http://www.3ware.com" - }, - "3dCart": { - "cats": [ - "1", - "6" - ], - "headers": { - "Set-Cookie": "3dvisit", - "X-Powered-By": "3DCART" - }, - "icon": "3dCart.png", - "script": "(?:twlh(?:track)?\\.asp|3d_upsell\\.js)", - "website": "http://www.3dcart.com" - }, - "3ware": { - "cats": [ - "22" - ], - "headers": { - "Server": "3ware\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "3ware.png", - "website": "http://www.3ware.com" - }, - "AD EBiS": { - "cats": [ - "10" - ], - "html": [ - "<!-- EBiS contents tag", - "<!--EBiS tag", - "<!-- Tag EBiS", - "<!-- EBiS common tag" - ], - "icon": "ebis.png", - "website": "http://www.ebis.ne.jp" - }, - "Amber": { - "cats": [ - "18", - "22" - ], - "headers": { - "X-Powered-By": "^Amber$" - }, - "icon": "amber.png", - "website": "https://amberframework.org" - }, - "AMPcms": { - "cats": [ - "1" - ], - "env": "^amp_js_init$", - "headers": { - "Set-Cookie": "^AMP=", - "X-AMP-Version": "([\\d.]+)\\;version:\\1" - }, - "icon": "AMPcms.png", - "implies": "PHP", - "website": "http://www.ampcms.org" - }, - "AOLserver": { - "cats": [ - "22" - ], - "headers": { - "Server": "AOLserver/?([\\d.]+)?\\;version:\\1" - }, - "icon": "AOLserver.png", - "website": "http://aolserver.com" - }, - "AT Internet Analyzer": { - "cats": [ - "10" - ], - "env": [ - "^xtsite$", - "^ATInternet$" - ], - "icon": "AT Internet.png", - "website": "http://atinternet.com/en" - }, - "AT Internet XiTi": { - "cats": [ - "10" - ], - "env": "^Xt_", - "icon": "AT Internet.png", - "script": "xiti\\.com/hit\\.xiti", - "website": "http://atinternet.com/en" - }, - "ATEN": { - "cats": [ - "22" - ], - "headers": { - "Server": "ATEN HTTP Server(?:\\(?V?([\\d\\.]+)\\)?)?\\;version:\\1" - }, - "icon": "ATEN.png", - "website": "http://www.aten.com" - }, - "AWStats": { - "cats": [ - "10" - ], - "icon": "AWStats.png", - "implies": "Perl", - "meta": { - "generator": "AWStats ([\\d.]+(?: \\(build [\\d.]+\\))?)\\;version:\\1" - }, - "website": "http://awstats.sourceforge.net" - }, - "Accessible Portal": { - "cats": [ - "1" - ], - "icon": "Accessible Portal.png", - "implies": "PHP", - "meta": { - "generator": "Accessible Portal" - }, - "website": "http://www.accessibleportal.com" - }, - "Act-On": { - "cats": [ - "32" - ], - "env": "^ActOn$", - "icon": "ActOn.png", - "website": "http://act-on.com" - }, - "Prebid": { - "cats": [ - "36" - ], - "icon": "Prebid.png", - "env": [ - "pbjs", - "PREBID_TIMEOUT" - ], - "script": [ - "/prebid\\.js", - "adnxs\\.com/[^\"]*(?:prebid|/pb\\.js)" - ], - "website": "http://prebid.org" - }, - "AdInfinity": { - "cats": [ - "36" - ], - "icon": "AdInfinity.png", - "script": "adinfinity\\.com\\.au", - "website": "http://adinfinity.com.au" - }, - "AdRiver": { - "cats": [ - "36" - ], - "env": "^adriver$", - "html": "(?:<embed[^>]+(?:src=\"https?://mh\\d?\\.adriver\\.ru/|flashvars=\"[^\"]*(?:http:%3A//(?:ad|mh\\d?)\\.adriver\\.ru/|adriver_banner))|<(?:(?:iframe|img)[^>]+src|a[^>]+href)=\"https?://ad\\.adriver\\.ru/)", - "icon": "AdRiver.png", - "script": "(?:adriver\\.core\\.\\d\\.js|https?://(?:content|ad|masterh\\d)\\.adriver\\.ru/)", - "website": "http://adriver.ru" - }, - "AdRoll": { - "cats": [ - "36" - ], - "env": "^adroll_", - "icon": "AdRoll.svg", - "script": "(?:a|s)\\.adroll\\.com", - "website": "http://adroll.com" - }, - "Adcash": { - "cats": [ - "36" - ], - "env": "^(?:ac_bgclick_URL|ct_(?:siteunder|tag|n(?:SuUrl(?:Opp)?)|Su(?:Loaded|Url)))$", - "icon": "Adcash.svg", - "script": "^[^\\/]*//(?:[^\\/]+\\.)?adcash\\.com/(?:script|ad)/", - "url": "^https?://(?:[^\\/]+\\.)?adcash\\.com/script/pop_", - "website": "http://adcash.com" - }, - "AddShoppers": { - "cats": [ - "5" - ], - "icon": "AddShoppers.png", - "script": "cdn\\.shop\\.pe/widget/", - "website": "http://www.addshoppers.com" - }, - "AddThis": { - "cats": [ - "5" - ], - "env": "^addthis", - "icon": "AddThis.svg", - "script": "addthis\\.com/js/", - "website": "http://www.addthis.com" - }, - "AddToAny": { - "cats": [ - "5" - ], - "env": "^a2apage_init$", - "icon": "AddToAny.png", - "script": "addtoany\\.com/menu/page\\.js", - "website": "http://www.addtoany.com" - }, - "Adminer": { - "cats": [ - "3" - ], - "html": [ - "Adminer</a> <span class=\"version\">([\\d.]+)</span>\\;version:\\1", - "onclick=\"bodyClick\\(event\\);\" onload=\"verifyVersion\\('([\\d.]+)'\\);\">\\;version:\\1" - ], - "icon": "adminer.png", - "implies": "PHP", - "website": "http://www.adminer.org" - }, - "Adnegah": { - "cats": [ - "36" - ], - "headers": { - "X-Advertising-By": "adnegah\\.net" - }, - "html": "<iframe [^>]*src=\"[^\"]+adnegah\\.net", - "icon": "adnegah.png", - "script": "[^a-z]adnegah.*\\.js$", - "website": "https://Adnegah.net" - }, - "Adobe ColdFusion": { - "cats": [ - "18" - ], - "env": "^_cfEmails$", - "headers": { - "Cookie": "CFTOKEN=" - }, - "html": "<!-- START headerTags\\.cfm", - "icon": "Adobe ColdFusion.svg", - "implies": "CFML", - "script": "/cfajax/", - "url": "\\.cfm(?:$|\\?)", - "website": "http://adobe.com/products/coldfusion-family.html" - }, - "Adobe Experience Manager": { - "cats": [ - "1" - ], - "html": [ - "<div class=\"[^\"]*parbase", - "<div[^>]+data-component-path=\"[^\"+]jcr:" - ], - "icon": "Adobe Experience Manager.svg", - "implies": "Java", - "script": "/etc/designs/", - "website": "http://www.adobe.com/au/marketing-cloud/enterprise-content-management.html" - }, - "Adobe GoLive": { - "cats": [ - "20" - ], - "icon": "Adobe GoLive.png", - "meta": { - "generator": "Adobe GoLive(?:\\s([\\d.]+))?\\;version:\\1" - }, - "website": "http://www.adobe.com/products/golive" - }, - "Adobe Muse": { - "cats": [ - "20" - ], - "icon": "Adobe Muse.svg", - "meta": { - "generator": "^Muse(?:$| ?/?(\\d[\\d.]+))\\;version:\\1" - }, - "website": "http://muse.adobe.com" - }, - "Adobe RoboHelp": { - "cats": [ - "4" - ], - "env": "^gbWh(?:Ver|Lang|Msg|Util|Proxy)$", - "icon": "Adobe RoboHelp.svg", - "meta": { - "generator": "^Adobe RoboHelp(?: ([\\d]+))?\\;version:\\1" - }, - "script": "(?:wh(?:utils|ver|proxy|lang|topic|msg)|ehlpdhtm)\\.js", - "website": "http://adobe.com/products/robohelp.html" - }, - "Advanced Web Stats": { - "cats": [ - "10" - ], - "html": "aws\\.src = [^<]+caphyon-analytics", - "icon": "Advanced Web Stats.png", - "implies": "Java", - "website": "http://www.advancedwebstats.com" - }, - "Advert Stream": { - "cats": [ - "36" - ], - "env": "^advst_is_above_the_fold$", - "icon": "Advert Stream.png", - "script": "(?:ad\\.advertstream\\.com|adxcore\\.com)", - "website": "http://www.advertstream.com" - }, - "Adzerk": { - "cats": [ - "36" - ], - "env": "^ados(?:Results)?$", - "html": "<iframe [^>]*src=\"[^\"]+adzerk\\.net", - "icon": "Adzerk.png", - "script": "adzerk\\.net/ados\\.js", - "website": "http://adzerk.com" - }, - "Aegea": { - "cats": [ - "11" - ], - "headers": { - "X-Powered-By": "^E2 Aegea v(\\d+)$\\;version:\\1" - }, - "icon": "Aegea.png", - "implies": [ - "PHP", - "jQuery" - ], - "website": "http://blogengine.ru" - }, - "AfterBuy": { - "cats": [ - "6" - ], - "html": [ - "<dd>This OnlineStore is brought to you by ViA-Online GmbH Afterbuy\\. Information and contribution at https://www\\.afterbuy\\.de</dd>" - ], - "icon": "after-buy.png", - "script": "shop-static\\.afterbuy\\.de", - "website": "http://www.afterbuy.de" - }, + "$schema": "../schema.json", + "apps": { + "1&1": { + "cats": [ + 6 + ], + "icon": "1and1.svg", + "implies": "PHP", + "url": "/shop/catalog/browse\\?sessid=", + "website": "http://1and1.com" + }, + "Google Analytics Enhanced eCommerce": { + "cats": [ + 10 + ], + "js": { + "gaplugins.EC": "" + }, + "icon": "Google Analytics.svg", + "script": "google-analytics\\.com\\/plugins\\/ua\\/ec\\.js", + "website": "https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce" + }, + "1C-Bitrix": { + "cats": [ + 1 + ], + "headers": { + "Set-Cookie": "^BITRIX_", + "X-Powered-CMS": "^Bitrix Site Manager" + }, + "html": "(?:<link[^>]+components/bitrix|(?:src|href)=\"/bitrix/(?:js|templates))", + "icon": "1C-Bitrix.png", + "implies": "PHP", + "script": "1c-bitrix", + "website": "http://www.1c-bitrix.ru" + }, + "animate.css": { + "cats": [ + 18 + ], + "html": [ + "<link [^>]+(?:/([\\d.]+)/)?animate\\.(?:min\\.)?css\\;version:\\1" + ], + "website": "https://daneden.github.io/animate.css/" + }, + "2z Project": { + "cats": [ + 1 + ], + "icon": "2z Project.png", + "meta": { + "generator": "2z project ([\\d.]+)\\;version:\\1" + }, + "website": "http://2zproject-cms.ru" + }, + "3DM": { + "cats": [ + 19 + ], + "html": "<title>3ware 3DM([\\d\\.]+)?\\;version:\\1", + "icon": "3DM.png", + "implies": "3ware", + "website": "http://www.3ware.com" + }, + "3dCart": { + "cats": [ + 1, + 6 + ], + "headers": { + "Set-Cookie": "3dvisit", + "X-Powered-By": "3DCART" + }, + "icon": "3dCart.png", + "script": "(?:twlh(?:track)?\\.asp|3d_upsell\\.js)", + "website": "http://www.3dcart.com" + }, + "3ware": { + "cats": [ + 22 + ], + "headers": { + "Server": "3ware\\/?([\\d\\.]+)?\\;version:\\1" + }, + "icon": "3ware.png", + "website": "http://www.3ware.com" + }, + "A-Frame": { + "cats": [ + 25 + ], + "html": "<a-scene[^<>]*>", + "icon": "A-Frame.svg", + "implies": "three.js", + "js": { + "AFRAME.version": "(.*)\\;version:\\1" + }, + "scripts": "/?([\\d.]+)?/aframe(?:\\.min)?\\.js\\;version:\\1", + "website": "https://aframe.io" + }, + "AD EBiS": { + "cats": [ + 10 + ], + "html": [ + "<!-- EBiS contents tag", + "<!--EBiS tag", + "<!-- Tag EBiS", + "<!-- EBiS common tag" + ], + "icon": "ebis.png", + "website": "http://www.ebis.ne.jp" + }, + "Accelerated Mobile Pages": { + "cats": [ + 12 + ], + "html": "<html[^>]* (?:amp|⚡)", + "icon": "Accelerated-Mobile-Pages.svg", + "website": "https://www.ampproject.org" + }, + "Amber": { + "cats": [ + 18, + 22 + ], + "headers": { + "X-Powered-By": "^Amber$" + }, + "icon": "amber.png", + "website": "https://amberframework.org" + }, + "AMPcms": { + "cats": [ + 1 + ], + "js": { + "amp_js_init": "" + }, + "headers": { + "Set-Cookie": "^AMP=", + "X-AMP-Version": "([\\d.]+)\\;version:\\1" + }, + "icon": "AMPcms.png", + "implies": "PHP", + "website": "http://www.ampcms.org" + }, + "AOLserver": { + "cats": [ + 22 + ], + "headers": { + "Server": "AOLserver/?([\\d.]+)?\\;version:\\1" + }, + "icon": "AOLserver.png", + "website": "http://aolserver.com" + }, + "AT Internet Analyzer": { + "cats": [ + 10 + ], + "js": { + "xtsite": "", + "ATInternet": "" + }, + "icon": "AT Internet.png", + "website": "http://atinternet.com/en" + }, + "AT Internet XiTi": { + "cats": [ + 10 + ], + "js": { + "xt_click": "" + }, + "icon": "AT Internet.png", + "script": "xiti\\.com/hit\\.xiti", + "website": "http://atinternet.com/en" + }, + "ATEN": { + "cats": [ + 22 + ], + "headers": { + "Server": "ATEN HTTP Server(?:\\(?V?([\\d\\.]+)\\)?)?\\;version:\\1" + }, + "icon": "ATEN.png", + "website": "http://www.aten.com" + }, + "AWStats": { + "cats": [ + 10 + ], + "icon": "AWStats.png", + "implies": "Perl", + "meta": { + "generator": "AWStats ([\\d.]+(?: \\(build [\\d.]+\\))?)\\;version:\\1" + }, + "website": "http://awstats.sourceforge.net" + }, + "Accessible Portal": { + "cats": [ + 1 + ], + "icon": "Accessible Portal.png", + "implies": "PHP", + "meta": { + "generator": "Accessible Portal" + }, + "website": "http://www.accessibleportal.com" + }, + "Act-On": { + "cats": [ + 32 + ], + "js": { + "ActOn": "" + }, + "icon": "ActOn.png", + "website": "http://act-on.com" + }, + "Prebid": { + "cats": [ + 36 + ], + "icon": "Prebid.png", + "js": { + "pbjs": "", + "PREBID_TIMEOUT": "" + }, + "script": [ + "/prebid\\.js", + "adnxs\\.com/[^\"]*(?:prebid|/pb\\.js)" + ], + "website": "http://prebid.org" + }, + "AdInfinity": { + "cats": [ + 36 + ], + "icon": "AdInfinity.png", + "script": "adinfinity\\.com\\.au", + "website": "http://adinfinity.com.au" + }, + "AdRiver": { + "cats": [ + 36 + ], + "js": { + "adriver": "" + }, + "html": "(?:<embed[^>]+(?:src=\"https?://mh\\d?\\.adriver\\.ru/|flashvars=\"[^\"]*(?:http:%3A//(?:ad|mh\\d?)\\.adriver\\.ru/|adriver_banner))|<(?:(?:iframe|img)[^>]+src|a[^>]+href)=\"https?://ad\\.adriver\\.ru/)", + "icon": "AdRiver.png", + "script": "(?:adriver\\.core\\.\\d\\.js|https?://(?:content|ad|masterh\\d)\\.adriver\\.ru/)", + "website": "http://adriver.ru" + }, + "AdRoll": { + "cats": [ + 36 + ], + "js": { + "adroll_adv_id": "", + "adroll_pix_id": "" + }, + "icon": "AdRoll.svg", + "script": "(?:a|s)\\.adroll\\.com", + "website": "http://adroll.com" + }, + "Adcash": { + "cats": [ + 36 + ], + "js": { + "ac_bgclick_URL": "", + "ct_siteunder": "", + "ct_tag": "", + "ct_nSuUrl": "", + "ct_nOpp": "", + "SuLoaded": "", + "SuUrl": "" + }, + "icon": "Adcash.svg", + "script": "^[^\\/]*//(?:[^\\/]+\\.)?adcash\\.com/(?:script|ad)/", + "url": "^https?://(?:[^\\/]+\\.)?adcash\\.com/script/pop_", + "website": "http://adcash.com" + }, + "AddShoppers": { + "cats": [ + 5 + ], + "icon": "AddShoppers.png", + "script": "cdn\\.shop\\.pe/widget/", + "website": "http://www.addshoppers.com" + }, + "AddThis": { + "cats": [ + 5 + ], + "js": { + "addthis": "" + }, + "icon": "AddThis.svg", + "script": "addthis\\.com/js/", + "website": "http://www.addthis.com" + }, + "AddToAny": { + "cats": [ + 5 + ], + "js": { + "a2apage_init": "" + }, + "icon": "AddToAny.png", + "script": "addtoany\\.com/menu/page\\.js", + "website": "http://www.addtoany.com" + }, + "Adminer": { + "cats": [ + 3 + ], + "html": [ + "Adminer</a> <span class=\"version\">([\\d.]+)</span>\\;version:\\1", + "onclick=\"bodyClick\\(event\\);\" onload=\"verifyVersion\\('([\\d.]+)'\\);\">\\;version:\\1" + ], + "icon": "adminer.png", + "implies": "PHP", + "website": "http://www.adminer.org" + }, + "Adnegah": { + "cats": [ + 36 + ], + "headers": { + "X-Advertising-By": "adnegah\\.net" + }, + "html": "<iframe [^>]*src=\"[^\"]+adnegah\\.net", + "icon": "adnegah.png", + "script": "[^a-z]adnegah.*\\.js$", + "website": "https://Adnegah.net" + }, + "Adobe ColdFusion": { + "cats": [ + 18 + ], + "js": { + "_cfEmails": "" + }, + "headers": { + "Cookie": "CFTOKEN=" + }, + "html": "<!-- START headerTags\\.cfm", + "icon": "Adobe ColdFusion.svg", + "implies": "CFML", + "script": "/cfajax/", + "url": "\\.cfm(?:$|\\?)", + "website": "http://adobe.com/products/coldfusion-family.html" + }, + "Adobe Experience Manager": { + "cats": [ + 1 + ], + "html": [ + "<div class=\"[^\"]*parbase", + "<div[^>]+data-component-path=\"[^\"+]jcr:" + ], + "icon": "Adobe Experience Manager.svg", + "implies": "Java", + "script": "/etc/designs/", + "website": "http://www.adobe.com/au/marketing-cloud/enterprise-content-management.html" + }, + "Adobe GoLive": { + "cats": [ + 20 + ], + "icon": "Adobe GoLive.png", + "meta": { + "generator": "Adobe GoLive(?:\\s([\\d.]+))?\\;version:\\1" + }, + "website": "http://www.adobe.com/products/golive" + }, + "Adobe Muse": { + "cats": [ + 20 + ], + "icon": "Adobe Muse.svg", + "meta": { + "generator": "^Muse(?:$| ?/?(\\d[\\d.]+))\\;version:\\1" + }, + "website": "http://muse.adobe.com" + }, + "Adobe RoboHelp": { + "cats": [ + 4 + ], + "js": { + "gbWhVer": "", + "gbWhLang": "", + "gbWhMsg": "", + "gbWhUtil": "", + "gbWhProxy": "" + }, + "icon": "Adobe RoboHelp.svg", + "meta": { + "generator": "^Adobe RoboHelp(?: ([\\d]+))?\\;version:\\1" + }, + "script": "(?:wh(?:utils|ver|proxy|lang|topic|msg)|ehlpdhtm)\\.js", + "website": "http://adobe.com/products/robohelp.html" + }, + "Advanced Web Stats": { + "cats": [ + 10 + ], + "html": "aws\\.src = [^<]+caphyon-analytics", + "icon": "Advanced Web Stats.png", + "implies": "Java", + "website": "http://www.advancedwebstats.com" + }, + "Advert Stream": { + "cats": [ + 36 + ], + "js": { + "advst_is_above_the_fold": "" + }, + "icon": "Advert Stream.png", + "script": "(?:ad\\.advertstream\\.com|adxcore\\.com)", + "website": "http://www.advertstream.com" + }, + "Adzerk": { + "cats": [ + 36 + ], + "js": { + "ados": "", + "adosResults": "" + }, + "html": "<iframe [^>]*src=\"[^\"]+adzerk\\.net", + "icon": "Adzerk.png", + "script": "adzerk\\.net/ados\\.js", + "website": "http://adzerk.com" + }, + "Aegea": { + "cats": [ + 11 + ], + "headers": { + "X-Powered-By": "^E2 Aegea v(\\d+)$\\;version:\\1" + }, + "icon": "Aegea.png", + "implies": [ + "PHP", + "jQuery" + ], + "website": "http://blogengine.ru" + }, + "AfterBuy": { + "cats": [ + 6 + ], + "html": [ + "<dd>This OnlineStore is brought to you by ViA-Online GmbH Afterbuy\\. Information and contribution at https://www\\.afterbuy\\.de</dd>" + ], + "icon": "after-buy.png", + "script": "shop-static\\.afterbuy\\.de", + "website": "http://www.afterbuy.de" + }, "Afosto": { "cats": [ - "6" + 6 + ], + "headers": { + "X-Powered-By": "Afosto SaaS BV" + }, + "icon": "Afosto.svg", + "website": "http://afosto.com" + }, + "Aircall": { + "cats": [ + 52 + ], + "icon": "aircall.png", + "script": "^https?://cdn\\.aircall\\.io/", + "website": "http://aircall.io" + }, + "Airee": { + "cats": [ + 31 + ], + "headers": { + "Server": "Airee" + }, + "icon": "Airee.png", + "website": "http://xn--80aqc2a.xn--p1ai" + }, + "Akamai": { + "cats": [ + 31 + ], + "headers": { + "X-Akamai-Transformed": "" + }, + "icon": "akamai.svg", + "website": "http://akamai.com" + }, + "Akka HTTP": { + "cats": [ + 18, + 22 + ], + "headers": { + "Server": "akka-http(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "akka-http.png", + "website": "http://akka.io" + }, + "Algolia Realtime Search": { + "cats": [ + 29 + ], + "js": { + "AlgoliaSearch": "" + }, + "icon": "Algolia Realtime Search.svg", + "website": "http://www.algolia.com" + }, + "Allegro RomPager": { + "cats": [ + 22 + ], + "headers": { + "Server": "Allegro-Software-RomPager(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "Allegro RomPager.png", + "website": "http://allegrosoft.com/embedded-web-server-s2" + }, + "AlloyUI": { + "cats": [ + 12 + ], + "js": { + "AUI": "" + }, + "icon": "AlloyUI.png", + "implies": [ + "Bootstrap", + "YUI" + ], + "script": "^https?://cdn\\.alloyui\\.com/", + "website": "http://www.alloyui.com" + }, + "Amaya": { + "cats": [ + 20 + ], + "icon": "Amaya.png", + "meta": { + "generator": "Amaya(?: V?([\\d.]+[a-z]))?\\;version:\\1" + }, + "website": "http://www.w3.org/Amaya" + }, + "Amazon Cloudfront": { + "cats": [ + 31 + ], + "headers": { + "X-Amz-Cf-Id": "" + }, + "icon": "Amazon-Cloudfront.svg", + "website": "http://aws.amazon.com/cloudfront/" + }, + "Amazon EC2": { + "cats": [ + 22 + ], + "headers": { + "Server": "\\(Amazon\\)" + }, + "icon": "aws-ec2.svg", + "website": "http://aws.amazon.com/ec2/" + }, + "Amazon S3": { + "cats": [ + 19 + ], + "headers": { + "Server": "AmazonS3" + }, + "icon": "aws-s3.svg", + "website": "http://aws.amazon.com/s3/" + }, + "Ametys": { + "cats": [ + 1 + ], + "icon": "Ametys.png", + "implies": "Java", + "meta": { + "generator": "(?:Ametys|Anyware Technologies)" + }, + "script": "ametys\\.js", + "website": "http://ametys.org" + }, + "Amiro.CMS": { + "cats": [ + 1 + ], + "icon": "Amiro.CMS.png", + "implies": "PHP", + "meta": { + "generator": "Amiro" + }, + "website": "http://amirocms.com" + }, + "Angular Material": { + "cats": [ + 18 + ], + "js": { + "ngMaterial": "" + }, + "icon": "AngularJS.svg", + "implies": "AngularJS", + "script": [ + "/([\\d.]+(?:\\-?rc[.\\d]*)*)/angular-material(?:\\.min)?\\.js\\;version:\\1", + "angular-material.*\\.js" + ], + "website": "http://material.angularjs.org" + }, + "Angular": { + "cats": [ + 12 + ], + "html": "<[^>]+ ng-version=\"([\\d.]+)\">\\;version:\\1", + "icon": "Angular.svg", + "website": "https://angular.io" + }, + "AngularJS": { + "cats": [ + 12 + ], + "js": { + "angular": "", + "angular.version.full": "(.*)\\;version:\\1" + }, + "html": "<[^>]+ ng-version=\"([\\d.]+)\">\\;version:\\1", + "icon": "AngularJS.svg", + "script": [ + "angular(?:\\-|\\.)([\\d.]*\\d)[^/]*\\.js\\;version:\\1", + "/([\\d.]+(?:\\-?rc[.\\d]*)*)/angular(?:\\.min)?\\.js\\;version:\\1", + "angular.*\\.js" + ], + "website": "https://angularjs.org" + }, + "Apache": { + "cats": [ + 22 + ], + "headers": { + "Server": "(?:Apache(?:$|/([\\d.]+)|[^/-])|(?:^|\b)HTTPD)\\;version:\\1" + }, + "icon": "Apache.svg", + "website": "http://apache.org" + }, + "Apache HBase": { + "cats": [ + 34 + ], + "html": "<style[^>]+static/hbase", + "icon": "Apache HBase.png", + "implies": "Java", + "website": "http://hbase.apache.org" + }, + "Apache Hadoop": { + "cats": [ + 34 + ], + "html": "<style[^>]+static/hadoop", + "icon": "Apache Hadoop.svg", + "website": "http://hadoop.apache.org" + }, + "Apache JSPWiki": { + "cats": [ + 8 + ], + "html": "<html[^>]* xmlns:jspwiki=", + "icon": "Apache JSPWiki.png", + "implies": "Apache Tomcat", + "script": "jspwiki", + "url": "wiki\\.jsp", + "website": "http://jspwiki.org" + }, + "Apache Tomcat": { + "cats": [ + 22 + ], + "headers": { + "Server": "^Apache-Coyote(/1\\.1)?$\\;version:\\1?4.1+:", + "X-Powered-By": "\bTomcat\b(?:-([\\d.]+))?\\;version:\\1" + }, + "icon": "Apache Tomcat.svg", + "implies": "Java", + "website": "http://tomcat.apache.org" + }, + "Apache Traffic Server": { + "cats": [ + 22 + ], + "headers": { + "Server": "ATS/?([\\d.]+)?\\;version:\\1" + }, + "icon": "Apache Traffic Server.png", + "website": "http://trafficserver.apache.org/" + }, + "Apache Wicket": { + "cats": [ + 18 + ], + "js": { + "Wicket": "" + }, + "icon": "Apache Wicket.svg", + "implies": "Java", + "website": "http://wicket.apache.org" + }, + "ApexPages": { + "cats": [ + 51 + ], + "headers": { + "X-Powered-By": "Salesforce\\.com ApexPages" + }, + "icon": "ApexPages.png", + "implies": "Salesforce", + "website": "https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_intro.htm" + }, + "Apostrophe CMS": { + "cats": [ + 1 + ], + "html": "<[^>]+data-apos-refreshable[^>]", + "icon": "apostrophecms.svg", + "implies": "Node.js", + "website": "http://apostrophecms.org" + }, + "AppNexus": { + "cats": [ + 36 + ], + "html": "<(?:iframe|img)[^>]+adnxs\\.(?:net|com)", + "icon": "AppNexus.svg", + "script": "adnxs\\.(?:net|com)", + "website": "http://appnexus.com" + }, + "Arastta": { + "cats": [ + 6 + ], + "excludes": "OpenCart", + "headers": { + "Arastta": "(.*)\\;version:\\1", + "X-Arastta": "" + }, + "html": "Powered by <a [^>]*href=\"https?://(?:www\\.)?arastta\\.org[^>]+>Arastta", + "icon": "Arastta.svg", + "implies": "PHP", + "script": "arastta\\.js", + "website": "http://arastta.org" + }, + "Arc Forum": { + "cats": [ + 2 + ], + "html": "ping\\.src = node\\.href;\\s+[^>]+\\s+}\\s+</script>", + "icon": "Arc Forum.png", + "website": "http://arclanguage.org" + }, + "ArcGIS API for JavaScript": { + "cats": [ + 35 + ], + "script": [ + "js\\.arcgis\\.com", + "basemaps\\.arcgis\\.com" + ], + "icon": "arcgis_icon.png", + "website": "https://developers.arcgis.com/javascript/" + }, + "Artifactory": { + "cats": [ + 47 + ], + "js": { + "ArtifactoryUpdates": "" + }, + "html": [ + "<span class=\"version\">Artifactory(?: Pro)?(?: Power Pack)?(?: ([\\d.]+))?\\;version:\\1" + ], + "icon": "Artifactory.svg", + "script": [ + "wicket/resource/org\\.artifactory\\." + ], + "website": "http://jfrog.com/open-source/#os-arti" + }, + "Artifactory Web Server": { + "cats": [ + 22 + ], + "headers": { + "Server": "Artifactory(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "Artifactory.svg", + "implies": [ + "Artifactory" + ], + "website": "http://jfrog.com/open-source/#os-arti" + }, + "ArvanCloud": { + "cats": [ + 31 + ], + "js": { + "ArvanCloud": "" + }, + "headers": { + "AR-PoweredBy": "Arvan Cloud \\(arvancloud\\.com\\)" + }, + "icon": "ArvanCloud.png", + "website": "http://www.ArvanCloud.com" + }, + "AsciiDoc": { + "cats": [ + 1, + 20, + 27 + ], + "js": { + "asciidoc": "" + }, + "icon": "AsciiDoc.png", + "meta": { + "generator": "^AsciiDoc ([\\d.]+)\\;version:\\1" + }, + "website": "http://www.methods.co.nz/asciidoc" + }, + "Asciinema": { + "cats": [ + 14 + ], + "js": { + "asciinema": "" + }, + "script": "asciinema\\.org/", + "icon": "asciinema.png", + "html": "<asciinema-player", + "website": "https://asciinema.org/" + }, + "Atlassian Bitbucket": { + "cats": [ + 47 + ], + "js": { + "bitbucket": "" + }, + "icon": "Atlassian Bitbucket.svg", + "implies": "Python", + "html": "<li>Atlassian Bitbucket <span title=\"[a-z0-9]+\" id=\"product-version\" data-commitid=\"[a-z0-9]+\" data-system-build-number=\"[a-z0-9]+\"> v([\\d.]+)<\\;version:\\1", + "meta": { + "application-name": "Bitbucket" + }, + "website": "http://www.atlassian.com/software/bitbucket/overview/" + }, + "Atlassian Confluence": { + "cats": [ + 8 + ], + "headers": { + "X-Confluence-Request-Time": "" + }, + "html": "Powered by <a href=[^>]+atlassian\\.com/software/confluence(?:[^>]+>Atlassian Confluence</a> ([\\d.]+))?\\;version:\\1", + "icon": "Atlassian Confluence.svg", + "implies": "Java", + "meta": { + "confluence-request-time": "" + }, + "website": "http://www.atlassian.com/software/confluence/overview/team-collaboration-software" + }, + "Atlassian FishEye": { + "cats": [ + 47 + ], + "headers": { + "Set-cookie": "FESESSIONID" + }, + "html": "<title>(?:Log in to )?FishEye (?:and Crucible )?([\\d.]+)?\\;version:\\1", + "icon": "Atlassian FishEye.svg", + "website": "http://www.atlassian.com/software/fisheye/overview/" + }, + "Atlassian Jira": { + "cats": [ + 13 + ], + "js": { + "jira": "" + }, + "html": "Powered by\\s+]+atlassian\\.com/(?:software/jira|jira-bug-tracking/)[^>]+>Atlassian\\s+JIRA(?:[^v]*v(?:ersion: )?(\\d+\\.\\d+(?:\\.\\d+)?))?\\;version:\\1", + "icon": "Atlassian Jira.svg", + "implies": "Java", + "meta": { + "ajs-version-number": "([\\d\\.]+)\\;version:\\1", + "application-name": "JIRA" + }, + "website": "http://www.atlassian.com/software/jira/overview/" + }, + "Atlassian Jira Issue Collector": { + "cats": [ + 13, + 47 + ], + "icon": "Atlassian Jira.svg", + "script": [ + "jira-issue-collector-plugin", + "atlassian\\.jira\\.collector\\.plugin" + ], + "website": "http://www.atlassian.com/software/jira/overview/" + }, + "Aurelia": { + "cats": [ + 12 + ], + "html": [ + "<[^>]+aurelia-app=[^>]", + "<[^>]+data-main=[^>]aurelia-bootstrapper", + "<[^>]+au-target-id=[^>]\\d" + ], + "icon": "Aurelia.svg", + "script": [ + "aurelia(?:\\.min)?\\.js" + ], + "website": "http://aurelia.io" + }, + "Avangate": { + "cats": [ + 6 + ], + "js": { + "avng8_": "", + "__avng8_": "" + }, + "html": "]* href=\"^https?://edge\\.avangate\\.net/", + "icon": "Avangate.svg", + "script": "^https?://edge\\.avangate\\.net/", + "website": "http://avangate.com" + }, + "BEM": { + "cats": [ + 12 + ], + "html": "<[^>]+data-bem", + "icon": "BEM.png", + "website": "http://en.bem.info" + }, + "BIGACE": { + "cats": [ + 1 + ], + "html": "(?:Powered by ]+BIGACE|", + "icon": "Business Catalyst.png", + "script": "CatalystScripts", + "website": "http://businesscatalyst.com" + }, + "BuySellAds": { + "cats": [ + 36 + ], + "js": { + "_bsa": "", + "_bsap": "", + "_bsaPRO": "", + "_bsap_serving_callback": "" + }, + "html": "]*>[^<]+?bsa\\.src\\s*=\\s*['\"](?:https?:)?\\/{2}\\w\\d\\.buysellads\\.com\\/[\\w\\d\\/]+?bsa\\.js['\"]", + "icon": "BuySellAds.png", + "script": "^https?://s\\d\\.buysellads\\.com/", + "website": "http://buysellads.com" + }, + "C++": { + "cats": [ + 27 + ], + "icon": "C++.png", + "website": "http://isocpp.org" + }, + "CFML": { + "cats": [ + 27 + ], + "icon": "CFML.png", + "website": "http://adobe.com/products/coldfusion-family.html" + }, + "CKEditor": { + "cats": [ + 24 + ], + "js": { + "CKEDITOR": "", + "CKEDITOR.version": "(.*)\\;version:\\1" + }, + "icon": "CKEditor.png", + "website": "http://ckeditor.com" + }, + "CMS Made Simple": { + "cats": [ + 1 + ], + "headers": { + "Set-Cookie": "^CMSSESSID" + }, + "icon": "CMS Made Simple.png", + "implies": "PHP", + "meta": { + "generator": "CMS Made Simple" + }, + "website": "http://cmsmadesimple.org" + }, + "CMSimple": { + "cats": [ + 1 + ], + "implies": "PHP", + "meta": { + "generator": "CMSimple( [\\d.]+)?\\;version:\\1" + }, + "website": "http://www.cmsimple.org/en" + }, + "CO2Stats": { + "cats": [ + 10 + ], + "html": "src=[^>]+co2stats\\.com/propres\\.php", + "icon": "CO2Stats.png", + "website": "http://co2stats.com" + }, + "CPG Dragonfly": { + "cats": [ + 1 + ], + "headers": { + "X-Powered-By": "^Dragonfly CMS" + }, + "icon": "CPG Dragonfly.png", + "implies": "PHP", + "meta": { + "generator": "CPG Dragonfly" + }, + "website": "http://dragonflycms.org" + }, + "CS Cart": { + "cats": [ + 6 + ], + "js": { + "fn_compare_strings": "" + }, + "html": [ + " Powered by (?:]+cs-cart\\.com|CS-Cart)", + "\\.cm-noscript[^>]+" + ], + "icon": "CS Cart.png", + "implies": "PHP", + "website": "http://www.cs-cart.com" + }, + "CacheFly": { + "cats": [ + 31 + ], + "headers": { + "Server": "^CFS ", + "X-CF1": "", + "X-CF2": "" + }, + "icon": "CacheFly.png", + "website": "http://www.cachefly.com" + }, + "Caddy": { + "cats": [ + 22 + ], + "headers": { + "Server": "^Caddy$" + }, + "icon": "caddy.svg", + "implies": "Go", + "website": "http://caddyserver.com" + }, + "CakePHP": { + "cats": [ + 18 + ], + "headers": { + "Set-Cookie": "cakephp=" + }, + "icon": "CakePHP.png", + "implies": "PHP", + "meta": { + "application-name": "CakePHP" + }, + "website": "http://cakephp.org" + }, + "Canon": { + "cats": [ + 40 + ], + "icon": "Canon.png", + "website": "http://www.canon.com" + }, + "Canon HTTP Server": { + "cats": [ + 22 + ], + "headers": { + "Server": "CANON HTTP Server(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "Canon.png", + "implies": "Canon", + "website": "http://www.canon.com" + }, + "Captch Me": { + "cats": [ + 16, + 36 + ], + "js": { + "Captchme": "" + }, + "icon": "Captch Me.svg", + "script": "^https?://api\\.captchme\\.net/", + "website": "http://captchme.com" + }, + "Carbon Ads": { + "cats": [ + 36 + ], + "js": { + "_carbonads": "" + }, + "html": "<[a-z]+ [^>]*id=\"carbonads-container\"", + "icon": "Carbon Ads.png", + "script": "[^\\/]*\\/\\/(?:engine|srv)\\.carbonads\\.com\\/", + "website": "http://carbonads.net" + }, + "Cargo": { + "cats": [ + 1 + ], + "html": "]+Cargo feed", + "icon": "Cargo.png", + "implies": "PHP", + "meta": { + "cargo_title": "" + }, + "script": "/cargo\\.", + "website": "http://cargocollective.com" + }, + "Catberry.js": { + "cats": [ + 12, + 18 + ], + "js": { + "catberry": "", + "catberry.version": "(.*)\\;version:\\1" + }, + "headers": { + "X-Powered-By": "Catberry" + }, + "icon": "Catberry.js.png", + "implies": "Node.js", + "website": "http://catberry.org" + }, + "Catwalk": { + "cats": [ + 22 + ], + "headers": { + "Server": "Catwalk\\/?([\\d\\.]+)?\\;version:\\1" + }, + "icon": "Catwalk.png", + "implies": "Canon", + "website": "http://www.canon.com" + }, + "CentOS": { + "cats": [ + 28 + ], + "headers": { + "Server": "CentOS", + "X-Powered-By": "CentOS" + }, + "icon": "CentOS.png", + "website": "http://centos.org" + }, + "CenteHTTPd": { + "cats": [ + 22 + ], + "headers": { + "Server": "CenteHTTPd(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "CenteHTTPd.png", + "website": "http://cente.jp/cente/app/HTTPdc.html" + }, + "Chameleon": { + "cats": [ + 1 + ], + "icon": "Chameleon.png", + "implies": [ + "Apache", + "PHP" + ], + "meta": { + "generator": "chameleon-cms" + }, + "website": "http://chameleon-system.de" + }, + "Chamilo": { + "cats": [ + 21 + ], + "headers": { + "X-Powered-By": "Chamilo ([\\d.]+)\\;version:\\1" + }, + "html": "\">Chamilo ([\\d.]+)\\;version:\\1", + "icon": "Chamilo.png", + "implies": "PHP", + "meta": { + "generator": "Chamilo ([\\d.]+)\\;version:\\1" + }, + "website": "http://www.chamilo.org" + }, + "Chart.js": { + "cats": [ + 25 + ], + "js": { + "Chart": "\\;confidence:50", + "chart.ctx.bezierCurveTo": "" + }, + "icon": "Chart.js.svg", + "script": [ + "Chart(?:\\.bundle)?(?:\\.min)?\\.js\\;confidence:50", + "chartjs\\.org/dist/([\\d.]+(?:-[^/]+)?|master|latest)/Chart.*\\.js\\;version:\\1", + "cdnjs\\.cloudflare\\.com/ajax/libs/Chart\\.js/([\\d.]+(?:-[^/]+)?)/Chart.*\\.js\\;version:\\1", + "cdn\\.jsdelivr\\.net/npm/chart\\.js@([\\d.]+(?:-[^/]+)?|latest)/dist/Chart.*\\.js\\;version:\\1", + "cdn\\.jsdelivr\\.net/gh/chartjs/Chart\\.js@([\\d.]+(?:-[^/]+)?|latest)/dist/Chart.*\\.js\\;version:\\1" + ], + "website": "http://www.chartjs.org" + }, + "Chartbeat": { + "cats": [ + 10 + ], + "js": { + "_sf_endpt": "", + "_sf_async_config": "" + }, + "icon": "Chartbeat.png", + "script": "chartbeat\\.js", + "website": "http://chartbeat.com" + }, + "Cherokee": { + "cats": [ + 22 + ], + "headers": { + "Server": "Cherokee(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "Cherokee.png", + "website": "http://www.cherokee-project.com" + }, + "CherryPy": { + "cats": [ + 18, + 22 + ], + "headers": { + "Server": "CherryPy\\/?([\\d\\.]+)?\\;version:\\1" + }, + "icon": "CherryPy.png", + "implies": "Python", + "website": "http://www.cherrypy.org" + }, + "Chitika": { + "cats": [ + 36 + ], + "js": { + "ch_client": "", + "ch_color_site_link": "" + }, + "icon": "Chitika.png", + "script": "scripts\\.chitika\\.net/", + "website": "http://chitika.com" + }, + "Ckan": { + "cats": [ + 1 + ], + "headers": { + "Access-Control-Allow-Headers": "X-CKAN-API-KEY", + "Link": "; rel=shortlink" + }, + "icon": "Ckan.png", + "implies": [ + "Python", + "Solr", + "Java", + "PostgreSQL" + ], + "meta": { + "generator": ".*ckan.*" + }, + "website": "http://ckan.org/" + }, + "ClickHeat": { + "cats": [ + 10 + ], + "js": { + "clickHeatServer": "" + }, + "icon": "ClickHeat.png", + "implies": "PHP", + "script": "clickheat.*\\.js", + "website": "http://www.labsmedia.com/clickheat/index.html" + }, + "ClickTale": { + "cats": [ + 10 + ], + "js": { + "clickTaleStartEventSignal": "" + }, + "icon": "ClickTale.png", + "website": "http://www.clicktale.com" + }, + "Clicky": { + "cats": [ + 10 + ], + "js": { + "clicky": "" + }, + "icon": "Clicky.png", + "script": "static\\.getclicky\\.com", + "website": "http://getclicky.com" + }, + "Clientexec": { + "cats": [ + 6 + ], + "html": "clientexec\\.[^>]*\\s?=\\s?[^>]*;", + "icon": "Clientexec.png", + "website": "http://www.clientexec.com" + }, + "Clipboard.js": { + "cats": [ + 19 + ], + "icon": "Clipboard.js.svg", + "script": "clipboard(?:\\.min)?\\.js", + "website": "https://clipboardjs.com/" + }, + "CloudCart": { + "cats": [ + 6 + ], + "icon": "cloudcart.svg", + "meta": { + "author": "^CloudCart LLC$" + }, + "script": "/cloudcart-(?:assets|storage)/", + "website": "http://cloudcart.com" + }, + "Cloudcoins": { + "cats": [ + 56 + ], + "js": { + "CLOUDCOINS": "" + }, + "script": "https?://cdn\\.cloudcoins\\.co/javascript/cloudcoins\\.min\\.js", + "website": "https://cloudcoins.co" + }, + "CloudFlare": { + "cats": [ + 31 + ], + "js": { + "CloudFlare": "" + }, + "headers": { + "Server": "cloudflare" + }, + "icon": "CloudFlare.svg", + "website": "http://www.cloudflare.com" + }, + "Cloudera": { + "cats": [ + 34 + ], + "headers": { + "Server": "cloudera" + }, + "icon": "Cloudera.png", + "website": "http://www.cloudera.com" + }, + "CodeIgniter": { + "cats": [ + 18 + ], + "headers": { + "Set-Cookie": "(?:exp_last_activity|exp_tracker|ci_(?:session|(csrf_token)))\\;version:\\1?2+:" + }, + "html": "]+name=\"ci_csrf_token\"\\;version:2+", + "icon": "CodeIgniter.png", + "implies": "PHP", + "website": "http://codeigniter.com" + }, + "CodeMirror": { + "cats": [ + 19 + ], + "js": { + "CodeMirror": "", + "CodeMirror.version": "(.*)\\;version:\\1" + }, + "icon": "CodeMirror.png", + "website": "http://codemirror.net" + }, + "CoinHive": { + "cats": [ + 56 + ], + "js": { + "CoinHive": "" + }, + "script": "\\/(?:coinhive|(authedmine))(?:\\.min)?\\.js\\;version:\\1?opt-in:", + "url": "https?://cnhv\\.co/", + "icon": "CoinHive.svg", + "website": "https://coinhive.com" + }, + "CoinHive Captcha": { + "cats": [ + 16, + 56 + ], + "html": "(?:]+class=\"coinhive-captcha[^>]+data-key|]+data-key[^>]+class=\"coinhive-captcha)", + "script": "https?://authedmine\\.com/(?:lib/captcha|captcha)", + "icon": "CoinHive.svg", + "website": "https://coinhive.com" + }, + "Coinimp": { + "cats": [ + 56 + ], + "script": "https?://www\\.hashing\\.win/scripts/min\\.js", + "icon": "coinimp.png", + "website": "https://www.coinimp.com" + }, + "Coinlab": { + "cats": [ + 56 + ], + "js": { + "Coinlab": "" + }, + "script": "https?://coinlab\\.biz/lib/coinlab\\.js\\?id=", + "icon": "coinlab.png", + "website": "https://coinlab.biz/en" + }, + "Comandia": { + "cats": [ + 6 + ], + "js": { + "Comandia": "" + }, + "html": "]+=['\"]//cdn\\.mycomandia\\.com", + "icon": "Comandia.svg", + "website": "http://comandia.com" + }, + "Commerce Server": { + "cats": [ + 6 + ], + "headers": { + "COMMERCE-SERVER-SOFTWARE": "" + }, + "icon": "Commerce Server.png", + "implies": "Microsoft ASP.NET", + "website": "http://commerceserver.net" + }, + "CompaqHTTPServer": { + "cats": [ + 22 + ], + "headers": { + "Server": "CompaqHTTPServer\\/?([\\d\\.]+)?\\;version:\\1" + }, + "icon": "HP.svg", + "website": "http://www.hp.com" + }, + "Concrete5": { + "cats": [ + 1 + ], + "js": { + "CCM_IMAGE_PATH": "" + }, + "icon": "Concrete5.png", + "implies": "PHP", + "meta": { + "generator": "concrete5 - ([\\d.ab]+)\\;version:\\1" + }, + "script": "concrete/js/", + "website": "http://concrete5.org" + }, + "Connect": { + "cats": [ + 18 + ], + "headers": { + "X-Powered-By": "^Connect$" + }, + "icon": "Connect.png", + "implies": "Node.js", + "website": "http://www.senchalabs.org/connect" + }, + "Contao": { + "cats": [ + 1 + ], + "html": [ + "", + "]+(?:typolight|contao)\\.css" + ], + "icon": "Contao.png", + "implies": "PHP", + "meta": { + "generator": "^Contao Open Source CMS$" + }, + "website": "http://contao.org" + }, + "Contenido": { + "cats": [ + 1 + ], + "icon": "Contenido.png", + "implies": "PHP", + "meta": { + "generator": "Contenido ([\\d.]+)\\;version:\\1" + }, + "website": "http://contenido.org/en" + }, + "Contens": { + "cats": [ + 1 + ], + "icon": "Contens.png", + "implies": [ + "Java", + "CFML" + ], + "meta": { + "generator": "Contensis CMS Version ([\\d.]+)\\;version:\\1" + }, + "website": "http://www.contens.com/en/pub/index.cfm" + }, + "ContentBox": { + "cats": [ + 1, + 11 + ], + "icon": "ContentBox.png", + "implies": "Adobe ColdFusion", + "meta": { + "generator": "ContentBox powered by ColdBox" + }, + "website": "http://www.gocontentbox.org" + }, + "Contentful": { + "cats": [ + 1 + ], + "html": "<[^>]+(?:https?:)?//(?:assets|downloads|images|videos)\\.contentful\\.com", + "icon": "Contentful.svg", + "website": "http://www.contentful.com" + }, + "ConversionLab": { + "cats": [ + 10 + ], + "icon": "ConversionLab.png", + "script": "conversionlab\\.trackset\\.com/track/tsend\\.js", + "website": "http://www.trackset.it/conversionlab" + }, + "Coppermine": { + "cats": [ + 7 + ], + "html": "|" + ], + "icon": "Google Tag Manager.png", + "website": "http://www.google.com/tagmanager" + }, + "Google Wallet": { + "cats": [ + 41 + ], + "icon": "Google Wallet.png", + "script": [ + "checkout\\.google\\.com", + "wallet\\.google\\.com" + ], + "website": "http://wallet.google.com" + }, + "Google Web Server": { + "cats": [ + 22 + ], + "headers": { + "Server": "gws" + }, + "icon": "Google.svg", + "website": "http://en.wikipedia.org/wiki/Google_Web_Server" + }, + "Google Web Toolkit": { + "cats": [ + 18 + ], + "js": { + "__gwt_": "" + }, + "icon": "Google Web Toolkit.png", + "implies": "Java", + "meta": { + "gwt:property": "" + }, + "website": "http://developers.google.com/web-toolkit" + }, + "Graffiti CMS": { + "cats": [ + 1 + ], + "headers": { + "Set-Cookie": "graffitibot[^;]=" + }, + "icon": "Graffiti CMS.png", + "implies": "Microsoft ASP.NET", + "meta": { + "generator": "Graffiti CMS ([^\"]+)\\;version:\\1" + }, + "script": "/graffiti\\.js", + "website": "http://graffiticms.codeplex.com" + }, + "Grandstream": { + "cats": [ + 22, + 39 + ], + "headers": { + "Server": "Grandstream\\/?([\\d\\.]+)?\\;version:\\1" + }, + "icon": "Grandstream.png", + "website": "http://www.grandstream.com" + }, + "Grav": { + "cats": [ + 1 + ], + "icon": "Grav.png", + "implies": "PHP", + "meta": { + "generator": "GravCMS(?:\\s([\\d.]+))?\\;version:\\1" + }, + "website": "http://getgrav.org" + }, + "Gravatar": { + "cats": [ + 19 + ], + "js": { + "Gravatar": "" + }, + "html": "<[^>]+gravatar\\.com/avatar/", + "icon": "Gravatar.png", + "website": "http://gravatar.com" + }, + "Gravity Forms": { + "cats": [ + 19 + ], + "html": [ + "
]*gform_wrapper", + "
]*gform_body", + "
    ]*class=(?:\"|')[^>]*gform_fields", + "]*href=(?:\"|')[^>]*wp-content/plugins/gravityforms/css/" + ], + "script": "/wp-content/plugins/gravityforms/js/[^/]+\\.js\\?ver=([\\d.]+)$\\;version:\\1", + "icon": "gravityforms.svg", + "implies": "WordPress", + "website": "http://gravityforms.com" + }, + "Gravity Insights": { + "cats": [ + 10 + ], + "js": { + "gravityInsightsParams": "" + }, + "icon": "Gravity Insights.png", + "website": "http://insights.gravity.com" + }, + "Green Valley CMS": { + "cats": [ + 1 + ], + "html": "]+/dsresource\\?objectid=", + "icon": "Green Valley CMS.png", + "implies": "Apache Tomcat", + "meta": { + "DC.identifier": "/content\\.jsp\\?objectid=" + }, + "website": "http://www.greenvalley.nl/Public/Producten/Content_Management/CMS" + }, + "HERE": { + "cats": [ + 35 + ], + "icon": "HERE.png", + "script": "https?://js\\.cit\\.api\\.here\\.com/se/([\\d.]+)\\/\\;version:\\1", + "website": "http://developer.here.com" + }, + "HHVM": { + "cats": [ + 22 + ], + "headers": { + "X-Powered-By": "HHVM/?([\\d.]+)?\\;version:\\1" + }, + "icon": "HHVM.png", + "implies": "PHP\\;confidence:75", + "website": "http://hhvm.com" + }, + "HP": { + "cats": [ + 40 + ], + "icon": "HP.svg", + "website": "http://hp.com" + }, + "HP ChaiServer": { + "cats": [ + 22 + ], + "headers": { + "Server": "HP-Chai(?:Server|SOE)(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "HP.svg", + "implies": "HP", + "website": "http://hp.com" + }, + "HP Compact Server": { + "cats": [ + 22 + ], + "headers": { + "Server": "HP_Compact_Server(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "HP.svg", + "website": "http://hp.com" + }, + "HP ProCurve": { + "cats": [ + 37 + ], + "icon": "HP.svg", + "website": "http://hp.com/networking" + }, + "HP System Management": { + "cats": [ + 46 + ], + "headers": { + "Server": "HP System Management" + }, + "icon": "HP.svg", + "website": "http://hp.com" + }, + "HP iLO": { + "cats": [ + 22, + 46 + ], + "headers": { + "Server": "HP-iLO-Server(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "HP.svg", + "website": "http://hp.com" + }, + "HTTP Kit": { + "cats": [ + 22 + ], + "headers": { + "Server": "^http-kit" + }, + "implies": "Java", + "website": "http://http-kit.org" + }, + "HTTP-Server": { + "cats": [ + 22 + ], + "headers": { + "Server": "(?:^|[^-])\bHTTP-Server(?: ?/?V?([\\d.]+))?\\;version:\\1" + }, + "website": "http://example.com" + }, + "HTTP/2": { + "cats": [ + 19 + ], + "excludes": "SPDY", + "headers": { + "X-Firefox-Spdy": "h2" + }, + "icon": "http2.png", + "website": "http://http2.github.io" + }, + "Haddock": { + "cats": [ + 4 + ], + "html": "

    Produced by Haddock version ([0-9.]+)

    \\;version:\\1", + "script": "haddock-util\\.js", + "website": "http://www.haskell.org/haddock/" + }, + "Hammer.js": { + "cats": [ + 12 + ], + "js": { + "Hammer": "", + "Hammer.VERSION": "(.*)\\;version:\\1", + "Ha.VERSION": "(.*)\\;version:\\1" + }, + "icon": "Hammer.js.png", + "script": "hammer(?:\\.min)?\\.js", + "website": "https://hammerjs.github.io" + }, + "Handlebars": { + "cats": [ + 12 + ], + "js": { + "Handlebars": "", + "Handlebars.VERSION": "(.*)\\;version:\\1" + }, + "html": "<[^>]*type=[^>]text\\/x-handlebars-template", + "icon": "Handlebars.png", + "script": "handlebars(?:\\.runtime)?(?:-v([\\d.]+?))?(?:\\.min)?\\.js\\;version:\\1", + "website": "http://handlebarsjs.com" + }, + "Happy ICS Server": { + "cats": [ + 22 + ], + "headers": { + "Server": "Happy ICS Server(?:/([\\d.]+))?\\;version:\\1" + }, + "implies": "OmniTouch 8660 My Teamwork", + "website": "http://example.com" + }, + "Haravan": { + "cats": [ + 6 + ], + "js": { + "Haravan": "" + }, + "icon": "Haravan.png", + "script": "haravan.*\\.js", + "website": "https://www.haravan.com" + }, + "Haskell": { + "cats": [ + 27 + ], + "icon": "Haskell.png", + "website": "http://wiki.haskell.org/Haskell" + }, + "HeadJS": { + "cats": [ + 12 + ], + "js": { + "head.browser.name": "" + }, + "html": "<[^>]*data-headjs-load", + "icon": "HeadJS.png", + "script": "head\\.(?:core|load)(?:\\.min)?\\.js", + "website": "http://headjs.com" + }, + "Heap": { + "cats": [ + 10 + ], + "js": { + "heap": "" + }, + "icon": "Heap.png", + "script": "heap-\\d+\\.js", + "website": "http://heapanalytics.com" + }, + "Hello Bar": { + "cats": [ + 5 + ], + "js": { + "HelloBar": "" + }, + "icon": "Hello Bar.png", + "script": "hellobar\\.js", + "website": "http://hellobar.com" + }, + "Hexo": { + "cats": [ + 11 + ], + "icon": "Hexo.png", + "html": [ + "Powered by ]*>Hexo]*>Created with Highcharts ([\\d.]*)\\;version:\\1", + "icon": "Highcharts.png", + "script": "highcharts.*\\.js", + "website": "https://www.highcharts.com" + }, + "Highlight.js": { + "cats": [ + 19 + ], + "icon": "Highlight.js.png", + "script": "/highlight\\.js/[\\d.]+?/highlight\\.min\\.js", + "website": "https://highlightjs.org/" + }, + "Highstock": { + "cats": [ + 25 + ], + "html": "]*>Created with Highstock ([\\d.]*)\\;version:\\1", + "icon": "Highcharts.png", + "script": "highstock(?:\\-|\\.)?([\\d\\.]*\\d).*\\.js\\;version:\\1", + "website": "http://highcharts.com/products/highstock" + }, + "Hippo": { + "cats": [ + 1 + ], + "html": "<[^>]+/binaries/(?:[^/]+/)*content/gallery/", + "icon": "Hippo.png", + "website": "http://onehippo.org" + }, + "Hogan.js": { + "cats": [ + 12 + ], + "js": { + "Hogan": "" + }, + "icon": "Hogan.js.png", + "script": [ + "hogan-(?:-|\\.)([\\d.]*\\d)[^/]*\\.js\\;version:\\1", + "([\\d.]+)/hogan(?:\\.min)?\\.js\\;version:\\1" + ], + "website": "https://twitter.github.io/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 + ], + "headers": { + "Set-Cookie": "hotaru_mobile=" + }, + "icon": "Hotaru CMS.png", + "implies": "PHP", + "meta": { + "generator": "Hotaru CMS" + }, + "website": "http://hotarucms.org" + }, + "Hotjar": { + "cats": [ + 10 + ], + "js": { + "HotLeadfactory": "", + "HotleadController": "", + "hj.apiUrlBase": "" + }, + "icon": "Hotjar.png", + "script": "^//static\\.hotjar\\.com/c/hotjar-", + "website": "https://www.hotjar.com" + }, + "HubSpot": { + "cats": [ + 32 + ], + "js": { + "_hsq": "", + "hubspot": "" + }, + "html": "", + "icon": "InProces.png", + "script": "brein/inproces/website/websitefuncties\\.js", + "website": "http://www.brein.nl/oplossing/product/website" + }, + "Incapsula": { + "cats": [ + 31 + ], + "headers": { + "X-CDN": "Incapsula" + }, + "icon": "Incapsula.png", + "website": "http://www.incapsula.com" + }, + "Indexhibit": { + "cats": [ + 1 + ], + "html": "<(?:link|a href) [^>]+ndxz-studio", + "implies": [ + "PHP", + "Apache", + "Exhibit" + ], + "meta": { + "generator": "Indexhibit" + }, + "website": "http://www.indexhibit.org" + }, + "Indico": { + "cats": [ + 1 + ], + "headers": { + "Set-cookie": "MAKACSESSION" + }, + "html": "Powered by\\s+(?:CERN )?(?:CDS )?Indico( [\\d\\.]+)?\\;version:\\1", + "icon": "Indico.png", + "website": "http://indico-software.org" + }, + "Indy": { + "cats": [ + 22 + ], + "headers": { + "Server": "Indy(?:/([\\d.]+))?\\;version:\\1" + }, + "website": "http://indyproject.org" + }, + "InfernoJS": { + "cats": [ + 12 + ], + "js": { + "Inferno": "", + "Inferno.version": "(.*)\\;version:\\1" + }, + "icon": "InfernoJS.png", + "website": "https://infernojs.org" + }, + "Infusionsoft": { + "cats": [ + 32 + ], + "html": [ + "]*name=\"infusionsoft_version\" [^>]*value=\"([^>]*)\" [^>]*\\/>\\;version:\\1", + "]*value=\"([^>]*)\" [^>]*name=\"infusionsoft_version\" [^>]*\\/>\\;version:\\1" + ], + "icon": "infusionsoft.svg", + "website": "http://infusionsoft.com" + }, + "InstantCMS": { + "cats": [ + 1 + ], + "headers": { + "Set-Cookie": "InstantCMS\\[logdate\\]=" + }, + "icon": "InstantCMS.png", + "implies": "PHP", + "meta": { + "generator": "InstantCMS" + }, + "website": "http://www.instantcms.ru" + }, + "Intel Active Management Technology": { + "cats": [ + 22, + 46 + ], + "headers": { + "Server": "Intel\\(R\\) Active Management Technology(?: ([\\d.]+))?\\;version:\\1" + }, + "icon": "Intel Active Management Technology.png", + "website": "http://intel.com" + }, + "IntenseDebate": { + "cats": [ + 15 + ], + "icon": "IntenseDebate.png", + "script": "intensedebate\\.com", + "website": "http://intensedebate.com" + }, + "Intercom": { + "cats": [ + 10 + ], + "js": { + "Intercom": "" + }, + "icon": "Intercom.png", + "script": "(?:api\\.intercom\\.io/api|static\\.intercomcdn\\.com/intercom\\.v1)", + "website": "https://www.intercom.com" + }, + "Intershop": { + "cats": [ + 6 + ], + "icon": "Intershop.png", + "script": "(?:is-bin|INTERSHOP)", + "website": "http://intershop.com" + }, + "Invenio": { + "cats": [ + 50 + ], + "headers": { + "Set-cookie": "INVENIOSESSION" + }, + "html": "(?:Powered by|System)\\s+(?:CERN )?(?:CDS )?Invenio\\s*v?([\\d\\.]+)?\\;version:\\1", + "icon": "Invenio.png", + "website": "http://invenio-software.org" + }, + "Inwemo": { + "cats": [ + 56 + ], + "js": { + "Inwemo": "" + }, + "script": "https?://cdn\\.inwemo\\.com/inwemo\\.min\\.js", + "icon": "inwemo.png", + "website": "https://inwemo.com/" + }, + "Ionicons": { + "cats": [ + 17 + ], + "html": "]* href=[^>]+ionicons(?:\\.min)?\\.css", + "icon": "Ionicons.png", + "website": "http://ionicons.com" + }, + "JAlbum": { + "cats": [ + 7 + ], + "icon": "JAlbum.png", + "implies": "Java", + "meta": { + "generator": "JAlbum( [\\d.]+)?\\;version:\\1" + }, + "website": "http://jalbum.net/en" + }, + "JBoss Application Server": { + "cats": [ + 22 + ], + "headers": { + "X-Powered-By": "JBoss(?:-([\\d.]+))?\\;version:\\1" + }, + "icon": "JBoss Application Server.png", + "website": "http://jboss.org/jbossas.html" + }, + "JBoss Web": { + "cats": [ + 22 + ], + "excludes": "Apache Tomcat", + "headers": { + "X-Powered-By": "JBossWeb(?:-([\\d.]+))?\\;version:\\1" + }, + "icon": "JBoss Web.png", + "implies": "JBoss Application Server", + "website": "http://jboss.org/jbossweb" + }, + "JC-HTTPD": { + "cats": [ + 22 + ], + "excludes": "Apache", + "headers": { + "Server": "JC-HTTPD(?:/([\\d.]+))?\\;version:\\1" + }, + "icon": "JC-HTTPD.png", + "implies": "Canon", + "website": "http://canon.com" + }, + "JET Enterprise": { + "cats": [ + 6 + ], + "headers": { + "powered": "jet-enterprise" + }, + "icon": "JET Enterprise.svg", + "website": "http://www.jetecommerce.com.br/" + }, + "JS Charts": { + "cats": [ + 25 + ], + "js": { + "JSChart": "" + }, + "icon": "JS Charts.png", + "script": "jscharts.*\\.js", + "website": "http://www.jscharts.com" + }, + "JTL Shop": { + "cats": [ + 6 + ], + "headers": { + "Set-Cookie": "JTLSHOP=" + }, + "html": "(?:]+name=\"JTLSHOP|]*>Jekyll]+id=\"wrapper_r\"|<[^>]+(?:feed|components)/com_|]+class=\"pill)\\;confidence:50", + "icon": "Joomla.svg", + "implies": "PHP", + "meta": { + "generator": "Joomla!(?: ([\\d.]+))?\\;version:\\1" + }, + "url": "option=com_", + "website": "https://www.joomla.org" + }, + "JSEcoin": { + "cats": [ + 56 + ], + "js": { + "jseMine": "" + }, + "script": "^(?:https):?//load\\.jsecoin\\.com/server/load/", + "icon": "JSEcoin.png", + "website": "https://jsecoin.com/" + }, + "K2": { + "cats": [ + 19 + ], + "js": { + "K2RatingURL": "" + }, + "html": "", + "icon": "Lightspeed.svg", + "script": "http://assets\\.webshopapp\\.com", + "url": "seoshop.webshopapp.com", + "website": "http://www.lightspeedhq.com/products/ecommerce/" + }, + "Lighty": { + "cats": [ + 18 + ], + "headers": { + "Set-Cookie": "lighty_version" + }, + "icon": "Lighty.png", + "implies": "PHP", + "website": "http://gitlab.com/lighty/framework" + }, + "LimeSurvey": { + "cats": [ + 19 + ], + "headers": { + "generator": "LimeSurvey" + }, + "icon": "LimeSurvey.png", + "website": "http://limesurvey.org/" + }, + "LinkSmart": { + "cats": [ + 36 + ], + "js": { + "_mb_site_guid": "", + "LS_JSON": "", + "LinkSmart": "" + }, + "icon": "LinkSmart.png", + "script": "^https?://cdn\\.linksmart\\.com/linksmart_([\\d.]+?)(?:\\.min)?\\.js\\;version:\\1", + "website": "http://linksmart.com" + }, + "Linkedin": { + "cats": [ + 5 + ], + "icon": "Linkedin.svg", + "script": "//platform\\.linkedin\\.com/in\\.js", + "website": "http://linkedin.com" + }, + "List.js": { + "cats": [ + 12 + ], + "js": { + "List": "" + }, + "icon": "List.js.png", + "script": "^list\\.(?:min\\.)?js$", + "website": "http://listjs.com" + }, + "LiteSpeed": { + "cats": [ + 22 + ], + "headers": { + "Server": "^LiteSpeed$" + }, + "icon": "LiteSpeed.svg", + "website": "http://litespeedtech.com" + }, + "Lithium": { + "cats": [ + 1 + ], + "js": { + "LITHIUM": "" + }, + "headers": { + "Set-Cookie": "LithiumVisitor=" + }, + "html": " ]+Powered by Lithium", + "icon": "Lithium.png", + "implies": "PHP", + "website": "https://www.lithium.com" + }, + "LiveAgent": { + "cats": [ + 52 + ], + "js": { + "LiveAgent": "" + }, + "icon": "LiveAgent.png", + "website": "https://www.ladesk.com" + }, + "LiveChat": { + "cats": [ + 52 + ], + "icon": "LiveChat.png", + "script": "cdn\\.livechatinc\\.com/.*tracking\\.js", + "website": "http://livechatinc.com" + }, + "LiveJournal": { + "cats": [ + 11 + ], + "icon": "LiveJournal.png", + "url": "\\.livejournal\\.com", + "website": "http://www.livejournal.com" + }, + "LivePerson": { + "cats": [ + 52 + ], + "icon": "LivePerson.png", + "script": "^https?://lptag\\.liveperson\\.net/tag/tag\\.js", + "website": "https://www.liveperson.com/" + }, + "LiveStreet CMS": { + "cats": [ + 1 + ], + "js": { + "LIVESTREET_SECURITY_KEY": "" + }, + "headers": { + "X-Powered-By": "LiveStreet CMS" + }, + "icon": "LiveStreet CMS.png", + "implies": "PHP", + "website": "http://livestreetcms.com" + }, + "Livefyre": { + "cats": [ + 15 + ], + "js": { + "fyre": "", + "FyreLoader": "", + "LF.CommentCount": "", + "L.version": "(.*)\\;confidence:0\\;version:\\1" + }, + "html": "<[^>]+(?:id|class)=\"livefyre", + "icon": "Livefyre.png", + "script": "livefyre_init\\.js", + "website": "http://livefyre.com" + }, + "Liveinternet": { + "cats": [ + 10 + ], + "html": [ + "]*>[^]{0,128}?src\\s*=\\s*['\"]//counter\\.yadro\\.ru/hit(?:;\\S+)?\\?(?:t\\d+\\.\\d+;)?r", + "", + "", + "]*/sites/[a-z\\d]{24}/theme/stylesheets", + "icon": "Locomotive.png", + "implies": [ + "Ruby on Rails", + "MongoDB" + ], + "website": "http://www.locomotivecms.com" + }, + "Logitech Media Server": { + "cats": [ + 22, + 38 + ], + "headers": { + "Server": "Logitech Media Server(?: \\(([\\d\\.]+))?\\;version:\\1" + }, + "icon": "Logitech Media Server.png", + "website": "http://www.mysqueezebox.com" + }, + "Lotus Domino": { + "cats": [ + 22 + ], + "headers": { + "Server": "Lotus-Domino" + }, + "icon": "Lotus Domino.png", + "implies": "Java", + "website": "http://www-01.ibm.com/software/lotus/products/domino" + }, + "Lua": { + "cats": [ + 27 + ], + "headers": { + "X-Powered-By": "\bLua(?: ([\\d.]+))?\\;version:\\1" + }, + "icon": "Lua.png", + "website": "http://www.lua.org" + }, + "Lucene": { + "cats": [ + 34 + ], + "icon": "Lucene.png", + "implies": "Java", + "website": "http://lucene.apache.org/core/" + }, + "Luigi’s Box": { + "cats": [ + 10, + 29 + ], + "js": { + "Luigis": "" + }, + "icon": "Luigisbox.svg", + "website": "https://www.luigisbox.com" + }, + "M.R. Inc BoxyOS": { + "cats": [ + 28 + ], + "icon": "M.R. Inc.png", + "website": "http://mrincworld.com" + }, + "M.R. Inc SiteFrame": { + "cats": [ + 18 + ], + "headers": { + "Powered-By": "M\\.R\\. Inc SiteFrame" + }, + "icon": "M.R. Inc.png", + "website": "http://mrincworld.com" + }, + "M.R. Inc Webserver": { + "cats": [ + 22 + ], + "headers": { + "Server": "M\\.R\\. Inc Webserver" + }, + "icon": "M.R. Inc.png", + "implies": [ + "M.R. Inc BoxyOS" + ], + "website": "http://mrincworld.com" + }, + "MHonArc": { + "cats": [ + 50 + ], + "html": "\\;version:\\1", + "icon": "mhonarc.png", + "website": "http://www.mhonarc.at" + }, + "MOBOTIX": { + "cats": [ + 39 + ], + "icon": "MOBOTIX.png", + "meta": { + "author": "MOBOTIX AG\\;confidence:40", + "copyright": "MOBOTIX AG\\;confidence:40", + "publisher": "MOBOTIX AG\\;confidence:40" + }, + "url": "control/userimage\\.html\\;confidence:70", + "website": "http://mobotix.com" + }, + "MODX": { + "cats": [ + 1 + ], + "js": { + "MODX": "", + "MODX_MEDIA_PATH": "" + }, + "headers": { + "Set-Cookie": "SN5[a-f\\d]{12}", + "X-Powered-By": "^MODX" + }, + "html": [ + "]+>Powered by MODX", + "<(?:link|script)[^>]+assets/snippets/\\;confidence:20", + "]+id=\"ajaxSearch_form\\;confidence:20", + "]+id=\"ajaxSearch_input\\;confidence:20" + ], + "icon": "MODX.png", + "implies": "PHP", + "meta": { + "generator": "MODX[^\\d.]*([\\d.]+)?\\;version:\\1" + }, + "website": "http://modx.com" + }, + "MadAdsMedia": { + "cats": [ + 36 + ], + "js": { + "setMIframe": "", + "setMRefURL": "" + }, + "icon": "MadAdsMedia.png", + "script": "^https?://(?:ads-by|pixel)\\.madadsmedia\\.com/", + "website": "http://madadsmedia.com" + }, + "Magento": { + "cats": [ + 6 + ], + "js": { + "Mage": "", + "VarienForm": "" + }, + "headers": { + "Set-Cookie": "frontend=\\;confidence:50" + }, + "html": [ + "", - "icon": "Arc Forum.png", - "website": "http://arclanguage.org" - }, - "ArcGIS API for JavaScript":{ - "cats": [ - "35" - ], - "script": [ - "js\\.arcgis\\.com", - "basemaps\\.arcgis\\.com" - ], - "icon": "arcgis_icon.png", - "website": "https://developers.arcgis.com/javascript/" - }, - "Artifactory": { - "cats": [ - "47" - ], - "env": "^ArtifactoryUpdates$", - "html": [ - "Artifactory(?: Pro)?(?: Power Pack)?(?: ([\\d.]+))?\\;version:\\1" - ], - "icon": "Artifactory.svg", - "script": [ - "wicket/resource/org\\.artifactory\\." - ], - "website": "http://jfrog.com/open-source/#os-arti" - }, - "Artifactory Web Server": { - "cats": [ - "22" - ], - "headers": { - "Server": "Artifactory(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "Artifactory.svg", - "implies": [ - "Artifactory" - ], - "website": "http://jfrog.com/open-source/#os-arti" - }, - "ArvanCloud": { - "cats": [ - "31" - ], - "env": "^ArvanCloud$", - "headers": { - "AR-PoweredBy": "Arvan Cloud \\(arvancloud\\.com\\)" - }, - "icon": "ArvanCloud.png", - "website": "http://www.ArvanCloud.com" - }, - "AsciiDoc": { - "cats": [ - "1", - "20", - "27" - ], - "env": "^asciidoc$", - "icon": "AsciiDoc.png", - "meta": { - "generator": "^AsciiDoc ([\\d.]+)\\;version:\\1" - }, - "website": "http://www.methods.co.nz/asciidoc" - }, - "Atlassian Bitbucket": { - "cats": [ - "47" - ], - "env": "^bitbucket$", - "icon": "Atlassian Bitbucket.svg", - "implies": "Python", - "html": "
  • Atlassian Bitbucket v([\\d.]+)<\\;version:\\1", - "meta": { - "application-name": "Bitbucket" - }, - "website": "http://www.atlassian.com/software/bitbucket/overview/" - }, - "Atlassian Confluence": { - "cats": [ - "8" - ], - "headers": { - "X-Confluence-Request-Time": "" - }, - "html": "Powered by ]+atlassian\\.com/software/confluence(?:[^>]+>Atlassian Confluence ([\\d.]+))?\\;version:\\1", - "icon": "Atlassian Confluence.svg", - "implies": "Java", - "meta": { - "confluence-request-time": "" - }, - "website": "http://www.atlassian.com/software/confluence/overview/team-collaboration-software" - }, - "Atlassian FishEye": { - "cats": [ - "47" - ], - "headers": { - "Set-cookie": "FESESSIONID" - }, - "html": "(?:Log in to )?FishEye (?:and Crucible )?([\\d.]+)?\\;version:\\1", - "icon": "Atlassian FishEye.svg", - "website": "http://www.atlassian.com/software/fisheye/overview/" - }, - "Atlassian Jira": { - "cats": [ - "13" - ], - "env": "^jira$", - "html": "Powered by\\s+]+atlassian\\.com/(?:software/jira|jira-bug-tracking/)[^>]+>Atlassian\\s+JIRA(?:[^v]*v(?:ersion: )?(\\d+\\.\\d+(?:\\.\\d+)?))?\\;version:\\1", - "icon": "Atlassian Jira.svg", - "implies": "Java", - "meta": { - "ajs-version-number": "([\\d\\.]+)\\;version:\\1", - "application-name": "JIRA" - }, - "website": "http://www.atlassian.com/software/jira/overview/" - }, - "Atlassian Jira Issue Collector": { - "cats": [ - "13", - "47" - ], - "icon": "Atlassian Jira.svg", - "script": [ - "jira-issue-collector-plugin", - "atlassian\\.jira\\.collector\\.plugin" - ], - "website": "http://www.atlassian.com/software/jira/overview/" - }, - "Aurelia": { - "cats": [ - "12" - ], - "html": [ - "<[^>]+aurelia-app=[^>]", - "<[^>]+data-main=[^>]aurelia-bootstrapper", - "<[^>]+au-target-id=[^>]\\d" - ], - "icon": "Aurelia.svg", - "script": [ - "aurelia(?:\\.min)?\\.js" - ], - "website": "http://aurelia.io" - }, - "Avangate": { - "cats": [ - "6" - ], - "env": "^(?:__)?avng8_", - "html": "]* href=\"^https?://edge\\.avangate\\.net/", - "icon": "Avangate.svg", - "script": "^https?://edge\\.avangate\\.net/", - "website": "http://avangate.com" - }, - "BEM": { - "cats": [ - "12" - ], - "html": "<[^>]+data-bem", - "icon": "BEM.png", - "website": "http://en.bem.info" - }, - "BIGACE": { - "cats": [ - "1" - ], - "html": "(?:Powered by ]+BIGACE|", - "icon": "Business Catalyst.png", - "script": "CatalystScripts", - "website": "http://businesscatalyst.com" - }, - "BuySellAds": { - "cats": [ - "36" - ], - "env": "^_bsa", - "html": "]*>[^<]+?bsa\\.src\\s*=\\s*['\"](?:https?:)?\\/{2}\\w\\d\\.buysellads\\.com\\/[\\w\\d\\/]+?bsa\\.js['\"]", - "icon": "BuySellAds.png", - "script": "^https?://s\\d\\.buysellads\\.com/", - "website": "http://buysellads.com" - }, - "C++": { - "cats": [ - "27" - ], - "icon": "C++.png", - "website": "http://isocpp.org" - }, - "CFML": { - "cats": [ - "27" - ], - "icon": "CFML.png", - "website": "http://adobe.com/products/coldfusion-family.html" - }, - "CKEditor": { - "cats": [ - "24" - ], - "env": "^CKEDITOR$", - "icon": "CKEditor.png", - "website": "http://ckeditor.com" - }, - "CMS Made Simple": { - "cats": [ - "1" - ], - "headers": { - "Set-Cookie": "^CMSSESSID" - }, - "icon": "CMS Made Simple.png", - "implies": "PHP", - "meta": { - "generator": "CMS Made Simple" - }, - "website": "http://cmsmadesimple.org" - }, - "CMSimple": { - "cats": [ - "1" - ], - "implies": "PHP", - "meta": { - "generator": "CMSimple( [\\d.]+)?\\;version:\\1" - }, - "website": "http://www.cmsimple.org/en" - }, - "CO2Stats": { - "cats": [ - "10" - ], - "html": "src=[^>]+co2stats\\.com/propres\\.php", - "icon": "CO2Stats.png", - "website": "http://co2stats.com" - }, - "CPG Dragonfly": { - "cats": [ - "1" - ], - "headers": { - "X-Powered-By": "^Dragonfly CMS" - }, - "icon": "CPG Dragonfly.png", - "implies": "PHP", - "meta": { - "generator": "CPG Dragonfly" - }, - "website": "http://dragonflycms.org" - }, - "CS Cart": { - "cats": [ - "6" - ], - "env": "^fn_compare_strings$", - "html": [ - " Powered by (?:]+cs-cart\\.com|CS-Cart)", - "\\.cm-noscript[^>]+" - ], - "icon": "CS Cart.png", - "implies": "PHP", - "website": "http://www.cs-cart.com" - }, - "CacheFly": { - "cats": [ - "31" - ], - "headers": { - "Server": "^CFS ", - "X-CF1": "", - "X-CF2": "" - }, - "icon": "CacheFly.png", - "website": "http://www.cachefly.com" - }, - "Caddy": { - "cats": [ - "22" - ], - "headers": { - "Server": "^Caddy$" - }, - "icon": "caddy.svg", - "implies": "Go", - "website": "http://caddyserver.com" - }, - "CakePHP": { - "cats": [ - "18" - ], - "headers": { - "Set-Cookie": "cakephp=" - }, - "icon": "CakePHP.png", - "implies": "PHP", - "meta": { - "application-name": "CakePHP" - }, - "website": "http://cakephp.org" - }, - "Canon": { - "cats": [ - "40" - ], - "icon": "Canon.png", - "website": "http://www.canon.com" - }, - "Canon HTTP Server": { - "cats": [ - "22" - ], - "headers": { - "Server": "CANON HTTP Server(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "Canon.png", - "implies": "Canon", - "website": "http://www.canon.com" - }, - "Captch Me": { - "cats": [ - "16", - "36" - ], - "env": "^Captchme", - "icon": "Captch Me.svg", - "script": "^https?://api\\.captchme\\.net/", - "website": "http://captchme.com" - }, - "Carbon Ads": { - "cats": [ - "36" - ], - "env": "^_carbonads", - "html": "<[a-z]+ [^>]*id=\"carbonads-container\"", - "icon": "Carbon Ads.png", - "script": "[^\\/]*\\/\\/(?:engine|srv)\\.carbonads\\.com\\/", - "website": "http://carbonads.net" - }, - "Cargo": { - "cats": [ - "1" - ], - "html": "]+Cargo feed", - "icon": "Cargo.png", - "implies": "PHP", - "meta": { - "cargo_title": "" - }, - "script": "/cargo\\.", - "website": "http://cargocollective.com" - }, - "Catberry.js": { - "cats": [ - "12", - "18" - ], - "env": "^catberry$", - "headers": { - "X-Powered-By": "Catberry" - }, - "icon": "Catberry.js.png", - "implies": "Node.js", - "website": "http://catberry.org" - }, - "Catwalk": { - "cats": [ - "22" - ], - "headers": { - "Server": "Catwalk\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "Catwalk.png", - "implies": "Canon", - "website": "http://www.canon.com" - }, - "CentOS": { - "cats": [ - "28" - ], - "headers": { - "Server": "CentOS", - "X-Powered-By": "CentOS" - }, - "icon": "CentOS.png", - "website": "http://centos.org" - }, - "CenteHTTPd": { - "cats": [ - "22" - ], - "headers": { - "Server": "CenteHTTPd(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "CenteHTTPd.png", - "website": "http://cente.jp/cente/app/HTTPdc.html" - }, - "Chameleon": { - "cats": [ - "1" - ], - "icon": "Chameleon.png", - "implies": [ - "Apache", - "PHP" - ], - "meta": { - "generator": "chameleon-cms" - }, - "website": "http://chameleon-system.de" - }, - "Chamilo": { - "cats": [ - "21" - ], - "headers": { - "X-Powered-By": "Chamilo ([\\d.]+)\\;version:\\1" - }, - "html": "\">Chamilo ([\\d.]+)\\;version:\\1", - "icon": "Chamilo.png", - "implies": "PHP", - "meta": { - "generator": "Chamilo ([\\d.]+)\\;version:\\1" - }, - "website": "http://www.chamilo.org" - }, - "Chart.js": { - "cats": [ - "25" - ], - "env": "^Chart$\\;confidence:50", - "icon": "Chart.js.svg", - "script": [ - "Chart(?:\\.bundle)?(?:\\.min)?\\.js\\;confidence:50", - "chartjs\\.org/dist/([\\d.]+(?:-[^/]+)?|master|latest)/Chart.*\\.js\\;version:\\1", - "cdnjs\\.cloudflare\\.com/ajax/libs/Chart\\.js/([\\d.]+(?:-[^/]+)?)/Chart.*\\.js\\;version:\\1", - "cdn\\.jsdelivr\\.net/npm/chart\\.js@([\\d.]+(?:-[^/]+)?|latest)/dist/Chart.*\\.js\\;version:\\1", - "cdn\\.jsdelivr\\.net/gh/chartjs/Chart\\.js@([\\d.]+(?:-[^/]+)?|latest)/dist/Chart.*\\.js\\;version:\\1" - ], - "website": "http://www.chartjs.org" - }, - "Chartbeat": { - "cats": [ - "10" - ], - "env": "^_sf_(?:endpt|async_config)$", - "icon": "Chartbeat.png", - "script": "chartbeat\\.js", - "website": "http://chartbeat.com" - }, - "Cherokee": { - "cats": [ - "22" - ], - "headers": { - "Server": "Cherokee(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "Cherokee.png", - "website": "http://www.cherokee-project.com" - }, - "CherryPy": { - "cats": [ - "18", - "22" - ], - "headers": { - "Server": "CherryPy\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "CherryPy.png", - "implies": "Python", - "website": "http://www.cherrypy.org" - }, - "Chitika": { - "cats": [ - "36" - ], - "env": "ch_c(?:lient|olor_site_link)", - "icon": "Chitika.png", - "script": "scripts\\.chitika\\.net/", - "website": "http://chitika.com" - }, - "Ckan": { - "cats": [ - "1" - ], - "headers": { - "Access-Control-Allow-Headers": "X-CKAN-API-KEY", - "Link": "; rel=shortlink" - }, - "icon": "Ckan.png", - "implies": [ - "Python", - "Solr", - "Java", - "PostgreSQL" - ], - "meta": { - "generator": ".*ckan.*" - }, - "website": "http://ckan.org/" - }, - "ClickHeat": { - "cats": [ - "10" - ], - "env": "^clickHeat", - "icon": "ClickHeat.png", - "implies": "PHP", - "script": "clickheat.*\\.js", - "website": "http://www.labsmedia.com/clickheat/index.html" - }, - "ClickTale": { - "cats": [ - "10" - ], - "env": "^ClickTale", - "icon": "ClickTale.png", - "website": "http://www.clicktale.com" - }, - "Clicky": { - "cats": [ - "10" - ], - "env": "^clicky$", - "icon": "Clicky.png", - "script": "static\\.getclicky\\.com", - "website": "http://getclicky.com" - }, - "Clientexec": { - "cats": [ - "6" - ], - "html": "clientexec\\.[^>]*\\s?=\\s?[^>]*;", - "icon": "Clientexec.png", - "website": "http://www.clientexec.com" - }, - "Clipboard.js": { - "cats": [ - "19" - ], - "env": "^Clipboard$", - "icon": "Clipboard.js.svg", - "script": "clipboard(?:\\.min)?\\.js", - "website": "https://clipboardjs.com/" - }, - "CloudCart": { - "cats": [ - "6" - ], - "icon": "cloudcart.svg", - "meta": { - "author": "^CloudCart LLC$" - }, - "script": "/cloudcart-(?:assets|storage)/", - "website": "http://cloudcart.com" - }, - "CloudFlare": { - "cats": [ - "31" - ], - "env": "^CloudFlare$", - "headers": { - "Server": "cloudflare" - }, - "icon": "CloudFlare.svg", - "website": "http://www.cloudflare.com" - }, - "Cloudera": { - "cats": [ - "34" - ], - "headers": { - "Server": "cloudera" - }, - "icon": "Cloudera.png", - "website": "http://www.cloudera.com" - }, - "CodeIgniter": { - "cats": [ - "18" - ], - "headers": { - "Set-Cookie": "(?:exp_last_activity|exp_tracker|ci_(?:session|(csrf_token)))\\;version:\\1?2+:" - }, - "html": "]+name=\"ci_csrf_token\"\\;version:2+", - "icon": "CodeIgniter.png", - "implies": "PHP", - "website": "http://codeigniter.com" - }, - "CodeMirror": { - "cats": [ - "19" - ], - "env": "^CodeMirror$", - "icon": "CodeMirror.png", - "website": "http://codemirror.net" - }, - "CoinHive": { - "cats": [ - "19" - ], - "env": "^CoinHive$", - "script": "\\/(?:coinhive|(authedmine))(?:\\.min)?\\.js\\;version:\\1?opt-in:", - "url": "https?://cnhv.co/", - "icon": "CoinHive.svg", - "website": "https://coinhive.com" - }, - "CoinHive Captcha": { - "cats": [ - "16" - ], - "html": "(?:]+class=\"coinhive-captcha[^>]+data-key|]+data-key[^>]+class=\"coinhive-captcha)", - "script": "https?://authedmine\\.com/(?:lib/captcha|captcha)", - "icon": "CoinHive.svg", - "website": "https://coinhive.com" - }, - "Comandia": { - "cats": [ - "6" - ], - "env": "^Comandia$", - "html": "]+=['\"]//cdn\\.mycomandia\\.com", - "icon": "Comandia.svg", - "website": "http://comandia.com" - }, - "Commerce Server": { - "cats": [ - "6" - ], - "headers": { - "COMMERCE-SERVER-SOFTWARE": "" - }, - "icon": "Commerce Server.png", - "implies": "Microsoft ASP.NET", - "website": "http://commerceserver.net" - }, - "CompaqHTTPServer": { - "cats": [ - "22" - ], - "headers": { - "Server": "CompaqHTTPServer\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "HP.svg", - "website": "http://www.hp.com" - }, - "Concrete5": { - "cats": [ - "1" - ], - "env": "^CCM_IMAGE_PATH$", - "icon": "Concrete5.png", - "implies": "PHP", - "meta": { - "generator": "concrete5 - ([\\d.ab]+)\\;version:\\1" - }, - "script": "concrete/js/", - "website": "http://concrete5.org" - }, - "Connect": { - "cats": [ - "18" - ], - "headers": { - "X-Powered-By": "^Connect$" - }, - "icon": "Connect.png", - "implies": "Node.js", - "website": "http://www.senchalabs.org/connect" - }, - "Contao": { - "cats": [ - "1" - ], - "html": [ - "", - "]+(?:typolight|contao)\\.css" - ], - "icon": "Contao.png", - "implies": "PHP", - "meta": { - "generator": "^Contao Open Source CMS$" - }, - "website": "http://contao.org" - }, - "Contenido": { - "cats": [ - "1" - ], - "icon": "Contenido.png", - "implies": "PHP", - "meta": { - "generator": "Contenido ([\\d.]+)\\;version:\\1" - }, - "website": "http://contenido.org/en" - }, - "Contens": { - "cats": [ - "1" - ], - "icon": "Contens.png", - "implies": [ - "Java", - "CFML" - ], - "meta": { - "generator": "Contensis CMS Version ([\\d.]+)\\;version:\\1" - }, - "website": "http://www.contens.com/en/pub/index.cfm" - }, - "ContentBox": { - "cats": [ - "1", - "11" - ], - "icon": "ContentBox.png", - "implies": "Adobe ColdFusion", - "meta": { - "generator": "ContentBox powered by ColdBox" - }, - "website": "http://www.gocontentbox.org" - }, - "Contentful": { - "cats": [ - "1" - ], - "html": "<[^>]+(?:https?:)?//(?:assets|downloads|images|videos)\\.contentful\\.com", - "icon": "Contentful.svg", - "website": "http://www.contentful.com" - }, - "ConversionLab": { - "cats": [ - "10" - ], - "icon": "ConversionLab.png", - "script": "conversionlab\\.trackset\\.com/track/tsend\\.js", - "website": "http://www.trackset.it/conversionlab" - }, - "Coppermine": { - "cats": [ - "7" - ], - "html": "|", + "Powered by Gerrit Code Review\\s*\"\\s*\\(([0-9.]+)\\)\\;version:\\1", - "<(?:div|style) id=\"gerrit_" - ], - "icon": "gerrit.svg", - "implies": [ - "Java", - "git" - ], - "meta": { - "title": "^Gerrit Code Review$" - }, - "script": "^gerrit_ui/gerrit_ui", - "website": "http://www.gerritcodereview.com" - }, - "Get Satisfaction": { - "cats": [ - "13" - ], - "env": "^GSFN", - "icon": "Get Satisfaction.png", - "website": "http://getsatisfaction.com" - }, - "GetSimple CMS": { - "cats": [ - "1" - ], - "icon": "GetSimple CMS.png", - "implies": "PHP", - "meta": { - "generator": "GetSimple" - }, - "website": "http://get-simple.info" - }, - "Ghost": { - "cats": [ - "11" - ], - "headers": { - "X-Ghost-Cache-Status": "" - }, - "icon": "Ghost.png", - "implies": "Node.js", - "meta": { - "generator": "Ghost(?:\\s([\\d.]+))?\\;version:\\1" - }, - "website": "http://ghost.org" - }, - "GitBook": { - "cats": [ - "4" - ], - "icon": "GitBook.png", - "meta": { - "generator": "GitBook(?:.([\\d.]+))?\\;version:\\1" - }, - "website": "http://gitbook.io" - }, - "GitLab": { - "cats": [ - "13", - "47" - ], - "env": "^GitLab$", - "headers": { - "Set-cookie": "_gitlab_session" - }, - "html": [ - "" - ], - "icon": "GitLab.svg", - "implies": "Ruby on Rails", - "meta": { - "description": "^GitLab", - "og:site_name": "^GitLab$" - }, - "website": "http://about.gitlab.com" - }, - "GitLab CI": { - "cats": [ - "44", - "47" - ], - "icon": "GitLab CI.png", - "implies": "Ruby on Rails", - "meta": { - "description": "GitLab Continuous Integration" - }, - "website": "http://about.gitlab.com/gitlab-ci" - }, - "GitPHP": { - "cats": [ - "47" - ], - "html": [ - "", - "icon": "InProces.png", - "script": "brein/inproces/website/websitefuncties\\.js", - "website": "http://www.brein.nl/oplossing/product/website" - }, - "Incapsula": { - "cats": [ - "31" - ], - "headers": { - "X-CDN": "Incapsula" - }, - "icon": "Incapsula.png", - "website": "http://www.incapsula.com" - }, - "Indexhibit": { - "cats": [ - "1" - ], - "html": "<(?:link|a href) [^>]+ndxz-studio", - "implies": [ - "PHP", - "Apache", - "Exhibit" - ], - "meta": { - "generator": "Indexhibit" - }, - "website": "http://www.indexhibit.org" - }, - "Indico": { - "cats": [ - "1" - ], - "headers": { - "Set-cookie": "MAKACSESSION" - }, - "html": "Powered by\\s+(?:CERN )?(?:CDS )?Indico( [\\d\\.]+)?\\;version:\\1", - "icon": "Indico.png", - "website": "http://indico-software.org" - }, - "Indy": { - "cats": [ - "22" - ], - "headers": { - "Server": "Indy(?:/([\\d.]+))?\\;version:\\1" - }, - "website": "http://indyproject.org" - }, - "InfernoJS": { - "cats": [ - "12" - ], - "env": "^Inferno$", - "icon": "InfernoJS.png", - "website": "https://infernojs.org/" - }, - "Infusionsoft": { - "cats": [ - "32" - ], - "html": [ - "]*name=\"infusionsoft_version\" [^>]*value=\"([^>]*)\" [^>]*\\/>\\;version:\\1", - "]*value=\"([^>]*)\" [^>]*name=\"infusionsoft_version\" [^>]*\\/>\\;version:\\1" - ], - "icon": "infusionsoft.svg", - "website": "http://infusionsoft.com" - }, - "InstantCMS": { - "cats": [ - "1" - ], - "headers": { - "Set-Cookie": "InstantCMS\\[logdate\\]=" - }, - "icon": "InstantCMS.png", - "implies": "PHP", - "meta": { - "generator": "InstantCMS" - }, - "website": "http://www.instantcms.ru" - }, - "Intel Active Management Technology": { - "cats": [ - "22", - "46" - ], - "headers": { - "Server": "Intel\\(R\\) Active Management Technology(?: ([\\d.]+))?\\;version:\\1" - }, - "icon": "Intel Active Management Technology.png", - "website": "http://intel.com" - }, - "IntenseDebate": { - "cats": [ - "15" - ], - "icon": "IntenseDebate.png", - "script": "intensedebate\\.com", - "website": "http://intensedebate.com" - }, - "Intercom": { - "cats": [ - "10" - ], - "env": "^Intercom$", - "icon": "Intercom.png", - "script": "(?:api\\.intercom\\.io/api|static\\.intercomcdn\\.com/intercom\\.v1)", - "website": "http://intercom.io" - }, - "Intershop": { - "cats": [ - "6" - ], - "icon": "Intershop.png", - "script": "(?:is-bin|INTERSHOP)", - "website": "http://intershop.com" - }, - "Invenio": { - "cats": [ - "50" - ], - "headers": { - "Set-cookie": "INVENIOSESSION" - }, - "html": "(?:Powered by|System)\\s+(?:CERN )?(?:CDS )?Invenio\\s*v?([\\d\\.]+)?\\;version:\\1", - "icon": "Invenio.png", - "website": "http://invenio-software.org" - }, - "Ionicons": { - "cats": [ - "17" - ], - "html": "]* href=[^>]+ionicons(?:\\.min)?\\.css", - "icon": "Ionicons.png", - "website": "http://ionicons.com" - }, - "JAlbum": { - "cats": [ - "7" - ], - "icon": "JAlbum.png", - "implies": "Java", - "meta": { - "generator": "JAlbum( [\\d.]+)?\\;version:\\1" - }, - "website": "http://jalbum.net/en" - }, - "JBoss Application Server": { - "cats": [ - "22" - ], - "headers": { - "X-Powered-By": "JBoss(?:-([\\d.]+))?\\;version:\\1" - }, - "icon": "JBoss Application Server.png", - "website": "http://jboss.org/jbossas.html" - }, - "JBoss Web": { - "cats": [ - "22" - ], - "excludes": "Apache Tomcat", - "headers": { - "X-Powered-By": "JBossWeb(?:-([\\d.]+))?\\;version:\\1" - }, - "icon": "JBoss Web.png", - "implies": "JBoss Application Server", - "website": "http://jboss.org/jbossweb" - }, - "JC-HTTPD": { - "cats": [ - "22" - ], - "excludes": "Apache", - "headers": { - "Server": "JC-HTTPD(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "JC-HTTPD.png", - "implies": "Canon", - "website": "http://canon.com" - }, - "JET Enterprise": { - "cats": [ - "6" - ], - "headers": { - "powered": "jet-enterprise" - }, - "icon": "JET Enterprise.svg", - "website": "http://www.jetecommerce.com.br/" - }, - "JS Charts": { - "cats": [ - "25" - ], - "env": "^JSChart$", - "icon": "JS Charts.png", - "script": "jscharts.*\\.js", - "website": "http://www.jscharts.com" - }, - "JTL Shop": { - "cats": [ - "6" - ], - "headers": { - "Set-Cookie": "JTLSHOP=" - }, - "html": "(?:]+name=\"JTLSHOP|]+id=\"wrapper_r\"|<[^>]+(?:feed|components)/com_|]+class=\"pill)\\;confidence:50", - "icon": "Joomla.svg", - "implies": "PHP", - "meta": { - "generator": "Joomla!(?: ([\\d.]+))?\\;version:\\1" - }, - "url": "option=com_", - "website": "http://joomla.org" - }, - "JSEcoin": { - "cats": [ - "19" - ], - "env": "^jseMine$", - "script": "^(?:https):?//load\\.jsecoin\\.com/server/load/", - "icon": "JSEcoin.png", - "website": "https://jsecoin.com/" - }, - "K2": { - "cats": [ - "19" - ], - "env": "^K2RatingURL$", - "html": "", - "icon": "Lightspeed.svg", - "script": "http://assets\\.webshopapp\\.com", - "url": "seoshop.webshopapp.com", - "website": "http://www.lightspeedhq.com/products/ecommerce/" - }, - "Lighty": { - "cats": [ - "18" - ], - "headers": { - "Set-Cookie": "lighty_version" - }, - "icon": "Lighty.png", - "implies": "PHP", - "website": "http://gitlab.com/lighty/framework" - }, - "LimeSurvey": { - "cats": [ - "19" - ], - "headers": { - "generator": "LimeSurvey" - }, - "icon": "LimeSurvey.png", - "website": "http://limesurvey.org/" - }, - "LinkSmart": { - "cats": [ - "36" - ], - "env": "^(?:_mb_site_guid$|LS_JSON|LinkSmart(?:_|$))", - "icon": "LinkSmart.png", - "script": "^https?://cdn\\.linksmart\\.com/linksmart_([\\d.]+?)(?:\\.min)?\\.js\\;version:\\1", - "website": "http://linksmart.com" - }, - "Linkedin": { - "cats": [ - "5" - ], - "icon": "Linkedin.svg", - "script": "//platform\\.linkedin\\.com/in\\.js", - "website": "http://linkedin.com" - }, - "List.js": { - "cats": [ - "12" - ], - "env": "^List$", - "icon": "List.js.png", - "script": "^list\\.(?:min\\.)?js$", - "website": "http://www.listjs.com" - }, - "LiteSpeed": { - "cats": [ - "22" - ], - "headers": { - "Server": "^LiteSpeed$" - }, - "icon": "LiteSpeed.svg", - "website": "http://litespeedtech.com" - }, - "Lithium": { - "cats": [ - "1" - ], - "env": [ - "^LITHIUM$" - ], - "headers": { - "Set-Cookie": "LithiumVisitor=" - }, - "html": " ]+Powered by Lithium", - "icon": "Lithium.png", - "implies": "PHP", - "website": "http://www.lithium.com" - }, - "LiveAgent": { - "cats": [ - "52" - ], - "env": "^LiveAgent$", - "icon": "LiveAgent.png", - "website": "http://www.ladesk.com" - }, - "LiveChat": { - "cats": [ - "52" - ], - "icon": "LiveChat.png", - "script": "cdn\\.livechatinc\\.com/.*tracking\\.js", - "website": "http://livechatinc.com" - }, - "LiveJournal": { - "cats": [ - "11" - ], - "icon": "LiveJournal.png", - "url": "\\.livejournal\\.com", - "website": "http://www.livejournal.com" - }, - "LivePerson": { - "cats": [ - "52" - ], - "icon": "LivePerson.png", - "script": "^https?://lptag\\.liveperson\\.net/tag/tag\\.js", - "website": "https://www.liveperson.com/" - }, - "LiveStreet CMS": { - "cats": [ - "1" - ], - "env": "^LIVESTREET", - "headers": { - "X-Powered-By": "LiveStreet CMS" - }, - "icon": "LiveStreet CMS.png", - "implies": "PHP", - "website": "http://livestreetcms.com" - }, - "Livefyre": { - "cats": [ - "15" - ], - "env": [ - "^fyre$", - "^FyreLoader$" - ], - "html": "<[^>]+(?:id|class)=\"livefyre", - "icon": "Livefyre.png", - "script": "livefyre_init\\.js", - "website": "http://livefyre.com" - }, - "Liveinternet": { - "cats": [ - "10" - ], - "html": [ - "]*>[^]{0,128}?src\\s*=\\s*['\"]//counter\\.yadro\\.ru/hit(?:;\\S+)?\\?(?:t\\d+\\.\\d+;)?r", - "", - "", - "]*/sites/[a-z\\d]{24}/theme/stylesheets", - "icon": "Locomotive.png", - "implies": [ - "Ruby on Rails", - "MongoDB" - ], - "website": "http://www.locomotivecms.com" - }, - "Logitech Media Server": { - "cats": [ - "22", - "38" - ], - "headers": { - "Server": "Logitech Media Server(?: \\(([\\d\\.]+))?\\;version:\\1" - }, - "icon": "Logitech Media Server.png", - "website": "http://www.mysqueezebox.com" - }, - "Lotus Domino": { - "cats": [ - "22" - ], - "headers": { - "Server": "Lotus-Domino" - }, - "icon": "Lotus Domino.png", - "implies": "Java", - "website": "http://www-01.ibm.com/software/lotus/products/domino" - }, - "Lua": { - "cats": [ - "27" - ], - "headers": { - "X-Powered-By": "\bLua(?: ([\\d.]+))?\\;version:\\1" - }, - "icon": "Lua.png", - "website": "http://www.lua.org" - }, - "Lucene": { - "cats": [ - "34" - ], - "icon": "Lucene.png", - "implies": "Java", - "website": "http://lucene.apache.org/core/" - }, - "Luigi’s Box": { - "cats": [ - "10", - "29" - ], - "env": "^Luigis$", - "icon": "Luigisbox.svg", - "website": "https://www.luigisbox.com" - }, - "M.R. Inc BoxyOS": { - "cats": [ - "28" - ], - "icon": "M.R. Inc.png", - "website": "http://mrincworld.com" - }, - "M.R. Inc SiteFrame": { - "cats": [ - "18" - ], - "headers": { - "Powered-By": "M\\.R\\. Inc SiteFrame" - }, - "icon": "M.R. Inc.png", - "website": "http://mrincworld.com" - }, - "M.R. Inc Webserver": { - "cats": [ - "22" - ], - "headers": { - "Server": "M\\.R\\. Inc Webserver" - }, - "icon": "M.R. Inc.png", - "implies": [ - "M.R. Inc BoxyOS" - ], - "website": "http://mrincworld.com" - }, - "MHonArc": { - "cats": [ - "50" - ], - "html": "\\;version:\\1", - "icon": "mhonarc.png", - "website": "http://www.mhonarc.at" - }, - "MOBOTIX": { - "cats": [ - "39" - ], - "icon": "MOBOTIX.png", - "meta": { - "author": "MOBOTIX AG\\;confidence:40", - "copyright": "MOBOTIX AG\\;confidence:40", - "publisher": "MOBOTIX AG\\;confidence:40" - }, - "url": "control/userimage\\.html\\;confidence:70", - "website": "http://mobotix.com" - }, - "MODX": { - "cats": [ - "1" - ], - "env": "^MODX_MEDIA_PATH$", - "headers": { - "Set-Cookie": "SN5[a-f\\d]{12}", - "X-Powered-By": "^MODX" - }, - "html": [ - "]+>Powered by MODX", - "<(?:link|script)[^>]+assets/snippets/\\;confidence:20", - "]+id=\"ajaxSearch_form\\;confidence:20", - "]+id=\"ajaxSearch_input\\;confidence:20" - ], - "icon": "MODX.png", - "implies": "PHP", - "meta": { - "generator": "MODX[^\\d.]*([\\d.]+)?\\;version:\\1" - }, - "website": "http://modx.com" - }, - "MadAdsMedia": { - "cats": [ - "36" - ], - "env": "^setM(?:Iframe|RefURL)$", - "icon": "MadAdsMedia.png", - "script": "^https?://(?:ads-by|pixel)\\.madadsmedia\\.com/", - "website": "http://madadsmedia.com" - }, - "Magento": { - "cats": [ - "6" - ], - "env": [ - "^(?:Mage|VarienForm)$" - ], - "headers": { - "Set-Cookie": "frontend=\\;confidence:50" - }, - "html": [ - " - - - - -
    -
    - -
    -
    - -
    -
    -

    Options

    - -

    - - - -

    - -
    -

    - -

    -
    -
    -
    - + + + + + Wappalyzer options + + + + + + + + + + + +
    +
    + +
    +
    + +
    +
    +

    Options

    + +

    + + + +

    + +
    +

    + + + +

    +
    +
    +
    + + diff --git a/src/drivers/webextension/images/pin-active.svg b/src/drivers/webextension/images/pin-active.svg new file mode 100644 index 000000000..12462f304 --- /dev/null +++ b/src/drivers/webextension/images/pin-active.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/drivers/webextension/images/pin.svg b/src/drivers/webextension/images/pin.svg new file mode 100644 index 000000000..20e42e6d0 --- /dev/null +++ b/src/drivers/webextension/images/pin.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/drivers/webextension/js/content.js b/src/drivers/webextension/js/content.js index 7ad284495..8404c4b92 100644 --- a/src/drivers/webextension/js/content.js +++ b/src/drivers/webextension/js/content.js @@ -1,58 +1,61 @@ /** global: browser */ +/** global: XMLSerializer */ if ( typeof browser !== 'undefined' && typeof document.body !== 'undefined' ) { - var html = document.documentElement.outerHTML; + try { + var html = new XMLSerializer().serializeToString(document); - if ( html.length > 50000 ) { - html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length); - } + if ( html.length > 500000 ) { + html = html.substring(0, 250000) + html.substring(html.length - 250000, html.length); + } - var scripts = Array.prototype.slice + const scripts = Array.prototype.slice .apply(document.scripts) - .filter(s => s.src) - .map(s => s.src); - - try { - browser.runtime.sendMessage({ - id: 'analyze', - subject: { html }, - source: 'content.js' - }); + .filter(script => script.src) + .map(script => script.src); browser.runtime.sendMessage({ id: 'analyze', - subject: { scripts }, + subject: { html, scripts }, source: 'content.js' }); - var container = document.createElement('wappalyzerData'); + const script = document.createElement('script'); - container.setAttribute('id', 'wappalyzerData'); - container.setAttribute('style', 'display: none'); + script.onload = () => { + addEventListener('message', event => { + if ( event.data.id !== 'js' ) { + return; + } - var script = document.createElement('script'); + browser.runtime.sendMessage({ + id: 'analyze', + subject: { + js: event.data.js + }, + source: 'content.js' + }); + }, true); - script.setAttribute('id', 'wappalyzerEnvDetection'); - script.setAttribute('src', browser.extension.getURL('js/inject.js')); - - container.addEventListener('wappalyzerEvent', (event => { - var env = event.target.childNodes[0].nodeValue; - - document.documentElement.removeChild(container); - document.documentElement.removeChild(script); - - env = env.split(' ').slice(0, 500); - - browser.runtime.sendMessage({ - id: 'analyze', - subject: { env }, + ( chrome || browser ).runtime.sendMessage({ + id: 'init_js', + subject: {}, source: 'content.js' + }, response => { + if ( response ) { + postMessage({ + id: 'patterns', + patterns: response.patterns + }, '*'); + } }); - }), true); + }; + + script.setAttribute('id', 'wappalyzer'); + script.setAttribute('src', browser.extension.getURL('js/inject.js')); - document.documentElement.appendChild(container); - document.documentElement.appendChild(script); - } catch(e) { + document.body.appendChild(script); + } catch (e) { log(e); } } diff --git a/src/drivers/webextension/js/driver.js b/src/drivers/webextension/js/driver.js index 4b9a40dc6..4c36f9729 100644 --- a/src/drivers/webextension/js/driver.js +++ b/src/drivers/webextension/js/driver.js @@ -10,6 +10,7 @@ const wappalyzer = new Wappalyzer(); var tabCache = {}; var headersCache = {}; var categoryOrder = []; +var options = {}; browser.tabs.onRemoved.addListener(tabId => { tabCache[tabId] = null; @@ -21,18 +22,14 @@ browser.tabs.onRemoved.addListener(tabId => { function getOption(name, defaultValue) { return new Promise((resolve, reject) => { const callback = item => { - resolve(item.hasOwnProperty(name) ? item[name] : defaultValue); + options[name] = item.hasOwnProperty(name) ? item[name] : defaultValue; + + resolve(options[name]); }; - try { - // Chrome, Firefox - browser.storage.local.get(name) - .then(callback) - .catch(error => wappalyzer.log(error, 'driver', 'error')); - } catch ( e ) { - // Edge - browser.storage.local.get(name, callback); - } + browser.storage.local.get(name) + .then(callback) + .catch(error => wappalyzer.log(error, 'driver', 'error')); }); } @@ -45,6 +42,8 @@ function setOption(name, value) { option[name] = value; browser.storage.local.set(option); + + options[name] = value; } /** @@ -81,7 +80,11 @@ fetch('../apps.json') wappalyzer.apps = json.apps; wappalyzer.categories = json.categories; - categoryOrder = Object.keys(wappalyzer.categories).sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority); + wappalyzer.parseJsPatterns(); + + categoryOrder = Object.keys(wappalyzer.categories) + .map(categoryId => parseInt(categoryId, 10)) + .sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority); }) .catch(error => { wappalyzer.log('GET apps.json: ' + error, 'driver', 'error'); @@ -111,6 +114,9 @@ getOption('version') setOption('version', version); }); +getOption('dynamicIcon', true); +getOption('pinnedCategory'); + // Run content script var callback = tabs => { tabs.forEach(tab => { @@ -122,13 +128,9 @@ var callback = tabs => { }) }; -try { - browser.tabs.query({}) - .then(callback) - .catch(error => wappalyzer.log(error, 'driver', 'error')); -} catch ( e ) { - browser.tabs.query({}, callback); -} +browser.tabs.query({}) + .then(callback) + .catch(error => wappalyzer.log(error, 'driver', 'error')); // Capture response headers browser.webRequest.onCompleted.addListener(request => { @@ -164,7 +166,7 @@ browser.webRequest.onCompleted.addListener(request => { ( chrome || browser ).runtime.onMessage.addListener((message, sender, sendResponse) => { if ( typeof message.id != 'undefined' ) { if ( message.id !== 'log' ) { - wappalyzer.log('Message received from ' + message.source + ': ' + message.id, 'driver'); + wappalyzer.log('Message received' + ( message.source ? ' from ' + message.source : '' ) + ': ' + message.id, 'driver'); } var response; @@ -181,7 +183,7 @@ browser.webRequest.onCompleted.addListener(request => { message.subject.headers = headersCache[url.canonical]; } - wappalyzer.analyze(url.hostname, url.canonical, message.subject, { + wappalyzer.analyze(url, message.subject, { tab: sender.tab }); @@ -192,9 +194,20 @@ browser.webRequest.onCompleted.addListener(request => { break; case 'get_apps': response = { - tabCache: tabCache[message.tab.id], - apps: wappalyzer.apps, - categories: wappalyzer.categories + tabCache: tabCache[message.tab.id], + apps: wappalyzer.apps, + categories: wappalyzer.categories, + pinnedCategory: options.pinnedCategory, + }; + + break; + case 'set_option': + setOption(message.key, message.value); + + break; + case 'init_js': + response = { + patterns: wappalyzer.jsPatterns }; break; @@ -217,7 +230,7 @@ wappalyzer.driver.log = (message, source, type) => { /** * Display apps */ -wappalyzer.driver.displayApps = (detected, context) => { +wappalyzer.driver.displayApps = (detected, meta, context) => { var tab = context.tab; tabCache[tab.id] = tabCache[tab.id] || { detected: [] }; @@ -225,45 +238,46 @@ wappalyzer.driver.displayApps = (detected, context) => { tabCache[tab.id].detected = detected; if ( Object.keys(detected).length ) { - getOption('dynamicIcon', true) - .then(dynamicIcon => { - var appName, found = false; - - // Find the main application to display - categoryOrder.forEach(match => { - Object.keys(detected).forEach(appName => { - var app = detected[appName]; - - app.props.cats.forEach(category => { - if ( category === match && !found ) { - var icon = app.props.icon || 'default.svg'; - - if ( !dynamicIcon ) { - icon = 'default.svg'; - } - - if ( /\.svg$/i.test(icon) ) { - icon = 'converted/' + icon.replace(/\.svg$/, '.png'); - } - - browser.pageAction.setIcon({ - tabId: tab.id, - path: '../images/icons/' + icon - }); - - found = true; - } - }); - }); + var appName, found = false; + + // Find the main application to display + [ options.pinnedCategory ].concat(categoryOrder).forEach(match => { + Object.keys(detected).forEach(appName => { + var app = detected[appName]; + + app.props.cats.forEach(category => { + if ( category === match && !found ) { + var icon = app.props.icon || 'default.svg'; + + if ( !options.dynamicIcon ) { + icon = 'default.svg'; + } + + if ( /\.svg$/i.test(icon) ) { + icon = 'converted/' + icon.replace(/\.svg$/, '.png'); + } + + try { + browser.pageAction.setIcon({ + tabId: tab.id, + path: '../images/icons/' + icon + }); + } catch(e) { + // Firefox for Android does not support setIcon see https://bugzilla.mozilla.org/show_bug.cgi?id=1331746 + } + + found = true; + } }); - - if ( typeof chrome !== 'undefined' ) { - // Browser polyfill doesn't seem to work here - chrome.pageAction.show(tab.id); - } else { - browser.pageAction.show(tab.id); - } }); + }); + + if ( typeof chrome !== 'undefined' ) { + // Browser polyfill doesn't seem to work here + chrome.pageAction.show(tab.id); + } else { + browser.pageAction.show(tab.id); + } } }; @@ -272,38 +286,43 @@ wappalyzer.driver.displayApps = (detected, context) => { */ wappalyzer.driver.getRobotsTxt = (host, secure = false) => { return new Promise((resolve, reject) => { - getOption('robotsTxtCache') - .then(robotsTxtCache => { - robotsTxtCache = robotsTxtCache || {}; - - if ( host in robotsTxtCache ) { - resolve(robotsTxtCache[host]); - } else { - var url = 'http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt'; - - fetch('http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt') - .then(response => { - if ( !response.ok ) { - if ( response.status === 404 ) { - return ''; - } else { - throw 'GET ' + response.url + ' was not ok'; - } - } - - return response.text(); - }) - .then(robotsTxt => { - robotsTxtCache[host] = wappalyzer.parseRobotsTxt(robotsTxt); - - setOption('robotsTxtCache', robotsTxtCache); + getOption('tracking', true) + .then(tracking => { + if ( !tracking ) { + return resolve([]); + } - resolve(robotsTxtCache[host]); + getOption('robotsTxtCache') + .then(robotsTxtCache => { + robotsTxtCache = robotsTxtCache || {}; - var hostname = host.replace(/:[0-9]+$/, '') - }) - .catch(reject); - } + if ( host in robotsTxtCache ) { + resolve(robotsTxtCache[host]); + } else { + const url = 'http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt'; + + fetch('http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt') + .then(response => { + if ( !response.ok ) { + if ( response.status === 404 ) { + return ''; + } else { + throw 'GET ' + response.url + ' was not ok'; + } + } + + return response.text(); + }) + .then(robotsTxt => { + robotsTxtCache[host] = wappalyzer.parseRobotsTxt(robotsTxt); + + setOption('robotsTxtCache', robotsTxtCache); + + resolve(robotsTxtCache[host]); + }) + .catch(reject); + } + }); }); }); }; @@ -316,7 +335,7 @@ wappalyzer.driver.ping = (hostnameCache, adCache) => { .then(tracking => { if ( tracking ) { if ( Object.keys(hostnameCache).length ) { - post('http://ping.wappalyzer.com/v3/', hostnameCache); + post('https://api.wappalyzer.com/ping/v1/', hostnameCache); } if ( adCache.length ) { diff --git a/src/drivers/webextension/js/iframe.js b/src/drivers/webextension/js/iframe.js index c62fdc471..2370a3eda 100644 --- a/src/drivers/webextension/js/iframe.js +++ b/src/drivers/webextension/js/iframe.js @@ -181,7 +181,7 @@ var exports = {}; video_assets: opt_video_assets, assets: opt_assets, version: '3', - mrev: 'b084b53-c', + mrev: '4aeaa5a-c', msgNum: this.msgNum, timestamp: new Date().getTime(), pageVis: document.visibilityState, @@ -890,7 +890,7 @@ var exports = {}; var _pageTags; var INIT_MS_BW_SEARCHES = 2000; var PAGE_TAG_RE = new RegExp('gpt|oascentral'); - var POST_MSG_ID = '1510070508-5767-8848-29475-8984'; + var POST_MSG_ID = '1511804838-25881-9878-26947-14879'; var AD_SERVER_RE = new RegExp('^(google_ads_iframe|oas_frame|atwAdFrame)'); function getPageTags(doc) { diff --git a/src/drivers/webextension/js/inject.js b/src/drivers/webextension/js/inject.js index cc56a76c5..26fc00de6 100644 --- a/src/drivers/webextension/js/inject.js +++ b/src/drivers/webextension/js/inject.js @@ -1,16 +1,61 @@ (function() { try { - var i, environmentVars = '', e = document.createEvent('Events'); + addEventListener('message', (event => { + if ( event.data.id !== 'patterns' ) { + return; + } - e.initEvent('wappalyzerEvent', true, false); + const patterns = event.data.patterns || {}; - for ( i in window ) { - environmentVars += i + ' '; - } + const js = {}; - document.getElementById('wappalyzerData').appendChild(document.createComment(environmentVars)); - document.getElementById('wappalyzerData').dispatchEvent(e); - } catch(e) { - // Fail quietly - } + for ( let appName in patterns ) { + if ( patterns.hasOwnProperty(appName) ) { + js[appName] = {}; + + for ( let chain in patterns[appName] ) { + if ( patterns[appName].hasOwnProperty(chain) ) { + js[appName][chain] = {}; + + for ( let index in patterns[appName][chain] ) { + const value = detectJs(chain); + + if ( value ) { + js[appName][chain][index] = value; + } + } + } + } + } + } + + postMessage({ id: 'js', js }, '*'); + }), false); + } catch(e) { + // Fail quietly + } + + function detectJs(chain) { + try { + const properties = chain.split('.'); + + var value = properties.length ? window : null; + + for ( let i = 0; i < properties.length; i ++ ) { + var property = properties[i]; + + if ( value.hasOwnProperty(property) ) { + value = value[property]; + } else { + value = null; + + break; + } + } + + return typeof value === 'string' || typeof value === 'number' ? value : !!value; + } catch(e) { + // Fail quietly + } + } }()); diff --git a/src/drivers/webextension/js/ms_background_scripts_api_bridge.js b/src/drivers/webextension/js/ms_background_scripts_api_bridge.js deleted file mode 100644 index d023cf1b0..000000000 --- a/src/drivers/webextension/js/ms_background_scripts_api_bridge.js +++ /dev/null @@ -1,846 +0,0 @@ -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 deleted file mode 100644 index 183aafc02..000000000 --- a/src/drivers/webextension/js/ms_content_scripts_api_bridge.js +++ /dev/null @@ -1,323 +0,0 @@ -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/network.js b/src/drivers/webextension/js/network.js index 5842b9818..6df8237ca 100644 --- a/src/drivers/webextension/js/network.js +++ b/src/drivers/webextension/js/network.js @@ -440,8 +440,9 @@ } if ( this.isYoutubeAdReq(frameUrl, requestUrl) ) { - var videoId = this.parseYoutubeVideoIdFromUrl(requestUrl); - if ( videoId ) { + var destVideoId = this.parseYoutubeVideoIdFromUrl(requestUrl); + var srcVideoId = this.parseYoutubeVideoIdFromUrl(frameUrl); + if ( srcVideoId && destVideoId ) { request.isYoutubeAd = true; request.isVideo = true; request.rawSrcUrl = frameUrl; @@ -535,7 +536,7 @@ return match[1]; } - re = /^https?:\/\/www\.youtube\.com\/watch\?v=(.*$)/; + re = /^https?:\/\/www\.youtube\.com\/watch.*(\?|&)v=([^&]*)/; match = re.exec(url); if ( match && match.length > 1 ) { return match[1]; diff --git a/src/drivers/webextension/js/options.js b/src/drivers/webextension/js/options.js index 9486a8edc..fc69619f8 100644 --- a/src/drivers/webextension/js/options.js +++ b/src/drivers/webextension/js/options.js @@ -1,5 +1,7 @@ /** global: browser */ -/** global: wappalyzer */ +/** global: Wappalyzer */ + +const wappalyzer = new Wappalyzer(); function getOption(name, defaultValue, callback) { browser.storage.local.get(name) diff --git a/src/drivers/webextension/js/popup.js b/src/drivers/webextension/js/popup.js index 237dbae7e..47d507bf1 100644 --- a/src/drivers/webextension/js/popup.js +++ b/src/drivers/webextension/js/popup.js @@ -1,25 +1,23 @@ /** global: chrome */ /** global: browser */ +var pinnedCategory = null; + var func = tabs => { ( chrome || browser ).runtime.sendMessage({ id: 'get_apps', tab: tabs[0], source: 'popup.js' }, response => { + pinnedCategory = response.pinnedCategory; + replaceDomWhenReady(appsToDomTemplate(response)); }); }; -try { - // Chrome, Firefox - browser.tabs.query({ active: true, currentWindow: true }) - .then(func) - .catch(console.error); -} catch ( e ) { - // Edge - browser.tabs.query({ active: true, currentWindow: true }, func); -} +browser.tabs.query({ active: true, currentWindow: true }) + .then(func) + .catch(console.error); function replaceDomWhenReady(dom) { if ( /complete|interactive|loaded/.test(document.readyState) ) { @@ -45,6 +43,34 @@ function replaceDom(domTemplate) { Array.prototype.forEach.call(nodes, node => { node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n); }); + + Array.from(document.querySelectorAll('.detected__category-pin-wrapper')).forEach(pin => { + pin.addEventListener('click', event => { + const categoryId = parseInt(pin.dataset.categoryId, 10); + + if ( categoryId === pinnedCategory ) { + pin.className = 'detected__category-pin-wrapper'; + + pinnedCategory = null; + } else { + const active = document.querySelector('.detected__category-pin-wrapper--active'); + + if ( active ) { + active.className = 'detected__category-pin-wrapper'; + } + + pin.className = 'detected__category-pin-wrapper detected__category-pin-wrapper--active'; + + pinnedCategory = categoryId; + } + + ( chrome || browser ).runtime.sendMessage({ + id: 'set_option', + key: 'pinnedCategory', + value: pinnedCategory, + }); + }); + }); } function appsToDomTemplate(response) { @@ -76,7 +102,7 @@ function appsToDomTemplate(response) { 'a', { class: 'detected__app', target: '_blank', - href: 'https://www.wappalyzer.com/applications/' + slugify(appName) + href: 'https://www.wappalyzer.com/technologies/' + slugify(appName) }, [ 'img', { class: 'detected__app-icon', @@ -86,8 +112,18 @@ function appsToDomTemplate(response) { 'span', { class: 'detected__app-name' }, - appName + ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) - ] + appName, + ], version ? [ + 'span', { + class: 'detected__app-version' + }, + version + ] : null, confidence < 100 ? [ + 'span', { + class: 'detected__app-confidence' + }, + confidence + '% sure' + ] : null ] ); } @@ -97,15 +133,31 @@ function appsToDomTemplate(response) { 'div', { class: 'detected__category' }, [ - 'a', { - class: 'detected__category-link', - target: '_blank', - href: 'https://www.wappalyzer.com/categories/' + slugify(response.categories[cat].name) + 'div', { + class: 'detected__category-name' }, [ - 'span', { - class: 'detected__category-name' + 'a', { + class: 'detected__category-link', + target: '_blank', + href: 'https://www.wappalyzer.com/categories/' + slugify(response.categories[cat].name) }, - browser.i18n.getMessage('categoryName' + cat) + browser.i18n.getMessage('categoryName' + cat), + ], [ + 'span', { + class: 'detected__category-pin-wrapper' + ( pinnedCategory == cat ? ' detected__category-pin-wrapper--active' : '' ), + 'data-category-id': cat, + 'title': browser.i18n.getMessage('categoryPin'), + }, [ + 'img', { + class: 'detected__category-pin detected__category-pin--active', + src: '../images/pin-active.svg' + }, + ], [ + 'img', { + class: 'detected__category-pin detected__category-pin--inactive', + src: '../images/pin.svg' + } + ] ] ], [ 'div', { diff --git a/src/drivers/webextension/manifest.edge.json b/src/drivers/webextension/manifest.edge.json deleted file mode 100644 index 6c5d4c690..000000000 --- a/src/drivers/webextension/manifest.edge.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "Wappalyzer", - "short_name": "Wappalyzer", - "author": "Elbert Alias", - "homepage_url": "https://www.wappalyzer.com/", - "description": "Identify web technologies", - "version": "5.1.6", - "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", - "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" - }, - "default_title": "Wappalyzer", - "default_popup": "html/popup.html" - }, - "background": { - "page": "html/background.html", - "persistent": true - }, - "content_scripts": [ - { - "matches": [ - "http://*/*", - "https://*/*" - ], - "js": [ - "node_modules/webextension-polyfill/dist/browser-polyfill.js", - "js/content.js" - ], - "run_at": "document_idle" - }, - { - "matches": [ - "http://*/*", - "https://*/*" - ], - "js": [ - "js/browser-polyfill.js", - "js/iframe.js" - ], - "run_at": "document_start", - "all_frames": true - } - ], - "web_accessible_resources": [ - "js/inject.js" - ], - "options_page": "html/options.html", - "permissions": [ - "storage", - "tabs", - "webRequest", - "webNavigation", - "http://*/*", - "https://*/*" - ], - "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 b46567b82..39c22718e 100644 --- a/src/drivers/webextension/manifest.json +++ b/src/drivers/webextension/manifest.json @@ -4,7 +4,7 @@ "author": "Elbert Alias", "homepage_url": "https://www.wappalyzer.com", "description": "Identify web technologies", - "version": "5.2.0", + "version": "5.4.5", "default_locale": "en", "manifest_version": 2, "icons": { diff --git a/src/drivers/webextension/package.json b/src/drivers/webextension/package.json index f27b81af6..9b344ae21 100644 --- a/src/drivers/webextension/package.json +++ b/src/drivers/webextension/package.json @@ -1,5 +1,5 @@ { "dependencies": { - "webextension-polyfill": "^0.1.1" + "webextension-polyfill": "^0.2.1" } } diff --git a/src/drivers/webextension/yarn.lock b/src/drivers/webextension/yarn.lock index 955172b78..e2e1d507d 100644 --- a/src/drivers/webextension/yarn.lock +++ b/src/drivers/webextension/yarn.lock @@ -2,6 +2,6 @@ # yarn lockfile v1 -webextension-polyfill@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.1.1.tgz#1d172e59b9ee8706d5ce2c55eebfe0cf23972d70" +webextension-polyfill@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.2.1.tgz#cdfc9126033039f1713553157d35beff1d4d6f4a" diff --git a/src/icons/A-Frame.svg b/src/icons/A-Frame.svg new file mode 100644 index 000000000..7ff8039aa --- /dev/null +++ b/src/icons/A-Frame.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/Accelerated-Mobile-Pages.svg b/src/icons/Accelerated-Mobile-Pages.svg new file mode 100644 index 000000000..23bcd2654 --- /dev/null +++ b/src/icons/Accelerated-Mobile-Pages.svg @@ -0,0 +1,12 @@ + + + + AMP-Brand-Blue-Icon + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/icons/Adyen.svg b/src/icons/Adyen.svg new file mode 100644 index 000000000..96d26b546 --- /dev/null +++ b/src/icons/Adyen.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/icons/Angular.svg b/src/icons/Angular.svg index c6ed1c78b..e92f0220d 100644 --- a/src/icons/Angular.svg +++ b/src/icons/Angular.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/icons/AngularJS.svg b/src/icons/AngularJS.svg index 003deea80..db879ab4f 100644 --- a/src/icons/AngularJS.svg +++ b/src/icons/AngularJS.svg @@ -1 +1,74 @@ - \ No newline at end of file + + + +image/svg+xml \ No newline at end of file diff --git a/src/icons/Ant Design.svg b/src/icons/Ant Design.svg new file mode 100644 index 000000000..e9f8c2a9d --- /dev/null +++ b/src/icons/Ant Design.svg @@ -0,0 +1,43 @@ + + + + Group 28 Copy 5 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/icons/Bootstrap.png b/src/icons/Bootstrap.png deleted file mode 100644 index 570ffef13..000000000 Binary files a/src/icons/Bootstrap.png and /dev/null differ diff --git a/src/icons/Bootstrap.svg b/src/icons/Bootstrap.svg new file mode 100644 index 000000000..2ee62447c --- /dev/null +++ b/src/icons/Bootstrap.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/icons/CNV.png b/src/icons/CNV.png new file mode 100644 index 000000000..d7e259224 Binary files /dev/null and b/src/icons/CNV.png differ diff --git a/src/icons/Flat UI.png b/src/icons/Flat UI.png new file mode 100644 index 000000000..7a0cc0a2c Binary files /dev/null and b/src/icons/Flat UI.png differ diff --git a/src/icons/GitHub.svg b/src/icons/GitHub.svg new file mode 100644 index 000000000..ba82ee92a --- /dev/null +++ b/src/icons/GitHub.svg @@ -0,0 +1,35 @@ + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/icons/Haravan.png b/src/icons/Haravan.png index e5d48e6b2..7390fbc65 100644 Binary files a/src/icons/Haravan.png and b/src/icons/Haravan.png differ diff --git a/src/icons/Hexo.png b/src/icons/Hexo.png new file mode 100644 index 000000000..b78023291 Binary files /dev/null and b/src/icons/Hexo.png differ diff --git a/src/icons/JET Enterprise.svg b/src/icons/JET Enterprise.svg index fa2687f49..b673a440d 100644 --- a/src/icons/JET Enterprise.svg +++ b/src/icons/JET Enterprise.svg @@ -1,7 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/src/icons/Jo.png b/src/icons/Jo.png deleted file mode 100644 index 477faf75b..000000000 Binary files a/src/icons/Jo.png and /dev/null differ diff --git a/src/icons/Kajabi.svg b/src/icons/Kajabi.svg new file mode 100644 index 000000000..dd6f7cd66 --- /dev/null +++ b/src/icons/Kajabi.svg @@ -0,0 +1 @@ +KajabiKajabi Logo diff --git a/src/icons/Koego.png b/src/icons/Koego.png deleted file mode 100644 index 72e498be8..000000000 Binary files a/src/icons/Koego.png and /dev/null differ diff --git a/src/icons/NextGEN Gallery.png b/src/icons/NextGEN Gallery.png new file mode 100644 index 000000000..4440d9824 Binary files /dev/null and b/src/icons/NextGEN Gallery.png differ diff --git a/src/icons/OpenUI5.png b/src/icons/OpenUI5.png new file mode 100644 index 000000000..17a2b943e Binary files /dev/null and b/src/icons/OpenUI5.png differ diff --git a/src/icons/Plataforma NEO.svg b/src/icons/Plataforma NEO.svg index 51a5595bf..5a112f6e0 100644 --- a/src/icons/Plataforma NEO.svg +++ b/src/icons/Plataforma NEO.svg @@ -1,4 +1,4 @@ - - - + + + \ No newline at end of file diff --git a/src/icons/Schneider.png b/src/icons/Schneider.png deleted file mode 100644 index d795ac7f5..000000000 Binary files a/src/icons/Schneider.png and /dev/null differ diff --git a/src/icons/Shoper.svg b/src/icons/Shoper.svg new file mode 100644 index 000000000..821b18c84 --- /dev/null +++ b/src/icons/Shoper.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + diff --git a/src/icons/Shopfa.svg b/src/icons/Shopfa.svg new file mode 100644 index 000000000..dafcfd5c3 --- /dev/null +++ b/src/icons/Shopfa.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/Sqreen.png b/src/icons/Sqreen.png new file mode 100644 index 000000000..c4e1000e6 Binary files /dev/null and b/src/icons/Sqreen.png differ diff --git a/src/icons/Tilda.svg b/src/icons/Tilda.svg new file mode 100644 index 000000000..d3c193bcb --- /dev/null +++ b/src/icons/Tilda.svg @@ -0,0 +1,18 @@ + + + + Page 1 + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/icons/Vox.png b/src/icons/Vox.png deleted file mode 100644 index 8644dd574..000000000 Binary files a/src/icons/Vox.png and /dev/null differ diff --git a/src/icons/amplitude.png b/src/icons/amplitude.png new file mode 100644 index 000000000..be4f72454 Binary files /dev/null and b/src/icons/amplitude.png differ diff --git a/src/icons/asciinema.png b/src/icons/asciinema.png new file mode 100644 index 000000000..d547cbc3a Binary files /dev/null and b/src/icons/asciinema.png differ diff --git a/src/icons/coinhave.png b/src/icons/coinhave.png new file mode 100644 index 000000000..2162530ab Binary files /dev/null and b/src/icons/coinhave.png differ diff --git a/src/icons/coinimp.png b/src/icons/coinimp.png new file mode 100644 index 000000000..80b82ded7 Binary files /dev/null and b/src/icons/coinimp.png differ diff --git a/src/icons/coinlab.png b/src/icons/coinlab.png new file mode 100644 index 000000000..0f059c5ef Binary files /dev/null and b/src/icons/coinlab.png differ diff --git a/src/icons/deepminer.png b/src/icons/deepminer.png new file mode 100644 index 000000000..e85712f8e Binary files /dev/null and b/src/icons/deepminer.png differ diff --git a/src/icons/freshmarketer.png b/src/icons/freshmarketer.png new file mode 100644 index 000000000..245f94dfe Binary files /dev/null and b/src/icons/freshmarketer.png differ diff --git a/src/icons/gosquared.png b/src/icons/gosquared.png new file mode 100644 index 000000000..d08059fc2 Binary files /dev/null and b/src/icons/gosquared.png differ diff --git a/src/icons/inspectlet.png b/src/icons/inspectlet.png new file mode 100644 index 000000000..7370bad21 Binary files /dev/null and b/src/icons/inspectlet.png differ diff --git a/src/icons/inwemo.png b/src/icons/inwemo.png new file mode 100644 index 000000000..1dd0d690e Binary files /dev/null and b/src/icons/inwemo.png differ diff --git a/src/icons/laterpay.png b/src/icons/laterpay.png new file mode 100644 index 000000000..b425ec8e9 Binary files /dev/null and b/src/icons/laterpay.png differ diff --git a/src/icons/monerominer.png b/src/icons/monerominer.png new file mode 100644 index 000000000..5fb978053 Binary files /dev/null and b/src/icons/monerominer.png differ diff --git a/src/icons/mouseflow.png b/src/icons/mouseflow.png new file mode 100644 index 000000000..471ca7360 Binary files /dev/null and b/src/icons/mouseflow.png differ diff --git a/src/icons/mypage-platform.png b/src/icons/mypage-platform.png new file mode 100644 index 000000000..99687ec47 Binary files /dev/null and b/src/icons/mypage-platform.png differ diff --git a/src/icons/revslider.png b/src/icons/revslider.png new file mode 100644 index 000000000..3b2cd2ac5 Binary files /dev/null and b/src/icons/revslider.png differ diff --git a/src/icons/styled-components.png b/src/icons/styled-components.png new file mode 100644 index 000000000..8d24ba2ca Binary files /dev/null and b/src/icons/styled-components.png differ diff --git a/src/icons/tilda.png b/src/icons/tilda.png deleted file mode 100644 index 72e82be4f..000000000 Binary files a/src/icons/tilda.png and /dev/null differ diff --git a/src/icons/transifex.png b/src/icons/transifex.png new file mode 100644 index 000000000..4c90c29a6 Binary files /dev/null and b/src/icons/transifex.png differ diff --git a/src/icons/vwo.svg b/src/icons/vwo.svg new file mode 100644 index 000000000..ac70798e9 --- /dev/null +++ b/src/icons/vwo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/webmine.png b/src/icons/webmine.png new file mode 100644 index 000000000..ba3534e5a Binary files /dev/null and b/src/icons/webmine.png differ diff --git a/src/icons/xwiki.png b/src/icons/xwiki.png new file mode 100644 index 000000000..cba1e5440 Binary files /dev/null and b/src/icons/xwiki.png differ diff --git a/src/wappalyzer.js b/src/wappalyzer.js index a3f714e56..df7e3bd1e 100644 --- a/src/wappalyzer.js +++ b/src/wappalyzer.js @@ -18,6 +18,7 @@ class Wappalyzer { this.apps = {}; this.categories = {}; this.driver = {}; + this.jsPatterns = {}; this.detected = {}; this.hostnameCache = {}; @@ -37,28 +38,28 @@ class Wappalyzer { this.driver.log(message, source || '', type || 'debug'); } - analyze(hostname, url, data, context) { + analyze(url, data, context) { var apps = {}; - // Remove hash from URL - data.url = url = url.split('#')[0]; - if ( typeof data.html !== 'string' ) { data.html = ''; } - if ( this.detected[url] === undefined ) { - this.detected[url] = {}; + if ( this.detected[url.canonical] === undefined ) { + this.detected[url.canonical] = {}; } + // Additional information + const matches = data.html.match(/]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i); + + const language = matches && matches.length ? matches[1] : null; + Object.keys(this.apps).forEach(appName => { - apps[appName] = this.detected[url] && this.detected[url][appName] ? this.detected[url][appName] : new Application(appName, this.apps[appName]); + apps[appName] = this.detected[url.canonical] && this.detected[url.canonical][appName] ? this.detected[url.canonical][appName] : new Application(appName, this.apps[appName]); var app = apps[appName]; - if ( url ) { - this.analyzeUrl(app, url); - } + this.analyzeUrl(app, url); if ( data.html ) { this.analyzeHtml(app, data.html); @@ -82,6 +83,12 @@ class Wappalyzer { } }) + if ( data.js ) { + Object.keys(data.js).forEach(appName => { + this.analyzeJs(apps[appName], data.js[appName]); + }); + } + Object.keys(apps).forEach(appName => { var app = apps[appName]; @@ -91,16 +98,16 @@ class Wappalyzer { }); this.resolveExcludes(apps); - this.resolveImplies(apps, url); + this.resolveImplies(apps, url.canonical); - this.cacheDetectedApps(apps, url); - this.trackDetectedApps(apps, url, hostname, data.html); + this.cacheDetectedApps(apps, url.canonical); + this.trackDetectedApps(apps, url, language); if ( Object.keys(apps).length ) { - this.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url, 'core'); + this.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url.canonical, 'core'); } - this.driver.displayApps(this.detected[url], context); + this.driver.displayApps(this.detected[url.canonical], { language }, context); } /** @@ -117,11 +124,17 @@ class Wappalyzer { return new Promise((resolve, reject) => { var parsed = this.parseUrl(url); + if ( parsed.protocol !== 'http:' && parsed.protocol !== 'https:' ) { + return reject(); + } + this.driver.getRobotsTxt(parsed.host, parsed.protocol === 'https:') .then(robotsTxt => { - robotsTxt.forEach(disallow => parsed.pathname.indexOf(disallow) === 0 && reject()); - - resolve(); + if (robotsTxt.some(disallowedPath => parsed.pathname.indexOf(disallowedPath) === 0)) { + return reject(); + } else { + return resolve(); + } }); }); }; @@ -169,7 +182,7 @@ class Wappalyzer { * */ ping() { - if ( Object.keys(this.hostnameCache).length + this.adCache.length > 200 ) { + if ( Object.keys(this.hostnameCache).length + this.adCache.length > 50 ) { this.driver.ping(this.hostnameCache, this.adCache); this.hostnameCache = {}; @@ -240,6 +253,17 @@ class Wappalyzer { return parsed; } + /** + * Parse JavaScript patterns + */ + parseJsPatterns() { + Object.keys(this.apps).forEach(appName => { + if ( this.apps[appName].js ) { + this.jsPatterns[appName] = this.parsePatterns(this.apps[appName].js); + } + }); + } + resolveExcludes(apps) { var excludes = []; @@ -322,49 +346,42 @@ class Wappalyzer { /** * Track detected applications */ - trackDetectedApps(apps, url, hostname, html) { + trackDetectedApps(apps, url, language) { if ( !( this.driver.ping instanceof Function ) ) { return; } - Object.keys(apps).forEach(appName => { - var app = apps[appName]; + const hostname = url.protocol + '//' + url.hostname; - if ( this.detected[url][appName].getConfidence() >= 100 ) { - if ( validation.hostname.test(hostname) && !validation.hostnameBlacklist.test(url) ) { - this.robotsTxtAllows(url) - .then(() => { - if ( !( hostname in this.hostnameCache ) ) { - this.hostnameCache[hostname] = { - applications: {}, - meta: {} - }; - } + Object.keys(apps).forEach(appName => { + const app = apps[appName]; + + if ( this.detected[url.canonical][appName].getConfidence() >= 100 ) { + if ( validation.hostname.test(url.hostname) && !validation.hostnameBlacklist.test(url.hostname) ) { + if ( !( hostname in this.hostnameCache ) ) { + this.hostnameCache[hostname] = { + applications: {}, + meta: {} + }; + } - if ( !( appName in this.hostnameCache[hostname].applications ) ) { - this.hostnameCache[hostname].applications[appName] = { - hits: 0 - }; - } + if ( !( appName in this.hostnameCache[hostname].applications ) ) { + this.hostnameCache[hostname].applications[appName] = { + hits: 0 + }; + } - this.hostnameCache[hostname].applications[appName].hits ++; + this.hostnameCache[hostname].applications[appName].hits ++; - if ( apps[appName].version ) { - this.hostnameCache[hostname].applications[appName].version = app.version; - } - }) - .catch(() => this.log('Disallowed in robots.txt: ' + url), 'core') + if ( apps[appName].version ) { + this.hostnameCache[hostname].applications[appName].version = app.version; + } } } }); - // Additional information if ( hostname in this.hostnameCache ) { - var match = html.match(/]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i); - - if ( match && match.length ) { - this.hostnameCache[hostname].meta['language'] = match[1]; - } + this.hostnameCache[hostname].meta['language'] = language; } this.ping(); @@ -378,8 +395,8 @@ class Wappalyzer { if ( patterns.length ) { patterns.forEach(pattern => { - if ( pattern.regex.test(url) ) { - this.addDetected(app, pattern, 'url', url); + if ( pattern.regex.test(url.canonical) ) { + this.addDetected(app, pattern, 'url', url.canonical); } }); } @@ -425,13 +442,16 @@ class Wappalyzer { analyzeMeta(app, html) { var regex = /]+>/ig; var patterns = this.parsePatterns(app.props.meta); - var content; - var match; + var content = ''; + var matches = []; - while ( patterns && ( match = regex.exec(html) ) ) { + while ( patterns && ( matches = regex.exec(html) ) ) { for ( var meta in patterns ) { - if ( new RegExp('(name|property)=["\']' + meta + '["\']', 'i').test(match) ) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); + + const r = new RegExp('(?:name|property)=["\']' + meta + '["\']', 'i'); + + if ( new RegExp('(?:name|property)=["\']' + meta + '["\']', 'i').test(matches[0]) ) { + content = matches[0].match(/content=("|')([^"']+)("|')/i); patterns[meta].forEach(pattern => { if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { @@ -483,6 +503,22 @@ class Wappalyzer { } } + /** + * Analyze JavaScript variables + */ + analyzeJs(app, results) { + Object.keys(results).forEach(string => { + Object.keys(results[string]).forEach(index => { + const pattern = this.jsPatterns[app.name][string][index]; + const value = results[string][index]; + + if ( pattern.regex.test(value) ) { + this.addDetected(app, pattern, 'js', value); + } + }); + }); + } + /** * Analyze robots.txt */ diff --git a/yarn.lock b/yarn.lock index c87638c01..afff3337d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,26 +2,31 @@ # yarn lockfile v1 -file-type@3.8.*: - version "3.8.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.8.0.tgz#bcadf6a8f624ebe4a10e5ad26727b6b93f16d78d" +file-type@7.4.*: + version "7.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.4.0.tgz#2a7c94f62a0030150bb7d9b6c70cfa1d3e759c86" html-comment-regex@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" -is-svg@2.0.*: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.0.1.tgz#f93ab3bf1d6bbca30e9753cd3485b1300eebc013" +is-svg@2.1.*: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" dependencies: html-comment-regex "^1.1.0" -pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" -read-chunk@2.0.*: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.0.0.tgz#3246e877829116cec059674c4d5f300f7a9261f3" +read-chunk@2.1.*: + version "2.1.0" + resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655" dependencies: - pify "^2.3.0" + pify "^3.0.0" + safe-buffer "^5.1.1" + +safe-buffer@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"