PluginProbe ʕ •ᴥ•ʔ
Wordfence Security – Firewall, Malware Scan, and Login Security / 1.5.3
Wordfence Security – Firewall, Malware Scan, and Login Security v1.5.3
8.2.2 8.2.1 8.2.0 3.7.1 3.7.2 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.8.8 3.8.9 3.9.1 4.0.1 4.0.2 4.0.3 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.1 5.1.2 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.2.1 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.1 5.3.10 5.3.11 5.3.12 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.3.8 5.3.9 6.0.1 6.0.10 6.0.11 6.0.12 6.0.14 6.0.15 6.0.16 6.0.17 6.0.18 6.0.19 6.0.2 6.0.20 6.0.21 6.0.22 6.0.23 6.0.24 6.0.25 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.0.8 6.0.9 6.1.1 6.1.10 6.1.11 6.1.12 6.1.14 6.1.15 6.1.16 6.1.17 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.1.9 6.2.0 6.2.1 6.2.10 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.2.8 6.2.9 6.3.0 6.3.1 6.3.10 6.3.11 6.3.12 6.3.14 6.3.15 6.3.16 6.3.17 6.3.18 6.3.19 6.3.2 6.3.20 6.3.21 6.3.22 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.3.8 6.3.9 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1.0 7.1.1 7.1.10 7.1.11 7.1.12 7.1.14 7.1.15 7.1.16 7.1.17 7.1.18 7.1.19 7.1.2 7.1.20 7.1.3 7.1.4 7.1.5 7.1.6 7.1.7 7.1.8 7.1.9 7.10.0 7.10.1 7.10.2 7.10.3 7.10.4 7.10.5 7.10.6 7.10.7 7.11.0 7.11.1 7.11.2 7.11.3 7.11.4 7.11.5 7.11.6 7.11.7 7.2.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.4.0 7.4.1 7.4.10 7.4.11 7.4.12 7.4.14 7.4.2 7.4.3 trunk 7.4.4 1.1 7.4.5 1.2 7.4.6 1.3 7.4.7 1.3.1 7.4.8 1.3.2 7.4.9 1.3.3 7.5.0 1.4.2 7.5.1 1.4.3 7.5.10 1.4.4 7.5.11 1.4.5 7.5.2 1.4.6 7.5.3 1.4.7 7.5.4 1.4.8 7.5.5 1.5.1 7.5.6 1.5.2 7.5.7 1.5.3 7.5.8 1.5.4 7.5.9 1.5.5 7.6.0 1.5.6 7.6.1 2.0.1 7.6.2 2.0.2 7.7.0 2.0.3 7.7.1 2.0.5 7.8.0 2.0.6 7.8.1 2.0.7 7.8.2 2.1.0 7.9.0 2.1.1 7.9.1 2.1.2 7.9.2 2.1.3 7.9.3 2.1.4 8.0.0 2.1.5 8.0.1 3.0.2 8.0.2 3.0.3 8.0.3 3.0.4 8.0.4 3.0.5 8.0.5 3.0.6 8.1.0 3.0.7 8.1.1 3.0.8 8.1.2 3.0.9 8.1.3 3.1.0 8.1.4 3.1.1 v1.4.1 3.1.2 3.1.4 3.1.6 3.2.1 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.1 3.4.4 3.4.5 3.5.1 3.5.2 3.6.1 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9
wordfence / js / admin.js
wordfence / js Last commit date
admin.js 14 years ago jquery.colorbox-min.js 14 years ago jquery.dataTables.min.js 14 years ago jquery.tmpl.min.js 14 years ago jquery.tools.min.js 14 years ago
admin.js
687 lines
1 if(! window['wordfenceAdmin']){
2 window['wordfenceAdmin'] = {
3 loading16: '<div class="wfLoading16"></div>',
4 dbCheckTables: [],
5 dbCheckCount_ok: 0,
6 dbCheckCount_skipped: 0,
7 dbCheckCount_errors: 0,
8 issues: [],
9 ignoreData: false,
10 iconErrorMsgs: [],
11 scanIDLoaded: 0,
12 colorboxQueue: [],
13 colorboxOpen: false,
14 scanPending: false,
15 mode: '',
16 visibleIssuesPanel: 'new',
17 preFirstScanMsgsLoaded: false,
18 newestActivityTime: 0, //must be 0 to force loading of all initially
19 elementGeneratorIter: 1,
20 reloadConfigPage: false,
21 nonce: false,
22 init: function(){
23 this.nonce = WordfenceAdminVars.firstNonce;
24 if(jQuery('#wordfenceMode_scan').length > 0){
25 this.mode = 'scan';
26 this.noScanHTML = jQuery('#wfNoScanYetTmpl').tmpl().html();
27 } else if(jQuery('#wordfenceMode_activity').length > 0){
28 this.mode = 'activity';
29 this.activityMode = 'hit';
30 this.updateTicker(true);
31 } else if(jQuery('#wordfenceMode_options').length > 0){
32 this.mode = 'options';
33 jQuery('.wfConfigElem').change(function(){ jQuery('#securityLevel').val('CUSTOM'); });
34 this.updateTicker(true);
35 } else if(jQuery('#wordfenceMode_blockedIPs').length > 0){
36 this.mode = 'blocked';
37 this.staticTabChanged();
38 this.updateTicker(true);
39 } else {
40 this.mode = false;
41 }
42 if(this.mode){ //We are in a Wordfence page
43 var self = this;
44 this.liveInt = setInterval(function(){ self.updateTicker(); }, 2000);
45 jQuery(document).bind('cbox_closed', function(){ self.colorboxIsOpen = false; self.colorboxServiceQueue(); });
46 }
47
48 },
49 updateTicker: function(forceUpdate){
50 if( (! forceUpdate) && this.tickerUpdatePending){
51 return;
52 }
53 this.tickerUpdatePending = true;
54 var self = this;
55 var alsoGet = '';
56 var otherParams = '';
57 if(this.mode == 'activity' && /^(?:404|hit|human|ruser|gCrawler|crawler|loginLogout)$/.test(this.activityMode)){
58 alsoGet = 'logList_' + this.activityMode;
59 otherParams = this.newestActivityTime;
60 }
61 this.ajax('wordfence_ticker', {
62 alsoGet: alsoGet,
63 otherParams: otherParams
64 }, function(res){ self.handleTickerReturn(res); }, function(){ self.tickerUpdatePending = false; });
65 },
66 handleTickerReturn: function(res){
67 this.tickerUpdatePending = false;
68 var statusMsgChanged = false;
69 var newMsg = "";
70 var oldMsg = jQuery('#wfLiveStatus').html();
71 if( res.msg ){
72 newMsg = res.msg;
73 } else {
74 newMsg = "Idle";
75 }
76 if(newMsg && oldMsg && newMsg != oldMsg){
77 statusMsgChanged = true;
78 }
79 if(newMsg && newMsg != oldMsg){
80 jQuery('#wfLiveStatus').hide().html(newMsg).fadeIn(200);
81 }
82
83 if(this.mode == 'scan'){
84 if(res.running){
85 jQuery('.wfStartScanButton').addClass('button-wf-grey').val("A scan is in progress...").unbind('click').click(function(){ wordfenceAdmin.scanRunningMsg(); }).show();
86 } else {
87 if(! this.scanPending){
88 jQuery('.wfStartScanButton').removeClass('button-wf-grey').val("Start a Wordfence Scan").unbind('click').click(function(){ wordfenceAdmin.startScan(); }).show();
89 }
90 }
91 if(res.currentScanID && res.currentScanID != this.scanIDLoaded){
92 this.scanIDLoaded = res.currentScanID;
93 this.loadIssues();
94 } else if( (! res.currentScanID) && (! this.scanIDLoaded)){
95 //We haven't done our first scan yet.
96 if(! this.preFirstScanMsgsLoaded){
97 this.preFirstScanMsgsLoaded = true;
98 jQuery('#wfSummaryTables').html(this.noScanHTML);
99 this.switchIssuesTab(jQuery('#wfNewIssuesTab'), 'new');
100 jQuery('#wfActivity').html('<p>No events to report yet. Please complete your first scan.</p>');
101 }
102 }
103 } else if(this.mode == 'activity'){
104 if(res.alsoGet != 'logList_' + this.activityMode){ return; } //user switched panels since ajax request started
105 if(/^(?:topScanners|topLeechers)$/.test(this.activityMode)){
106 if(statusMsgChanged){ this.updateTicker(true); } return;
107 }
108 if(res.events.length > 0){
109 this.newestActivityTime = res.events[0]['ctime'];
110 }
111 var haveEvents = false;
112 if(jQuery('#wfActivity_' + this.activityMode + ' .wfActEvent').length > 0){
113 haveEvents = true;
114 }
115 if(res.events.length > 0){
116 if(! haveEvents){
117 jQuery('#wfActivity_' + this.activityMode).empty();
118 }
119 for(i = res.events.length - 1; i >= 0; i--){
120 var elemID = '#wfActEvent_' + res.events[i].id;
121 if(jQuery(elemID).length < 1){
122 res.events[i]['activityMode'] = this.activityMode;
123 var newElem;
124 if(this.activityMode == 'loginLogout'){
125 newElem = jQuery('#wfLoginLogoutEventTmpl').tmpl(res.events[i]);
126 } else {
127 newElem = jQuery('#wfHitsEventTmpl').tmpl(res.events[i]);
128 }
129 jQuery(newElem).find('.wfTimeAgo').data('wfctime', res.events[i].ctime);
130 newElem.prependTo('#wfActivity_' + this.activityMode).fadeIn();
131 }
132 }
133 this.reverseLookupIPs();
134 } else {
135 if(! haveEvents){
136 jQuery('#wfActivity_' + this.activityMode).html('<div>No events to report yet.</div>');
137 }
138 }
139 var self = this;
140 jQuery('.wfTimeAgo').each(function(idx, elem){
141 jQuery(elem).html(self.makeTimeAgo(res.serverTime - jQuery(elem).data('wfctime')) + ' ago');
142 });
143 }
144 if(statusMsgChanged){ this.updateTicker(true); } return;
145 },
146 reverseLookupIPs: function(){
147 var ips = [];
148 jQuery('.wfReverseLookup').each(function(idx, elem){
149 var txt = jQuery(elem).text();
150 if(/^\d+\.\d+\.\d+\.\d+$/.test(txt) && (! jQuery(elem).data('wfReverseDone'))){
151 jQuery(elem).data('wfReverseDone', true);
152 ips.push(jQuery(elem).text());
153 }
154 });
155 if(ips.length < 1){ return; }
156 var uni = {};
157 var uniqueIPs = [];
158 for(var i = 0; i < ips.length; i++){
159 if(! uni[ips[i]]){
160 uni[ips[i]] = true;
161 uniqueIPs.push(ips[i]);
162 }
163 }
164 this.ajax('wordfence_reverseLookup', {
165 ips: uniqueIPs.join(',')
166 },
167 function(res){
168 if(res.ok){
169 jQuery('.wfReverseLookup').each(function(idx, elem){
170 var txt = jQuery(elem).text();
171 for(ip in res.ips){
172 if(txt == ip){
173 if(res.ips[ip]){
174 jQuery(elem).html('<strong>Hostname:</strong>&nbsp;' + res.ips[ip]);
175 } else {
176 jQuery(elem).html('');
177 }
178 }
179 }
180 });
181 }
182 }
183 );
184 },
185 activateWF: function(key){
186 jQuery('.wfAjax24').show();
187 this.ajax('wordfence_activate', {
188 key: jQuery('#wordfenceKey').val(),
189 email: jQuery('#email').val()
190 },
191 function(res){
192 jQuery('.wfAjax24').hide();
193 if(res.ok){
194 window.location = "admin.php?page=Wordfence&wfAct=" + Math.floor(Math.random()*999999999);
195 return;
196 } else if(res.errorAlert){
197 jQuery.colorbox({ width: '400px', html:
198 "<h3>An error occured:</h3><p>" + res.errorAlert + "</p>"
199 });
200 }
201
202 });
203 },
204 startScan: function(){
205 var self = this;
206 jQuery('.wfStartScanButton').addClass('button-wf-grey').val("A scan is in progress...").unbind('click').click(function(){ wordfenceAdmin.scanRunningMsg(); }).show();
207 //scanPending prevents the button from switching to grey when clicked and then quickly to blue and grey again as the ticker us updated.
208 this.scanPending = true;
209 var self = this;
210 setTimeout(function(){ self.scanPending = false; }, 10000);
211 this.ajax('wordfence_scan', {}, function(res){ } );
212 },
213 loadIssues: function(callback){
214 if(this.mode != 'scan'){
215 return;
216 }
217 var self = this;
218 this.ajax('wordfence_loadIssues', { }, function(res){
219 self.displayIssues(res, callback);
220 });
221 },
222 sev2num: function(str){
223 if(/wfProbSev1/.test(str)){
224 return 1;
225 } else if(/wfProbSev2/.test(str)){
226 return 2;
227 } else {
228 return 0;
229 }
230 },
231 displayIssues: function(res, callback){
232 var self = this;
233 res.summary['lastScanCompleted'] = res['lastScanCompleted'];
234 jQuery('#wfSummaryTables').html( jQuery('#wfScanSummaryTmpl').tmpl(res.summary).html() );
235 jQuery('.wfIssuesContainer').hide();
236 for(issueStatus in res.issuesLists){
237 var containerID = 'wfIssues_dataTable_' + issueStatus;
238 var tableID = 'wfIssuesTable_' + issueStatus;
239 if(jQuery('#' + containerID).length < 1){
240 //Invalid issue status
241 continue;
242 }
243 if(res.issuesLists[issueStatus].length < 1){
244 if(issueStatus == 'new'){
245 if(res.lastScanCompleted == 'ok'){
246 jQuery('#' + containerID).html('<p style="font-size: 20px; color: #0A0;">Congratulations! You have no security issues on your site.</p>');
247 } else if(res['lastScanCompleted']){
248 //jQuery('#' + containerID).html('<p style="font-size: 12px; color: #A00;">The latest scan failed: ' + res.lastScanCompleted + '</p>');
249 } else {
250 jQuery('#' + containerID).html();
251 }
252
253 } else {
254 jQuery('#' + containerID).html('<p>There are currently <strong>no issues</strong> being ignored on this site.</p>');
255 }
256 continue;
257 }
258 jQuery('#' + containerID).html('<table cellpadding="0" cellspacing="0" border="0" class="display" id="' + tableID + '"></table>');
259
260 jQuery.fn.dataTableExt.oSort['severity-asc'] = function(y,x){ x = WFAD.sev2num(x); y = WFAD.sev2num(y); if(x < y){ return 1; } if(x > y){ return -1; } return 0; };
261 jQuery.fn.dataTableExt.oSort['severity-desc'] = function(y,x){ x = WFAD.sev2num(x); y = WFAD.sev2num(y); if(x > y){ return 1; } if(x < y){ return -1; } return 0; };
262
263 jQuery('#' + tableID).dataTable({
264 "bFilter": false,
265 "bInfo": false,
266 "bPaginate": false,
267 "bLengthChange": false,
268 "bAutoWidth": false,
269 "aaData": res.issuesLists[issueStatus],
270 "aoColumns": [
271 {
272 "sTitle": '<div class="th_wrapp">Severity</div>',
273 "sWidth": '128px',
274 "sClass": "center",
275 "sType": 'severity',
276 "fnRender": function(obj) {
277 var cls = "";
278 cls = 'wfProbSev' + obj.aData.severity;
279 return '<span class="' + cls + '"></span>';
280 }
281 },
282 {
283 "sTitle": '<div class="th_wrapp">Issue</div>',
284 "bSortable": false,
285 "sWidth": '400px',
286 "sType": 'html',
287 fnRender: function(obj){
288 var tmplName = 'issueTmpl_' + obj.aData.type;
289 return jQuery('#' + tmplName).tmpl(obj.aData).html();
290 }
291 }
292 ]
293 });
294 }
295 if(callback){
296 jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500, function(){ callback(); });
297 } else {
298 jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500);
299 }
300 return true;
301 },
302 ajax: function(action, data, cb, cbErr){
303 if(typeof(data) == 'string'){
304 if(data.length > 0){
305 data += '&';
306 }
307 data += 'action=' + action + '&nonce=' + this.nonce;
308 } else if(typeof(data) == 'object'){
309 data['action'] = action;
310 data['nonce'] = this.nonce;
311 }
312 if(! cbErr){
313 cbErr = function(){};
314 }
315 var self = this;
316 jQuery.ajax({
317 type: 'POST',
318 url: WordfenceAdminVars.ajaxURL,
319 dataType: "json",
320 data: data,
321 success: function(json){
322 if(json && json.nonce){
323 self.nonce = json.nonce;
324 }
325 if(json && json.errorMsg){
326 self.colorbox('400px', 'An error occured', json.errorMsg);
327 }
328 cb(json);
329 },
330 error: cbErr
331 });
332 },
333 colorbox: function(width, heading, body){
334 this.colorboxQueue.push([width, heading, body]);
335 this.colorboxServiceQueue();
336 },
337 colorboxServiceQueue: function(){
338 if(this.colorboxIsOpen){ return; }
339 if(this.colorboxQueue.length < 1){ return; }
340 var elem = this.colorboxQueue.shift();
341 this.colorboxOpen(elem[0], elem[1], elem[2]);
342 },
343 colorboxOpen: function(width, heading, body){
344 this.colorboxIsOpen = true;
345 jQuery.colorbox({ width: width, html: "<h3>" + heading + "</h3><p>" + body + "</p>"});
346 },
347 scanRunningMsg: function(){ this.colorbox('400px', "A scan is running", "A scan is currently in progress. Please wait until it finishes before starting another scan."); },
348 errorMsg: function(msg){ this.colorbox('400px', "An error occured:", msg); },
349 deleteFile: function(issueID){
350 var self = this;
351 this.ajax('wordfence_deleteFile', {
352 issueID: issueID
353 }, function(res){ self.doneDeleteFile(res); });
354 },
355 doneDeleteFile: function(res){
356 if(res.ok){
357 var self = this;
358 this.loadIssues(function(){ self.colorbox('400px', "Success deleting file", "The file " + res.file + " containing " + res.filesize + " bytes was successfully deleted."); });
359 } else if(res.errorMsg){
360 this.loadIssues();
361 }
362 },
363 restoreFile: function(issueID){
364 var self = this;
365 this.ajax('wordfence_restoreFile', {
366 issueID: issueID
367 }, function(res){ self.doneRestoreFile(res); });
368 },
369 doneRestoreFile: function(res){
370 this.loadIssues();
371 if(res.ok){
372 this.colorbox("400px", "File restored OK", "The file " + res.file + " was restored succesfully.");
373 }
374 },
375 deleteIssue: function(id){
376 var self = this;
377 this.ajax('wordfence_deleteIssue', { id: id }, function(res){
378 self.loadIssues();
379 if(res.errMsg){
380 self.colorbox('400px', "An error occured", res.errMsg);
381 }
382 });
383 },
384 updateIssueStatus: function(id, st){
385 var self = this;
386 this.ajax('wordfence_updateIssueStatus', { id: id, 'status': st }, function(res){
387 self.loadIssues();
388 if(res.errMsg){
389 self.colorbox('400px', "An error occured", res.errMsg);
390 }
391 });
392 },
393 updateAllIssues: function(op){ // deleteIgnored, deleteNew, ignoreAllNew
394 var head = "Please confirm";
395 if(op == 'deleteIgnored'){
396 body = "You have chosen to remove all ignored issues. Once these issues are removed they will be re-scanned by Wordfence and if they have not been fixed, they will appear in the 'new issues' list. Are you sure you want to do this?";
397 } else if(op == 'deleteNew'){
398 body = "You have chosen to mark all new issues as fixed. If you have not really fixed these issues, they will reappear in the new issues list on the next scan. If you have not fixed them and want them excluded from scans you should choose to 'ignore' them instead. Are you sure you want to mark all new issues as fixed?";
399 } else if(op == 'ignoreAllNew'){
400 body = "You have chosen to ignore all new issues. That means they will be excluded from future scans. You should only do this if you're sure all new issues are not a problem. Are you sure you want to ignore all new issues?";
401 } else {
402 return;
403 }
404 this.colorbox('450px', head, body + '<br /><br /><center><input type="button" name="but1" value="Cancel" onclick="jQuery.colorbox.close();" />&nbsp;&nbsp;&nbsp;<input type="button" name="but2" value="Yes I\'m sure" onclick="jQuery.colorbox.close(); WFAD.confirmUpdateAllIssues(\'' + op + '\');" /><br />');
405 },
406 confirmUpdateAllIssues: function(op){
407 var self = this;
408 this.ajax('wordfence_updateAllIssues', { op: op }, function(res){ self.loadIssues(); });
409 },
410 es: function(val){
411 if(val){
412 return val;
413 } else {
414 return "";
415 }
416 },
417 noQuotes: function(str){
418 return str.replace(/"/g,'&#34;').replace(/\'/g, '&#145;');
419 },
420 commify: function(num){
421 return ("" + num).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
422 },
423 switchToLiveTab: function(elem){
424 jQuery('.wfTab1').removeClass('selected');
425 jQuery(elem).addClass('selected');
426 jQuery('.wfDataPanel').hide();
427 var self = this;
428 jQuery('#wfActivity').fadeIn(function(){ self.completeLiveTabSwitch(); });
429 },
430 completeLiveTabSwitch: function(){
431 this.ajax('wordfence_loadActivityLog', {}, function(res){
432 var html = '<a href="#" class="wfALogMailLink" onclick="WFAD.emailActivityLog(); return false;"></a><a href="#" class="wfALogReloadLink" onclick="WFAD.reloadActivityData(); return false;"></a>';
433 if(res.events && res.events.length > 0){
434 jQuery('#wfActivity').empty();
435 for(var i = 0; i < res.events.length; i++){
436 var timeTaken = '0.0000';
437 if(res.events[i + 1]){
438 timeTaken = (res.events[i].ctime - res.events[i + 1].ctime).toFixed(4);
439 }
440 var red = "";
441 if(res.events[i].type == 'error'){
442 red = ' class="wfWarn" ';
443 }
444 html += '<div ' + red + 'class="wfALogEntry"><span ' + red + 'class="wfALogTime">[' + res.events[i].type + '&nbsp;:&nbsp;' + timeTaken + '&nbsp;:&nbsp;' + res.events[i].timeAgo + ' ago]</span>&nbsp;' + res.events[i].msg + "</div>";
445 }
446 jQuery('#wfActivity').html(html);
447 } else {
448 jQuery('#wfActivity').html("<p>&nbsp;&nbsp;No activity to report yet. Please complete your first scan.</p>");
449 }
450 });
451 },
452 emailActivityLog: function(){
453 this.colorbox('400px', 'Email Wordfence Activity Log', "Enter the email address you would like to send the Wordfence activity log to. Note that the activity log may contain thousands of lines of data. This log is usually only sent to a member of the Wordfence support team. It also contains your PHP configuration from the phpinfo() function for diagnostic data.<br /><br /><input type='text' value='support@wordfence.com' size='20' id='wfALogRecip' /><input type='button' value='Send' onclick=\"WFAD.completeEmailActivityLog();\" /><input type='button' value='Cancel' onclick='jQuery.colorbox.close();' /><br /><br />");
454 },
455 completeEmailActivityLog: function(){
456 jQuery.colorbox.close();
457 var email = jQuery('#wfALogRecip').val();
458 if(! /^[^@]+@[^@]+$/.test(email)){
459 alert("Please enter a valid email address.");
460 return;
461 }
462 var self = this;
463 this.ajax('wordfence_sendActivityLog', { email: jQuery('#wfALogRecip').val() }, function(res){
464 if(res.ok){
465 self.colorbox('400px', 'Activity Log Sent', "Your Wordfence activity log was sent to " + email + "<br /><br /><input type='button' value='Close' onclick='jQuery.colorbox.close();' /><br /><br />");
466 }
467 });
468 },
469 reloadActivityData: function(){
470 jQuery('#wfActivity').html('<div class="wfLoadingWhite32"></div>'); //&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />
471 this.completeLiveTabSwitch();
472 },
473 switchToSummaryTab: function(elem){
474 jQuery('.wfTab1').removeClass('selected');
475 jQuery(elem).addClass('selected');
476 jQuery('.wfDataPanel').hide();
477 jQuery('#wfSummaryTables').fadeIn();
478 },
479 switchIssuesTab: function(elem, type){
480 jQuery('.wfTab2').removeClass('selected');
481 jQuery('.wfIssuesContainer').hide();
482 jQuery(elem).addClass('selected');
483 this.visibleIssuesPanel = type;
484 jQuery('#wfIssues_' + type).fadeIn();
485 },
486 switchTab: function(tabElement, tabClass, contentClass, selectedContentID, callback){
487 jQuery('.' + tabClass).removeClass('selected');
488 jQuery(tabElement).addClass('selected');
489 jQuery('.' + contentClass).hide().html('<div class="wfLoadingWhite32"></div>');
490 var func = function(){};
491 if(callback){
492 func = function(){ callback(); };
493 }
494 jQuery('#' + selectedContentID).fadeIn(func);
495 },
496 activityTabChanged: function(){
497 var mode = jQuery('.wfDataPanel:visible')[0].id.replace('wfActivity_','');
498 if(! mode){ return; }
499 this.activityMode = mode;
500 this.reloadActivities();
501 },
502 reloadActivities: function(){
503 jQuery('#wfActivity_' + this.activityMode).html('<div class="wfLoadingWhite32"></div>');
504 this.newestActivityTime = 0;
505 this.updateTicker(true);
506 },
507 staticTabChanged: function(){
508 var mode = jQuery('.wfDataPanel:visible')[0].id.replace('wfActivity_','');
509 if(! mode){ return; }
510 this.activityMode = mode;
511
512 var self = this;
513 this.ajax('wordfence_loadStaticPanel', {
514 mode: this.activityMode
515 }, function(res){
516 self.completeLoadStaticPanel(res);
517 });
518 },
519 completeLoadStaticPanel: function(res){
520 var contentElem = '#wfActivity_' + this.activityMode;
521 jQuery(contentElem).empty();
522 if(res.results && res.results.length > 0){
523 var tmpl;
524 if(this.activityMode == 'topScanners' || this.activityMode == 'topLeechers'){
525 tmpl = '#wfLeechersTmpl';
526 } else if(this.activityMode == 'blockedIPs'){
527 tmpl = '#wfBlockedIPsTmpl';
528 } else if(this.activityMode == 'lockedOutIPs'){
529 tmpl = '#wfLockedOutIPsTmpl';
530 } else if(this.activityMode == 'throttledIPs'){
531 tmpl = '#wfThrottledIPsTmpl';
532 } else { return; }
533 jQuery(tmpl).tmpl(res).prependTo(contentElem);
534 this.reverseLookupIPs();
535 } else {
536 if(this.activityMode == 'topScanners' || this.activityMode == 'topLeechers'){
537 jQuery(contentElem).html("No site hits have been logged yet. Check back soon.");
538 } else if(this.activityMode == 'blockedIPs'){
539 jQuery(contentElem).html("No IP addresses have been blocked yet. If you manually block an IP address or if Wordfence automatically blocks one, it will appear here.");
540 } else if(this.activityMode == 'lockedOutIPs'){
541 jQuery(contentElem).html("No IP addresses have been locked out from signing in or using the password recovery system.");
542 } else if(this.activityMode == 'throttledIPs'){
543 jQuery(contentElem).html("No IP addresses have been throttled yet. If an IP address accesses the site too quickly and breaks one of the Wordfence rules, it will appear here.");
544 } else { return; }
545 }
546 },
547 ucfirst: function(str){
548 str = "" + str;
549 return str.charAt(0).toUpperCase() + str.slice(1);
550 },
551 makeIPTrafLink: function(IP){
552 return '/?_wfsf=IPTraf&nonce=' + this.nonce + '&IP=' + encodeURIComponent(IP);
553 },
554 makeDiffLink: function(dat){
555 return '/?_wfsf=diff&nonce=' + this.nonce +
556 '&file=' + encodeURIComponent(this.es(dat['file'])) +
557 '&cType=' + encodeURIComponent(this.es(dat['cType'])) +
558 '&cKey=' + encodeURIComponent(this.es(dat['cKey'])) +
559 '&cName=' + encodeURIComponent(this.es(dat['cName'])) +
560 '&cVersion=' + encodeURIComponent(this.es(dat['cVersion']));
561 },
562 makeTimeAgo: function(t){
563 var months = Math.floor(t / (86400 * 30));
564 var days = Math.floor(t / 86400);
565 var hours = Math.floor(t / 3600);
566 var minutes = Math.floor(t / 60);
567 if(months > 0){
568 days -= months * 30;
569 return this.pluralize(months, 'month', days, 'day');
570 } else if(days > 0){
571 hours -= days * 24;
572 return this.pluralize(days, 'day', hours, 'hour');
573 } else if(hours > 0) {
574 minutes -= hours * 60;
575 return this.pluralize(hours, 'hour', minutes, 'min');
576 } else if(minutes > 0) {
577 //t -= minutes * 60;
578 return this.pluralize(minutes, 'minute');
579 } else {
580 return Math.round(t) + " seconds";
581 }
582 },
583 pluralize: function(m1, t1, m2, t2){
584 if(m1 != 1) {
585 t1 = t1 + 's';
586 }
587 if(m2 != 1) {
588 t2 = t2 + 's';
589 }
590 if(m1 && m2){
591 return m1 + ' ' + t1 + ' ' + m2 + ' ' + t2;
592 } else {
593 return m1 + ' ' + t1;
594 }
595 },
596 blockIP: function(IP, reason){
597 var self = this;
598 this.ajax('wordfence_blockIP', {
599 IP: IP,
600 reason: reason
601 }, function(res){
602 if(res.errorMsg){
603 return;
604 } else {
605 self.reloadActivities();
606 }
607 });
608 },
609 unlockOutIP: function(IP){
610 var self = this;
611 this.ajax('wordfence_unlockOutIP', {
612 IP: IP
613 }, function(res){ self.staticTabChanged(); });
614 },
615 unblockIP: function(IP){
616 var self = this;
617 this.ajax('wordfence_unblockIP', {
618 IP: IP
619 }, function(res){ self.staticTabChanged(); });
620 },
621 makeElemID: function(){
622 return 'wfElemGen' + this.elementGeneratorIter++;
623 },
624 pulse: function(sel){
625 jQuery(sel).fadeIn(function(){
626 setTimeout(function(){ jQuery(sel).fadeOut(); }, 2000);
627 });
628 },
629 saveConfig: function(){
630 var qstr = jQuery('#wfConfigForm').serialize();
631 var self = this;
632 jQuery('.wfSavedMsg').hide();
633 jQuery('.wfAjax24').show();
634 this.ajax('wordfence_saveConfig', qstr, function(res){
635 jQuery('.wfAjax24').hide();
636 if(res.ok){
637 if(res['reload'] == 'reload' || WFAD.reloadConfigPage){
638 self.colorbox('400px', "Please reload this page", "You selected a config option that requires a page reload. Click the button below to reload this page to update the menu.<br /><br /><center><input type='button' name='wfReload' value='Reload page' onclick='window.location.reload();' /></center>");
639 return;
640 } else {
641 self.pulse('.wfSavedMsg');
642 }
643 } else if(res.errorMsg){
644 return;
645 } else {
646 self.colorbox('400px', 'An error occured', 'We encountered an error trying to save your changes.');
647 }
648 });
649 },
650 changeSecurityLevel: function(){
651 var level = jQuery('#securityLevel').val();
652 for(var k in WFSLevels[level].checkboxes){
653 if(k != 'liveTraf_ignorePublishers'){
654 jQuery('#' + k).prop("checked", WFSLevels[level].checkboxes[k]);
655 }
656 }
657 for(var k in WFSLevels[level].otherParams){
658 if(! /^(?:apiKey|securityLevel|alertEmails|liveTraf_ignoreUsers|liveTraf_ignoreIPs|liveTraf_ignoreUA|liveTraf_hitsMaxSize)$/.test(k)){
659 jQuery('#' + k).val(WFSLevels[level].otherParams[k]);
660 }
661 }
662 },
663 clearAllBlocked: function(op){
664 if(op == 'blocked'){
665 body = "Are you sure you want to clear all blocked IP addresses and allow visitors from those addresses to access the site again?";
666 } else if(op == 'locked'){
667 body = "Are you sure you want to clear all locked IP addresses and allow visitors from those addresses to sign in again?";
668 } else {
669 return;
670 }
671 this.colorbox('450px', "Please confirm", body +
672 '<br /><br /><center><input type="button" name="but1" value="Cancel" onclick="jQuery.colorbox.close();" />&nbsp;&nbsp;&nbsp;' +
673 '<input type="button" name="but2" value="Yes I\'m sure" onclick="jQuery.colorbox.close(); WFAD.confirmClearAllBlocked(\'' + op + '\');"><br />');
674 },
675 confirmClearAllBlocked: function(op){
676 var self = this;
677 this.ajax('wordfence_clearAllBlocked', { op: op }, function(res){
678 self.staticTabChanged();
679 });
680 }
681 };
682 window['WFAD'] = window['wordfenceAdmin'];
683 }
684 jQuery(function(){
685 wordfenceAdmin.init();
686 });
687