fix: remove CSP-blocked inline event handlers (onerror, onclick)
- Remove all onerror="this.style.display='none'" from avatar imgs in layout_header.php, DashboardView.php, and TicketView.php (PHP + JS) - Replace onclick SLA dismiss with data-action="dismiss-priority-banner" attribute; handler wired via existing click delegation in TicketView.php - Global capture-phase error delegation in layout_footer.php handles all avatar image failures by adding .lt-avatar-img-err class (CSS display:none) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+10
-10
@@ -212,12 +212,7 @@ $progressClass = $slaBreached ? 'lt-progress--red' : ($slaPct >= 75 ? 'lt-progr
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="lt-alert-close" aria-label="Dismiss"
|
||||
onclick="(function(btn){
|
||||
var id=btn.closest('[data-alert-id]').dataset.alertId;
|
||||
try{sessionStorage.setItem('lt_dismissed_'+id,'1');}catch(e){}
|
||||
btn.closest('.lt-alert').classList.add('dismissed');
|
||||
})(this)">✕</button>
|
||||
<button type="button" class="lt-alert-close" data-action="dismiss-priority-banner" aria-label="Dismiss">✕</button>
|
||||
</div>
|
||||
<script nonce="<?= htmlspecialchars($nonce, ENT_QUOTES, 'UTF-8') ?>">
|
||||
(function(){
|
||||
@@ -564,8 +559,7 @@ $progressClass = $slaBreached ? 'lt-progress--red' : ($slaPct >= 75 ? 'lt-progr
|
||||
<?php if ($commentUserId > 0): ?>
|
||||
<img src="/api/user_avatar.php?user_id=<?= $commentUserId ?>"
|
||||
alt=""
|
||||
class="lt-avatar-img"
|
||||
onerror="this.style.display='none'">
|
||||
class="lt-avatar-img">
|
||||
<?php endif ?>
|
||||
<span class="lt-avatar-initials"><?= htmlspecialchars($initials) ?></span>
|
||||
</div>
|
||||
@@ -978,7 +972,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
for (var i = 0; i < (w.display_name || '').length; i++) hash = ((hash << 5) - hash + (w.display_name || '').charCodeAt(i)) | 0;
|
||||
var color = avatarColors[Math.abs(hash) % 4];
|
||||
html += '<div class="lt-avatar lt-avatar--xs ' + color + '" title="' + lt.escHtml(w.display_name) + '" aria-label="' + lt.escHtml(w.display_name) + '">' +
|
||||
'<img src="/api/user_avatar.php?user_id=' + w.user_id + '" alt="" class="lt-avatar-img" onerror="this.style.display=\'none\'">' +
|
||||
'<img src="/api/user_avatar.php?user_id=' + w.user_id + '" alt="" class="lt-avatar-img">' +
|
||||
'<span class="lt-avatar-initials">' + lt.escHtml(initials) + '</span>' +
|
||||
'</div>';
|
||||
});
|
||||
@@ -1121,6 +1115,12 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (typeof editComment === 'function') editComment(parseInt(commentId, 10));
|
||||
} else if (action === 'delete-comment' && commentId) {
|
||||
if (typeof deleteComment === 'function') deleteComment(parseInt(commentId, 10));
|
||||
} else if (action === 'dismiss-priority-banner') {
|
||||
var banner = target.closest('[data-alert-id]');
|
||||
if (banner) {
|
||||
try { sessionStorage.setItem('lt_dismissed_' + banner.dataset.alertId, '1'); } catch(ex) {}
|
||||
banner.classList.add('dismissed');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1237,7 +1237,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
' data-action="delete-comment" data-comment-id="' + commentId + '" aria-label="Delete comment">Del</button>' : '';
|
||||
var threadLine = parentId ? '<div class="thread-line" aria-hidden="true"></div>' : '';
|
||||
var avatarImg = userId > 0 ?
|
||||
'<img src="/api/user_avatar.php?user_id=' + userId + '" alt="" class="lt-avatar-img" onerror="this.style.display=\'none\'">' : '';
|
||||
'<img src="/api/user_avatar.php?user_id=' + userId + '" alt="" class="lt-avatar-img">' : '';
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.className = 'comment ' + depthClass + ' ' + threadClass;
|
||||
|
||||
Reference in New Issue
Block a user