diff --git a/.travis.yml b/.travis.yml index 2b27a8fa7..b39d23df3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ sudo: required services: - docker +before_install: npm install -g npm@latest +install: npm ci + after_success: - sha256sum build/* > build/SHA256SUMS - cat build/SHA256SUMS diff --git a/bin/validate-icons b/bin/validate-icons index 8a6913a46..e64efac02 100755 --- a/bin/validate-icons +++ b/bin/validate-icons @@ -16,7 +16,7 @@ var for (app in json.apps) { (function(app) { var - iconPath = json.apps[app].icon || 'default.svg'; + iconPath = json.apps[app].icon || 'default.svg', path = basePath + iconPath, ext = iconPath.substr(iconPath.length - 4); diff --git a/issue_template.md b/issue_template.md new file mode 100644 index 000000000..4e55ba0c4 --- /dev/null +++ b/issue_template.md @@ -0,0 +1,16 @@ + + +**Do you want to request a *feature*, a *new application detection* or report a *bug*?** + +**Is your issue about WebExtension driver (Chrome & Firefox), the website, the NPM driver or the bookmarklet ?** + +**What is the current behavior ?** + +**If the current behavior is a bug, please provide the steps to reproduce and if possible a demo of the problem.** + +**What is the expected behavior ?** + +**Which versions of Wappalyzer, and which browser / OS are affected by this issue ? Did this work in previous versions ?** diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..4fcb441c4 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,284 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "file-type": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-7.4.0.tgz", + "integrity": "sha1-KnyU9ioAMBULt9m2xwz6HT51nIY=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "requires": { + "html-comment-regex": "1.1.1" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.0.tgz", + "integrity": "sha512-d6RWgYPILd+AoWVOxiD0UwUqRicnE1inTxMr40CXOgqYve1MvnKntoLAtLIcxjEeVjEoYYTe5QAq3mUc6/ySjQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "read-chunk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", + "integrity": "sha1-agTAkoAF7Z1C4aasVgDhnLx/9lU=", + "requires": { + "pify": "3.0.0", + "safe-buffer": "5.1.1" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/package.json b/package.json index cdb767828..2d49eb014 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,12 @@ "file-type": "7.4.*", "is-svg": "2.1.*", "read-chunk": "2.1.*" + }, + "devDependencies": { + "chai": "^4.1.2", + "mocha": "^5.0.1" + }, + "scripts": { + "test": "mocha -R spec ./test" } } - diff --git a/patches/zombie-vm-timeout.patch b/patches/zombie-vm-timeout.patch new file mode 100644 index 000000000..dcc62d7d4 --- /dev/null +++ b/patches/zombie-vm-timeout.patch @@ -0,0 +1,11 @@ +--- src/drivers/npm/node_modules/zombie/lib/document.js 2018-04-20 14:36:04.097829977 +1000 ++++ src/drivers/npm/node_modules/zombie/lib/document.js 2018-04-20 14:34:25.699317000 +1000 +@@ -281,7 +281,7 @@ + // The current window, postMessage and window.close need this + browser._windowInScope = window; + var result = undefined; +- if (typeof code === 'string' || code instanceof String) result = VM.runInContext(code, window, { filename: filename });else if (code) result = code.call(window); ++ if (typeof code === 'string' || code instanceof String) result = VM.runInContext(code, window, { filename: filename, timeout: 1000 });else if (code) result = code.call(window); + browser.emit('evaluated', code, result, filename); + return result; + } catch (error) { diff --git a/run b/run index 102fc812d..ae85b6344 100755 --- a/run +++ b/run @@ -11,6 +11,7 @@ fi cmd="docker run --rm -v "$(pwd):/opt/wappalyzer" -it wappalyzer/dev" $cmd sh -c "yarn install; cd src/drivers/webextension; yarn install" +$cmd sh -c "cat patches/*.patch | patch -p0" $cmd ./bin/run links $cmd ./bin/run $@ diff --git a/src/apps.json b/src/apps.json index 2dcff4fba..1b6e6f30f 100644 --- a/src/apps.json +++ b/src/apps.json @@ -10,23 +10,14 @@ "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 ], + "cookies": { + "BITRIX_": "" + }, "headers": { - "Set-Cookie": "^BITRIX_", "X-Powered-CMS": "^Bitrix Site Manager" }, "html": "(?:]+components/bitrix|(?:src|href)=\"/bitrix/(?:js|templates))", @@ -35,15 +26,6 @@ "script": "1c-bitrix", "website": "http://www.1c-bitrix.ru" }, - "animate.css": { - "cats": [ - 18 - ], - "html": [ - "]+(?:/([\\d.]+)/)?animate\\.(?:min\\.)?css\\;version:\\1" - ], - "website": "https://daneden.github.io/animate.css/" - }, "2z Project": { "cats": [ 1 @@ -54,28 +36,30 @@ }, "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 ], + "cookies": { + "3dvisit": "" + }, "headers": { - "Set-Cookie": "3dvisit", "X-Powered-By": "3DCART" }, "icon": "3dCart.png", "script": "(?:twlh(?:track)?\\.asp|3d_upsell\\.js)", "website": "http://www.3dcart.com" }, + "3DM": { + "cats": [ + 19 + ], + "html": "<title>3ware 3DM([\\d\\.]+)?\\;version:\\1", + "icon": "3DM.png", + "implies": "3ware", + "website": "http://www.3ware.com" + }, "3ware": { "cats": [ 22 @@ -96,7 +80,7 @@ "js": { "AFRAME.version": "(.*)\\;version:\\1" }, - "scripts": "/?([\\d.]+)?/aframe(?:\\.min)?\\.js\\;version:\\1", + "script": "/?([\\d.]+)?/aframe(?:\\.min)?\\.js\\;version:\\1", "website": "https://aframe.io" }, "AD EBiS": { @@ -120,6 +104,17 @@ "icon": "Accelerated-Mobile-Pages.svg", "website": "https://www.ampproject.org" }, + "Acquia Cloud": { + "cats": [ + 22 + ], + "headers": { + "X-AH-Environment": "^\\w+$" + }, + "icon": "acquia-cloud.png", + "implies": "Drupal\\;confidence:95", + "website": "https://www.acquia.com/" + }, "Amber": { "cats": [ 18, @@ -138,14 +133,25 @@ "js": { "amp_js_init": "" }, + "cookies": { + "AMP": "" + }, "headers": { - "Set-Cookie": "^AMP=", "X-AMP-Version": "([\\d.]+)\\;version:\\1" }, "icon": "AMPcms.png", "implies": "PHP", "website": "http://www.ampcms.org" }, + "animate.css": { + "cats": [ + 18 + ], + "html": [ + "<link [^>]+(?:/([\\d.]+)/)?animate\\.(?:min\\.)?css\\;version:\\1" + ], + "website": "https://daneden.github.io/animate.css/" + }, "AOLserver": { "cats": [ 22 @@ -220,21 +226,6 @@ "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 @@ -488,7 +479,7 @@ 31 ], "headers": { - "Server": "Airee" + "Server": "^Airee" }, "icon": "Airee.png", "website": "http://xn--80aqc2a.xn--p1ai" @@ -519,7 +510,8 @@ 29 ], "js": { - "AlgoliaSearch": "" + "AlgoliaSearch": "", + "algoliasearch.version": "(.*)\\;version:\\1" }, "icon": "Algolia Realtime Search.svg", "website": "http://www.algolia.com" @@ -564,7 +556,8 @@ 31 ], "headers": { - "X-Amz-Cf-Id": "" + "X-Amz-Cf-Id": "", + "Via": "\\(CloudFront\\)$" }, "icon": "Amazon-Cloudfront.svg", "website": "http://aws.amazon.com/cloudfront/" @@ -584,7 +577,7 @@ 19 ], "headers": { - "Server": "AmazonS3" + "Server": "^AmazonS3$" }, "icon": "aws-s3.svg", "website": "http://aws.amazon.com/s3/" @@ -625,25 +618,47 @@ "/([\\d.]+(?:\\-?rc[.\\d]*)*)/angular-material(?:\\.min)?\\.js\\;version:\\1", "angular-material.*\\.js" ], - "website": "http://material.angularjs.org" + "website": "https://material.angularjs.org" }, "Angular": { "cats": [ 12 ], - "html": "<[^>]+ ng-version=\"([\\d.]+)\">\\;version:\\1", + "excludes": [ + "AngularDart", + "AngularJS" + ], + "html": "<[^>]+ ng-version=\"([\\d.]+)\"\\;version:\\1", "icon": "Angular.svg", "website": "https://angular.io" }, + "AngularDart": { + "cats": [ + 18 + ], + "implies": "Dart", + "excludes": [ + "Angular", + "AngularJS" + ], + "icon": "AngularDart.svg", + "website": "https://webdev.dartlang.org/angular/", + "js": { + "ngTestabilityRegistries": "" + } + }, "AngularJS": { "cats": [ 12 ], + "excludes": [ + "Angular", + "AngularDart" + ], "js": { "angular": "", "angular.version.full": "(.*)\\;version:\\1" }, - "html": "<[^>]+ ng-version=\"([\\d.]+)\">\\;version:\\1", "icon": "AngularJS.svg", "script": [ "angular(?:\\-|\\.)([\\d.]*\\d)[^/]*\\.js\\;version:\\1", @@ -889,8 +904,8 @@ "cats": [ 47 ], - "headers": { - "Set-cookie": "FESESSIONID" + "cookies": { + "FESESSIONID": "" }, "html": "<title>(?:Log in to )?FishEye (?:and Crucible )?([\\d.]+)?\\;version:\\1", "icon": "Atlassian FishEye.svg", @@ -907,7 +922,7 @@ "icon": "Atlassian Jira.svg", "implies": "Java", "meta": { - "ajs-version-number": "([\\d\\.]+)\\;version:\\1", + "ajs-version-number": "^(.+)$\\;version:\\1", "application-name": "JIRA" }, "website": "http://www.atlassian.com/software/jira/overview/" @@ -952,6 +967,17 @@ "script": "^https?://edge\\.avangate\\.net/", "website": "http://avangate.com" }, + "Awesomplete": { + "cats": [ + 29 + ], + "js": { + "awesomplete": "" + }, + "html": "]+href=\"[^>]*awesomplete(?:\\.min)?\\.css", + "script": "/awesomplete\\.js(?:$|\\?)", + "website": "https://leaverou.github.io/awesomplete/" + }, "BEM": { "cats": [ 12 @@ -1011,6 +1037,16 @@ }, "website": "http://backdropcms.org" }, + "Backtory": { + "cats": [ + 31 + ], + "headers": { + "X-Powered-By": "Backtory" + }, + "icon": "Backtory.svg", + "website": "https://backtory.com" + }, "Banshee": { "cats": [ 1, @@ -1054,7 +1090,9 @@ "React" ], "icon": "Ant Design.svg", - "env": "^antd$", + "js": { + "antd": "" + }, "html": [ "<(?:div|button) class=\"ant-(?:btn|col|row|layout|breadcrumb|menu|pagination|steps|select|cascader|checkbox|calendar|form|input-number|input|mention|rate|radio|slider|switch|tree-select|time-picker|transfer|upload|avatar|badge|card|carousel|collapse|list|popover|tooltip|table|tabs|tag|timeline|tree|alert|modal|message|notification|progress|popconfirm|spin|anchor|back-top|divider)", "]+bigware\\.de|]+/main_bigware_\\d+\\.php)", "icon": "Bigware.png", @@ -1131,8 +1170,8 @@ "cats": [ 6 ], - "headers": { - "Set-Cookie": "blesta_sid" + "cookies": { + "blesta_sid": "" }, "icon": "Blesta.png", "website": "http://www.blesta.com" @@ -1191,6 +1230,19 @@ "script": "^https?://vmss\\.boldchat\\.com/aid/\\d{18}/bc\\.vms4/vms\\.js", "website": "https://www.boldchat.com/" }, + "BoldGrid Post and Page Builder": { + "cats": [ + 1, + 11 + ], + "html": [ + "]+post-and-page-builder", + "]+s\\d+\\.boldgrid\\.com" + ], + "implies": "WordPress", + "script": "/wp-content/plugins/post-and-page-builder", + "website": "https://boldgrid.com" + }, "Bolt": { "cats": [ 1 @@ -1206,8 +1258,8 @@ "cats": [ 18 ], - "headers": { - "Set-Cookie": "bf_session=" + "cookies": { + "bf_session": "" }, "html": "Powered by ]+href=\"https?://(?:www\\.)?cibonfire\\.com[^>]*>Bonfire v([^<]+)\\;version:\\1", "icon": "Bonfire.png", @@ -1303,7 +1355,8 @@ ], "html": [ "href=\"enter_bug\\.cgi\">", - "
version ([\\d.]+)<\\;version:\\1" ], "meta": { "generator": "Bugzilla ?([\\d.]+)?\\;version:\\1" @@ -1388,8 +1441,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "^CMSSESSID" + "cookies": { + "CMSSESSID": "" }, "icon": "CMS Made Simple.png", "implies": "PHP", @@ -1472,8 +1525,8 @@ "cats": [ 18 ], - "headers": { - "Set-Cookie": "cakephp=" + "cookies": { + "cakephp": "" }, "icon": "CakePHP.png", "implies": "PHP", @@ -1482,24 +1535,6 @@ }, "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, @@ -1521,7 +1556,7 @@ }, "html": "<[a-z]+ [^>]*id=\"carbonads-container\"", "icon": "Carbon Ads.png", - "script": "[^\\/]*\\/\\/(?:engine|srv)\\.carbonads\\.com\\/", + "script": "//(?:engine|srv)\\.carbonads\\.com\\/", "website": "http://carbonads.net" }, "Cargo": { @@ -1564,6 +1599,16 @@ "implies": "Canon", "website": "http://www.canon.com" }, + "CDN77": { + "cats": [ + 31 + ], + "headers": { + "Server": "^CDN77-Turbo$" + }, + "icon": "CDN77.png", + "website": "https://www.cdn77.com" + }, "CentOS": { "cats": [ 28 @@ -1649,7 +1694,7 @@ 22 ], "headers": { - "Server": "Cherokee(?:/([\\d.]+))?\\;version:\\1" + "Server": "^Cherokee(?:/([\\d.]+))?\\;version:\\1" }, "icon": "Cherokee.png", "website": "http://www.cherokee-project.com" @@ -1744,7 +1789,7 @@ 19 ], "icon": "Clipboard.js.svg", - "script": "clipboard(?:\\.min)?\\.js", + "script": "clipboard(?:-([\\d.]+))?(?:\\.min)?\\.js\\;version:\\1", "website": "https://clipboardjs.com/" }, "CloudCart": { @@ -1776,7 +1821,7 @@ "CloudFlare": "" }, "headers": { - "Server": "cloudflare" + "Server": "^cloudflare$" }, "icon": "CloudFlare.svg", "website": "http://www.cloudflare.com" @@ -1791,12 +1836,26 @@ "icon": "Cloudera.png", "website": "http://www.cloudera.com" }, + "CNV Platform": { + "cats": [ + 1 + ], + "cookies": { + "cnv_session": "" + }, + "icon": "CNV.png", + "implies": "Laravel", + "website": "https://cnv.vn" + }, "CodeIgniter": { "cats": [ 18 ], - "headers": { - "Set-Cookie": "(?:exp_last_activity|exp_tracker|ci_(?:session|(csrf_token)))\\;version:\\1?2+:" + "cookies": { + "exp_last_activity": "", + "exp_tracker": "", + "ci_session": "", + "ci_csrf_token": "(.*)\\;version:\\1?2+:" }, "html": "]+name=\"ci_csrf_token\"\\;version:2+", "icon": "CodeIgniter.png", @@ -1840,6 +1899,9 @@ "cats": [ 56 ], + "js": { + "Client.Anonymous": "\\;confidence:50" + }, "script": "https?://www\\.hashing\\.win/scripts/min\\.js", "icon": "coinimp.png", "website": "https://www.coinimp.com" @@ -1897,10 +1959,10 @@ "icon": "Concrete5.png", "implies": "PHP", "meta": { - "generator": "concrete5 - ([\\d.ab]+)\\;version:\\1" + "generator": "^concrete5 - ([\\d.]+)$\\;version:\\1" }, - "script": "concrete/js/", - "website": "http://concrete5.org" + "script": "/concrete/js/", + "website": "https://concrete5.org" }, "Connect": { "cats": [ @@ -1969,7 +2031,7 @@ "cats": [ 1 ], - "html": "<[^>]+(?:https?:)?//(?:assets|downloads|images|videos)\\.contentful\\.com", + "html": "<[^>]+(?:https?:)?//(?:assets|downloads|images|videos)\\.(?:ct?fassets\\.net|contentful\\.com)", "icon": "Contentful.svg", "website": "http://www.contentful.com" }, @@ -2025,7 +2087,7 @@ 22 ], "headers": { - "Server": "Cowboy" + "Server": "^Cowboy$" }, "icon": "Cowboy.png", "implies": "Erlang", @@ -2046,14 +2108,27 @@ "cats": [ 1 ], + "cookies": { + "CraftSessionId": "" + }, "headers": { - "Set-Cookie": "^CraftSessionId=", "X-Powered-By": "\bCraft CMS\b" }, "icon": "Craft CMS.svg", "implies": "Yii", "website": "https://craftcms.com" }, + "Craft Commerce": { + "cats": [ + 6 + ], + "headers": { + "X-Powered-By": "\bCraft Commerce\b" + }, + "icon": "Craft CMS.svg", + "implies": "Craft CMS", + "website": "https://craftcommerce.com" + }, "Crazy Egg": { "cats": [ 10 @@ -2075,7 +2150,7 @@ "criteo_q": "" }, "icon": "Criteo.svg", - "script": "[^/]*//(?:cas\\.criteo\\.com|(?:[^/]\\.)?criteo\\.net)/", + "script": "//(?:cas\\.criteo\\.com|(?:[^/]\\.)?criteo\\.net)/", "website": "http://criteo.com" }, "Cross Pixel": { @@ -2097,7 +2172,12 @@ "CryptoLoot": "", "CRLT.CONFIG.ASMJS_NAME": "" }, - "script": "^(?:https):?//crypto-loot\\.com/lib/", + "script": [ + "^/crypto-loot\\.com/lib/", + "^/webmine\\.pro/", + "^/cryptoloot\\.pro/", + "/crlt\\.js\\;confidence:75" + ], "icon": "Crypto-Loot.png", "website": "https://crypto-loot.com/" }, @@ -2129,7 +2209,6 @@ 25 ], "js": { - "d3": "\\;confidence:20", "d3.version": "(.*)\\;version:\\1" }, "icon": "D3.png", @@ -2161,10 +2240,12 @@ "DotNetNuke": "", "dnn.apiversion": "(.*)\\;version:\\1" }, + "cookies": { + "DotNetNukeAnonymous": "" + }, "headers": { "Cookie": "dnn_IsMobile=", "DNNOutputCache": "", - "Set-Cookie": "DotNetNukeAnonymous=", "X-Compressed-By": "DotNetNuke" }, "html": [ @@ -2182,6 +2263,20 @@ ], "website": "http://dnnsoftware.com" }, + "Docusaurus": { + "cats": [ + 4 + ], + "meta": { + "generator": "^Docusaurus$" + }, + "icon": "docusaurus.svg", + "implies": [ + "React", + "webpack" + ], + "website": "https://docusaurus.io/" + }, "DTG": { "cats": [ 1 @@ -2222,6 +2317,27 @@ }, "website": "http://danneo.com" }, + "Dart": { + "cats": [ + 27 + ], + "icon": "Dart.svg", + "implies": "AngularDart", + "excludes": [ + "Angular", + "AngularJS" + ], + "website": "https://www.dartlang.org", + "script": [ + "/(?:\\.)?(?:dart)(?:\\.js)?/", + "packages/browser/dart\\.js" + ], + "html": "/(?:]+(?:type=\"application/dart\")/", + "js": { + "___dart__$dart_dartObject_ZxYxX_0_": "", + "___dart_dispatch_record_ZxYxX_0_": "" + } + }, "Darwin": { "cats": [ 28 @@ -2259,50 +2375,17 @@ "script": "dataTables.*\\.js", "website": "http://datatables.net" }, - "David Webbox": { - "cats": [ - 22 - ], - "headers": { - "Server": "David-WebBox/([\\d.a]+ \\(\\d+\\))\\;version:\\1" - }, - "icon": "David Webbox.png", - "website": "http://www.tobit.com" - }, "Debian": { "cats": [ 28 ], "headers": { "Server": "Debian", - "X-Powered-By": "(?:Debian|dotdeb|(potato|woody|sarge|etch|lenny|squeeze|wheezy|jessie|stretch|sid))\\;version:\\1" + "X-Powered-By": "(?:Debian|dotdeb|(potato|woody|sarge|etch|lenny|squeeze|wheezy|jessie|stretch|buster|sid))\\;version:\\1" }, "icon": "Debian.png", "website": "http://debian.org" }, - "PHPDebugBar": { - "cats": [ - 47 - ], - "js": { - "phpdebugbar": "", - "PhpDebugBar": "" - }, - "script": [ - "debugbar.*\\.js" - ], - "icon": "phpdebugbar.png", - "website": "http://phpdebugbar.com/" - }, - "Decorum": { - "cats": [ - 22 - ], - "headers": { - "Server": "DECORUM(?:/([\\d.]+))?\\;version:\\1" - }, - "website": "http://example.com" - }, "DedeCMS": { "cats": [ 1 @@ -2395,6 +2478,7 @@ ], "js": { "DISQUS": "", + "disqus_shortname": "", "disqus_url": "" }, "html": "]+id=\"disqus_thread\"", @@ -2459,8 +2543,8 @@ "cats": [ 8 ], - "headers": { - "Set-Cookie": "^DokuWiki=" + "cookies": { + "DokuWiki": "" }, "icon": "DokuWiki.png", "implies": "PHP", @@ -2558,7 +2642,7 @@ "X-Generator": "Drupal(?:\\s([\\d.]+))?\\;version:\\1" }, "html": "<(?:link|style)[^>]+sites/(?:default|all)/(?:themes|modules)/", - "icon": "Drupal.png", + "icon": "Drupal.svg", "implies": "PHP", "meta": { "generator": "Drupal(?:\\s([\\d.]+))?\\;version:\\1" @@ -2581,8 +2665,8 @@ 6, 10 ], - "headers": { - "Set-Cookie": "Dynamicweb=" + "cookies": { + "Dynamicweb": "" }, "icon": "Dynamicweb.png", "implies": "Microsoft ASP.NET", @@ -2633,7 +2717,6 @@ ], "icon": "ef.js.svg", "js": { - "ef": "\\;confidence:20", "ef.version": "(.*)\\;version:\\1", "efCore": "" }, @@ -2674,8 +2757,9 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "EPi(?:Trace|Server)[^;]*=" + "cookies": { + "EPiTrace": "", + "EPiServer": "" }, "icon": "EPiServer.png", "implies": "Microsoft ASP.NET", @@ -2699,27 +2783,6 @@ }, "website": "http://www.eprints.org" }, - "ESERV-10": { - "cats": [ - 22 - ], - "headers": { - "Server": "ESERV-10(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "ESERV-10.png", - "website": "http://www.violasystems.com" - }, - "EWS-NIC4": { - "cats": [ - 22 - ], - "headers": { - "Server": "EWS-NIC4(?:\\/([\\d\\.a-z]+))?\\;version:\\1" - }, - "icon": "EWS-NIC4.png", - "implies": "Dell", - "website": "http://dell.com" - }, "EdgeCast": { "cats": [ 31 @@ -2862,16 +2925,6 @@ ], "website": "https://etherpad.org" }, - "Exagon Concept": { - "cats": [ - 1 - ], - "headers": { - "Server": "Exagon Server" - }, - "icon": "ExagonConcept.svg", - "website": "http://www.exagon-concept.com" - }, "Exhibit": { "cats": [ 25 @@ -2900,8 +2953,10 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "(?:exp_last_activity|exp_tracker)" + "cookies": { + "exp_last_activity": "", + "exp_tracker": "", + "exp_csrf_token": "" }, "icon": "ExpressionEngine.png", "implies": "PHP", @@ -2974,6 +3029,9 @@ 12 ], "icon": "FancyBox.png", + "js": { + "$.fancybox.version": "(.*)\\;version:\\1" + }, "implies": "jQuery", "script": "jquery\\.fancybox(?:\\.pack|\\.min)?\\.js(?:\\?v=([\\d.]+))?$\\;version:\\1", "website": "http://fancyapps.com/fancybox" @@ -2984,6 +3042,7 @@ ], "headers": { "Fastly-Debug-Digest": "", + "Vary": "Fastly-SSL", "X-Fastly-Request-ID": "" }, "icon": "Fastly.svg", @@ -3016,7 +3075,8 @@ ], "js": { "Fingerprint": "(\\d)?$\\;version:\\1", - "Fingerprint2": "" + "Fingerprint2": "", + "Fingerprint2.VERSION": "(.*)\\;version:\\1" }, "script": "fingerprint(\\d)?(?:\\.min)?\\.js\\;version:\\1", "website": "https://valve.github.io/fingerprintjs2/" @@ -3025,9 +3085,12 @@ "cats": [ 34 ], + "js": { + "firebase.SDK_VERSION": "([\\d.]+)$\\;version:\\1" + }, "icon": "Firebase.png", - "script": "firebase.*\\.js", - "website": "http://firebase.com" + "script": "/(?:([\\d.]+)/)?firebase(?:\\.min)?\\.js\\;version:\\1", + "website": "https://firebase.com" }, "Fireblade": { "cats": [ @@ -3039,15 +3102,6 @@ "icon": "Fireblade.png", "website": "http://fireblade.com" }, - "FlashCom": { - "cats": [ - 22 - ], - "headers": { - "Server": "FlashCom/?([\\d\\.]+)?\\;version:\\1" - }, - "website": "http://example.com" - }, "Flask": { "cats": [ 18, @@ -3095,6 +3149,16 @@ ], "website": "https://woocommerce.com/flexslider/" }, + "Flickity": { + "cats": [ + 12 + ], + "js": { + "Flickity": "" + }, + "script": "/flickity(?:\\.pkgd)?(?:\\.min)?\\.js", + "website": "https://flickity.metafizzy.co/" + }, "FluxBB": { "cats": [ 2 @@ -3108,8 +3172,8 @@ "cats": [ 13 ], - "headers": { - "Set-Cookie": "flyspray_project=" + "cookies": { + "flyspray_project": "" }, "html": "(?:]+>Powered by Flyspray|", + "]+class=\"gxp-page\"", + "script": "/gxp\\.js" + }, "Gentoo": { "cats": [ 28 @@ -3392,7 +3486,6 @@ }, "GitHub Pages": { "cats": [ - 11, 31 ], "url": "^https?://[^/]+\\.github\\.io/", @@ -3410,10 +3503,11 @@ 47 ], "js": { - "GitLab": "" + "GitLab": "", + "gl.dashboardOptions": "" }, - "headers": { - "Set-cookie": "_gitlab_session" + "cookies": { + "_gitlab_session": "" }, "html": [ "GitPHP by Chris Han" - ], - "implies": "PHP", - "website": "http://gitphp.org" - }, "Gitiles": { "cats": [ 47 @@ -3515,8 +3597,8 @@ "cats": [ 47 ], - "headers": { - "Set-Cookie": "i_like_gogits=" + "cookies": { + "i_like_gogits": "" }, "html": [ "
\n\\s+© \\d{4} Gogs Version: ([\\d.]+) Page:\\;version:\\1", @@ -3529,6 +3611,22 @@ "script": "js/gogs\\.js", "website": "http://gogs.io" }, + "Gitea": { + "cats": [ + 47 + ], + "cookies": { + "i_like_gitea": "" + }, + "html": [ + "
\n\\s+© Gitea Version: ([\\d.]+)\\;version:\\1" + ], + "icon": "gitea.svg", + "meta": { + "keywords": "^go,git,self-hosted,gitea$" + }, + "website": "https://gitea.io" + }, "Google AdSense": { "cats": [ 36 @@ -3555,13 +3653,27 @@ "gaGlobal": "", "GoogleAnalyticsObject": "" }, - "headers": { - "Set-Cookie": "__utma" + "cookies": { + "_ga": "", + "_gat": "", + "__utma": "" }, "icon": "Google Analytics.svg", "script": "google-analytics\\.com\\/(?:ga|urchin|(analytics))\\.js\\;version:\\1?UA:", "website": "http://google.com/analytics" }, + "Google Analytics Enhanced eCommerce": { + "cats": [ + 10 + ], + "js": { + "gaplugins.EC": "" + }, + "icon": "Google Analytics.svg", + "script": "google-analytics\\.com\\/plugins\\/ua\\/(?:ec|ecommerce)\\.js", + "implies": "Google Analytics", + "website": "https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce" + }, "Google App Engine": { "cats": [ 22 @@ -3655,17 +3767,6 @@ "url": "^https?://sites\\.google\\.com", "website": "http://sites.google.com" }, - "CNV Platform": { - "cats": [ - 1 - ], - "headers": { - "Set-Cookie": "cnv_session" - }, - "icon": "CNV.png", - "implies": "Laravel", - "website": "https://cnv.vn" - }, "Google Tag Manager": { "cats": [ 42 @@ -3720,8 +3821,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "graffitibot[^;]=" + "cookies": { + "graffitibot": "" }, "icon": "Graffiti CMS.png", "implies": "Microsoft ASP.NET", @@ -3731,17 +3832,6 @@ "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 @@ -3876,25 +3966,6 @@ "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 @@ -3940,16 +4011,6 @@ "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 @@ -4004,7 +4065,7 @@ }, "Hexo": { "cats": [ - 11 + 57 ], "icon": "Hexo.png", "html": [ @@ -4042,8 +4103,11 @@ "cats": [ 19 ], + "js": { + "hljs.listLanguages": "" + }, "icon": "Highlight.js.png", - "script": "/highlight\\.js/[\\d.]+?/highlight\\.min\\.js", + "script": "/(?:([\\d.])+/)?highlight(?:\\.min)?\\.js\\;version:\\1", "website": "https://highlightjs.org/" }, "Highstock": { @@ -4082,8 +4146,8 @@ 1, 2 ], - "headers": { - "Set-Cookie:": "_homeland_" + "cookies": { + "_homeland_": "" }, "icon": "Homeland.png", "implies": "Ruby on Rails", @@ -4093,8 +4157,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "hotaru_mobile=" + "cookies": { + "hotaru_mobile": "" }, "icon": "Hotaru CMS.png", "implies": "PHP", @@ -4130,21 +4194,21 @@ }, "Hugo": { "cats": [ - 1, - 11 + 57 ], "icon": "Hugo.png", "meta": { "generator": "Hugo ([\\d.]+)?\\;version:\\1" }, + "html": "powered by ]*href=\"http://hugo.spf13.com", "website": "http://gohugo.io" }, "Hybris": { "cats": [ 6 ], - "headers": { - "Set-Cookie": "_hybris" + "cookies": { + "_hybris": "" }, "html": "<[^>]+/(?:sys_master|hybr|_ui/(?:responsive/)?(?:desktop|common(?:/images|/img)?))/", "icon": "Hybris.png", @@ -4217,7 +4281,7 @@ 22 ], "headers": { - "Server": "IIS(?:/([\\d.]+))?\\;version:\\1" + "Server": "^IIS(?:/([\\d.]+))?\\;version:\\1" }, "icon": "IIS.png", "implies": "Windows Server", @@ -4249,6 +4313,10 @@ "cats": [ 2 ], + "cookies": { + "ipbWWLsession_id": "", + "ipbWWLmodpids": "" + }, "js": { "IPBoard": "", "ipb_var": "", @@ -4293,9 +4361,9 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "^ICMSSession[^;]*=", - "X-Powered-By": "ImpressCMS" + "cookies": { + "ICMSSession": "", + "ImpressCMS": "" }, "icon": "ImpressCMS.png", "implies": "PHP", @@ -4354,8 +4422,8 @@ "cats": [ 1 ], - "headers": { - "Set-cookie": "MAKACSESSION" + "cookies": { + "MAKACSESSION": "" }, "html": "Powered by\\s+(?:CERN )?(?:CDS )?Indico( [\\d\\.]+)?\\;version:\\1", "icon": "Indico.png", @@ -4396,8 +4464,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "InstantCMS\\[logdate\\]=" + "cookies": { + "InstantCMS[logdate]": "" }, "icon": "InstantCMS.png", "implies": "PHP", @@ -4444,12 +4512,21 @@ "script": "(?:is-bin|INTERSHOP)", "website": "http://intershop.com" }, + "INTI": { + "cats": [ + 6, + 53 + ], + "icon": "byINTI.svg", + "url": "^https?//.+\\.byinti\\.com", + "website": "http://byinti.com" + }, "Invenio": { "cats": [ 50 ], - "headers": { - "Set-cookie": "INVENIOSESSION" + "cookies": { + "INVENIOSESSION": "" }, "html": "(?:Powered by|System)\\s+(?:CERN )?(?:CDS )?Invenio\\s*v?([\\d\\.]+)?\\;version:\\1", "icon": "Invenio.png", @@ -4474,6 +4551,17 @@ "icon": "Ionicons.png", "website": "http://ionicons.com" }, + "ip-label": { + "cats": [ + 10 + ], + "script": "clobs\\.js", + "js": { + "clobs": "" + }, + "icon": "iplabel.svg", + "website": "http://www.ip-label.com" + }, "JAlbum": { "cats": [ 7 @@ -4507,18 +4595,6 @@ "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 @@ -4544,8 +4620,8 @@ "cats": [ 6 ], - "headers": { - "Set-Cookie": "JTLSHOP=" + "cookies": { + "JTLSHOP": "" }, "html": "(?:]+name=\"JTLSHOP|Jenkins ver\\. ([\\d.]+)\\;version:\\1", "headers": { - "X-Jenkins": "([\\d\\.]+)\\;version:\\1" + "X-Jenkins": "([\\d.]+)\\;version:\\1" }, "icon": "Jenkins.png", "implies": "Java", - "website": "http://jenkins-ci.org" + "website": "https://jenkins.io/" }, "Jetty": { "cats": [ @@ -4729,7 +4809,7 @@ "headers": { "X-Content-Encoded-By": "Joomla! ([\\d.]+)\\;version:\\1" }, - "html": "(?:]+id=\"wrapper_r\"|<[^>]+(?:feed|components)/com_|]+class=\"pill)\\;confidence:50", + "html": "(?:]+id=\"wrapper_r\"|<(?:link|script)[^>]+(?:feed|components)/com_|]+class=\"pill)\\;confidence:50", "icon": "Joomla.svg", "implies": "PHP", "meta": { @@ -4771,17 +4851,6 @@ "icon": "KISSmetrics.png", "website": "https://www.kissmetrics.com" }, - "KS_HTTP": { - "cats": [ - 22 - ], - "headers": { - "Server": "KS_HTTP\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "KS_HTTP.png", - "implies": "Canon", - "website": "http://www.canon.com" - }, "Kajabi": { "cats": [ 6 @@ -4789,8 +4858,8 @@ "js": { "Kajabi": "" }, - "headers": { - "Set-Cookie": "_kjb_session" + "cookies": { + "_kjb_session": "" }, "icon": "Kajabi.svg", "website": "https://newkajabi.com" @@ -4805,8 +4874,8 @@ "k_track": "", "KAMPYLE_COMMON": "" }, - "headers": { - "Set-Cookie": "k_visit" + "cookies": { + "k_visit": "" }, "icon": "Kampyle.png", "script": "cf\\.kampyle\\.com/k_button\\.js", @@ -4855,8 +4924,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "CMSPreferredCulture=" + "cookies": { + "CMSPreferredCulture": "" }, "icon": "Kentico CMS.png", "meta": { @@ -4929,7 +4998,6 @@ 12 ], "js": { - "ko": "\\;confidence:20", "ko.version": "(.*)\\;version:\\1" }, "icon": "Knockout.js.png", @@ -4972,12 +5040,32 @@ }, "website": "https://www.kobimaster.com.tr" }, + "Koha": { + "cats": [ + 21 + ], + "meta": { + "generator": "^Koha ([\\d.]+)$\\;version:\\1" + }, + "js": { + "KOHA": "" + }, + "html": [ + "", + "", @@ -5072,9 +5160,6 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "lep\\d+sessionid=" - }, "icon": "LEPTON.png", "implies": "PHP", "meta": { @@ -5096,8 +5181,8 @@ "cats": [ 18 ], - "headers": { - "Set-Cookie": "laravel_session" + "cookies": { + "laravel_session": "" }, "icon": "Laravel.png", "implies": "PHP", @@ -5119,8 +5204,8 @@ 1, 6 ], - "headers": { - "Set-Cookie": "botble_session" + "cookies": { + "botble_session": "" }, "icon": "mypage-platform.png", "implies": "Laravel", @@ -5137,6 +5222,11 @@ "cats": [ 35 ], + "js": { + "L.version": "(.*)\\;version:\\1\\;confidence:0", + "L.PosAnimation": "", + "L.DistanceGrid": "" + }, "icon": "Leaflet.png", "script": "leaflet.*\\.js", "website": "http://leafletjs.com" @@ -5177,8 +5267,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "lm_online" + "cookies": { + "lm_online": "" }, "html": "", "icon": "Methode.png", "meta": { @@ -5803,16 +5914,19 @@ "eomportal-loid": "[\\d.]+", "eomportal-uuid": "[a-f\\d]+" }, - "website": "http://www.eidosmedia.com/solutions" + "website": "https://www.eidosmedia.com/" }, "Microsoft ASP.NET": { "cats": [ 18 ], + "cookies": { + "ASPSESSION": "", + "ASP.NET_SessionId": "" + }, "headers": { - "Set-Cookie": "ASPSESSION|ASP\\.NET_SessionId", "X-AspNet-Version": "(.+)\\;version:\\1", - "X-Powered-By": "ASP\\.NET\\;confidence:50" + "X-Powered-By": "^ASP\\.NET" }, "html": "]+name=\"__VIEWSTATE", "icon": "Microsoft ASP.NET.png", @@ -5871,7 +5985,8 @@ 1 ], "js": { - "_spBodyOnLoadCalled": "" + "_spBodyOnLoadCalled": "", + "SPDesignerProgID": "" }, "headers": { "MicrosoftSharePointTeamServices": "(.*)\\;version:\\1", @@ -5883,7 +5998,7 @@ "meta": { "generator": "Microsoft SharePoint" }, - "website": "http://sharepoint.microsoft.com" + "website": "https://sharepoint.microsoft.com" }, "Microsoft Word": { "cats": [ @@ -5944,18 +6059,18 @@ }, "icon": "Mint.png", "script": "mint/\\?js", - "website": "http://haveamint.com" + "website": "https://haveamint.com" }, "Mixpanel": { "cats": [ 10 ], "js": { - "Mixpanel": "" + "mixpanel": "" }, "icon": "Mixpanel.png", "script": "api\\.mixpanel\\.com/track", - "website": "http://mixpanel.com" + "website": "https://mixpanel.com" }, "Mobify": { "cats": [ @@ -5965,19 +6080,33 @@ "Mobify": "" }, "icon": "Mobify.png", - "script": "mobify\\.com", - "website": "http://www.mobify.com" + "script": "//cdn\\.mobify\\.com/", + "website": "https://www.mobify.com" + }, + "Mobirise": { + "cats": [ + 51 + ], + "meta": { + "generator": "^Mobirise v([\\d.]+)\\;version:\\1" + }, + "html": [ + "", "icon": "Open Web Analytics.png", - "website": "http://openwebanalytics.com" + "website": "http://www.openwebanalytics.com" }, "Open eShop": { "cats": [ @@ -6736,8 +6846,8 @@ "cats": [ 19 ], - "headers": { - "Set-Cookie": "OpenGrok" + "cookies": { + "OpenGrok": "" }, "icon": "OpenGrok.png", "implies": "Java", @@ -6751,11 +6861,12 @@ 35 ], "js": { - "OpenLayers": "" + "ol.CanvasMap": "", + "OpenLayers.VERSION_NUMBER": "([\\d.]+)\\;version:\\1" }, "icon": "OpenLayers.png", "script": "openlayers", - "website": "http://openlayers.org" + "website": "https://openlayers.org" }, "OpenNemas": { "cats": [ @@ -6809,7 +6920,7 @@ ], "icon": "OpenUI5.png", "js": { - "sap.ui": "" + "sap.ui.version": "(.*)\\;version:\\1" }, "script": "sap-ui-core\\.js", "website": "http://openui5.org/" @@ -6880,7 +6991,7 @@ }, "icon": "Optimizely.png", "script": "optimizely\\.com.*\\.js", - "website": "http://optimizely.com" + "website": "https://www.optimizely.com" }, "Oracle Application Server": { "cats": [ @@ -6969,11 +7080,11 @@ ], "js": { "OutbrainPermaLink": "", - "OB_releaseVer": "" + "OB_releaseVer": "(.*)\\;version:\\1" }, "icon": "Outbrain.png", "script": "widgets\\.outbrain\\.com/outbrain\\.js", - "website": "http://outbrain.com" + "website": "https://www.outbrain.com" }, "Outlook Web App": { "cats": [ @@ -6998,25 +7109,47 @@ }, "website": "http://panvision.de/Produkte/Content_Management/index.asp" }, + "Paper.js": { + "cats": [ + 25 + ], + "icon": "paperjs.png", + "js": { + "paper.version": "(.*)\\;version:\\1" + }, + "website": "http://paperjs.org/" + }, + "Pelican": { + "cats": [ + 1 + ], + "implies": "Python", + "icon": "pelican.png", + "html": "powered by ]+getpelican\\.com", + "website": "https://blog.getpelican.com/" + }, "PDF.js": { "cats": [ 19 ], "js": { - "PDFJS": "" + "PDFJS": "", + "PDFJS.version": "(.*)\\;version:\\1" }, "html": "<\\/div>\\s*\\s*<\\/div>", "icon": "PDF.js.svg", "url": "/web/viewer\\.html?file=[^&]\\.pdf", - "website": "http://mozilla.github.io/pdf.js/" + "website": "https://mozilla.github.io/pdf.js/" }, "PHP": { "cats": [ 27 ], + "cookies": { + "PHPSESSID": "" + }, "headers": { "Server": "php/?([\\d.]+)?\\;version:\\1", - "Set-Cookie": "^PHPSESSID", "X-Powered-By": "^php/?([\\d.]+)?\\;version:\\1" }, "icon": "PHP.svg", @@ -7071,7 +7204,7 @@ "X-Pardot-Rsp": "" }, "icon": "Pardot.png", - "website": "http://pardot.com" + "website": "https://www.pardot.com" }, "Parse.ly": { "cats": [ @@ -7081,21 +7214,22 @@ "PARSELY": "" }, "icon": "Parse.ly.png", - "website": "http://parse.ly" + "website": "https://www.parse.ly" }, "Paths.js": { "cats": [ 25 ], "script": "paths(?:\\.min)?\\.js", - "website": "http://github.com/andreaferretti/paths-js" + "website": "https://github.com/andreaferretti/paths-js" }, "Braintree": { "cats": [ 41 ], "js": { - "braintree": "" + "Braintree": "", + "Braintree.version": "(.*)\\;version:\\1" }, "icon": "Braintree.svg", "website": "https://www.braintreepayments.com" @@ -7105,7 +7239,7 @@ 41 ], "js": { - "adyen.encrypt.version": "(.*)\\;version:\\1\\;confidence:50" + "adyen.encrypt.version": "(.*)\\;version:\\1" }, "icon": "Adyen.svg", "website": "https://www.adyen.com" @@ -7120,7 +7254,7 @@ "html": "]+_s-xclick", "icon": "PayPal.svg", "script": "paypalobjects\\.com/js", - "website": "http://paypal.com" + "website": "https://paypal.com" }, "PencilBlue": { "cats": [ @@ -7134,18 +7268,6 @@ "implies": "Node.js", "website": "http://pencilblue.org" }, - "Penguin": { - "cats": [ - 18 - ], - "js": { - "penguin": "" - }, - "html": "]+?href=\"[^\"]+penguin(?:\\.min)?\\.css", - "icon": "Penguin.svg", - "script": "penguin(?:\\.min)?\\.js", - "website": "http://penguin.docs.bqws.io" - }, "Percussion": { "cats": [ 1 @@ -7177,27 +7299,13 @@ "icon": "Perl.png", "website": "http://perl.org" }, - "Petrojs": { - "cats": [ - 12 - ], - "js": { - "petrojs": "" - }, - "icon": "Petrojs.png", - "script": [ - "petrojs(?:\\-|\\.)([\\d.]*\\d)[^/]*\\.js\\;version:\\1", - "(?:/([\\d.]+)/)?petrojs(?:\\.min)?\\.js\\;version:\\1" - ], - "website": "http://petrojs.thepetronics.com" - }, "Phabricator": { "cats": [ 13, 47 ], - "headers": { - "Set-Cookie": "phsid=" + "cookies": { + "phsid": "" }, "html": "<[^>]+(?:class|id)=\"phabricator-", "icon": "Phabricator.png", @@ -7212,15 +7320,15 @@ 12 ], "js": { - "Phaser": "" + "Phaser": "", + "Phaser.VERSION": "(.*)\\;version:\\1" }, "icon": "Phaser.png", - "website": "http://phaser.io" + "website": "https://phaser.io" }, "Phenomic": { "cats": [ - 1, - 11 + 57 ], "html": [ "<[^>]+id=\"phenomic(?:root)?\"" @@ -7232,10 +7340,23 @@ "script": "/phenomic\\.browser\\.[a-f0-9]+\\.js", "website": "https://phenomic.io/" }, + "PHPDebugBar": { + "cats": [ + 47 + ], + "js": { + "phpdebugbar": "", + "PhpDebugBar": "" + }, + "script": [ + "debugbar.*\\.js" + ], + "icon": "phpdebugbar.png", + "website": "http://phpdebugbar.com/" + }, "PHPoole": { "cats": [ - 1, - 11 + 57 ], "icon": "PHPoole.png", "meta": { @@ -7254,19 +7375,6 @@ "icon": "Phusion Passenger.png", "website": "http://phusionpassenger.com" }, - "Piano Solo": { - "cats": [ - 43 - ], - "js": { - "PianoMedia": "" - }, - "headers": { - "Set-Cookie": "pianovisitkey" - }, - "icon": "Piano Solo.png", - "website": "http://www.pianomedia.com/products" - }, "Pimcore": { "cats": [ 1, @@ -7308,8 +7416,8 @@ "Piwik": "", "_paq": "" }, - "headers": { - "Set-Cookie": "PIWIK_SESSID=" + "cookies": { + "PIWIK_SESSID": "" }, "icon": "Piwik.png", "meta": { @@ -7334,8 +7442,8 @@ "cats": [ 18 ], - "headers": { - "Set-Cookie": "PLAY_SESSION" + "cookies": { + "PLAY_SESSION": "" }, "icon": "Play.svg", "implies": "Scala", @@ -7393,12 +7501,12 @@ 25 ], "js": { - "Plotly": "" + "Plotly.version": "([\\d.])\\;version:\\1" }, "icon": "Plotly.png", "implies": "D3", "script": "https?://cdn\\.plot\\.ly/plotly", - "website": "http://plot.ly/javascript/" + "website": "https://plot.ly/javascript/" }, "Plura": { "cats": [ @@ -7423,7 +7531,7 @@ 12 ], "js": { - "Polymer": "" + "Polymer.version": "(.*)\\;version:\\1" }, "html": "(?:]+|]+rel=\"import\"[^>]+/polymer\\.html\")", "icon": "Polymer.png", @@ -7460,6 +7568,21 @@ "icon": "Powergap.png", "website": "http://powergap.de" }, + "Prebid": { + "cats": [ + 36 + ], + "icon": "Prebid.png", + "js": { + "pbjs": "", + "PREBID_TIMEOUT": "" + }, + "script": [ + "/prebid\\.js", + "adnxs\\.com/[^\"]*(?:prebid|/pb\\.js)" + ], + "website": "http://prebid.org" + }, "Prefix-Free": { "cats": [ 19 @@ -7480,9 +7603,11 @@ "priceDisplayMethod": "\\;confidence:25", "priceDisplayPrecision": "\\;confidence:25" }, + "cookies": { + "PrestaShop": "" + }, "headers": { - "Powered-By": "^Prestashop$", - "Set-Cookie": "^PrestaShop" + "Powered-By": "^Prestashop$" }, "html": [ "Powered by ]+>PrestaShop", @@ -7544,7 +7669,7 @@ 12 ], "js": { - "Prototype": "" + "Prototype.Version": "(.*)\\;version:\\1" }, "icon": "Prototype.png", "script": "(?:prototype|protoaculous)(?:-([\\d.]*[\\d]))?.*\\.js\\;version:\\1", @@ -7600,8 +7725,10 @@ "cats": [ 1 ], + "cookies": { + "PUBLICCMS_USER": "" + }, "headers": { - "Set-Cookie": "PUBLICCMS_USER", "X-Powered-PublicCMS": "(.*)\\;version:\\1" }, "icon": "Public CMS.png", @@ -7631,8 +7758,10 @@ "cats": [ 1 ], + "cookies": { + "pyrocms": "" + }, "headers": { - "Set-Cookie": "pyrocms", "X-Streams-Distribution": "PyroCMS" }, "icon": "PyroCMS.png", @@ -7657,7 +7786,7 @@ "quantserve": "" }, "icon": "Quantcast.png", - "script": "edge\\.quantserve\\.com/quant\\.js", + "script": "\\.quantserve\\.com/quant\\.js", "website": "http://www.quantcast.com" }, "Question2Answer": { @@ -7702,15 +7831,6 @@ "icon": "Quill.png", "website": "http://quilljs.com" }, - "RAID HTTPServer": { - "cats": [ - 22 - ], - "headers": { - "Server": "RAID HTTPServer(?:/([\\d.]+))?\\;version:\\1" - }, - "website": "http://example.com" - }, "RBS Change": { "cats": [ 1, @@ -7811,21 +7931,12 @@ 25 ], "js": { - "Raphael": "" + "Raphael.version": "(.*)\\;version:\\1" }, "icon": "Raphael.png", "script": "raphael(?:-([\\d.]+))?(?:\\.min)?\\.js\\;version:\\1", "website": "http://dmitrybaranovskiy.github.io/raphael/" }, - "Rapid Logic": { - "cats": [ - 22 - ], - "headers": { - "Server": "Rapid Logic(?:/([\\d.]+))?\\;version:\\1" - }, - "website": "http://example.com" - }, "Raspbian": { "cats": [ 28 @@ -7865,7 +7976,8 @@ 12 ], "js": { - "React": "" + "react.version": "(.*)\\;version:\\1", + "React.version": "(.*)\\;version:\\1" }, "html": "<[^>]+data-react", "icon": "React.png", @@ -7904,8 +8016,8 @@ "cats": [ 13 ], - "headers": { - "Set-Cookie": "^_redmine_session" + "cookies": { + "_redmine_session": "" }, "html": "Powered by ]+Redmine", "icon": "Redmine.png", @@ -7915,6 +8027,19 @@ }, "website": "http://www.redmine.org" }, + "ReDoc": { + "cats": [ + 4 + ], + "html": "]+=\"brandQuaternaryFgrs\"", "icon": "Salesforce.svg", @@ -8387,20 +8517,22 @@ ], "icon": "Select2.png", "implies": "jQuery", - "script": "select2.*\\.js", - "website": "http://select2.github.io" + "js": { + "jQuery.fn.select2": "" + }, + "script": "select2(?:\\.min|\\.full)?\\.js", + "website": "https://select2.org/" }, "Semantic-ui": { "cats": [ 18 ], "html": [ - "(?:
]+\">)\\;confidence:30", - "(?:]+semantic(?:\\.css|\\.min\\.css)\">)" + "]+semantic(?:\\.min)\\.css\"" ], "icon": "Semantic-ui.png", - "script": "(?:semantic(?:\\.js|\\.min\\.js))", - "website": "http://semantic-ui.com" + "script": "/semantic(?:-([\\d.]+))?(?:\\.min)?\\.js\\;version:\\1", + "website": "https://semantic-ui.com" }, "Sencha Touch": { "cats": [ @@ -8545,6 +8677,16 @@ "script": "mediacdn\\.shopatron\\.com", "website": "http://ecommerce.shopatron.com" }, + "Shopcada": { + "cats": [ + 6 + ], + "js": { + "Shopcada": "" + }, + "icon": "Shopcada.png", + "website": "http://shopcada.com" + }, "Shoper": { "cats": [ 6 @@ -8709,8 +8851,8 @@ "cats": [ 1 ], - "headers": { - "Set-cookie": "SC_ANALYTICS_GLOBAL_COOKIE" + "cookies": { + "SC_ANALYTICS_GLOBAL_COOKIE": "" }, "html": "]+src=\"[^>]*/~/media/[^>]+\\.ashx", "icon": "Sitecore.png", @@ -8743,9 +8885,18 @@ ], "html": "(?:]*href=\"[^/]*//[^/]*serving-sys\\.com/|]*src=\"[^/]*//[^/]*serving-sys\\.com/)", "icon": "Sizmek.png", - "script": "[^/]*//[^/]*serving-sys\\.com/", + "script": "serving-sys\\.com/", "website": "http://sizmek.com" }, + "Slick": { + "cats": [ + 12 + ], + "html": "]+(?:/([\\d.]+)/)?slick-theme\\.css\\;version:\\1", + "implies": "jQuery", + "script": "(?:/([\\d.]+))?/slick(?:\\.min)?\\.js\\;version:\\1", + "website": "http://kenwheeler.github.io/slick" + }, "Slimbox": { "cats": [ 12 @@ -8813,7 +8964,7 @@ 12 ], "js": { - "Snap": "" + "Snap.version": "(.*)\\;version:\\1" }, "icon": "Snap.svg.png", "script": "snap\\.svg(?:-min)?\\.js", @@ -8846,12 +8997,13 @@ 12 ], "js": { - "io": "\\;confidence:20" + "io.Socket": "", + "io.version": "(.*)\\;version:\\1" }, "icon": "Socket.io.png", "implies": "Node.js", "script": "socket\\.io.*\\.js", - "website": "http://socket.io" + "website": "https://socket.io" }, "Solodev": { "cats": [ @@ -8877,8 +9029,8 @@ "cats": [ 6 ], - "headers": { - "Set-Cookie": "_solusquare=" + "cookies": { + "_solusquare": "" }, "meta": { "generator": "^Solusquare$" @@ -8928,6 +9080,7 @@ ], "js": { "SoundManager": "", + "soundManager.version": "V(.+) \\;version:\\1", "BaconPlayer": "" }, "icon": "SoundManager.png", @@ -8965,8 +9118,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "spincms_session" + "cookies": { + "spincms_session": "" }, "icon": "SpinCMS.png", "implies": "PHP", @@ -9016,6 +9169,19 @@ "icon": "Squarespace.png", "website": "http://www.squarespace.com" }, + "Pagevamp": { + "cats": [ + 1 + ], + "js": { + "Pagevamp": "" + }, + "headers": { + "X-ServedBy": "pagevamp" + }, + "icon": "Pagevamp.png", + "website": "https://www.pagevamp.com" + }, "SquirrelMail": { "cats": [ 30 @@ -9065,18 +9231,6 @@ "icon": "Stackla.png", "website": "http://stackla.com/" }, - "Stamplay": { - "cats": [ - 34, - 47 - ], - "headers": { - "Server": "Stamplay" - }, - "icon": "Stamplay.png", - "script": "stamplay.*\\.js", - "website": "http://stamplay.com" - }, "Starlet": { "cats": [ 22 @@ -9088,11 +9242,16 @@ "implies": "Perl", "website": "http://metacpan.org/pod/Starlet" }, - "StatCounter": { + "Statcounter": { "cats": [ 10 ], - "icon": "StatCounter.png", + "icon": "Statcounter.svg", + "js": { + "_statcounter": "\\;confidence:100", + "sc_project": "\\;confidence:50", + "sc_security": "\\;confidence:50" + }, "script": "statcounter\\.com/counter/counter", "website": "http://www.statcounter.com" }, @@ -9149,7 +9308,7 @@ 41 ], "js": { - "Stripe": "" + "Stripe.version": "(.*)\\;version:\\1" }, "html": "]+data-stripe", "icon": "Stripe.png", @@ -9332,8 +9491,8 @@ "cats": [ 8 ], - "headers": { - "Set-cookie": "TWIKISID" + "cookies": { + "TWIKISID": "" }, "html": "]*(?:title|alt)=\"This site is powered by the TWiki collaboration platform", "icon": "TWiki.png", @@ -9405,15 +9564,20 @@ 44 ], "html": "Version ([\\d\\.]+)\\;version:\\1", - "icon": "TeamCity.png", + "icon": "TeamCity.svg", "implies": [ + "Apache Tomcat", + "Java", "jQuery", - "Prototype" + "Moment.js", + "Prototype", + "React", + "Underscore.js" ], "meta": { "application-name": "TeamCity" }, - "website": "http://jetbrains.com/teamcity" + "website": "https://www.jetbrains.com/teamcity/" }, "Telescope": { "cats": [ @@ -9564,8 +9728,9 @@ "cats": [ 24 ], + "script": "/tinymce(?:\\.min)?\\.js", "js": { - "tinyMCE": "" + "tinyMCE.majorVersion": "([\\d.]+)\\;version:\\1" }, "icon": "TinyMCE.png", "website": "http://tinymce.com" @@ -9687,7 +9852,7 @@ 12 ], "js": { - "TweenMax": "" + "TweenMax.version": "(.*)\\;version:\\1" }, "icon": "TweenMax.png", "script": "TweenMax(?:\\.min)?\\.js", @@ -9742,6 +9907,10 @@ "]+?href=\"[^\"]*bootstrap(?:\\.min)?\\.css", "]+class=\"[^\"]*glyphicon glyphicon-" ], + "js": { + "bootstrap.Alert.VERSION": "(.*)\\;version:\\1", + "jQuery.fn.tooltip.Constructor.VERSION": "(.*)\\;version:\\1" + }, "icon": "Bootstrap.svg", "script": [ "twitter\\.github\\.com/bootstrap", @@ -9752,7 +9921,7 @@ }, "Twitter Emoji (Twemoji)": { "cats": [ - 25 + 19 ], "js": { "twemoji": "" @@ -9814,7 +9983,7 @@ 17 ], "js": { - "Typekit": "" + "Typekit.config.js": "(.*)\\;version:\\1" }, "icon": "Typekit.png", "script": "use\\.typekit\\.com", @@ -9824,8 +9993,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "uCoz=" + "cookies": { + "uCoz": "" }, "icon": "uCoz.svg", "website": "https://ucoz.ru" @@ -9932,6 +10101,9 @@ 12 ], "icon": "Underscore.js.png", + "js": { + "_.VERSION": "(.*)\\;version:\\1" + }, "script": "underscore.*\\.js(?:\\?ver=([\\d.]+))?\\;version:\\1", "website": "http://underscorejs.org" }, @@ -9995,8 +10167,8 @@ "js": { "Ushahidi": "" }, - "headers": { - "Set-Cookie": "^ushahidi=" + "cookies": { + "ushahidi": "" }, "icon": "Ushahidi.png", "implies": [ @@ -10014,8 +10186,8 @@ "js": { "vivvo": "" }, - "headers": { - "Set-Cookie": "VivvoSessionId" + "cookies": { + "VivvoSessionId": "" }, "icon": "VIVVO.png", "website": "http://vivvo.net" @@ -10050,6 +10222,18 @@ "icon": "VTEX Integrated Store.png", "website": "http://lojaintegrada.com.br" }, + "Vaadin": { + "cats": [ + 18 + ], + "js": { + "vaadin": "" + }, + "icon": "Vaadin.svg", + "implies": "Java", + "script": "vaadinBootstrap\\.js(?:\\?v=([\\d.]+))?\\;version:\\1", + "website": "https://vaadin.com" + }, "Vanilla": { "cats": [ 2 @@ -10067,7 +10251,7 @@ 23 ], "headers": { - "Via": ".*Varnish", + "Via": "varnish(?: \\(Varnish/([\\d.]+)\\))?\\;version:\\1", "X-Varnish": "", "X-Varnish-Action": "", "X-Varnish-Age": "", @@ -10115,8 +10299,8 @@ "cats": [ 1 ], - "headers": { - "Set-Cookie": "_gphw_mode=" + "cookies": { + "_gphw_mode": "" }, "icon": "vigbo.png", "html": "]* href=[^>]+(?:\\.vigbo\\.com|\\.gophotoweb\\.com)", @@ -10152,18 +10336,6 @@ "icon": "Vimeo.png", "website": "http://vimeo.com" }, - "Virata EmWeb": { - "cats": [ - 22 - ], - "headers": { - "Server": "Virata-EmWeb(?:/(R?[\\d._]+))?\\;version:\\1" - }, - "implies": [ - "HP" - ], - "website": "http://example.com" - }, "VirtueMart": { "cats": [ 6 @@ -10228,14 +10400,13 @@ 12 ], "js": { - "Vue": "" + "Vue.version": "(.*)\\;version:\\1" }, "html": "<[^>]+data-v-", "icon": "Vue.js.png", "script": [ "vue(?:\\-|\\.)([\\d.]*\\d)[^/]*\\.js\\;version:\\1", - "/([\\d.]+)/vue(?:\\.min)?\\.js\\;version:\\1", - "vue.*\\.js\\;confidence:20" + "(?:/([\\d.]+))?/vue(?:\\.min)?\\.js\\;version:\\1" ], "website": "http://vuejs.org" }, @@ -10274,12 +10445,32 @@ "cats": [ 6 ], - "headers": { - "Set-Cookie": "^WHMCS.*" + "cookies": { + "WHMCS": "" }, "icon": "WHMCS.png", "website": "http://www.whmcs.com" }, + "wpCache": { + "cats": [ + 23 + ], + "headers": { + "X-Powered-By": "wpCache(?:/([\\d.]+))?\\;version:\\1" + }, + "html": " - -image/svg+xml \ No newline at end of file + \ No newline at end of file diff --git a/src/icons/Backtory.svg b/src/icons/Backtory.svg new file mode 100644 index 000000000..9fb2e0c57 --- /dev/null +++ b/src/icons/Backtory.svg @@ -0,0 +1,86 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/icons/CDN77.png b/src/icons/CDN77.png new file mode 100644 index 000000000..7300be9d5 Binary files /dev/null and b/src/icons/CDN77.png differ diff --git a/src/icons/CakePHP.png b/src/icons/CakePHP.png index baece763b..a3f838b9b 100644 Binary files a/src/icons/CakePHP.png and b/src/icons/CakePHP.png differ diff --git a/src/icons/Canon.png b/src/icons/Canon.png deleted file mode 100644 index 1f55e03b3..000000000 Binary files a/src/icons/Canon.png and /dev/null differ diff --git a/src/icons/Dart.svg b/src/icons/Dart.svg new file mode 100644 index 000000000..ca5dcdad7 --- /dev/null +++ b/src/icons/Dart.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/src/icons/David Webbox.png b/src/icons/David Webbox.png deleted file mode 100644 index 16e72fa12..000000000 Binary files a/src/icons/David Webbox.png and /dev/null differ diff --git a/src/icons/Drupal.png b/src/icons/Drupal.png deleted file mode 100644 index b9b13f84f..000000000 Binary files a/src/icons/Drupal.png and /dev/null differ diff --git a/src/icons/Drupal.svg b/src/icons/Drupal.svg new file mode 100644 index 000000000..b32678feb --- /dev/null +++ b/src/icons/Drupal.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + diff --git a/src/icons/ESERV-10.png b/src/icons/ESERV-10.png deleted file mode 100644 index 3e2c434ef..000000000 Binary files a/src/icons/ESERV-10.png and /dev/null differ diff --git a/src/icons/EWS-NIC4.png b/src/icons/EWS-NIC4.png deleted file mode 100644 index 5803d6385..000000000 Binary files a/src/icons/EWS-NIC4.png and /dev/null differ diff --git a/src/icons/ExagonConcept.svg b/src/icons/ExagonConcept.svg deleted file mode 100644 index baaae65d8..000000000 --- a/src/icons/ExagonConcept.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/icons/Grandstream.png b/src/icons/Grandstream.png deleted file mode 100644 index a347c58c9..000000000 Binary files a/src/icons/Grandstream.png and /dev/null differ diff --git a/src/icons/JC-HTTPD.png b/src/icons/JC-HTTPD.png deleted file mode 100644 index 1f55e03b3..000000000 Binary files a/src/icons/JC-HTTPD.png and /dev/null differ diff --git a/src/icons/KS_HTTP.png b/src/icons/KS_HTTP.png deleted file mode 100644 index 1f55e03b3..000000000 Binary files a/src/icons/KS_HTTP.png and /dev/null differ diff --git a/src/icons/MOBOTIX.png b/src/icons/MOBOTIX.png deleted file mode 100644 index a4574629c..000000000 Binary files a/src/icons/MOBOTIX.png and /dev/null differ diff --git a/src/icons/Nedstat.png b/src/icons/Nedstat.png deleted file mode 100644 index 2ffb430b5..000000000 Binary files a/src/icons/Nedstat.png and /dev/null differ diff --git a/src/icons/Neonclear.png b/src/icons/Neonclear.png deleted file mode 100644 index 0e0dcc59c..000000000 Binary files a/src/icons/Neonclear.png and /dev/null differ diff --git a/src/icons/Pagevamp.png b/src/icons/Pagevamp.png new file mode 100644 index 000000000..246558737 Binary files /dev/null and b/src/icons/Pagevamp.png differ diff --git a/src/icons/Penguin.svg b/src/icons/Penguin.svg deleted file mode 100644 index edf330b32..000000000 --- a/src/icons/Penguin.svg +++ /dev/null @@ -1 +0,0 @@ -penguin 2 \ No newline at end of file diff --git a/src/icons/Petrojs.png b/src/icons/Petrojs.png deleted file mode 100644 index a44eaa35c..000000000 Binary files a/src/icons/Petrojs.png and /dev/null differ diff --git a/src/icons/Piano Solo.png b/src/icons/Piano Solo.png deleted file mode 100644 index 1d4be842c..000000000 Binary files a/src/icons/Piano Solo.png and /dev/null differ diff --git a/src/icons/Shopcada.png b/src/icons/Shopcada.png new file mode 100644 index 000000000..c27bef7d1 Binary files /dev/null and b/src/icons/Shopcada.png differ diff --git a/src/icons/Stamplay.png b/src/icons/Stamplay.png deleted file mode 100644 index 8f5b25759..000000000 Binary files a/src/icons/Stamplay.png and /dev/null differ diff --git a/src/icons/StatCounter.png b/src/icons/StatCounter.png deleted file mode 100644 index e3d2bcc3d..000000000 Binary files a/src/icons/StatCounter.png and /dev/null differ diff --git a/src/icons/Statcounter.svg b/src/icons/Statcounter.svg new file mode 100644 index 000000000..9f91885fe --- /dev/null +++ b/src/icons/Statcounter.svg @@ -0,0 +1 @@ + diff --git a/src/icons/TeamCity.png b/src/icons/TeamCity.png deleted file mode 100644 index 405f3f779..000000000 Binary files a/src/icons/TeamCity.png and /dev/null differ diff --git a/src/icons/TeamCity.svg b/src/icons/TeamCity.svg new file mode 100644 index 000000000..6083e574b --- /dev/null +++ b/src/icons/TeamCity.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/Vaadin.svg b/src/icons/Vaadin.svg new file mode 100644 index 000000000..6ebe998ee --- /dev/null +++ b/src/icons/Vaadin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/Woosa.png b/src/icons/Woosa.png new file mode 100644 index 000000000..fbb0baaaa Binary files /dev/null and b/src/icons/Woosa.png differ diff --git a/src/icons/ZURB Foundation.png b/src/icons/ZURB Foundation.png index 994035248..2e8240fbc 100644 Binary files a/src/icons/ZURB Foundation.png and b/src/icons/ZURB Foundation.png differ diff --git a/src/icons/Zenfolio.png b/src/icons/Zenfolio.png new file mode 100644 index 000000000..56867d629 Binary files /dev/null and b/src/icons/Zenfolio.png differ diff --git a/src/icons/acquia-cloud.png b/src/icons/acquia-cloud.png new file mode 100644 index 000000000..d85843e9a Binary files /dev/null and b/src/icons/acquia-cloud.png differ diff --git a/src/icons/byINTI.svg b/src/icons/byINTI.svg new file mode 100644 index 000000000..98f626891 --- /dev/null +++ b/src/icons/byINTI.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/src/icons/docusaurus.svg b/src/icons/docusaurus.svg new file mode 100644 index 000000000..81b7405ed --- /dev/null +++ b/src/icons/docusaurus.svg @@ -0,0 +1,35 @@ + + + + docusaurus + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/icons/genexus.png b/src/icons/genexus.png new file mode 100644 index 000000000..b4525d4cf Binary files /dev/null and b/src/icons/genexus.png differ diff --git a/src/icons/gitea.svg b/src/icons/gitea.svg new file mode 100644 index 000000000..ac1594adb --- /dev/null +++ b/src/icons/gitea.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/iplabel.svg b/src/icons/iplabel.svg new file mode 100644 index 000000000..b8c0f4079 --- /dev/null +++ b/src/icons/iplabel.svg @@ -0,0 +1,8 @@ +logo + + + + + + + diff --git a/src/icons/koha.png b/src/icons/koha.png new file mode 100644 index 000000000..3bdb0d688 Binary files /dev/null and b/src/icons/koha.png differ diff --git a/src/icons/marked.svg b/src/icons/marked.svg new file mode 100644 index 000000000..a67fb80e5 --- /dev/null +++ b/src/icons/marked.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/icons/mkdocs.png b/src/icons/mkdocs.png new file mode 100644 index 000000000..279d831ff Binary files /dev/null and b/src/icons/mkdocs.png differ diff --git a/src/icons/mobirise.png b/src/icons/mobirise.png new file mode 100644 index 000000000..8244640ea Binary files /dev/null and b/src/icons/mobirise.png differ diff --git a/src/icons/paperjs.png b/src/icons/paperjs.png new file mode 100644 index 000000000..37cb8a114 Binary files /dev/null and b/src/icons/paperjs.png differ diff --git a/src/icons/parselecom.png b/src/icons/parselecom.png new file mode 100644 index 000000000..ba23f2e5b Binary files /dev/null and b/src/icons/parselecom.png differ diff --git a/src/icons/pelican.png b/src/icons/pelican.png new file mode 100644 index 000000000..3fffd4858 Binary files /dev/null and b/src/icons/pelican.png differ diff --git a/src/icons/raychat.png b/src/icons/raychat.png new file mode 100644 index 000000000..813d354dd Binary files /dev/null and b/src/icons/raychat.png differ diff --git a/src/icons/raychat.svg b/src/icons/raychat.svg deleted file mode 100644 index 708303307..000000000 --- a/src/icons/raychat.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/icons/redoc.png b/src/icons/redoc.png new file mode 100644 index 000000000..f99f5d48f Binary files /dev/null and b/src/icons/redoc.png differ diff --git a/src/wappalyzer.js b/src/wappalyzer.js index df7e3bd1e..114919c70 100644 --- a/src/wappalyzer.js +++ b/src/wappalyzer.js @@ -19,7 +19,6 @@ class Wappalyzer { this.categories = {}; this.driver = {}; this.jsPatterns = {}; - this.detected = {}; this.hostnameCache = {}; this.adCache = []; @@ -38,21 +37,33 @@ class Wappalyzer { this.driver.log(message, source || '', type || 'debug'); } + asyncForEach(iterable, iterator) { + return Promise.all(( iterable || [] ).map(item => new Promise(resolve => setTimeout(() => resolve(iterator(item)), 1)))); + } + analyze(url, data, context) { - var apps = {}; + const startTime = new Date(); - if ( typeof data.html !== 'string' ) { - data.html = ''; - } + const promises = []; + + var apps = {}; 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); + var language = null; + + if ( data.html ) { + if ( typeof data.html !== 'string' ) { + data.html = ''; + } - const language = matches && matches.length ? matches[1] : null; + const matches = data.html.match(/]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i); + + language = matches && matches.length ? matches[1] : null; + } Object.keys(this.apps).forEach(appName => { apps[appName] = this.detected[url.canonical] && this.detected[url.canonical][appName] ? this.detected[url.canonical][appName] : new Application(appName, this.apps[appName]); @@ -62,52 +73,57 @@ class Wappalyzer { this.analyzeUrl(app, url); if ( data.html ) { - this.analyzeHtml(app, data.html); - this.analyzeMeta(app, data.html); + promises.push(this.analyzeHtml(app, data.html)); + promises.push(this.analyzeMeta(app, data.html)); } if ( data.scripts ) { - this.analyzeScripts(app, data.scripts); + promises.push(this.analyzeScripts(app, data.scripts)); } - if ( data.headers ) { - this.analyzeHeaders(app, data.headers); - } - - if ( data.env ) { - this.analyzeEnv(app, data.env); + if ( data.cookies ) { + promises.push(this.analyzeCookies(app, data.cookies)); } - if ( data.robotsTxt ) { - this.analyzeRobotsTxt(app, data.robotsTxt); + if ( data.headers ) { + promises.push(this.analyzeHeaders(app, data.headers)); } - }) + }); if ( data.js ) { Object.keys(data.js).forEach(appName => { - this.analyzeJs(apps[appName], data.js[appName]); + promises.push(this.analyzeJs(apps[appName], data.js[appName])); }); } - Object.keys(apps).forEach(appName => { - var app = apps[appName]; + return new Promise(resolve => { + Promise.all(promises) + .then(() => { + Object.keys(apps).forEach(appName => { + var app = apps[appName]; - if ( !app.detected || !app.getConfidence() ) { - delete apps[app.name]; - } - }); + if ( !app.detected || !app.getConfidence() ) { + delete apps[app.name]; + } + }); - this.resolveExcludes(apps); - this.resolveImplies(apps, url.canonical); + this.resolveExcludes(apps); + this.resolveImplies(apps, url.canonical); - this.cacheDetectedApps(apps, url.canonical); - this.trackDetectedApps(apps, url, language); + 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.canonical, 'core'); - } + this.log('Processing ' + Object.keys(data).join(', ') + ' took ' + (( new Date() - startTime ) / 1000).toFixed(2) + 's (' + url.hostname + ')', 'core'); + + if ( Object.keys(apps).length ) { + this.log('Identified ' + Object.keys(apps).join(', ') + ' (' + url.hostname + ')', 'core'); + } + + this.driver.displayApps(this.detected[url.canonical], { language }, context); - this.driver.displayApps(this.detected[url.canonical], { language }, context); + resolve(); + }); + }); } /** @@ -130,12 +146,12 @@ class Wappalyzer { this.driver.getRobotsTxt(parsed.host, parsed.protocol === 'https:') .then(robotsTxt => { - if (robotsTxt.some(disallowedPath => parsed.pathname.indexOf(disallowedPath) === 0)) { + if ( robotsTxt.some(disallowedPath => parsed.pathname.indexOf(disallowedPath) === 0) ) { return reject(); - } else { - return resolve(); } - }); + + return resolve(); + }, () => resolve()); }); }; @@ -393,13 +409,15 @@ class Wappalyzer { analyzeUrl(app, url) { var patterns = this.parsePatterns(app.props.url); - if ( patterns.length ) { - patterns.forEach(pattern => { - if ( pattern.regex.test(url.canonical) ) { - this.addDetected(app, pattern, 'url', url.canonical); - } - }); + if ( !patterns.length ) { + return Promise.resolve(); } + + return this.asyncForEach(patterns, pattern => { + if ( pattern.regex.test(url.canonical) ) { + this.addDetected(app, pattern, 'url', url.canonical); + } + }); } /** @@ -408,13 +426,15 @@ class Wappalyzer { analyzeHtml(app, html) { var patterns = this.parsePatterns(app.props.html); - if ( patterns.length ) { - patterns.forEach(pattern => { - if ( pattern.regex.test(html) ) { - this.addDetected(app, pattern, 'html', html); - } - }); + if ( !patterns.length ) { + return Promise.resolve(); } + + return this.asyncForEach(patterns, pattern => { + if ( pattern.regex.test(html) ) { + this.addDetected(app, pattern, 'html', html); + } + }); } /** @@ -423,115 +443,114 @@ class Wappalyzer { analyzeScripts(app, scripts) { var patterns = this.parsePatterns(app.props.script); - if ( patterns.length ) { - patterns.forEach(pattern => { - var match; + if ( !patterns.length ) { + return Promise.resolve(); + } - scripts.forEach(uri => { - if ( pattern.regex.test(uri) ) { - this.addDetected(app, pattern, 'script', uri); - } - }); + return this.asyncForEach(patterns, pattern => { + var match; + + scripts.forEach(uri => { + if ( pattern.regex.test(uri) ) { + this.addDetected(app, pattern, 'script', uri); + } }); - } + }); } /** * Analyze meta tag */ analyzeMeta(app, html) { - var regex = /]+>/ig; - var patterns = this.parsePatterns(app.props.meta); - var content = ''; + const regex = /]+>/ig; + const patterns = this.parsePatterns(app.props.meta); + const promises = []; + var matches = []; while ( patterns && ( matches = regex.exec(html) ) ) { for ( var meta in patterns ) { - const r = new RegExp('(?:name|property)=["\']' + meta + '["\']', 'i'); - if ( new RegExp('(?:name|property)=["\']' + meta + '["\']', 'i').test(matches[0]) ) { - content = matches[0].match(/content=("|')([^"']+)("|')/i); + if ( r.test(matches[0]) ) { + let content = matches[0].match(/content=("|')([^"']+)("|')/i); - patterns[meta].forEach(pattern => { + promises.push(this.asyncForEach(patterns[meta], pattern => { if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { this.addDetected(app, pattern, 'meta', content[2], meta); } - }); + })); } } } + + return promises ? Promise.all(promises) : Promise.resolve(); } /** - * analyze response headers + * Analyze response headers */ analyzeHeaders(app, headers) { - var patterns = this.parsePatterns(app.props.headers); - - if ( headers ) { - Object.keys(patterns).forEach(headerName => { - patterns[headerName].forEach(pattern => { - headerName = headerName.toLowerCase(); - - if ( headerName in headers ) { - headers[headerName].forEach(headerValue => { - if ( pattern.regex.test(headerValue) ) { - this.addDetected(app, pattern, 'headers', headerValue, headerName); - } - }); - } - }); - }); - } + const patterns = this.parsePatterns(app.props.headers); + const promises = []; + + Object.keys(patterns).forEach(headerName => { + promises.push(this.asyncForEach(patterns[headerName], pattern => { + headerName = headerName.toLowerCase(); + + if ( headerName in headers ) { + headers[headerName].forEach(headerValue => { + if ( pattern.regex.test(headerValue) ) { + this.addDetected(app, pattern, 'headers', headerValue, headerName); + } + }); + } + })); + }); + + return promises ? Promise.all(promises) : Promise.resolve(); } /** - * Analyze environment variables + * Analyze cookies */ - analyzeEnv(app, envs) { - var patterns = this.parsePatterns(app.props.env); - - if ( patterns.length ) { - patterns.forEach(pattern => { - Object.keys(envs).forEach(env => { - if ( pattern.regex.test(envs[env]) ) { - this.addDetected(app, pattern, 'env', envs[env]); - } - }) - }); - } + analyzeCookies(app, cookies) { + const patterns = this.parsePatterns(app.props.cookies); + const promises = []; + + Object.keys(patterns).forEach(cookieName => { + cookieName = cookieName.toLowerCase(); + + promises.push(this.asyncForEach(patterns[cookieName], pattern => { + const cookie = cookies.find(cookie => cookie.name.toLowerCase() === cookieName); + + if ( cookie && pattern.regex.test(cookie.value) ) { + this.addDetected(app, pattern, 'cookies', cookie.value, cookieName); + } + })); + }); + + return promises ? Promise.all(promises) : Promise.resolve(); } /** * Analyze JavaScript variables */ analyzeJs(app, results) { + const promises = []; + Object.keys(results).forEach(string => { - Object.keys(results[string]).forEach(index => { + promises.push(this.asyncForEach(Object.keys(results[string]), index => { const pattern = this.jsPatterns[app.name][string][index]; const value = results[string][index]; - if ( pattern.regex.test(value) ) { + if ( pattern && pattern.regex.test(value) ) { this.addDetected(app, pattern, 'js', value); } - }); + })); }); - } - - /** - * Analyze robots.txt - */ - analyzeRobotsTxt(app, robotsTxt) { - var patterns = this.parsePatterns(app.props.robotsTxt); - if ( patterns.length ) { - patterns.forEach(pattern => { - if ( pattern.regex.test(robotsTxt) ) { - this.addDetected(app, pattern, 'robotsTxt', robotsTxt); - } - }); - } + return promises ? Promise.all(promises) : Promise.resolve(); } /** @@ -559,7 +578,7 @@ class Wappalyzer { } // Replace back references - version = version.replace(new RegExp('\\\\' + i, 'g'), match || ''); + version = version.trim().replace(new RegExp('\\\\' + i, 'g'), match || ''); }); if ( version && versions.indexOf(version) === -1 ) { diff --git a/test/analyze.spec.js b/test/analyze.spec.js new file mode 100644 index 000000000..99cf6a516 --- /dev/null +++ b/test/analyze.spec.js @@ -0,0 +1,144 @@ +/* eslint-env mocha */ + +'use strict'; + +const assert = require('chai').assert; +const Wappalyzer = require('../src/wappalyzer'); + +describe('should analyze website elements properly', function () { + + it('should analyze html', async () => { + const html = ` + + + + Page title | Html detection + + + +

Technologies Test Page | Html detection

+ + + + + + `; + const wappalyzer = new Wappalyzer(); + wappalyzer.apps = { + "Google Tag Manager": { + "html": [ + "googletagmanager\\.com/ns\\.html[^>]+>", + "" + ] + } + }; + var applications = null; + wappalyzer.driver = { + log () {}, + displayApps (detectedMap) { + applications = detectedMap; + } + }; + + await wappalyzer.analyze({ canonical: 'example.com' }, { html }); + assert.equal(applications['Google Tag Manager'].name, 'Google Tag Manager'); + }); + + it('should analyze scripts', async () => { + const scripts = [ + 'http://www.google-analytics.com/analytics.js', + 'http://example.com/assets/js/jquery.min.js' + ]; + const wappalyzer = new Wappalyzer(); + wappalyzer.apps = { + "Google Analytics": { + "cats": [ + 10 + ], + "script": "google-analytics\\.com\\/(?:ga|urchin|(analytics))\\.js\\;version:\\1?UA:" + }, + "jQuery": { + "script": [ + "jquery(?:\\-|\\.)([\\d.]*\\d)[^/]*\\.js\\;version:\\1", + "/([\\d.]+)/jquery(?:\\.min)?\\.js\\;version:\\1", + "jquery.*\\.js(?:\\?ver(?:sion)?=([\\d.]+))?\\;version:\\1" + ] + } + }; + var applications = null; + wappalyzer.driver = { + log () {}, + displayApps (detectedMap) { + applications = detectedMap; + } + }; + + await wappalyzer.analyze({ canonical: 'example.com' }, { scripts }); + assert.equal(applications['Google Analytics'].name, 'Google Analytics'); + assert.equal(applications['jQuery'].name, 'jQuery'); + }); + + it('should analyze headers', async () => { + const headers = { + 'date': [ 'Thu, 01 Feb 2018 11:34:18 GMT' ], + 'connection': [ 'keep-alive' ], + 'x-powered-by': [ 'Express'], + 'etag': [ 'W/125-1jQLmiya7mfec43xR3Eb3pjdu64s' ], + 'content-length': [ '293' ], + 'content-type': [ 'text/html; charset=utf-8' ] + }; + const wappalyzer = new Wappalyzer(); + wappalyzer.apps = { + "Express": { + "headers": { + "X-Powered-By": "^Express$" + } + } + }; + var applications = null; + wappalyzer.driver = { + log () {}, + displayApps (detectedMap) { + applications = detectedMap; + } + }; + + await wappalyzer.analyze({ canonical: 'example.com' }, { headers }); + assert.equal(applications['Express'].name, 'Express'); + }); + + it('should analyze js globals', async () => { + const js = { + 'Moment.js': { 'moment': { '0': true } }, + 'Google Font API': { 'WebFonts': { '0': true } } + }; + const wappalyzer = new Wappalyzer(); + wappalyzer.apps = { + "Moment.js": { + "js": { + "moment": "", + "moment.version": "(.*)\\;version:\\1" + } + }, + "Google Font API": { + "js": { + "WebFonts": "" + } + } + }; + var applications = null; + wappalyzer.driver = { + log () {}, + displayApps (detectedMap) { + applications = detectedMap; + } + }; + + wappalyzer.parseJsPatterns(); + await wappalyzer.analyze({ canonical: 'example.com' }, { js }); + + assert.equal(applications['Google Font API'].name, 'Google Font API'); + assert.equal(applications['Moment.js'].name, 'Moment.js'); + }); +}); diff --git a/yarn.lock b/yarn.lock index afff3337d..e261850cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,20 +2,173 @@ # yarn lockfile v1 +assertion-error@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + +chai@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" + dependencies: + assertion-error "^1.0.1" + check-error "^1.0.1" + deep-eql "^3.0.0" + get-func-name "^2.0.0" + pathval "^1.0.0" + type-detect "^4.0.0" + +check-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + +commander@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +deep-eql@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + dependencies: + type-detect "^4.0.0" + +diff@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" + +escape-string-regexp@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + file-type@7.4.*: version "7.4.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.4.0.tgz#2a7c94f62a0030150bb7d9b6c70cfa1d3e759c86" +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +growl@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + 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" +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + 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" +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.1.tgz#759b62c836b0732382a62b6b1fb245ec1bc943ac" + dependencies: + browser-stdout "1.3.0" + commander "2.11.0" + debug "3.1.0" + diff "3.3.1" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.3" + he "1.1.1" + mkdirp "0.5.1" + supports-color "4.4.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +pathval@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -30,3 +183,17 @@ read-chunk@2.1.*: safe-buffer@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +supports-color@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + dependencies: + has-flag "^2.0.0" + +type-detect@^4.0.0: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"