fix(csp): remove all inline styles, scripts, and event handlers for strict CSP compliance

Replace ~50 inline style="" attributes with CSS classes, move 3 inline
<script> blocks to external JS files, replace all inline event handlers
(onclick, onerror) with addEventListener, and remove createElement('style')
from icons.js. All changes support the strict CSP policy (style-src 'self';
script-src 'self') without weakening it.
This commit is contained in:
Jared Wolff
2026-03-05 16:18:30 -05:00
parent f2d35ca792
commit c08926b817
28 changed files with 397 additions and 212 deletions
+10 -10
View File
@@ -31,8 +31,8 @@ const contextMenus = {
window.wopiEditor &&
await window.wopiEditor.canEdit(targetFile.name);
wopiEdit.style.display = show ? '' : 'none';
wopiEditTab.style.display = show ? '' : 'none';
wopiEdit.classList.toggle('hidden', !show);
wopiEditTab.classList.toggle('hidden', !show);
},
syncFavoriteOptionLabels() {
@@ -524,7 +524,7 @@ const contextMenus = {
const titleText = mode === 'file' ?
(window.i18n ? window.i18n.t('dialogs.move_file') : 'Move file') :
(window.i18n ? window.i18n.t('dialogs.move_folder') : 'Move folder');
dialogHeader.innerHTML = `<i class="fas fa-arrows-alt" style="color:#ff5e3a"></i> <span>${titleText}</span>`;
dialogHeader.innerHTML = `<i class="fas fa-arrows-alt dialog-header-icon"></i> <span>${titleText}</span>`;
// Load folders for the starting location
await this.loadMoveDialogFolders(startFolderId);
@@ -639,7 +639,7 @@ const contextMenus = {
const currentFolderOption = document.createElement('div');
currentFolderOption.className = 'folder-select-item folder-select-current';
currentFolderOption.innerHTML = `
<i class="fas fa-check-circle" style="color: #48bb78;"></i>
<i class="fas fa-check-circle check-icon"></i>
<span>${window.i18n ? window.i18n.t('dialogs.select_this_folder') : 'Select this folder'}</span>
`;
currentFolderOption.addEventListener('click', () => {
@@ -718,7 +718,7 @@ const contextMenus = {
const homeOption = document.createElement('div');
homeOption.className = 'folder-select-item folder-select-current';
homeOption.innerHTML = `
<i class="fas fa-check-circle" style="color: #48bb78;"></i>
<i class="fas fa-check-circle check-icon"></i>
<span>${window.i18n ? window.i18n.t('dialogs.move_to_home') : 'Move to Home folder'}</span>
`;
homeOption.addEventListener('click', () => {
@@ -889,7 +889,7 @@ const contextMenus = {
existingSharesContainer.innerHTML = '';
if (existingShares.length > 0) {
document.getElementById('existing-shares-section').style.display = 'block';
document.getElementById('existing-shares-section').classList.remove('hidden');
// Create elements for each existing share
existingShares.forEach(share => {
@@ -965,19 +965,19 @@ const contextMenus = {
await window.fileSharing.removeSharedLink(shareId);
btn.closest('.existing-share-item').remove();
if (existingSharesContainer.children.length === 0) {
document.getElementById('existing-shares-section').style.display = 'none';
document.getElementById('existing-shares-section').classList.add('hidden');
}
}
});
});
});
} else {
document.getElementById('existing-shares-section').style.display = 'none';
document.getElementById('existing-shares-section').classList.add('hidden');
}
// Hide new-share section from previous use
const newShareSection = document.getElementById('new-share-section');
if (newShareSection) newShareSection.style.display = 'none';
if (newShareSection) newShareSection.classList.add('hidden');
// Show dialog
shareDialog.style.display = 'flex';
@@ -1041,7 +1041,7 @@ const contextMenus = {
const shareUrl = document.getElementById('generated-share-url');
if (shareUrl) {
shareUrl.value = shareInfo.url;
document.getElementById('new-share-section').style.display = 'block';
document.getElementById('new-share-section').classList.remove('hidden');
shareUrl.focus();
shareUrl.select();
}
+1 -1
View File
@@ -401,7 +401,7 @@ const multiSelect = {
const n = items.length;
const titleText = this._t('batch.move_title', { count: n })
|| `Move ${n} item${n !== 1 ? 's' : ''}`;
dialogHeader.innerHTML = `<i class="fas fa-arrows-alt" style="color:#ff5e3a"></i> <span>${titleText}</span>`;
dialogHeader.innerHTML = `<i class="fas fa-arrows-alt dialog-header-icon"></i> <span>${titleText}</span>`;
const excludeIds = items.filter(i => i.type === 'folder').map(i => i.id);
await contextMenus.loadAllFolders(excludeIds[0] || null, 'batch');
+2 -2
View File
@@ -175,8 +175,8 @@ const search = {
const emptyState = document.createElement('div');
emptyState.className = 'empty-state';
emptyState.innerHTML = `
<i class="fas fa-search" style="font-size: 48px; color: var(--empty-icon, #ccc); margin-bottom: 16px;"></i>
<p style="color: var(--text-secondary, #64748b);">No results found for this search</p>
<i class="fas fa-search empty-state-icon"></i>
<p class="search-empty-text">No results found for this search</p>
`;
filesGrid.appendChild(emptyState);
return;
+1 -1
View File
@@ -120,7 +120,7 @@ class WopiEditor {
var spinner = document.createElement('div');
spinner.id = 'wopi-loading-spinner';
spinner.style.cssText = 'position:absolute;top:0;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;background:#f5f5f5;z-index:1;';
spinner.innerHTML = '<i class="fas fa-spinner fa-spin" style="font-size:48px;color:#666;"></i>';
spinner.innerHTML = '<i class="fas fa-spinner fa-spin empty-state-icon spinner"></i>';
frameHolder.appendChild(spinner);
var iframe = document.createElement('iframe');