forked from Rockachopa/Timmy-time-dashboard
Merge pull request 'fix: sanitize dynamic innerHTML in HTML templates (#47)' (#58) from fix/xss-sanitize into main
This commit is contained in:
@@ -327,7 +327,11 @@
|
||||
.then(function(data) {
|
||||
var list = document.getElementById('notif-list');
|
||||
if (!data.length) {
|
||||
list.innerHTML = '<div class="mc-notif-empty">No recent notifications</div>';
|
||||
list.innerHTML = '';
|
||||
var emptyDiv = document.createElement('div');
|
||||
emptyDiv.className = 'mc-notif-empty';
|
||||
emptyDiv.textContent = 'No recent notifications';
|
||||
list.appendChild(emptyDiv);
|
||||
return;
|
||||
}
|
||||
list.innerHTML = '';
|
||||
|
||||
@@ -120,14 +120,17 @@
|
||||
|
||||
function updateFromData(data) {
|
||||
if (data.is_working && data.current_task) {
|
||||
statusEl.innerHTML = '<span style="color: #ffaa00;">working...</span>';
|
||||
statusEl.textContent = 'working...';
|
||||
statusEl.style.color = '#ffaa00';
|
||||
banner.style.display = 'block';
|
||||
taskTitle.textContent = data.current_task.title;
|
||||
} else if (data.tasks_ahead > 0) {
|
||||
statusEl.innerHTML = '<span style="color: #888;">queue: ' + data.tasks_ahead + ' ahead</span>';
|
||||
statusEl.textContent = 'queue: ' + data.tasks_ahead + ' ahead';
|
||||
statusEl.style.color = '#888';
|
||||
banner.style.display = 'none';
|
||||
} else {
|
||||
statusEl.innerHTML = '<span style="color: #00ff88;">ready</span>';
|
||||
statusEl.textContent = 'ready';
|
||||
statusEl.style.color = '#00ff88';
|
||||
banner.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,17 +198,43 @@ function addActivityEvent(evt) {
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
item.innerHTML = `
|
||||
<div class="activity-icon">${icon}</div>
|
||||
<div class="activity-content">
|
||||
<div class="activity-label">${label}</div>
|
||||
${desc ? `<div class="activity-desc">${desc}</div>` : ''}
|
||||
<div class="activity-meta">
|
||||
<span class="activity-time">${time}</span>
|
||||
<span class="activity-source">${evt.source || 'system'}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
// Build DOM safely using createElement and textContent
|
||||
var iconDiv = document.createElement('div');
|
||||
iconDiv.className = 'activity-icon';
|
||||
iconDiv.textContent = icon;
|
||||
|
||||
var contentDiv = document.createElement('div');
|
||||
contentDiv.className = 'activity-content';
|
||||
|
||||
var labelDiv = document.createElement('div');
|
||||
labelDiv.className = 'activity-label';
|
||||
labelDiv.textContent = label;
|
||||
contentDiv.appendChild(labelDiv);
|
||||
|
||||
if (desc) {
|
||||
var descDiv = document.createElement('div');
|
||||
descDiv.className = 'activity-desc';
|
||||
descDiv.textContent = desc;
|
||||
contentDiv.appendChild(descDiv);
|
||||
}
|
||||
|
||||
var metaDiv = document.createElement('div');
|
||||
metaDiv.className = 'activity-meta';
|
||||
|
||||
var timeSpan = document.createElement('span');
|
||||
timeSpan.className = 'activity-time';
|
||||
timeSpan.textContent = time;
|
||||
|
||||
var sourceSpan = document.createElement('span');
|
||||
sourceSpan.className = 'activity-source';
|
||||
sourceSpan.textContent = evt.source || 'system';
|
||||
|
||||
metaDiv.appendChild(timeSpan);
|
||||
metaDiv.appendChild(sourceSpan);
|
||||
contentDiv.appendChild(metaDiv);
|
||||
|
||||
item.appendChild(iconDiv);
|
||||
item.appendChild(contentDiv);
|
||||
|
||||
// Add to top
|
||||
container.insertBefore(item, container.firstChild);
|
||||
|
||||
Reference in New Issue
Block a user