From af2640736368442edbe4aa3b73a4e17d3b68346f Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Fri, 13 Mar 2026 14:36:55 -0400 Subject: [PATCH] Fix setDur implicit event, title XSS, hardcoded pulse URL, suppress error toast - suppressions.html: setDur() now takes explicit element param instead of relying on implicit global event.target (which fails outside direct click handlers) - suppressions.html: removeSuppression() now shows error toast on failed DELETE - templates/index.html: escape description in title attribute with |e filter to prevent attribute breakout on quotes in description text - diagnose.py: derive Pulse execution URL from pulse_client.url instead of hardcoding http://pulse.lotusguild.org Co-Authored-By: Claude Sonnet 4.6 --- diagnose.py | 3 ++- templates/index.html | 2 +- templates/suppressions.html | 6 ++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/diagnose.py b/diagnose.py index 7b34d68..79c7d9c 100644 --- a/diagnose.py +++ b/diagnose.py @@ -108,7 +108,8 @@ class DiagnosticsRunner: pulse_url = None if execution_id: - pulse_url = f'http://pulse.lotusguild.org/executions/{execution_id}' + base = getattr(self.pulse, 'url', '').rstrip('/') + pulse_url = f'{base}/executions/{execution_id}' if base else None return { 'status': 'done', diff --git a/templates/index.html b/templates/index.html index 9a7b35a..93cb6e2 100644 --- a/templates/index.html +++ b/templates/index.html @@ -214,7 +214,7 @@ {{ e.event_type | replace('_', ' ') }} {{ e.target_name }} {{ e.target_detail or '–' }} - {{ e.description | truncate(60) }} + {{ e.description | truncate(60) }} {{ e.first_seen }} {{ e.consecutive_failures }} diff --git a/templates/suppressions.html b/templates/suppressions.html index 4449e58..c4ca7c6 100644 --- a/templates/suppressions.html +++ b/templates/suppressions.html @@ -180,10 +180,10 @@ document.getElementById('s-name').required = (t!=='all'); } - function setDur(mins) { + function setDur(mins, el) { document.getElementById('s-expires').value = mins || ''; document.querySelectorAll('.duration-pills .pill').forEach(p => p.classList.remove('active')); - event.target.classList.add('active'); + if (el) el.classList.add('active'); const hint = document.getElementById('s-dur-hint'); if (mins) { const h = Math.floor(mins/60), m = mins%60; @@ -224,6 +224,8 @@ if (data.success) { document.getElementById(`sup-row-${id}`)?.remove(); showToast('Suppression removed', 'success'); + } else { + showToast(data.error || 'Failed to remove suppression', 'error'); } }