1 | /** |
||
2 | * Bookmarklet driver |
||
3 | */ |
||
4 | |||
5 | /** global: wappalyzer */ |
||
6 | /** global: XMLHttpRequest */ |
||
7 | |||
8 | (function() { |
||
9 | wappalyzer.driver.document = document; |
||
10 | |||
11 | const container = document.getElementById('wappalyzer-container'); |
||
12 | const url = wappalyzer.parseUrl(window.top.location.href); |
||
13 | const hasOwn = Object.prototype.hasOwnProperty; |
||
14 | |||
15 | /** |
||
16 | * Log messages to console |
||
17 | */ |
||
18 | wappalyzer.driver.log = (message, source, type) => { |
||
19 | console.log('[wappalyzer ' + type + ']', '[' + source + ']', message); |
||
0 ignored issues
–
show
Debugging Code
introduced
by
![]() |
|||
20 | }; |
||
21 | |||
22 | function getPageContent() { |
||
23 | wappalyzer.log('func: getPageContent', 'driver'); |
||
24 | |||
25 | var scripts = Array.prototype.slice |
||
26 | .apply(document.scripts) |
||
27 | .filter(s => s.src) |
||
28 | .map(s => s.src); |
||
29 | |||
30 | var html = new window.XMLSerializer().serializeToString(document).split('\n'); |
||
31 | |||
32 | html = html |
||
33 | .slice(0, 1000).concat(html.slice(html.length - 1000)) |
||
34 | .map(line => line.substring(0, 1000)) |
||
35 | .join('\n'); |
||
36 | |||
37 | wappalyzer.analyze(url, { |
||
38 | html: html, |
||
39 | scripts: scripts |
||
40 | }); |
||
41 | } |
||
42 | |||
43 | function getResponseHeaders() { |
||
44 | wappalyzer.log('func: getResponseHeaders', 'driver'); |
||
45 | |||
46 | var xhr = new XMLHttpRequest(); |
||
47 | |||
48 | xhr.open('GET', url, true); |
||
49 | |||
50 | xhr.onreadystatechange = () => { |
||
51 | if ( xhr.readyState === 4 && xhr.status ) { |
||
52 | var headers = xhr.getAllResponseHeaders().split("\n"); |
||
53 | |||
54 | if ( headers.length > 0 && headers[0] != '' ) { |
||
55 | wappalyzer.log('responseHeaders: ' + xhr.getAllResponseHeaders(), 'driver'); |
||
56 | |||
57 | var responseHeaders = {}; |
||
58 | |||
59 | headers.forEach(line => { |
||
60 | var name, value; |
||
61 | |||
62 | if ( line ) { |
||
63 | name = line.substring(0, line.indexOf(': ')); |
||
64 | value = line.substring(line.indexOf(': ') + 2, line.length - 1); |
||
65 | |||
66 | if ( !responseHeaders[name.toLowerCase()] ){ |
||
67 | responseHeaders[name.toLowerCase()] = [] |
||
68 | } |
||
69 | responseHeaders[name.toLowerCase()].push(value); |
||
70 | } |
||
71 | }); |
||
72 | |||
73 | wappalyzer.analyze(url, { |
||
74 | headers: responseHeaders |
||
75 | }); |
||
76 | } |
||
77 | } |
||
78 | } |
||
79 | |||
80 | xhr.send(); |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Display apps |
||
85 | */ |
||
86 | wappalyzer.driver.displayApps = detected => { |
||
0 ignored issues
–
show
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.
The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression. This operator is most often used in Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator. This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements. var a,b,c;
a = 1, b = 1, c= 3;
could just as well be written as: var a,b,c;
a = 1;
b = 1;
c = 3;
To learn more about the sequence operator, please refer to the MDN. ![]() |
|||
87 | wappalyzer.log('func: diplayApps', 'driver'); |
||
88 | |||
89 | var first = true; |
||
90 | var app; |
||
91 | var category; |
||
92 | var html; |
||
93 | |||
94 | html = |
||
95 | '<a id="wappalyzer-close" href="javascript: document.body.removeChild(document.getElementById(\'wappalyzer-container\')); void(0);">' + |
||
96 | 'Close' + |
||
97 | '</a>' + |
||
98 | '<div id="wappalyzer-apps">'; |
||
99 | |||
100 | if ( detected != null && Object.keys(detected).length ) { |
||
101 | for ( app in detected ) { |
||
102 | if ( !hasOwn.call(detected, app) ) { |
||
103 | continue; |
||
104 | } |
||
105 | |||
106 | var version = detected[app].version, |
||
107 | confidence = detected[app].confidence; |
||
108 | |||
109 | html += |
||
110 | '<div class="wappalyzer-app' + ( first ? ' wappalyzer-first' : '' ) + '">' + |
||
111 | '<a target="_blank" class="wappalyzer-application" href="' + wappalyzer.config.websiteURL + 'applications/' + app.toLowerCase().replace(/ /g, '-').replace(/[^a-z0-9-]/g, '') + '">' + |
||
112 | '<strong>' + |
||
113 | '<img src="' + wappalyzer.config.websiteURL + 'images/icons/' + (wappalyzer.apps[app].icon || 'default.svg') + '" width="16" height="16"/> ' + app + |
||
114 | '</strong>' + |
||
115 | ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) + |
||
116 | '</a>'; |
||
117 | |||
118 | for ( let i in wappalyzer.apps[app].cats ) { |
||
119 | if ( !hasOwn.call(wappalyzer.apps[app].cats, i) ) { |
||
120 | continue; |
||
121 | } |
||
122 | |||
123 | category = wappalyzer.categories[wappalyzer.apps[app].cats[i]].name; |
||
124 | |||
125 | html += '<a target="_blank" class="wappalyzer-category" href="' + wappalyzer.config.websiteURL + 'categories/' + slugify(category) + '">' + category + '</a>'; |
||
126 | } |
||
127 | |||
128 | html += '</div>'; |
||
129 | |||
130 | first = false; |
||
131 | } |
||
132 | } else { |
||
133 | html += '<div id="wappalyzer-empty">No applications detected</div>'; |
||
134 | } |
||
135 | |||
136 | html += '</div>'; |
||
137 | |||
138 | container.innerHTML = html; |
||
139 | }, |
||
140 | |||
141 | /** |
||
142 | * Open a tab |
||
143 | */ |
||
144 | function openTab(args) { |
||
145 | open(args.url); |
||
146 | } |
||
147 | |||
148 | function slugify(string) { |
||
149 | return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, ''); |
||
150 | } |
||
151 | |||
152 | getPageContent(); |
||
153 | getResponseHeaders(); |
||
154 | })(); |
||
155 |