[grade=A urn:ump:josd2g7kqv476vux6euigmygdkijya2s4tsbyivtobw5ftzuf6ba] fix(DC-170): revive 19 CSP-blocked inline handlers across the dashboard — audit P0-3
The meta CSP (no unsafe-inline/unsafe-hashes) blocks ALL inline event
handlers; 19 controls were silently dead in every modern browser.
Revived:
- Disk Safety: toolbar button, injected modal Close/Save/Clean Up, and
the 5 settings sliders (oninput -> input listeners; value labels
never updated)
- AI chat FAB click; hover scale moved to a #ai-chat-fab:hover rule
- TOTP/login logo broken-image fallbacks: capture-phase error
delegation + WeakSet + complete/naturalWidth race guard in
totp-auth.js; updateTotpLogo never resurrects a broken logo
(6 onerror attrs stripped from index.html + auth-gate.js templates)
- favicon-preview data-URI fallback (same race guard)
- app-selector folder-chip remove buttons (data-remove-folder)
- premium upsells in backup-restore + workflows (data-upgrade-msg) —
their old onclick also called scrollToSection('license'), a function
that has never existed anywhere in the codebase; now opens the real
license UI via window.openLicenseModal (license.js)
- health-check Edit/Delete dispatch the same CustomEvents via
data-health-action/data-service-id
- smart-arr Test button via data-smart-test
Verified: zero inline handler attributes remain across index.html +
hand-written js (grep); node --check clean x12; status suite 68/68;
dist rebuilt (SW dashcaddy-shell-36d9aa3364, CSP hash unchanged).
r1 grade C (missed sliders + logo onerror) -> r2 grade A:
urn:ump:mptri3qhywc2e47f2ba4qjafhwm3olzvrvt5vphxoyhea3vgt32a /
urn:ump:josd2g7kqv476vux6euigmygdkijya2s4tsbyivtobw5ftzuf6ba
This commit is contained in:
15 files changed
+439
-348
No files matched your search
@@ -33,7 +33,7 @@
|
||||
<div style="background:var(--bg-card,#1a1a2e);border-radius:12px;padding:28px;max-width:520px;width:90%;max-height:85vh;overflow-y:auto;border:1px solid var(--border,#333);">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;">
|
||||
<h2 style="margin:0;font-size:1.3rem;">💾 Disk Safety</h2>
|
||||
<button onclick="document.getElementById('disk-settings-modal').remove()" style="background:none;border:none;font-size:1.5rem;cursor:pointer;color:var(--text-muted,#888);">×</button>
|
||||
<button id="disk-close-btn" aria-label="Close" style="background:none;border:none;font-size:1.5rem;cursor:pointer;color:var(--text-muted,#888);">×</button>
|
||||
</div>
|
||||
|
||||
<div style="background:rgba(99,102,241,0.08);border:1px solid rgba(99,102,241,0.2);border-radius:8px;padding:14px;margin-bottom:20px;">
|
||||
@@ -65,13 +65,26 @@
|
||||
</div>
|
||||
|
||||
<div style="display:flex;gap:10px;margin-top:24px;">
|
||||
<button onclick="saveDiskSettings()" style="flex:1;padding:10px 16px;background:#6366f1;color:#fff;border:none;border-radius:8px;cursor:pointer;font-weight:600;">Save Settings</button>
|
||||
<button onclick="cleanupDiskNow()" style="flex:1;padding:10px 16px;background:rgba(239,68,68,0.15);color:#f87171;border:1px solid rgba(239,68,68,0.3);border-radius:8px;cursor:pointer;font-weight:600;">Clean Up Now</button>
|
||||
<button id="disk-save-btn" style="flex:1;padding:10px 16px;background:#6366f1;color:#fff;border:none;border-radius:8px;cursor:pointer;font-weight:600;">Save Settings</button>
|
||||
<button id="disk-cleanup-btn" style="flex:1;padding:10px 16px;background:rgba(239,68,68,0.15);color:#f87171;border:1px solid rgba(239,68,68,0.3);border-radius:8px;cursor:pointer;font-weight:600;">Clean Up Now</button>
|
||||
</div>
|
||||
<p style="font-size:0.8rem;color:var(--text-muted,#666);margin-top:12px;text-align:center;">Some changes apply on next container restart.</p>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(modal);
|
||||
// Audit P0-3 (2026-10-27): the meta CSP blocks inline event handlers, so
|
||||
// the injected onclick/oninput attributes were dead — Save/Clean Up/
|
||||
// Close did nothing and slider value labels never updated. Wire after
|
||||
// injection instead.
|
||||
document.getElementById('disk-close-btn').addEventListener('click', () => modal.remove());
|
||||
document.getElementById('disk-save-btn').addEventListener('click', () => saveDiskSettings());
|
||||
document.getElementById('disk-cleanup-btn').addEventListener('click', () => cleanupDiskNow());
|
||||
modal.querySelectorAll('input[type="range"]').forEach((inp) => {
|
||||
inp.addEventListener('input', () => {
|
||||
const out = document.getElementById(`${inp.id}-val`);
|
||||
if (out) out.textContent = inp.value;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function settingRow(label, id, current, unit, displayVal, min, max) {
|
||||
@@ -79,7 +92,7 @@
|
||||
<div>
|
||||
<label style="font-size:0.85rem;color:var(--text-muted,#aaa);display:block;margin-bottom:4px;">${label}</label>
|
||||
<div style="display:flex;align-items:center;gap:10px;">
|
||||
<input type="range" id="disk-${id}" min="${min}" max="${max}" value="${displayVal}" oninput="document.getElementById('disk-${id}-val').textContent=this.value"
|
||||
<input type="range" id="disk-${id}" min="${min}" max="${max}" value="${displayVal}"
|
||||
style="flex:1;accent-color:#6366f1;">
|
||||
<span id="disk-${id}-val" style="min-width:50px;text-align:right;font-weight:600;">${displayVal}</span>
|
||||
<span style="font-size:0.8rem;color:var(--text-muted,#666);min-width:60px;">${unit}</span>
|
||||
@@ -130,4 +143,9 @@
|
||||
window.openDiskSettings = function() { loadDiskSettings(); };
|
||||
window.saveDiskSettings = saveDiskSettings;
|
||||
window.cleanupDiskNow = cleanupDiskNow;
|
||||
|
||||
// Audit P0-3: index.html's Disk button carried an inline handler calling
|
||||
// openDiskSettings() — dead under the meta CSP. Wired here instead.
|
||||
const diskOpenBtn = document.getElementById('disk-settings-open');
|
||||
if (diskOpenBtn) diskOpenBtn.addEventListener('click', () => loadDiskSettings());
|
||||
})();
|
||||
Reference in new issue
Block a user