diff --git a/.env.example b/.env.example index 6ff8470..7b393e6 100644 --- a/.env.example +++ b/.env.example @@ -23,7 +23,7 @@ AI_API_KEY=your-mistral-api-key AI_RATE_LIMIT_DELAY_MS=1000 # Git Integration (Required for contributions) -GIT_REPO_URL=https://git.cc24.dev/mstoeck3/cc24-hub +GIT_REPO_URL=https://git.cc24.dev/mstoeck3/forensic-pathways GIT_PROVIDER=gitea GIT_API_ENDPOINT=https://git.cc24.dev/api/v1 GIT_API_TOKEN=your-git-api-token diff --git a/.gitignore b/.gitignore index 3aed3a2..35db4ed 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,4 @@ temp/ .astro/settings.json .astro/data-store.json .astro/content.d.ts +prompt.md diff --git a/README.md b/README.md index d210ee0..bc5cad4 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,8 @@ Ein kuratiertes Verzeichnis für Digital Forensics und Incident Response (DFIR) ```bash # Repository klonen -git clone https://git.cc24.dev/mstoeck3/cc24-hub.git -cd cc24-hub +git clone https://git.cc24.dev/mstoeck3/forensic-pathways.git +cd forensic-pathways # Dependencies installieren npm install @@ -117,8 +117,8 @@ sudo systemctl enable nginx ```bash # Klonen des Repositorys -sudo git clone https://git.cc24.dev/mstoeck3/cc24-hub /opt/cc24-hub -cd /opt/cc24-hub +sudo git clone https://git.cc24.dev/mstoeck3/forensic-pathways /opt/forensic-pathways +cd /opt/forensic-pathways # Abhängigkeiten installieren sudo npm install @@ -127,12 +127,12 @@ sudo npm install sudo npm run build # Berechtigungen setzen -sudo chown -R www-data:www-data /opt/cc24-hub +sudo chown -R www-data:www-data /opt/forensic-pathways ``` #### 3. Umgebungsvariablen konfigurieren -Erstelle `/opt/cc24-hub/.env`: +Erstelle `/opt/forensic-pathways/.env`: ```bash # =========================================== @@ -160,7 +160,7 @@ AI_API_KEY=your-mistral-api-key AI_RATE_LIMIT_DELAY_MS=1000 # Git Integration (Required for contributions) -GIT_REPO_URL=https://git.cc24.dev/mstoeck3/cc24-hub +GIT_REPO_URL=https://git.cc24.dev/mstoeck3/forensic-pathways GIT_PROVIDER=gitea GIT_API_ENDPOINT=https://git.cc24.dev/api/v1 GIT_API_TOKEN=your-git-api-token @@ -178,13 +178,13 @@ NEXTCLOUD_PUBLIC_URL=https://your-nextcloud.com/s/ ```bash # Berechtigungen sichern -sudo chmod 600 /opt/cc24-hub/.env -sudo chown www-data:www-data /opt/cc24-hub/.env +sudo chmod 600 /opt/forensic-pathways/.env +sudo chown www-data:www-data /opt/forensic-pathways/.env ``` #### 4. Nginx konfigurieren -Erstelle `/etc/nginx/sites-available/cc24-hub`: +Erstelle `/etc/nginx/sites-available/forensic-pathways`: ```nginx server { @@ -212,7 +212,7 @@ server { # Static Files location / { try_files $uri $uri/ @nodejs; - root /opt/cc24-hub/dist; + root /opt/forensic-pathways/dist; index index.html; # Cache static assets @@ -244,14 +244,14 @@ server { ```bash # Site aktivieren -sudo ln -s /etc/nginx/sites-available/cc24-hub /etc/nginx/sites-enabled/ +sudo ln -s /etc/nginx/sites-available/forensic-pathways /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` #### 5. Systemd Service einrichten -Erstelle `/etc/systemd/system/cc24-hub.service`: +Erstelle `/etc/systemd/system/forensic-pathways.service`: ```ini [Unit] @@ -263,7 +263,7 @@ Wants=nginx.service Type=exec User=www-data Group=www-data -WorkingDirectory=/opt/cc24-hub +WorkingDirectory=/opt/forensic-pathways Environment=NODE_ENV=production ExecStart=/usr/bin/node ./dist/server/entry.mjs Restart=always @@ -276,7 +276,7 @@ NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes -ReadWritePaths=/opt/cc24-hub +ReadWritePaths=/opt/forensic-pathways CapabilityBoundingSet= # Resource Limits @@ -290,11 +290,11 @@ WantedBy=multi-user.target ```bash # Service aktivieren und starten sudo systemctl daemon-reload -sudo systemctl enable cc24-hub -sudo systemctl start cc24-hub +sudo systemctl enable forensic-pathways +sudo systemctl start forensic-pathways # Status prüfen -sudo systemctl status cc24-hub +sudo systemctl status forensic-pathways ``` ## 🔧 Konfiguration @@ -438,7 +438,7 @@ domain-agnostic-software: ```bash # Repository aktualisieren -cd /opt/cc24-hub +cd /opt/forensic-pathways sudo git pull # Dependencies aktualisieren @@ -448,7 +448,7 @@ sudo npm install sudo npm run build # Service neustarten -sudo systemctl restart cc24-hub +sudo systemctl restart forensic-pathways ``` ## 💾 Backup @@ -456,10 +456,10 @@ sudo systemctl restart cc24-hub Wichtige Dateien für Backup: ```bash -/opt/cc24-hub/src/data/tools.yaml -/opt/cc24-hub/.env -/etc/nginx/sites-available/cc24-hub -/etc/systemd/system/cc24-hub.service +/opt/forensic-pathways/src/data/tools.yaml +/opt/forensic-pathways/.env +/etc/nginx/sites-available/forensic-pathways +/etc/systemd/system/forensic-pathways.service ``` ## 🤝 Beiträge @@ -475,7 +475,7 @@ Contributions sind willkommen! Bitte: Bei Problemen oder Fragen: -- **Issues:** [Repository Issues](https://git.cc24.dev/mstoeck3/cc24-hub/issues) +- **Issues:** [Repository Issues](https://git.cc24.dev/mstoeck3/forensic-pathways/issues) - **Dokumentation:** Siehe `/knowledgebase` auf der Website ## 📄 Lizenz diff --git a/context.md b/context.md index e043f36..c8f937d 100644 --- a/context.md +++ b/context.md @@ -268,7 +268,7 @@ This architecture emphasizes maintainability, user experience, and extensibility 2. **Add selectively**: Include 1-3 secondary files based on the specific development task 3. **Reference others**: Mention other relevant files by name/purpose without including full content -user01@altiera /v/h/u/P/cc24-hub (main)> tree src +user01@altiera /v/h/u/P/forensic-pathways (main)> tree src src ├── components │ ├── AIQueryInterface.astro diff --git a/src/components/AIQueryInterface.astro b/src/components/AIQueryInterface.astro index 7e13157..66e0412 100644 --- a/src/components/AIQueryInterface.astro +++ b/src/components/AIQueryInterface.astro @@ -444,39 +444,46 @@ document.addEventListener('DOMContentLoaded', () => { } }; - // Smart Prompting Input Handling + // Smart Prompting Input Handling - Fixed Race Conditions aiInput.addEventListener('input', () => { console.log('[DEBUG] Input event triggered, length:', aiInput.value.trim().length); const inputLength = aiInput.value.trim().length; - // Clear existing timeout + // Clear ALL existing timeouts and abort controllers clearTimeout(enhancementTimeout); - - // Cancel any pending enhancement call if (enhancementAbortController) { enhancementAbortController.abort(); + enhancementAbortController = null; } - // Hide suggestions if input is too short + // Hide suggestions immediately if input is too short if (inputLength < 40) { showPromptingStatus('hidden'); return; } - // Show analyzing state after 1 second - setTimeout(() => { - if (aiInput.value.trim().length >= 50) { - showPromptingStatus('analyzing'); - } - }, 1000); - - // Trigger AI enhancement after 1.5 seconds + // Single consolidated timeout for all smart prompting logic enhancementTimeout = setTimeout(() => { - console.log('[DEBUG] Enhancement timeout fired, calling triggerSmartPrompting'); - if (aiInput.value.trim().length >= 40) { - triggerSmartPrompting(); + const currentLength = aiInput.value.trim().length; + + // Double-check length hasn't changed during timeout + if (currentLength < 40) { + showPromptingStatus('hidden'); + return; } - }, 1500); + + // Show analyzing state first + if (currentLength >= 50) { + showPromptingStatus('analyzing'); + + // Trigger enhancement after showing analyzing state + setTimeout(() => { + if (aiInput.value.trim().length >= 50) { + triggerSmartPrompting(); + } + }, 500); + } + }, 1000); // Single timeout instead of multiple }); aiInput.addEventListener('input', updateCharacterCount); diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 7fa188a..481e1c2 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -11,7 +11,7 @@

- + diff --git a/src/components/TargetedScenarios.astro b/src/components/TargetedScenarios.astro new file mode 100644 index 0000000..159bb06 --- /dev/null +++ b/src/components/TargetedScenarios.astro @@ -0,0 +1,181 @@ +--- +import { getToolsData } from '../utils/dataService.js'; + +const data = await getToolsData(); +const scenarios = data.scenarios || []; + +// Configuration +const maxDisplayed = 9; +const displayedScenarios = scenarios.slice(0, maxDisplayed); +--- + +
+
+

Gezielte Tool-Suche

+

+ Finden Sie schnell das passende Werkzeug für Ihre spezifische Anforderung +

+
+ +
+ + + {scenarios.length > 0 && ( +
+ {displayedScenarios.map((scenario) => ( +
+ {scenario.icon} + {scenario.friendly_name} +
+ ))} +
+ )} + + {scenarios.length > maxDisplayed && ( +
+ +
+ )} +
+ +
+

+ Tipp: Die Szenarien durchsuchen automatisch nach passenden Tags und Beschreibungen. + Für KI-gestützte Empfehlungen nutzen Sie den entsprechenden Modus. +

+
+
+ + \ No newline at end of file diff --git a/src/components/ToolFilters.astro b/src/components/ToolFilters.astro index 591e3d9..052e818 100644 --- a/src/components/ToolFilters.astro +++ b/src/components/ToolFilters.astro @@ -117,15 +117,24 @@ const sortedTags = Object.entries(tagFrequency) window.toolsData = toolsData; document.addEventListener('DOMContentLoaded', () => { - const searchInput = document.getElementById('search-input'); - const domainSelect = document.getElementById('domain-select'); - const phaseButtons = document.querySelectorAll('.phase-button'); - const proprietaryCheckbox = document.getElementById('include-proprietary'); - const tagCloudItems = document.querySelectorAll('.tag-cloud-item'); - const tagCloud = document.getElementById('tag-cloud'); - const tagCloudToggle = document.getElementById('tag-cloud-toggle'); - const viewToggles = document.querySelectorAll('.view-toggle'); - const aiViewToggle = document.getElementById('ai-view-toggle'); + // Cache DOM elements once + const elements = { + searchInput: document.getElementById('search-input'), + domainSelect: document.getElementById('domain-select'), + phaseButtons: document.querySelectorAll('.phase-button'), + proprietaryCheckbox: document.getElementById('include-proprietary'), + tagCloudItems: document.querySelectorAll('.tag-cloud-item'), + tagCloud: document.getElementById('tag-cloud'), + tagCloudToggle: document.getElementById('tag-cloud-toggle'), + viewToggles: document.querySelectorAll('.view-toggle'), + aiViewToggle: document.getElementById('ai-view-toggle') + }; + + // Verify critical elements exist + if (!elements.searchInput || !elements.domainSelect || !elements.proprietaryCheckbox) { + console.error('Critical filter elements not found'); + return; + } let selectedTags = new Set(); let selectedPhase = ''; @@ -133,7 +142,7 @@ const sortedTags = Object.entries(tagFrequency) function initTagCloud() { const visibleCount = 22; - tagCloudItems.forEach((item, index) => { + elements.tagCloudItems.forEach((item, index) => { if (index >= visibleCount) { item.style.display = 'none'; } @@ -145,22 +154,22 @@ const sortedTags = Object.entries(tagFrequency) const visibleCount = 22; if (isTagCloudExpanded) { - tagCloud.classList.add('expanded'); - tagCloudToggle.textContent = 'Weniger zeigen'; - tagCloudToggle.setAttribute('data-expanded', 'true'); + elements.tagCloud.classList.add('expanded'); + elements.tagCloudToggle.textContent = 'Weniger zeigen'; + elements.tagCloudToggle.setAttribute('data-expanded', 'true'); - tagCloudItems.forEach(item => { + elements.tagCloudItems.forEach(item => { if (!item.classList.contains('hidden')) { item.style.display = 'inline-flex'; } }); } else { - tagCloud.classList.remove('expanded'); - tagCloudToggle.textContent = 'Mehr zeigen'; - tagCloudToggle.setAttribute('data-expanded', 'false'); + elements.tagCloud.classList.remove('expanded'); + elements.tagCloudToggle.textContent = 'Mehr zeigen'; + elements.tagCloudToggle.setAttribute('data-expanded', 'false'); let visibleIndex = 0; - tagCloudItems.forEach(item => { + elements.tagCloudItems.forEach(item => { if (!item.classList.contains('hidden')) { if (visibleIndex < visibleCount) { item.style.display = 'inline-flex'; @@ -174,11 +183,11 @@ const sortedTags = Object.entries(tagFrequency) } function filterTagCloud() { - const searchTerm = searchInput.value.toLowerCase(); + const searchTerm = elements.searchInput.value.toLowerCase(); let visibleCount = 0; const maxVisibleWhenCollapsed = 22; - tagCloudItems.forEach(item => { + elements.tagCloudItems.forEach(item => { const tagName = item.getAttribute('data-tag').toLowerCase(); const shouldShow = tagName.includes(searchTerm); @@ -196,10 +205,10 @@ const sortedTags = Object.entries(tagFrequency) } }); - const hasHiddenTags = Array.from(tagCloudItems).some(item => + const hasHiddenTags = Array.from(elements.tagCloudItems).some(item => !item.classList.contains('hidden') && item.style.display === 'none' ); - tagCloudToggle.style.display = hasHiddenTags ? 'block' : 'none'; + elements.tagCloudToggle.style.display = hasHiddenTags ? 'block' : 'none'; } function isToolHosted(tool) { @@ -224,7 +233,7 @@ const sortedTags = Object.entries(tagFrequency) el.classList.remove('highlight-row', 'highlight-column'); }); - const selectedDomain = domainSelect.value; + const selectedDomain = elements.domainSelect.value; if (selectedDomain) { const domainRow = matrixTable.querySelector(`tr[data-domain="${selectedDomain}"]`); @@ -252,9 +261,9 @@ const sortedTags = Object.entries(tagFrequency) } function filterTools() { - const searchTerm = searchInput.value.toLowerCase(); - const selectedDomain = domainSelect.value; - const includeProprietary = proprietaryCheckbox.checked; + const searchTerm = elements.searchInput.value.toLowerCase(); + const selectedDomain = elements.domainSelect.value; + const includeProprietary = elements.proprietaryCheckbox.checked; const filtered = window.toolsData.filter(tool => { const domains = tool.domains || []; @@ -314,7 +323,7 @@ const sortedTags = Object.entries(tagFrequency) selectedPhase = ''; button.classList.remove('active'); } else { - phaseButtons.forEach(btn => btn.classList.remove('active')); + elements.phaseButtons.forEach(btn => btn.classList.remove('active')); selectedPhase = phase; button.classList.add('active'); } @@ -323,7 +332,7 @@ const sortedTags = Object.entries(tagFrequency) } function handleViewToggle(view) { - viewToggles.forEach(btn => { + elements.viewToggles.forEach(btn => { btn.classList.toggle('active', btn.getAttribute('data-view') === view); }); @@ -339,37 +348,38 @@ const sortedTags = Object.entries(tagFrequency) function clearTagFilters() { selectedTags.clear(); - tagCloudItems.forEach(item => item.classList.remove('active')); + elements.tagCloudItems.forEach(item => item.classList.remove('active')); filterTools(); } function clearAllFilters() { - searchInput.value = ''; - domainSelect.value = ''; + elements.searchInput.value = ''; + elements.domainSelect.value = ''; selectedPhase = ''; - phaseButtons.forEach(btn => btn.classList.remove('active')); + elements.phaseButtons.forEach(btn => btn.classList.remove('active')); clearTagFilters(); filterTagCloud(); } - searchInput.addEventListener('input', () => { + // Event listeners using cached elements + elements.searchInput.addEventListener('input', () => { filterTagCloud(); filterTools(); }); - domainSelect.addEventListener('change', filterTools); - proprietaryCheckbox.addEventListener('change', filterTools); - tagCloudToggle.addEventListener('click', toggleTagCloud); + elements.domainSelect.addEventListener('change', filterTools); + elements.proprietaryCheckbox.addEventListener('change', filterTools); + elements.tagCloudToggle.addEventListener('click', toggleTagCloud); - tagCloudItems.forEach(item => { + elements.tagCloudItems.forEach(item => { item.addEventListener('click', () => handleTagClick(item)); }); - phaseButtons.forEach(btn => { + elements.phaseButtons.forEach(btn => { btn.addEventListener('click', () => handlePhaseClick(btn)); }); - viewToggles.forEach(btn => { + elements.viewToggles.forEach(btn => { btn.addEventListener('click', () => handleViewToggle(btn.getAttribute('data-view'))); }); diff --git a/src/components/ToolMatrix.astro b/src/components/ToolMatrix.astro index 79666af..f371d52 100644 --- a/src/components/ToolMatrix.astro +++ b/src/components/ToolMatrix.astro @@ -672,6 +672,13 @@ domains.forEach((domain: any) => { const primaryModal = document.getElementById('tool-details-primary'); const secondaryModal = document.getElementById('tool-details-secondary'); + // Debounce rapid calls + if (window.modalHideInProgress) return; + window.modalHideInProgress = true; + + setTimeout(() => { + window.modalHideInProgress = false; + }, 100); if (modalType === 'both' || modalType === 'all') { if (primaryModal) { @@ -702,13 +709,19 @@ domains.forEach((domain: any) => { if (contributeButtonSecondary) contributeButtonSecondary.style.display = 'none'; } + // Consolidated state checking with safety checks const primaryActive = primaryModal && primaryModal.classList.contains('active'); const secondaryActive = secondaryModal && secondaryModal.classList.contains('active'); + // Update overlay and body classes atomically if (!primaryActive && !secondaryActive) { if (overlay) overlay.classList.remove('active'); document.body.classList.remove('modals-side-by-side'); - } else if (primaryActive !== secondaryActive) { + } else if (primaryActive && secondaryActive) { + // Both active - ensure side-by-side class + document.body.classList.add('modals-side-by-side'); + } else { + // Only one active - remove side-by-side class document.body.classList.remove('modals-side-by-side'); } }; diff --git a/src/data/tools.yaml b/src/data/tools.yaml index 983a535..2a53a74 100644 --- a/src/data/tools.yaml +++ b/src/data/tools.yaml @@ -2153,3 +2153,34 @@ domain-agnostic-software: - 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-traffic + icon: 🌐 + friendly_name: "Netzwerk-Traffic" + - id: mobile-forensik + icon: 📱 + friendly_name: "Mobile Geräte" + - id: malware-analysis + icon: 🦠 + friendly_name: "Malware-Analyse" + - id: timeline-analysis + icon: ⏰ + friendly_name: "Timeline-Erstellung" + - id: file-recovery + icon: 💾 + friendly_name: "Datei-Wiederherstellung" + - id: browser-forensik + icon: 🌍 + friendly_name: "Browser-Forensik" + - id: email-forensik + icon: 📧 + friendly_name: "E-Mail-Forensik" + - id: log-analysis + icon: 📊 + friendly_name: "Log-Analyse" \ No newline at end of file diff --git a/src/data/tools.yaml.example b/src/data/tools.yaml.example index 09e6c69..a0eb87a 100644 --- a/src/data/tools.yaml.example +++ b/src/data/tools.yaml.example @@ -204,3 +204,10 @@ domain-agnostic-software: - 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" diff --git a/src/env.d.ts b/src/env.d.ts index 7e97e35..18e4c31 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -22,10 +22,25 @@ declare global { findToolByIdentifier: (tools: any[], identifier: string) => any | undefined; isToolHosted: (tool: any) => boolean; - checkClientAuth: () => Promise<{authenticated: boolean; authRequired: boolean; expires?: string}>; - requireClientAuth: (callback?: () => void, returnUrl?: string) => Promise; - showIfAuthenticated: (selector: string) => Promise; + checkClientAuth: (context?: string) => Promise<{authenticated: boolean; authRequired: boolean; expires?: string}>; + requireClientAuth: (callback?: () => void, returnUrl?: string, context?: string) => Promise; + showIfAuthenticated: (selector: string, context?: string) => Promise; setupAuthButtons: (selector?: string) => void; + + // Consolidated scroll utilities + scrollToElement: (element: Element | null, options?: ScrollIntoViewOptions) => void; + scrollToElementById: (elementId: string, options?: ScrollIntoViewOptions) => void; + scrollToElementBySelector: (selector: string, options?: ScrollIntoViewOptions) => void; + + // Additional global functions that might be called + applyScenarioSearch?: (scenarioId: string) => void; + selectPhase?: (phase: string) => void; + selectApproach?: (approach: string) => void; + navigateToGrid?: (toolName: string) => void; + navigateToMatrix?: (toolName: string) => void; + toggleAllScenarios?: () => void; + showShareDialog?: (shareButton: Element) => void; + modalHideInProgress?: boolean; } } diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 440689b..84f1288 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -73,6 +73,35 @@ const { title, description = 'ForensicPathways - A comprehensive directory of di getStoredTheme }; + // Consolidated scrolling utility + (window as any).scrollToElement = function(element, options = {}) { + if (!element) return; + + // Calculate target position manually to avoid double-scroll + setTimeout(() => { + const headerHeight = document.querySelector('nav')?.offsetHeight || 80; + const elementRect = element.getBoundingClientRect(); + const absoluteElementTop = elementRect.top + window.pageYOffset; + const targetPosition = absoluteElementTop - headerHeight - 20; // Adjust this 20 as needed + + window.scrollTo({ + top: targetPosition, + behavior: 'smooth' + }); + }, 100); + }; + + // Convenience functions for common scroll targets + (window as any).scrollToElementById = function(elementId, options = {}) { + const element = document.getElementById(elementId); + (window as any).scrollToElement(element, options); + }; + + (window as any).scrollToElementBySelector = function(selector, options = {}) { + const element = document.querySelector(selector); + (window as any).scrollToElement(element, options); + }; + function createToolSlug(toolName) { if (!toolName || typeof toolName !== 'string') { console.warn('[toolHelpers] Invalid toolName provided to createToolSlug:', toolName); diff --git a/src/pages/about.astro b/src/pages/about.astro index a0041b5..90018c9 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -205,7 +205,7 @@ import BaseLayout from '../layouts/BaseLayout.astro'; Möchtest du direkt am Sourcecode mitarbeiten? Schau dir die Anleitung unter
/contribute an oder besuche unser Repository:

- diff --git a/src/pages/contribute/index.astro b/src/pages/contribute/index.astro index c7ab134..bf88ba3 100644 --- a/src/pages/contribute/index.astro +++ b/src/pages/contribute/index.astro @@ -166,7 +166,7 @@ const { authenticated, userEmail, userId } = authResult;
- + diff --git a/src/pages/index.astro b/src/pages/index.astro index f8592a4..7b5d0c4 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -4,74 +4,152 @@ import ToolCard from '../components/ToolCard.astro'; import ToolFilters from '../components/ToolFilters.astro'; import ToolMatrix from '../components/ToolMatrix.astro'; import AIQueryInterface from '../components/AIQueryInterface.astro'; +import TargetedScenarios from '../components/TargetedScenarios.astro'; import { getToolsData } from '../utils/dataService.js'; const data = await getToolsData(); const tools = data.tools; +const phases = data.phases; --- -
-
-

ForensicPathways

- -

- Das richtige Werkzeug zur richtigen Zeit – in der digitalen Forensik entscheidet oft die Wahl der passenden Methode oder Software über Erfolg oder Misserfolg einer Untersuchung. +

+
+

ForensicPathways

+

Das richtige Werkzeug zur richtigen Zeit

+

+ Systematische digitale Forensik nach bewährter NIST SP 800-86 Methodik.
+ Wählen Sie Ihren Ansatz für die Werkzeugauswahl:

- -

- Unser kuratiertes Verzeichnis bietet euch eine strukturierte Übersicht über bewährte Methoden und Tools, - kategorisiert nach forensischen Domänen und Untersuchungsphasen nach Kent, Chevalier, Grance & Dang. -

- -

- Info: - Die lila gekennzeichneten Einträge sind über das Single-Sign-On der CC24-Cloud direkt zugänglich. - Teilnehmer der Seminargruppe CC24-w1 können die gehostete Infrastruktur nutzen. - Sollten spezielle Berechtigungen für den Zugriff erforderlich sein oder etwas nicht funktionieren, kontaktiert mich. -

- -
- - - - - - - Infos zu SSO & Zugang - + +
+
+
+
🔍
+

Vollständige Ermittlung

+
+

+ Systematisches Vorgehen durch alle vier NIST-Phasen einer forensischen Untersuchung +

+
    +
  • Methodische Schritt-für-Schritt Anleitung
  • +
  • Vollständige Dokumentationskette
  • +
  • Rechtssichere Beweisführung
  • +
  • Ideal für komplexe Fälle
  • +
+
+ +
+
+
🎯
+

Gezieltes Problem lösen

+
+

+ Direkter Zugang zu spezifischen Tools und Methoden für bekannte Anforderungen +

+
    +
  • Schnelle Tool-Suche
  • +
  • Spezifische Problemlösungen
  • +
  • Erfahrene Anwender
  • +
  • Effizient für Einzelaufgaben
  • +
+
+
+ +
+

+ ℹ️ + Die lila gekennzeichneten Einträge sind über das Single-Sign-On der CC24-Cloud direkt zugänglich. + Teilnehmer der Seminargruppe CC24-w1 können die gehostete Infrastruktur nutzen. + Kontakt bei Problemen +

- - - - - - - - - - Beitragen - - - - - - - - - Entdecken - +
+ + + + + + + Infos zu SSO & Zugang + + + + + + + + + + + + Beitragen + + +
- + + +
+
+

NIST SP 800-86 Forensische Methodik

+

+ Wählen Sie eine Phase aus dem bewährten Vier-Phasen-Modell +

+
+ +
+ {phases.map((phase: any, index: number) => { + const phaseTools = tools.filter((tool: any) => + tool.phases && tool.phases.includes(phase.id) + ); + + return ( +
+
{index + 1}
+
{phase.name}
+

+ {phase.description} +

+ {phaseTools.length} Tools +
+ ); + })} +
+ +
+

+ Tipp: Für komplexe Ermittlungen empfiehlt sich das sequenzielle Durchlaufen aller Phasen. + Jede Phase baut methodisch auf der vorherigen auf. +

+
+
+ + +
+
+

Alle verfügbaren Werkzeuge durchsuchen

+

+ Nutzen Sie die erweiterten Filter und Kategorien für eine detaillierte Suche +

+
@@ -92,9 +170,71 @@ const tools = data.tools; -