SCAFU / additional-views.js
Simeon G
🔒 Apply critical security hardening for production launch
15d35e8
Raw
History Blame Contribute Delete
10.4 kB
// Additional View Renderers for SCAFU v3
// Insert these functions into app-demo.html after renderReportsView()
function renderResultsView() {
const results = window.SCAFU?.scanResults || [];
const critical = results.filter(r => r.severity === 'critical');
const high = results.filter(r => r.severity === 'high');
const medium = results.filter(r => r.severity === 'medium');
const low = results.filter(r => r.severity === 'low');
return `
<div class="border-b border-white/10 p-6">
<div class="flex items-center justify-between mb-4">
<div>
<h1 class="text-2xl font-bold mb-1">Scan Results</h1>
<p class="text-sm text-slate-400">Detailed vulnerability findings from latest scan</p>
</div>
<div class="flex items-center gap-2">
<button class="px-4 py-2 rounded-lg border border-white/20 text-slate-400 hover:bg-white/5 text-sm font-medium">
<svg class="w-4 h-4 inline mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"></path></svg>
Filter
</button>
<button onclick="exportReport()" class="px-4 py-2 rounded-lg bg-emerald-500 text-slate-950 hover:bg-emerald-600 text-sm font-semibold">
Export Report
</button>
</div>
</div>
<!-- Stats Bar -->
<div class="grid grid-cols-4 gap-4">
<div class="rounded-lg border border-red-400/30 bg-red-500/10 p-3">
<div class="text-xs text-slate-500 uppercase tracking-wider mb-1">Critical</div>
<div class="text-2xl font-bold text-red-400 font-mono">${critical.length}</div>
</div>
<div class="rounded-lg border border-orange-400/30 bg-orange-500/10 p-3">
<div class="text-xs text-slate-500 uppercase tracking-wider mb-1">High</div>
<div class="text-2xl font-bold text-orange-400 font-mono">${high.length}</div>
</div>
<div class="rounded-lg border border-yellow-400/30 bg-yellow-500/10 p-3">
<div class="text-xs text-slate-500 uppercase tracking-wider mb-1">Medium</div>
<div class="text-2xl font-bold text-yellow-400 font-mono">${medium.length}</div>
</div>
<div class="rounded-lg border border-white/10 bg-white/5 p-3">
<div class="text-xs text-slate-500 uppercase tracking-wider mb-1">Total</div>
<div class="text-2xl font-bold text-white font-mono">${results.length}</div>
</div>
</div>
</div>
<div class="flex-1 overflow-y-auto p-6">
${results.length === 0 ? `
<div class="flex flex-col items-center justify-center h-full text-center">
<svg class="w-24 h-24 text-slate-600 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<h3 class="text-xl font-bold text-slate-400 mb-2">No Results Yet</h3>
<p class="text-sm text-slate-500 mb-4">Run a scan to see vulnerability findings here</p>
<button onclick="switchTab('scanners')" class="px-6 py-2 rounded-lg bg-emerald-500 text-slate-950 hover:bg-emerald-600 font-semibold">
Start Scan
</button>
</div>
` : `
<div class="space-y-4">
${results.map(vuln => renderVulnerabilityCard(vuln)).join('')}
</div>
`}
</div>
`;
}
function renderVulnerabilityCard(vuln) {
const severityColors = {
critical: { bg: 'bg-red-500/10', border: 'border-red-400/30', text: 'text-red-400', badge: 'bg-red-500/20' },
high: { bg: 'bg-orange-500/10', border: 'border-orange-400/30', text: 'text-orange-400', badge: 'bg-orange-500/20' },
medium: { bg: 'bg-yellow-500/10', border: 'border-yellow-400/30', text: 'text-yellow-400', badge: 'bg-yellow-500/20' },
low: { bg: 'bg-blue-500/10', border: 'border-blue-400/30', text: 'text-blue-400', badge: 'bg-blue-500/20' }
};
const colors = severityColors[vuln.severity] || severityColors.medium;
return `
<div class="rounded-xl border ${colors.border} ${colors.bg} p-6 cursor-pointer hover:border-opacity-60 transition-all" onclick='showVulnerabilityDetail(${JSON.stringify(vuln)})'>
<div class="flex items-start justify-between mb-4">
<div class="flex-1">
<div class="flex items-center gap-3 mb-2">
<span class="px-3 py-1 rounded text-xs font-bold uppercase ${colors.badge} ${colors.text} border ${colors.border}">${vuln.severity}</span>
<span class="px-3 py-1 rounded bg-white/5 text-slate-400 text-xs font-mono">CVSS ${vuln.cvss}</span>
<span class="px-3 py-1 rounded bg-white/5 text-slate-400 text-xs font-mono">${vuln.cwe}</span>
</div>
<h3 class="text-lg font-bold text-white mb-2">${vuln.title}</h3>
<p class="text-sm text-slate-300 mb-3">${vuln.description}</p>
<div class="flex items-center gap-4 text-xs text-slate-400">
<span class="flex items-center gap-1">
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
${vuln.scanner}
</span>
<span>•</span>
<span class="font-mono">${vuln.url}</span>
</div>
</div>
<button class="p-2 rounded-lg hover:bg-white/5 flex-shrink-0">
<svg class="w-5 h-5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
</button>
</div>
<div class="grid grid-cols-2 gap-4 pt-4 border-t border-white/10">
<div>
<div class="text-xs text-slate-500 mb-1">Impact</div>
<div class="text-sm text-slate-300">${vuln.impact.substring(0, 80)}${vuln.impact.length > 80 ? '...' : ''}</div>
</div>
<div>
<div class="text-xs text-slate-500 mb-1">Remediation</div>
<div class="text-sm text-slate-300">${vuln.remediation.substring(0, 80)}${vuln.remediation.length > 80 ? '...' : ''}</div>
</div>
</div>
</div>
`;
}
function showVulnerabilityDetail(vuln) {
const severityColors = {
critical: { bg: 'bg-red-500/10', border: 'border-red-400/30', text: 'text-red-400' },
high: { bg: 'bg-orange-500/10', border: 'border-orange-400/30', text: 'text-orange-400' },
medium: { bg: 'bg-yellow-500/10', border: 'border-yellow-400/30', text: 'text-yellow-400' },
low: { bg: 'bg-blue-500/10', border: 'border-blue-400/30', text: 'text-blue-400' }
};
const colors = severityColors[vuln.severity] || severityColors.medium;
showModal(vuln.title, `
<div class="space-y-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<span class="px-3 py-1 rounded text-xs font-bold uppercase ${colors.bg} ${colors.text} border ${colors.border}">${vuln.severity}</span>
<span class="px-3 py-1 rounded bg-white/5 text-slate-400 text-xs font-mono">CVSS ${vuln.cvss}</span>
<span class="px-3 py-1 rounded bg-white/5 text-slate-400 text-xs font-mono">${vuln.cwe}</span>
</div>
<span class="text-xs text-slate-500">Found by ${vuln.scanner}</span>
</div>
<div class="${colors.bg} border ${colors.border} rounded-lg p-4">
<div class="text-sm font-semibold ${colors.text} mb-2">⚠️ Exploitable Vulnerability</div>
<div class="text-sm text-slate-300">${vuln.description}</div>
</div>
<div>
<div class="text-sm font-semibold text-slate-300 mb-2">Location</div>
<div class="bg-slate-800 rounded-lg p-3 font-mono text-xs text-slate-300">
${vuln.url}
</div>
</div>
<div>
<div class="text-sm font-semibold text-slate-300 mb-2">Impact</div>
<div class="text-sm text-slate-400">${vuln.impact}</div>
</div>
<div>
<div class="text-sm font-semibold text-slate-300 mb-2">Proof of Concept</div>
<div class="bg-slate-950 rounded-lg p-4 font-mono text-xs text-emerald-400 overflow-x-auto">
<pre>${vuln.exploitCode}</pre>
</div>
</div>
<div>
<div class="text-sm font-semibold text-slate-300 mb-2">Remediation</div>
<div class="text-sm text-slate-400">${vuln.remediation}</div>
</div>
<div class="flex gap-3">
<button class="flex-1 px-4 py-2 rounded-lg border border-emerald-400/30 text-emerald-400 hover:bg-emerald-500/10">
Copy Proof of Concept
</button>
<button class="flex-1 px-4 py-2 rounded-lg bg-emerald-500 text-slate-950 hover:bg-emerald-600">
Export Finding
</button>
</div>
</div>
`);
}
// History view remains using the existing renderReportsView but with scan history data
// This can be added later or kept as the Reports view