content overhaul
This commit is contained in:
@@ -526,7 +526,7 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Scenarios</label>
|
||||
<label>🎮 Scenario Tags <small style="color: #666;">(adds scenario: prefix to tags)</small></label>
|
||||
<div id="scenariosCheckbox" class="checkbox-group"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -777,11 +777,14 @@
|
||||
{ id: 'specific-os', name: 'Betriebssysteme', description: 'Operating Systems which focus on forensics' }
|
||||
],
|
||||
scenarios: [
|
||||
{ id: 'registry', icon: '🗃️', friendly_name: 'Registry-Analyse' },
|
||||
{ id: 'memory-forensics', icon: '🧠', friendly_name: 'Memory-Forensik' },
|
||||
{ id: 'network-analysis', icon: '🌐', friendly_name: 'Netzwerk-Analyse' },
|
||||
{ id: 'malware-analysis', icon: '🦠', friendly_name: 'Malware-Analyse' },
|
||||
{ id: 'mobile-forensics', icon: '📱', friendly_name: 'Mobile-Forensik' }
|
||||
{ id: 'scenario:disk_imaging', icon: '💽', friendly_name: 'Datenträgerabbild' },
|
||||
{ id: 'scenario:memory_dump', icon: '🧠', friendly_name: 'RAM-Analyse' },
|
||||
{ id: 'scenario:file_recovery', icon: '🗑️', friendly_name: 'Datenrettung' },
|
||||
{ id: 'scenario:browser_history', icon: '🌍', friendly_name: 'Browser-Spuren' },
|
||||
{ id: 'scenario:credential_theft', icon: '🛑', friendly_name: 'Zugangsdiebstahl' },
|
||||
{ id: 'scenario:remote_access', icon: '📡', friendly_name: 'Fernzugriffe' },
|
||||
{ id: 'scenario:persistence', icon: '♻️', friendly_name: 'Persistenzsuche' },
|
||||
{ id: 'scenario:windows-registry', icon: '📜', friendly_name: 'Registry-Analyse' }
|
||||
]
|
||||
};
|
||||
|
||||
@@ -819,7 +822,7 @@
|
||||
// Search in description
|
||||
if (tool.description && tool.description.toLowerCase().includes(term)) return true;
|
||||
|
||||
// Search in tags
|
||||
// Search in tags (includes scenarios as scenario: prefixed tags)
|
||||
if (tool.tags && tool.tags.some(tag => tag.toLowerCase().includes(term))) return true;
|
||||
|
||||
// Search in related concepts
|
||||
@@ -828,10 +831,13 @@
|
||||
// Search in related software
|
||||
if (tool.related_software && tool.related_software.some(software => software.toLowerCase().includes(term))) return true;
|
||||
|
||||
// Search in scenarios
|
||||
if (tool.scenarios && tool.scenarios.some(scenario => {
|
||||
const scenarioData = yamlData.scenarios.find(s => s.id === scenario);
|
||||
return scenarioData && scenarioData.friendly_name.toLowerCase().includes(term);
|
||||
// Search in scenario friendly names (from tags that start with scenario:)
|
||||
if (tool.tags && tool.tags.some(tag => {
|
||||
if (tag.startsWith('scenario:')) {
|
||||
const scenarioData = yamlData.scenarios.find(s => s.id === tag);
|
||||
return scenarioData && scenarioData.friendly_name.toLowerCase().includes(term);
|
||||
}
|
||||
return false;
|
||||
})) return true;
|
||||
|
||||
// Search in type
|
||||
@@ -1052,16 +1058,15 @@
|
||||
const icon = document.getElementById('toolIcon').value.trim();
|
||||
if (icon) tool.icon = icon;
|
||||
|
||||
// Add domains, phases, and scenarios
|
||||
// Add domains, phases
|
||||
tool.domains = getCheckedValues('#domainsCheckbox input:checked');
|
||||
tool.phases = getCheckedValues('#phasesCheckbox input:checked');
|
||||
|
||||
const scenarios = getCheckedValues('#scenariosCheckbox input:checked');
|
||||
if (scenarios.length > 0) tool.scenarios = scenarios;
|
||||
|
||||
// Add tags, related concepts, and related software
|
||||
// Add tags and scenario tags (scenarios get added to tags with scenario: prefix)
|
||||
const tags = getTags();
|
||||
if (tags.length > 0) tool.tags = tags;
|
||||
const scenarioTags = getCheckedValues('#scenariosCheckbox input:checked');
|
||||
const allTags = [...tags, ...scenarioTags];
|
||||
if (allTags.length > 0) tool.tags = allTags;
|
||||
|
||||
const relatedConcepts = getRelatedConcepts();
|
||||
if (relatedConcepts.length > 0) tool.related_concepts = relatedConcepts;
|
||||
@@ -1118,9 +1123,19 @@
|
||||
|
||||
function clearForm() {
|
||||
document.getElementById('toolForm').reset();
|
||||
|
||||
// Clear all tag inputs properly
|
||||
document.getElementById('tagsInput').innerHTML = '<input type="text" id="tagInputField" placeholder="Add tags..." onkeydown="handleTagInput(event)" style="border: none; outline: none; flex: 1; min-width: 100px;">';
|
||||
document.getElementById('relatedConceptsInput').innerHTML = '<input type="text" id="relatedConceptInputField" placeholder="Add concept names..." onkeydown="handleRelatedConceptInput(event)" style="border: none; outline: none; flex: 1; min-width: 100px;">';
|
||||
document.getElementById('relatedSoftwareInput').innerHTML = '<input type="text" id="relatedSoftwareInputField" placeholder="Add software names..." onkeydown="handleRelatedSoftwareInput(event)" style="border: none; outline: none; flex: 1; min-width: 100px;">';
|
||||
|
||||
// Clear all checkboxes
|
||||
document.querySelectorAll('#domainsCheckbox input[type="checkbox"]').forEach(cb => cb.checked = false);
|
||||
document.querySelectorAll('#phasesCheckbox input[type="checkbox"]').forEach(cb => cb.checked = false);
|
||||
document.querySelectorAll('#scenariosCheckbox input[type="checkbox"]').forEach(cb => cb.checked = false);
|
||||
document.querySelectorAll('#platformsCheckbox input[type="checkbox"]').forEach(cb => cb.checked = false);
|
||||
document.querySelectorAll('#domainAgnosticCheckbox input[type="checkbox"]').forEach(cb => cb.checked = false);
|
||||
|
||||
currentEditingIndex = -1;
|
||||
toggleConditionalFields();
|
||||
}
|
||||
@@ -1155,14 +1170,21 @@
|
||||
// Set checkboxes
|
||||
setCheckboxValues('#domainsCheckbox input', tool.domains || []);
|
||||
setCheckboxValues('#phasesCheckbox input', tool.phases || []);
|
||||
setCheckboxValues('#scenariosCheckbox input', tool.scenarios || []);
|
||||
setCheckboxValues('#platformsCheckbox input', tool.platforms || []);
|
||||
setCheckboxValues('#domainAgnosticCheckbox input', tool['domain-agnostic-software'] || []);
|
||||
|
||||
// Set tags
|
||||
// Separate scenario tags from regular tags
|
||||
const allTags = tool.tags || [];
|
||||
const scenarioTags = allTags.filter(tag => tag.startsWith('scenario:'));
|
||||
const regularTags = allTags.filter(tag => !tag.startsWith('scenario:'));
|
||||
|
||||
// Set scenario checkboxes based on scenario tags
|
||||
setCheckboxValues('#scenariosCheckbox input', scenarioTags);
|
||||
|
||||
// Set regular tags
|
||||
const tagsContainer = document.getElementById('tagsInput');
|
||||
tagsContainer.innerHTML = '<input type="text" id="tagInputField" placeholder="Add tags..." onkeydown="handleTagInput(event)" style="border: none; outline: none; flex: 1; min-width: 100px;">';
|
||||
(tool.tags || []).forEach(tag => addTag('tagsInput', tag));
|
||||
regularTags.forEach(tag => addTag('tagsInput', tag));
|
||||
|
||||
// Set related concepts
|
||||
const conceptsContainer = document.getElementById('relatedConceptsInput');
|
||||
@@ -1241,10 +1263,11 @@
|
||||
const card = document.createElement('div');
|
||||
card.className = `tool-card ${tool.type || 'software'}`;
|
||||
|
||||
const tags = (tool.tags || []).map(tag => `<span class="tag">${tag}</span>`).join('');
|
||||
const tags = (tool.tags || []).filter(tag => !tag.startsWith('scenario:')).map(tag => `<span class="tag">${tag}</span>`).join('');
|
||||
const knowledgebaseIndicator = tool.knowledgebase ? '<span class="tag" style="background: #e8f5e8; color: #27ae60;">📚 KB</span>' : '';
|
||||
const relatedSoftwareIndicator = (tool.related_software && tool.related_software.length > 0) ? '<span class="tag" style="background: #e3f2fd; color: #1976d2;">🔗 SW</span>' : '';
|
||||
const scenariosIndicator = (tool.scenarios && tool.scenarios.length > 0) ? '<span class="tag" style="background: #f3e5f5; color: #7b1fa2;">🎮 SC</span>' : '';
|
||||
const scenarioTags = (tool.tags || []).filter(tag => tag.startsWith('scenario:'));
|
||||
const scenariosIndicator = scenarioTags.length > 0 ? '<span class="tag" style="background: #f3e5f5; color: #7b1fa2;">🎮 SC</span>' : '';
|
||||
|
||||
card.innerHTML = `
|
||||
<h3>${tool.icon ? tool.icon + ' ' : ''}${tool.name} <span style="font-size: 0.7em; color: #666;">[${tool.type || 'software'}]</span></h3>
|
||||
@@ -1294,7 +1317,10 @@
|
||||
const indicators = [];
|
||||
if (tool.knowledgebase) indicators.push('📚');
|
||||
if (tool.related_software?.length > 0) indicators.push('🔗');
|
||||
if (tool.scenarios?.length > 0) indicators.push('🎮');
|
||||
|
||||
// Check for scenario tags
|
||||
const scenarioTags = (tool.tags || []).filter(tag => tag.startsWith('scenario:'));
|
||||
if (scenarioTags.length > 0) indicators.push('🎮');
|
||||
|
||||
card.innerHTML = `
|
||||
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
|
||||
@@ -1517,17 +1543,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
// NEW: Scenario operations
|
||||
// Scenario operations (work with tags that have scenario: prefix)
|
||||
function bulkAddScenarios() {
|
||||
if (selectedTools.size === 0) return showMessage('No tools selected', 'error');
|
||||
const scenarios = prompt('Enter scenario IDs to add (comma-separated):');
|
||||
const scenarios = prompt('Enter scenario IDs to add (comma-separated, e.g., scenario:memory_dump,scenario:registry):');
|
||||
if (scenarios) {
|
||||
const scenarioList = scenarios.split(',').map(s => s.trim()).filter(s => s);
|
||||
const scenarioList = scenarios.split(',').map(s => {
|
||||
const trimmed = s.trim();
|
||||
return trimmed.startsWith('scenario:') ? trimmed : `scenario:${trimmed}`;
|
||||
}).filter(s => s !== 'scenario:');
|
||||
selectedTools.forEach(index => {
|
||||
const tool = yamlData.tools[index];
|
||||
tool.scenarios = [...new Set([...(tool.scenarios || []), ...scenarioList])];
|
||||
tool.tags = [...new Set([...(tool.tags || []), ...scenarioList])];
|
||||
});
|
||||
showMessage(`Added scenarios to ${selectedTools.size} tools`);
|
||||
showMessage(`Added scenario tags to ${selectedTools.size} tools`);
|
||||
renderBulkGrid();
|
||||
}
|
||||
}
|
||||
@@ -1536,26 +1565,33 @@
|
||||
if (selectedTools.size === 0) return showMessage('No tools selected', 'error');
|
||||
const scenarios = prompt('Enter scenario IDs to remove (comma-separated):');
|
||||
if (scenarios) {
|
||||
const scenarioList = scenarios.split(',').map(s => s.trim()).filter(s => s);
|
||||
const scenarioList = scenarios.split(',').map(s => {
|
||||
const trimmed = s.trim();
|
||||
return trimmed.startsWith('scenario:') ? trimmed : `scenario:${trimmed}`;
|
||||
}).filter(s => s !== 'scenario:');
|
||||
selectedTools.forEach(index => {
|
||||
const tool = yamlData.tools[index];
|
||||
if (tool.scenarios) {
|
||||
tool.scenarios = tool.scenarios.filter(scenario => !scenarioList.includes(scenario));
|
||||
if (tool.scenarios.length === 0) delete tool.scenarios;
|
||||
if (tool.tags) {
|
||||
tool.tags = tool.tags.filter(tag => !scenarioList.includes(tag));
|
||||
if (tool.tags.length === 0) delete tool.tags;
|
||||
}
|
||||
});
|
||||
showMessage(`Removed scenarios from ${selectedTools.size} tools`);
|
||||
showMessage(`Removed scenario tags from ${selectedTools.size} tools`);
|
||||
renderBulkGrid();
|
||||
}
|
||||
}
|
||||
|
||||
function bulkClearScenarios() {
|
||||
if (selectedTools.size === 0) return showMessage('No tools selected', 'error');
|
||||
if (confirm(`Are you sure you want to clear ALL scenarios from ${selectedTools.size} selected tools?`)) {
|
||||
if (confirm(`Are you sure you want to clear ALL scenario tags from ${selectedTools.size} selected tools?`)) {
|
||||
selectedTools.forEach(index => {
|
||||
delete yamlData.tools[index].scenarios;
|
||||
const tool = yamlData.tools[index];
|
||||
if (tool.tags) {
|
||||
tool.tags = tool.tags.filter(tag => !tag.startsWith('scenario:'));
|
||||
if (tool.tags.length === 0) delete tool.tags;
|
||||
}
|
||||
});
|
||||
showMessage(`Cleared scenarios from ${selectedTools.size} tools`);
|
||||
showMessage(`Cleared scenario tags from ${selectedTools.size} tools`);
|
||||
renderBulkGrid();
|
||||
}
|
||||
}
|
||||
@@ -1769,12 +1805,15 @@ ${tool.domains && tool.domains.length > 0 ? `## Anwendungsbereiche
|
||||
|
||||
${tool.domains.map(domain => `- ${domain}`).join('\n')}\n\n` : ''}${tool.phases && tool.phases.length > 0 ? `## Ermittlungsphasen
|
||||
|
||||
${tool.phases.map(phase => `- ${phase}`).join('\n')}\n\n` : ''}${tool.scenarios && tool.scenarios.length > 0 ? `## Anwendungsszenarien
|
||||
${tool.phases.map(phase => `- ${phase}`).join('\n')}\n\n` : ''}${(() => {
|
||||
const scenarioTags = (tool.tags || []).filter(tag => tag.startsWith('scenario:'));
|
||||
return scenarioTags.length > 0 ? `## Anwendungsszenarien
|
||||
|
||||
${tool.scenarios.map(scenario => {
|
||||
const scenarioData = yamlData.scenarios.find(s => s.id === scenario);
|
||||
return scenarioData ? `- ${scenarioData.icon} ${scenarioData.friendly_name}` : `- ${scenario}`;
|
||||
}).join('\n')}\n\n` : ''}## ${tool.type === 'concept' ? 'Grundlagen' : tool.type === 'method' ? 'Vorgehensweise' : 'Installation & Nutzung'}
|
||||
${scenarioTags.map(scenarioTag => {
|
||||
const scenarioData = yamlData.scenarios.find(s => s.id === scenarioTag);
|
||||
return scenarioData ? `- ${scenarioData.icon} ${scenarioData.friendly_name}` : `- ${scenarioTag}`;
|
||||
}).join('\n')}\n\n` : '';
|
||||
})()}## ${tool.type === 'concept' ? 'Grundlagen' : tool.type === 'method' ? 'Vorgehensweise' : 'Installation & Nutzung'}
|
||||
|
||||
${tool.type === 'concept' ?
|
||||
`### Kernkonzepte
|
||||
@@ -1863,7 +1902,7 @@ TODO: Füge weitere nützliche Links und Ressourcen hinzu.
|
||||
});
|
||||
}
|
||||
|
||||
// Enhanced Validation including scenarios and related_software
|
||||
// Enhanced Validation
|
||||
function validateYAML() {
|
||||
if (!yamlData) return showMessage('No data to validate', 'error');
|
||||
|
||||
@@ -1873,7 +1912,7 @@ TODO: Füge weitere nützliche Links und Ressourcen hinzu.
|
||||
if (!yamlData.tools) validationResults.push('❌ Missing tools section');
|
||||
if (!yamlData.domains) validationResults.push('❌ Missing domains section');
|
||||
if (!yamlData.phases) validationResults.push('❌ Missing phases section');
|
||||
if (!yamlData.scenarios) validationResults.push('⚠️ Missing scenarios section');
|
||||
if (!yamlData.scenarios) validationResults.push('⚠️ Missing scenarios section (for reference)');
|
||||
|
||||
// Validate tools
|
||||
yamlData.tools?.forEach((tool, index) => {
|
||||
@@ -1904,12 +1943,13 @@ TODO: Füge weitere nützliche Links und Ressourcen hinzu.
|
||||
});
|
||||
}
|
||||
|
||||
// Validate scenarios references
|
||||
if (tool.scenarios && tool.scenarios.length > 0) {
|
||||
tool.scenarios.forEach(scenarioId => {
|
||||
const exists = yamlData.scenarios?.some(s => s.id === scenarioId);
|
||||
// Validate scenario tags (check tags that start with scenario:)
|
||||
if (tool.tags && tool.tags.length > 0) {
|
||||
const scenarioTags = tool.tags.filter(tag => tag.startsWith('scenario:'));
|
||||
scenarioTags.forEach(scenarioTag => {
|
||||
const exists = yamlData.scenarios?.some(s => s.id === scenarioTag);
|
||||
if (!exists) {
|
||||
validationResults.push(`⚠️ Tool ${index + 1}: Scenario "${scenarioId}" not found in scenarios`);
|
||||
validationResults.push(`⚠️ Tool ${index + 1}: Scenario tag "${scenarioTag}" not found in scenarios reference`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user