Authentication Required
\${reason}
Redirecting to login...
`;
if (content.includes(oldHTML)) {
content = content.replace(oldHTML, newHTML);
fs.writeFileSync(filePath, content);
return 6; // 6 inline styles fixed
}
return 0;
}
// Fix progress bar widths by using data attributes
function fixProgressBars() {
const files = [
'public/js/admin/audit-analytics.js',
'public/js/admin/rule-editor.js',
'public/js/admin/rule-manager.js'
];
let totalFixed = 0;
files.forEach(file => {
const filePath = path.join(__dirname, '..', file);
let content = fs.readFileSync(filePath, 'utf8');
let fileFixed = 0;
// Pattern 1:
const pattern1 = /(
]*class="[^"]*(?:bg-blue-600|bg-green-500|bg-blue-500|bg-yellow-500)[^"]*"[^>]*)\s+style="width:\s*\$\{([^}]+)\}%"/g;
content = content.replace(pattern1, (match, before, variable) => {
fileFixed++;
return `${before} data-width="\${${variable}}"`;
});
// Pattern 2:
or style="width: 100%">
const pattern2 = /(
]*(?:id="[^"]*-bar")[^>]*)\s+style="width:\s*(0|100)%"/g;
content = content.replace(pattern2, (match, before, value) => {
fileFixed++;
return `${before} data-width="${value}"`;
});
// Pattern 3: style="height: ${barHeight}%"
const pattern3 = /style="height:\s*\$\{([^}]+)\}%"/g;
content = content.replace(pattern3, (match, variable) => {
fileFixed++;
return `data-height="\${${variable}}"`;
});
if (fileFixed > 0) {
fs.writeFileSync(filePath, content);
console.log(`â ${file}: Fixed ${fileFixed} inline style(s)`);
totalFixed += fileFixed;
}
});
return totalFixed;
}
// Add width-setting helper after DOM insertion
function addProgressBarHelper() {
const files = [
{ file: 'public/js/admin/audit-analytics.js', hasProgressBars: true },
{ file: 'public/js/admin/rule-editor.js', hasProgressBars: true },
{ file: 'public/js/admin/rule-manager.js', hasProgressBars: true }
];
const helper = `
// Set widths from data attributes (CSP compliance)
function setProgressBarWidths(container) {
const elements = container.querySelectorAll('[data-width], [data-height]');
elements.forEach(el => {
if (el.dataset.width) {
el.style.width = el.dataset.width + '%';
}
if (el.dataset.height) {
el.style.height = el.dataset.height + '%';
}
});
}`;
files.forEach(({ file, hasProgressBars }) => {
if (!hasProgressBars) return;
const filePath = path.join(__dirname, '..', file);
let content = fs.readFileSync(filePath, 'utf8');
// Check if helper already exists
if (content.includes('setProgressBarWidths')) {
return;
}
// Add helper function before the last closing brace/parenthesis of the file
// Find a good insertion point - typically after other helper functions
const insertionPoint = content.lastIndexOf('})()');
if (insertionPoint > 0) {
content = content.slice(0, insertionPoint) + helper + '\n\n' + content.slice(insertionPoint);
fs.writeFileSync(filePath, content);
console.log(`â ${file}: Added setProgressBarWidths helper`);
}
});
}
// Main execution
console.log('\nđ§ Fixing admin CSP violations...\n');
let totalFixed = 0;
console.log('1. Fixing auth-check.js inline styles...');
totalFixed += fixAuthCheck();
console.log('\n2. Converting progress bar widths to data attributes...');
totalFixed += fixProgressBars();
console.log('\n3. Adding progress bar width helpers...');
addProgressBarHelper();
console.log(`\nâ
Total inline styles fixed: ${totalFixed}`);
console.log('\nâ ď¸ Note: Inline event handlers require manual refactoring');
console.log(' Run scripts/fix-admin-event-handlers.js for those.\n');