grepleaks 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/grepleaks.js +95 -17
- package/package.json +1 -1
package/bin/grepleaks.js
CHANGED
|
@@ -9,7 +9,7 @@ const readline = require('readline');
|
|
|
9
9
|
const { exec } = require('child_process');
|
|
10
10
|
const archiver = require('archiver');
|
|
11
11
|
|
|
12
|
-
const VERSION = '1.0.
|
|
12
|
+
const VERSION = '1.0.3';
|
|
13
13
|
const API_URL = 'https://grepleaks.com/api/v1';
|
|
14
14
|
const WEB_URL = 'https://grepleaks.com';
|
|
15
15
|
const CONFIG_DIR = path.join(os.homedir(), '.grepleaks');
|
|
@@ -491,18 +491,46 @@ function generateMarkdownReport(result) {
|
|
|
491
491
|
const score = result.security_score || 0;
|
|
492
492
|
const grade = result.grade_level || 'N/A';
|
|
493
493
|
const projectName = result.project_name || 'Unknown Project';
|
|
494
|
+
const lang = getLang();
|
|
495
|
+
|
|
496
|
+
const dateStr = new Date().toLocaleDateString(lang === 'fr' ? 'fr-FR' : 'en-US', {
|
|
497
|
+
year: 'numeric',
|
|
498
|
+
month: 'long',
|
|
499
|
+
day: 'numeric'
|
|
500
|
+
});
|
|
494
501
|
|
|
495
|
-
|
|
502
|
+
// Count by severity
|
|
503
|
+
const counts = { critical: 0, high: 0, medium: 0, low: 0 };
|
|
504
|
+
for (const v of vulns) {
|
|
505
|
+
const sev = (v.severity || 'low').toLowerCase();
|
|
506
|
+
if (counts[sev] !== undefined) counts[sev]++;
|
|
507
|
+
}
|
|
496
508
|
|
|
497
|
-
|
|
498
|
-
md
|
|
499
|
-
md +=
|
|
500
|
-
|
|
509
|
+
// Header
|
|
510
|
+
let md = `# ${t('reportTitle')}\n\n`;
|
|
511
|
+
md += `> **${projectName}** | ${dateStr}\n\n`;
|
|
512
|
+
|
|
513
|
+
// Score card
|
|
514
|
+
const scoreEmoji = score >= 90 ? '🛡️' : score >= 75 ? '✅' : score >= 50 ? '⚠️' : '🚨';
|
|
515
|
+
md += `## ${scoreEmoji} ${lang === 'fr' ? 'Score de Sécurité' : 'Security Score'}: ${score}/100 (${grade})\n\n`;
|
|
516
|
+
|
|
517
|
+
// Summary table
|
|
518
|
+
if (vulns.length > 0) {
|
|
519
|
+
md += `| ${lang === 'fr' ? 'Sévérité' : 'Severity'} | ${lang === 'fr' ? 'Nombre' : 'Count'} |\n`;
|
|
520
|
+
md += `|----------|-------|\n`;
|
|
521
|
+
if (counts.critical > 0) md += `| 🔴 Critical | ${counts.critical} |\n`;
|
|
522
|
+
if (counts.high > 0) md += `| 🟠 High | ${counts.high} |\n`;
|
|
523
|
+
if (counts.medium > 0) md += `| 🟡 Medium | ${counts.medium} |\n`;
|
|
524
|
+
if (counts.low > 0) md += `| 🟢 Low | ${counts.low} |\n`;
|
|
525
|
+
md += `\n`;
|
|
526
|
+
}
|
|
501
527
|
|
|
528
|
+
// Vulnerabilities
|
|
502
529
|
if (vulns.length === 0) {
|
|
503
|
-
md += `## ${t('reportNoVulns')}\n\n`;
|
|
530
|
+
md += `## ✅ ${t('reportNoVulns')}\n\n`;
|
|
504
531
|
md += `${t('reportCongrats')}\n`;
|
|
505
532
|
} else {
|
|
533
|
+
md += `---\n\n`;
|
|
506
534
|
md += `## ${t('reportVulnsDetected')}\n\n`;
|
|
507
535
|
|
|
508
536
|
const bySeverity = { CRITICAL: [], HIGH: [], MEDIUM: [], LOW: [] };
|
|
@@ -518,21 +546,71 @@ function generateMarkdownReport(result) {
|
|
|
518
546
|
severity === 'HIGH' ? '🟠' :
|
|
519
547
|
severity === 'MEDIUM' ? '🟡' : '🟢';
|
|
520
548
|
|
|
521
|
-
|
|
549
|
+
const severityLabel = lang === 'fr'
|
|
550
|
+
? { CRITICAL: 'Critique', HIGH: 'Élevée', MEDIUM: 'Moyenne', LOW: 'Faible' }[severity]
|
|
551
|
+
: severity.charAt(0) + severity.slice(1).toLowerCase();
|
|
552
|
+
|
|
553
|
+
md += `### ${emoji} ${severityLabel}\n\n`;
|
|
554
|
+
|
|
555
|
+
for (let i = 0; i < items.length; i++) {
|
|
556
|
+
const v = items[i];
|
|
557
|
+
|
|
558
|
+
// Title from description (first sentence or truncated)
|
|
559
|
+
let title = v.description || 'Security Issue';
|
|
560
|
+
const firstSentence = title.match(/^[^.!?]+[.!?]/);
|
|
561
|
+
if (firstSentence) {
|
|
562
|
+
title = firstSentence[0];
|
|
563
|
+
} else if (title.length > 80) {
|
|
564
|
+
title = title.substring(0, 77) + '...';
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
md += `<details>\n<summary><strong>${title}</strong></summary>\n\n`;
|
|
568
|
+
|
|
569
|
+
// Location
|
|
570
|
+
if (v.location) {
|
|
571
|
+
md += `📍 **${lang === 'fr' ? 'Emplacement' : 'Location'}:** \`${v.location}\`\n\n`;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// CVE
|
|
575
|
+
if (v.cve) {
|
|
576
|
+
md += `🔖 **CVE:** [${v.cve}](https://nvd.nist.gov/vuln/detail/${v.cve})\n\n`;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Package info
|
|
580
|
+
if (v.package_name) {
|
|
581
|
+
md += `📦 **Package:** \`${v.package_name}\``;
|
|
582
|
+
if (v.current_version) md += ` v${v.current_version}`;
|
|
583
|
+
md += `\n`;
|
|
584
|
+
if (v.fixed_version) {
|
|
585
|
+
md += `✅ **${lang === 'fr' ? 'Correction' : 'Fix'}:** ${lang === 'fr' ? 'Mettre à jour vers' : 'Upgrade to'} v${v.fixed_version}\n`;
|
|
586
|
+
}
|
|
587
|
+
md += `\n`;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Code snippet
|
|
591
|
+
if (v.code_snippet) {
|
|
592
|
+
md += `**${lang === 'fr' ? 'Code concerné' : 'Affected code'}:**\n\`\`\`\n${v.code_snippet}\n\`\`\`\n\n`;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Recommendation
|
|
596
|
+
const rec = v.llm_recommendation || v.recommendation;
|
|
597
|
+
if (rec) {
|
|
598
|
+
md += `💡 **${t('reportRecommendation')}**\n\n${rec}\n\n`;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// Reference
|
|
602
|
+
if (v.reference_url) {
|
|
603
|
+
md += `🔗 [${lang === 'fr' ? 'Plus d\'informations' : 'Learn more'}](${v.reference_url})\n\n`;
|
|
604
|
+
}
|
|
522
605
|
|
|
523
|
-
|
|
524
|
-
md += `#### ${v.title || 'Vulnerability'}\n\n`;
|
|
525
|
-
md += `- **${t('reportFile')}** \`${v.file || 'N/A'}\`\n`;
|
|
526
|
-
if (v.line) md += `- **${t('reportLine')}** ${v.line}\n`;
|
|
527
|
-
md += `- **${t('reportScanner')}** ${v.scanner || 'N/A'}\n`;
|
|
528
|
-
if (v.description) md += `\n${v.description}\n`;
|
|
529
|
-
if (v.recommendation) md += `\n**${t('reportRecommendation')}** ${v.recommendation}\n`;
|
|
530
|
-
md += `\n---\n\n`;
|
|
606
|
+
md += `</details>\n\n`;
|
|
531
607
|
}
|
|
532
608
|
}
|
|
533
609
|
}
|
|
534
610
|
|
|
535
|
-
|
|
611
|
+
// Footer
|
|
612
|
+
md += `---\n\n`;
|
|
613
|
+
md += `<sub>${t('reportGeneratedBy')} [grepleaks](https://grepleaks.com) ${scoreEmoji}</sub>\n`;
|
|
536
614
|
|
|
537
615
|
return md;
|
|
538
616
|
}
|