// lib/audit.js — Tamper-evident audit log storage import { hashChain, hashEvent } from './hash.js'; const MAX_EVENTS = 1000; const MAX_VIOLATIONS = 500; export async function addEvent(event) { const { auditLog = [] } = await chrome.storage.local.get(['auditLog']); auditLog.push(event); if (auditLog.length > MAX_EVENTS) { auditLog.splice(0, auditLog.length - MAX_EVENTS); } await chrome.storage.local.set({ auditLog }); } export async function addViolation(violation) { const { violations = [] } = await chrome.storage.local.get(['violations']); violations.push(violation); if (violations.length > MAX_VIOLATIONS) { violations.splice(0, violations.length - MAX_VIOLATIONS); } await chrome.storage.local.set({ violations }); } export async function getAuditLog(limit = 100) { const { auditLog = [] } = await chrome.storage.local.get(['auditLog']); return auditLog.slice(-limit).reverse(); } export async function getViolations(limit = 100) { const { violations = [] } = await chrome.storage.local.get(['violations']); return violations.slice(-limit).reverse(); } export async function getStats() { const { auditLog = [], violations = [], activeAgents = {} } = await chrome.storage.local.get([ 'auditLog', 'violations', 'activeAgents' ]); const totalEvents = auditLog.length; const totalViolations = violations.length; const activeCount = Object.keys(activeAgents).length; const severityCounts = { info: 0, low: 0, medium: 0, high: 0, critical: 0 }; for (const v of violations) { severityCounts[v.severity] = (severityCounts[v.severity] || 0) + 1; } const last24h = Date.now() - 24 * 60 * 60 * 1000; const recentEvents = auditLog.filter(e => new Date(e.timestamp).getTime() > last24h).length; const recentViolations = violations.filter(v => new Date(v.timestamp).getTime() > last24h).length; const detectorCounts = {}; for (const v of violations) { detectorCounts[v.detector] = (detectorCounts[v.detector] || 0) + 1; } const riskScore = Math.min(100, Math.round( (severityCounts.critical * 25) + (severityCounts.high * 10) + (severityCounts.medium * 5) + (severityCounts.low * 1) + (totalEvents > 0 ? (totalViolations / totalEvents) * 20 : 0) )); const complianceStatus = riskScore < 20 ? 'compliant' : riskScore < 50 ? 'at-risk' : 'non-compliant'; return { totalEvents, totalViolations, activeCount, severityCounts, recentEvents, recentViolations, detectorCounts, riskScore, complianceStatus, lastUpdated: new Date().toISOString() }; } export async function exportAuditLog() { const { auditLog = [], violations = [] } = await chrome.storage.local.get(['auditLog', 'violations']); return { exportDate: new Date().toISOString(), totalEvents: auditLog.length, totalViolations: violations.length, events: auditLog, violations: violations, integrity: hashChain(auditLog) }; } export async function searchAuditLog(query) { const { auditLog = [] } = await chrome.storage.local.get(['auditLog']); const q = query.toLowerCase(); return auditLog.filter(e => (e.agent || '').toLowerCase().includes(q) || (e.type || '').toLowerCase().includes(q) || (e.tool || '').toLowerCase().includes(q) || (e.target || '').toLowerCase().includes(q) || (e.url || '').toLowerCase().includes(q) ).reverse().slice(0, 100); } export async function verifyIntegrity() { const { auditLog = [] } = await chrome.storage.local.get(['auditLog']); if (auditLog.length === 0) return { valid: true, eventsChecked: 0 }; const expected = hashChain(auditLog); const stored = (await chrome.storage.local.get(['auditChainHash'])).auditChainHash; const valid = stored === expected; await chrome.storage.local.set({ auditChainHash: expected }); return { valid, eventsChecked: auditLog.length, expected }; }