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> ' + 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();" /> <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,'"').replace(/\'/g, '‘'); |
| 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 + ' : ' + timeTaken + ' : ' + res.events[i].timeAgo + ' ago]</span> ' + res.events[i].msg + "</div>"; |
| 445 | } |
| 446 | jQuery('#wfActivity').html(html); |
| 447 | } else { |
| 448 | jQuery('#wfActivity').html("<p> 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>'); // <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <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();" /> ' + |
| 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 |