(type, data)
| 441 | } |
| 442 | |
| 443 | async function addFinding(type, data) { |
| 444 | const findings = await getFindings(); |
| 445 | |
| 446 | const exists = findings[type].some(f => { |
| 447 | if (type === 'params') return f.url === data.url; |
| 448 | if (type === 'headers') return f.url === data.url && f.header === data.header; |
| 449 | return f.path === data.path; |
| 450 | }); |
| 451 | |
| 452 | if (!exists) { |
| 453 | findings[type].push({ ...data, timestamp: Date.now() }); |
| 454 | findings[type].sort((a, b) => { |
| 455 | const scores = { critical: 4, high: 3, medium: 2, low: 1 }; |
| 456 | return (scores[b.severity] || 0) - (scores[a.severity] || 0); |
| 457 | }); |
| 458 | await saveFindings(findings); |
| 459 | |
| 460 | const colors = { critical: '#e74c3c', high: '#e67e22', medium: '#f1c40f', low: '#3498db' }; |
| 461 | console.log(`%c[debugHunter] [${data.severity?.toUpperCase()}] ${type}: ${data.url || data.path}`, |
| 462 | `background: ${colors[data.severity] || '#27ae60'}; color: white; padding: 2px 6px; border-radius: 3px`); |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | async function removeFinding(type, identifier) { |
| 467 | const findings = await getFindings(); |
no test coverage detected