Fix quarantine action button escaping

pull/624/head
Broque Thomas 1 week ago
parent de560cac85
commit 52ee406a6c

@ -3137,21 +3137,17 @@ function renderQuarantineEntry(entry) {
const triggerLabel = triggerLabels[entry.trigger] || entry.trigger || 'Unknown';
const triggerColor = triggerColors[entry.trigger] || '#888';
// Issue #608 (AfonsoG6): the prior code injected `entry.id` raw
// into single-quoted JS string literals inside HTML onclick
// attributes. Filenames containing an apostrophe broke JS
// parsing — Approve and Delete buttons silently no-op'd.
// JSON.stringify wraps the value in valid JS literal syntax
// (handles ', \, " and unicode); escapeHtml then guards the HTML
// attribute boundary so the JS string round-trips intact.
const idJs = escapeHtml(JSON.stringify(entry.id));
// Keep dynamic filenames/ids out of inline JS. Quarantine ids are derived
// from filenames, so quotes in the filename can break onclick attributes
// if they are interpolated as JS string literals.
const entryIdAttr = escapeHtml(String(entry.id || ''));
const approveLabel = entry.has_full_context ? 'Approve' : 'Recover';
const approveTitle = entry.has_full_context
? 'Re-run post-processing with only the failing check skipped'
: 'Legacy entry — move to Staging, finish via Import flow';
const approveCall = entry.has_full_context
? `approveQuarantineEntry(${idJs})`
: `recoverQuarantineEntry(${idJs})`;
? 'approveQuarantineEntryFromButton(this)'
: 'recoverQuarantineEntryFromButton(this)';
const meta = [entry.expected_artist, entry.original_filename].filter(Boolean).join(' — ');
const triggerBadge = `<span class="library-history-badge" style="border-color:${triggerColor};color:${triggerColor}">${escapeHtml(triggerLabel)}</span>`;
@ -3179,8 +3175,8 @@ function renderQuarantineEntry(entry) {
</div>
<div class="library-history-entry-badges">${triggerBadge}</div>
<div class="library-history-entry-time">${formatHistoryTime(entry.timestamp)}</div>
<button class="lh-audit-btn" title="${approveTitle}" onclick="event.stopPropagation();${approveCall}">${approveLabel}</button>
<button class="lh-audit-btn" title="Delete permanently" style="border-color:rgba(248,113,113,0.4);color:#f87171" onclick="event.stopPropagation();deleteQuarantineEntry(${idJs})">Delete</button>
<button class="lh-audit-btn" title="${approveTitle}" data-entry-id="${entryIdAttr}" onclick="event.stopPropagation();${approveCall}">${approveLabel}</button>
<button class="lh-audit-btn" title="Delete permanently" data-entry-id="${entryIdAttr}" style="border-color:rgba(248,113,113,0.4);color:#f87171" onclick="event.stopPropagation();deleteQuarantineEntryFromButton(this)">Delete</button>
<span class="lh-expand-btn">&#x25BE;</span>
</div>
<div class="library-history-entry-details">
@ -3191,6 +3187,22 @@ function renderQuarantineEntry(entry) {
</div>`;
}
function getQuarantineEntryIdFromButton(button) {
return button?.dataset?.entryId || '';
}
function approveQuarantineEntryFromButton(button) {
return approveQuarantineEntry(getQuarantineEntryIdFromButton(button));
}
function recoverQuarantineEntryFromButton(button) {
return recoverQuarantineEntry(getQuarantineEntryIdFromButton(button));
}
function deleteQuarantineEntryFromButton(button) {
return deleteQuarantineEntry(getQuarantineEntryIdFromButton(button));
}
async function approveQuarantineEntry(entryId) {
const ok = await showConfirmDialog({
title: 'Approve Quarantined File',

Loading…
Cancel
Save