| @@ -1299,9 +1299,9 @@ | ||
| 1299 | 1299 | html += '<tr>'; |
| 1300 | 1300 | html += '<th scope="row" class="check-column"><input type="checkbox" class="vigilante-fi-cb" value="' + esc(file.file) + '"></th>'; |
| 1301 | 1301 | html += '<td><code style="color: #d63638;">' + esc(file.file) + '</code></td>'; |
| 1302 | 1302 | html += '<td>' + esc(file.reason || strings.unknown) + '</td>'; |
| 1303 | - html += '<td>' + esc(file.type || strings.unknown) + '</td>'; | |
| 1303 | + html += '<td>' + esc(file.type === 'vigilante_self' ? (strings.selfType || 'Vigilant (self)') : (file.type || strings.unknown)) + '</td>'; | |
| 1304 | 1304 | html += '<td><button type="button" class="button button-small vigilante-ignore-file" data-file="' + esc(file.file) + '">' + (strings.ignore || 'Ignore') + '</button></td>'; |
| 1305 | 1305 | html += '</tr>'; |
| 1306 | 1306 | }); |
| 1307 | 1307 | html += '</tbody></table>'; |
| @@ -1322,9 +1322,9 @@ | ||
| 1322 | 1322 | html += '<tr>'; |
| 1323 | 1323 | html += '<th scope="row" class="check-column"><input type="checkbox" class="vigilante-fi-cb" value="' + esc(file.file) + '"></th>'; |
| 1324 | 1324 | html += '<td><code style="color: #b32d2e;">' + esc(file.file) + '</code></td>'; |
| 1325 | 1325 | html += '<td>' + esc(file.reason || strings.unknown) + '</td>'; |
| 1326 | - html += '<td>' + esc(file.type || strings.unknown) + '</td>'; | |
| 1326 | + html += '<td>' + esc(file.type === 'vigilante_self' ? (strings.selfType || 'Vigilant (self)') : (file.type || strings.unknown)) + '</td>'; | |
| 1327 | 1327 | html += '<td><button type="button" class="button button-small vigilante-ignore-file" data-file="' + esc(file.file) + '">' + (strings.ignore || 'Ignore') + '</button></td>'; |
| 1328 | 1328 | html += '</tr>'; |
| 1329 | 1329 | }); |
| 1330 | 1330 | html += '</tbody></table>'; |
| @@ -1340,8 +1340,16 @@ | ||
| 1340 | 1340 | } else { |
| 1341 | 1341 | regularModified.push(file); |
| 1342 | 1342 | } |
| 1343 | 1343 | }); |
| 1344 | + // A missing file of Vigilant is critical and the generic missing | |
| 1345 | + // files have no table: list it with the modified files, or the | |
| 1346 | + // screen said "All clear" with a module deleted. | |
| 1347 | + results.missing.forEach(function(file) { | |
| 1348 | + if (file && file.type === 'vigilante_self') { | |
| 1349 | + regularModified.push(file); | |
| 1350 | + } | |
| 1351 | + }); | |
| 1344 | 1352 | |
| 1345 | 1353 | // Critical config files section (same visual treatment as suspicious files) |
| 1346 | 1354 | if (criticalModified.length > 0) { |
| 1347 | 1355 | html += '<div class="vigilante-file-list vigilante-critical-config-files">'; |
| @@ -1399,9 +1407,15 @@ | ||
| 1399 | 1407 | // Expandable diff row |
| 1400 | 1408 | html += '<tr id="vigilante-critical-content-' + fileId + '" class="vigilante-critical-content-row" style="display:none;">'; |
| 1401 | 1409 | html += '<td colspan="3" style="padding: 0;">'; |
| 1402 | 1410 | html += '<div class="vigilante-critical-content" style="max-height: 400px; overflow: auto; background: #fff; padding: 10px; font-size: 12px; line-height: 1.5; font-family: Consolas, Monaco, monospace; border-top: 1px solid #c3c4c7;">'; |
| 1403 | - if (diffUnavailable) { | |
| 1411 | + if (diff.network) { | |
| 1412 | + html += '<p style="color: #50575e; font-style: italic; margin: 0;">' + escHtml(strings.diffNetwork || '') + '</p>'; | |
| 1413 | + } else if (diff.rescan) { | |
| 1414 | + html += '<p style="color: #50575e; font-style: italic; margin: 0;">' + escHtml(strings.diffRescan || '') + '</p>'; | |
| 1415 | + } else if (diff.redaction) { | |
| 1416 | + html += '<p style="color: #50575e; font-style: italic; margin: 0;">' + escHtml(strings.diffRedaction || '') + '</p>'; | |
| 1417 | + } else if (diffUnavailable) { | |
| 1404 | 1418 | html += '<p style="color: #50575e; font-style: italic; margin: 0;">' + (strings.diffUnavailable || 'Diff not available.') + '</p>'; |
| 1405 | 1419 | } else if (added.length === 0 && removed.length === 0) { |
| 1406 | 1420 | html += '<p style="color: #50575e; font-style: italic; margin: 0;">' + (strings.diffEmpty || 'No line changes detected.') + '</p>'; |
| 1407 | 1421 | } else { |
| @@ -1434,9 +1448,9 @@ | ||
| 1434 | 1448 | regularModified.forEach(function(file) { |
| 1435 | 1449 | html += '<tr>'; |
| 1436 | 1450 | html += '<th scope="row" class="check-column"><input type="checkbox" class="vigilante-fi-cb" value="' + esc(file.file) + '"></th>'; |
| 1437 | 1451 | html += '<td><code>' + esc(file.file) + '</code></td>'; |
| 1438 | - html += '<td>' + esc(file.type || strings.unknown) + '</td>'; | |
| 1452 | + html += '<td>' + esc(file.type === 'vigilante_self' ? (strings.selfType || 'Vigilant (self)') : (file.type || strings.unknown)) + '</td>'; | |
| 1439 | 1453 | html += '<td><button type="button" class="button button-small vigilante-ignore-file" data-file="' + esc(file.file) + '">' + (strings.ignore || 'Ignore') + '</button></td>'; |
| 1440 | 1454 | html += '</tr>'; |
| 1441 | 1455 | }); |
| 1442 | 1456 | html += '</tbody></table>'; |
| @@ -1442,9 +1456,9 @@ | ||
| 1442 | 1456 | html += '</tbody></table>'; |
| 1443 | 1457 | html += '</div>'; |
| 1444 | 1458 | } |
| 1445 | 1459 | |
| 1446 | - if (results.modified.length === 0 && results.suspicious.length === 0 && results.extra.length === 0) { | |
| 1460 | + if (criticalModified.length === 0 && regularModified.length === 0 && results.suspicious.length === 0 && results.extra.length === 0) { | |
| 1447 | 1461 | html += '<div class="vigilante-all-clear"><span class="dashicons dashicons-yes-alt"></span> ' + strings.allClear + '</div>'; |
| 1448 | 1462 | } |
| 1449 | 1463 | |
| 1450 | 1464 | $container.html(html).show(); |
| @@ -1993,9 +2007,10 @@ | ||
| 1993 | 2007 | severity: log.severity || 'info', |
| 1994 | 2008 | is_ip_whitelisted: !!log.is_ip_whitelisted, |
| 1995 | 2009 | is_ip_blacklisted: !!log.is_ip_blacklisted, |
| 1996 | 2010 | is_ua_whitelisted: !!log.is_ua_whitelisted, |
| 1997 | - is_ua_blacklisted: !!log.is_ua_blacklisted | |
| 2011 | + is_ua_blacklisted: !!log.is_ua_blacklisted, | |
| 2012 | + self: log.self_guidance || null | |
| 1998 | 2013 | }; |
| 1999 | 2014 | |
| 2000 | 2015 | var displayType = typeLabels[log.event_type] || log.event_type; |
| 2001 | 2016 | var displaySeverity = severityLabels[log.severity] || log.severity; |
| @@ -2632,9 +2647,43 @@ | ||
| 2632 | 2647 | |
| 2633 | 2648 | var html = ''; |
| 2634 | 2649 | |
| 2635 | 2650 | var s = vigilanteAdmin.strings; |
| 2651 | + var esc = Vigilante_Admin.escapeHtml; | |
| 2636 | 2652 | |
| 2653 | + // -- Section: what happened (self-protection entries) -- | |
| 2654 | + // Text only: every value below is printed as text, never as an | |
| 2655 | + // attribute, and the link is a fixed URL built with esc_url(). | |
| 2656 | + if (details.self && details.self.title) { | |
| 2657 | + html += '<div class="vigilante-popup-section">'; | |
| 2658 | + html += '<h4 class="vigilante-popup-section-title">' + esc(s.logWhatHappened || 'What happened') + '</h4>'; | |
| 2659 | + html += '<p><strong>' + esc(details.self.title) + '</strong></p>'; | |
| 2660 | + if (details.self.files && details.self.files.length) { | |
| 2661 | + html += '<ul class="vigilante-popup-files">'; | |
| 2662 | + details.self.files.slice(0, 20).forEach(function(file) { | |
| 2663 | + html += '<li><code>' + esc(file) + '</code></li>'; | |
| 2664 | + }); | |
| 2665 | + if (details.self.files.length > 20) { | |
| 2666 | + html += '<li>' + esc('+' + (details.self.files.length - 20)) + '</li>'; | |
| 2667 | + } | |
| 2668 | + html += '</ul>'; | |
| 2669 | + } | |
| 2670 | + if (details.self.meaning) { | |
| 2671 | + html += '<p><strong>' + esc(s.logWhatItMeans || 'What it means') + ':</strong> ' + esc(details.self.meaning) + '</p>'; | |
| 2672 | + } | |
| 2673 | + if (details.self.steps && details.self.steps.length) { | |
| 2674 | + html += '<p><strong>' + esc(s.logWhatToDo || 'What to do') + ':</strong></p><ol>'; | |
| 2675 | + details.self.steps.forEach(function(step) { | |
| 2676 | + html += '<li>' + esc(step) + '</li>'; | |
| 2677 | + }); | |
| 2678 | + html += '</ol>'; | |
| 2679 | + } | |
| 2680 | + if (vigilanteAdmin.selfBoxUrl) { | |
| 2681 | + html += '<p><a href="' + esc(vigilanteAdmin.selfBoxUrl) + '">' + esc(s.logSelfSeeDetails || 'Open File Integrity for the full detail') + '</a></p>'; | |
| 2682 | + } | |
| 2683 | + html += '</div>'; | |
| 2684 | + } | |
| 2685 | + | |
| 2637 | 2686 | // -- Section: Request -- |
| 2638 | 2687 | html += '<div class="vigilante-popup-section">'; |
| 2639 | 2688 | html += '<h4 class="vigilante-popup-section-title">' + this.escapeHtml(s.logRequest || 'Request') + '</h4>'; |
| 2640 | 2689 | html += '<table class="vigilante-details-table">'; |
| @@ -4254,8 +4303,18 @@ | ||
| 4254 | 4303 | $target.addClass('vigilante-focus-flash'); |
| 4255 | 4304 | setTimeout(function() { |
| 4256 | 4305 | $target.removeClass('vigilante-focus-flash'); |
| 4257 | 4306 | }, 1800); |
| 4307 | + | |
| 4308 | + // And once more when everything has loaded: anything that | |
| 4309 | + // changes height above the target (images, notices, the admin | |
| 4310 | + // bar on a narrow screen) moves it after the first scroll, and | |
| 4311 | + // then the link looks like it only opened the tab. | |
| 4312 | + $(window).one('load', function() { | |
| 4313 | + if ($target[0] && 'scrollIntoView' in $target[0]) { | |
| 4314 | + $target[0].scrollIntoView({ behavior: 'smooth', block: 'center' }); | |
| 4315 | + } | |
| 4316 | + }); | |
| 4258 | 4317 | }, 150); |
| 4259 | 4318 | }, |
| 4260 | 4319 | |
| 4261 | 4320 | /** Escape text for HTML. */ |