Fix quarantine action button escaping
This commit is contained in:
parent
de560cac85
commit
52ee406a6c
1 changed files with 24 additions and 12 deletions
|
|
@ -3137,21 +3137,17 @@ function renderQuarantineEntry(entry) {
|
||||||
const triggerLabel = triggerLabels[entry.trigger] || entry.trigger || 'Unknown';
|
const triggerLabel = triggerLabels[entry.trigger] || entry.trigger || 'Unknown';
|
||||||
const triggerColor = triggerColors[entry.trigger] || '#888';
|
const triggerColor = triggerColors[entry.trigger] || '#888';
|
||||||
|
|
||||||
// Issue #608 (AfonsoG6): the prior code injected `entry.id` raw
|
// Keep dynamic filenames/ids out of inline JS. Quarantine ids are derived
|
||||||
// into single-quoted JS string literals inside HTML onclick
|
// from filenames, so quotes in the filename can break onclick attributes
|
||||||
// attributes. Filenames containing an apostrophe broke JS
|
// if they are interpolated as JS string literals.
|
||||||
// parsing — Approve and Delete buttons silently no-op'd.
|
const entryIdAttr = escapeHtml(String(entry.id || ''));
|
||||||
// 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));
|
|
||||||
const approveLabel = entry.has_full_context ? 'Approve' : 'Recover';
|
const approveLabel = entry.has_full_context ? 'Approve' : 'Recover';
|
||||||
const approveTitle = entry.has_full_context
|
const approveTitle = entry.has_full_context
|
||||||
? 'Re-run post-processing with only the failing check skipped'
|
? 'Re-run post-processing with only the failing check skipped'
|
||||||
: 'Legacy entry — move to Staging, finish via Import flow';
|
: 'Legacy entry — move to Staging, finish via Import flow';
|
||||||
const approveCall = entry.has_full_context
|
const approveCall = entry.has_full_context
|
||||||
? `approveQuarantineEntry(${idJs})`
|
? 'approveQuarantineEntryFromButton(this)'
|
||||||
: `recoverQuarantineEntry(${idJs})`;
|
: 'recoverQuarantineEntryFromButton(this)';
|
||||||
|
|
||||||
const meta = [entry.expected_artist, entry.original_filename].filter(Boolean).join(' — ');
|
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>`;
|
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>
|
||||||
<div class="library-history-entry-badges">${triggerBadge}</div>
|
<div class="library-history-entry-badges">${triggerBadge}</div>
|
||||||
<div class="library-history-entry-time">${formatHistoryTime(entry.timestamp)}</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="${approveTitle}" data-entry-id="${entryIdAttr}" 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="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">▾</span>
|
<span class="lh-expand-btn">▾</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="library-history-entry-details">
|
<div class="library-history-entry-details">
|
||||||
|
|
@ -3191,6 +3187,22 @@ function renderQuarantineEntry(entry) {
|
||||||
</div>`;
|
</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) {
|
async function approveQuarantineEntry(entryId) {
|
||||||
const ok = await showConfirmDialog({
|
const ok = await showConfirmDialog({
|
||||||
title: 'Approve Quarantined File',
|
title: 'Approve Quarantined File',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue