Add files via upload

This commit is contained in:
公明
2026-05-28 11:20:14 +08:00
committed by GitHub
parent e40f7cb468
commit e037f383f5
+35 -10
View File
@@ -695,7 +695,13 @@ async function linkFactToExistingVulnerability() {
const items = data.Vulnerabilities || data.vulnerabilities || data.items || []; const items = data.Vulnerabilities || data.vulnerabilities || data.items || [];
if (!items.length) return alert(tp('projects.noVulnerabilitiesInProject')); if (!items.length) return alert(tp('projects.noVulnerabilitiesInProject'));
const lines = items.map((v, i) => `${i + 1}. [${v.severity}] ${v.title} (${v.id})`); const lines = items.map((v, i) => `${i + 1}. [${v.severity}] ${v.title} (${v.id})`);
const pick = prompt(tpFmt('projects.promptLinkFactToVuln', `Enter index to link fact "${f.fact_key}":\n\n${lines.join('\n')}`, { factKey: f.fact_key, lines: lines.join('\n') })); const pick = prompt(
tp('projects.promptLinkFactToVuln', {
factKey: f.fact_key,
lines: lines.join('\n'),
interpolation: { escapeValue: false },
}) || `Enter index to link fact "${f.fact_key}":\n\n${lines.join('\n')}`,
);
if (pick == null || pick === '') return; if (pick == null || pick === '') return;
const idx = parseInt(pick, 10) - 1; const idx = parseInt(pick, 10) - 1;
if (Number.isNaN(idx) || idx < 0 || idx >= items.length) return alert(tp('projects.invalidIndex')); if (Number.isNaN(idx) || idx < 0 || idx >= items.length) return alert(tp('projects.invalidIndex'));
@@ -733,7 +739,11 @@ async function createVulnerabilityFromCurrentFact() {
conversation_id: convId, conversation_id: convId,
project_id: currentProjectId, project_id: currentProjectId,
title: (f.summary || f.fact_key).slice(0, 200), title: (f.summary || f.fact_key).slice(0, 200),
description: tpFmt('projects.generatedFromFact', `Generated from project fact ${f.fact_key}`, { factKey: f.fact_key }), description:
tp('projects.generatedFromFact', {
factKey: f.fact_key,
interpolation: { escapeValue: false },
}) || `Generated from project fact ${f.fact_key}`,
severity, severity,
status: 'open', status: 'open',
type: f.category || 'finding', type: f.category || 'finding',
@@ -764,7 +774,12 @@ async function createVulnerabilityFromCurrentFact() {
related_vulnerability_id: vuln.id, related_vulnerability_id: vuln.id,
}), }),
}); });
alert(tpFmt('projects.createVulnerabilityAndLinkSuccess', `Created and linked vulnerability: ${vuln.title || vuln.id}`, { value: vuln.title || vuln.id })); const createdVulnLabel = vuln.title || vuln.id;
const successMsg = tp('projects.createVulnerabilityAndLinkSuccess', {
value: createdVulnLabel,
interpolation: { escapeValue: false },
});
alert(successMsg || `Created and linked vulnerability: ${createdVulnLabel}`);
closeFactDetailModal(); closeFactDetailModal();
loadProjectFacts(); loadProjectFacts();
if (currentProjectTab === 'vulns') loadProjectVulnerabilities(); if (currentProjectTab === 'vulns') loadProjectVulnerabilities();
@@ -779,7 +794,12 @@ function inferSeverityFromFact(f) {
} }
async function deprecateProjectFactByKey(factKey) { async function deprecateProjectFactByKey(factKey) {
if (!confirm(tpFmt('projects.confirmDeprecateFact', `Deprecate fact ${factKey}?`, { factKey }))) return; if (!confirm(
tp('projects.confirmDeprecateFact', {
factKey,
interpolation: { escapeValue: false },
}) || `Deprecate fact ${factKey}?`,
)) return;
const res = await apiFetch(`/api/projects/${currentProjectId}/facts/deprecate`, { const res = await apiFetch(`/api/projects/${currentProjectId}/facts/deprecate`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
@@ -790,7 +810,12 @@ async function deprecateProjectFactByKey(factKey) {
} }
async function restoreProjectFactByKey(factKey) { async function restoreProjectFactByKey(factKey) {
if (!confirm(tpFmt('projects.confirmRestoreFact', `Restore fact ${factKey}? It will re-enter the board index with tentative status.`, { factKey }))) return; if (!confirm(
tp('projects.confirmRestoreFact', {
factKey,
interpolation: { escapeValue: false },
}) || `Restore fact ${factKey}? It will re-enter the board index with tentative status.`,
)) return;
const res = await apiFetch(`/api/projects/${currentProjectId}/facts/restore`, { const res = await apiFetch(`/api/projects/${currentProjectId}/facts/restore`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
@@ -883,11 +908,11 @@ async function viewFactsForVulnerability(vulnId) {
return; return;
} }
const pick = prompt( const pick = prompt(
tpFmt( tp('projects.promptChooseFactByIndex', {
'projects.promptChooseFactByIndex', count: facts.length,
`This vulnerability is linked to ${facts.length} facts. Enter index to view:\n${facts.map((f, i) => `${i + 1}. ${f.fact_key}`).join('\n')}`, lines: facts.map((f, i) => `${i + 1}. ${f.fact_key}`).join('\n'),
{ count: facts.length, lines: facts.map((f, i) => `${i + 1}. ${f.fact_key}`).join('\n') }, interpolation: { escapeValue: false },
), }) || `This vulnerability is linked to ${facts.length} facts. Enter index to view:\n${facts.map((f, i) => `${i + 1}. ${f.fact_key}`).join('\n')}`,
); );
if (pick == null || pick === '') { if (pick == null || pick === '') {
loadProjectFacts(); loadProjectFacts();