diff --git a/deploy-static.sh b/deploy-static.sh deleted file mode 100644 index e8fff0e..0000000 --- a/deploy-static.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/bash - -# CC24-Hub - Node.js Deployment Script - -set -e - -PROJECT_DIR="/var/www/dfir-tools-hub" -SERVICE_NAME="dfir-tools-hub" -SERVICE_PORT="3000" - -echo "🔧 Setting up Node.js deployment..." - -cd $PROJECT_DIR - -# Install PM2 globally if not present -if ! command -v pm2 &> /dev/null; then - sudo npm install -g pm2 -fi - -# Install dependencies -npm ci --production - -# Update astro.config.mjs for Node.js adapter -cat > astro.config.mjs << 'EOF' -import { defineConfig } from 'astro/config'; - -export default defineConfig({ - output: 'server', - adapter: '@astrojs/node', - server: { - port: 3000, - host: '127.0.0.1' - } -}); -EOF - -# Install Node.js adapter -npm install @astrojs/node - -# Build for Node.js -npm run build - -# Create PM2 ecosystem file -cat > ecosystem.config.js << EOF -module.exports = { - apps: [{ - name: '$SERVICE_NAME', - script: './dist/server/entry.mjs', - instances: 'max', - exec_mode: 'cluster', - env: { - NODE_ENV: 'production', - PORT: $SERVICE_PORT, - HOST: '127.0.0.1' - }, - error_file: '/var/log/pm2/$SERVICE_NAME-error.log', - out_file: '/var/log/pm2/$SERVICE_NAME-out.log', - log_file: '/var/log/pm2/$SERVICE_NAME.log', - time: true, - max_memory_restart: '1G' - }] -}; -EOF - -# Create log directory -sudo mkdir -p /var/log/pm2 -sudo chown -R $(whoami):$(whoami) /var/log/pm2 - -# Start/restart with PM2 -pm2 delete $SERVICE_NAME 2>/dev/null || true -pm2 start ecosystem.config.js -pm2 save -pm2 startup - -echo "🔧 Configuring nginx reverse proxy..." - -# Create nginx configuration for Node.js -sudo tee /etc/nginx/sites-available/$SERVICE_NAME << EOF -upstream dfir_backend { - server 127.0.0.1:$SERVICE_PORT; -} - -server { - listen 80; - server_name dfir-tools.yourdomain.com; # Replace with your domain - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Content-Type-Options "nosniff" always; - add_header X-XSS-Protection "1; mode=block" always; - - # Proxy to Node.js application - location / { - proxy_pass http://dfir_backend; - proxy_http_version 1.1; - proxy_set_header Upgrade \$http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto \$scheme; - proxy_cache_bypass \$http_upgrade; - - # Timeouts - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - } - - # Health check endpoint - location /health { - access_log off; - proxy_pass http://dfir_backend/health; - } -} -EOF - -# Enable site and reload nginx -sudo ln -sf /etc/nginx/sites-available/$SERVICE_NAME /etc/nginx/sites-enabled/ -sudo nginx -t && sudo systemctl reload nginx - -echo "✅ Node.js deployment completed!" -echo "🔍 Status: pm2 status" -echo "📋 Logs: pm2 logs $SERVICE_NAME" \ No newline at end of file diff --git a/framework.md b/framework.md deleted file mode 100644 index 972a3ec..0000000 --- a/framework.md +++ /dev/null @@ -1,47 +0,0 @@ -Proposed Framework Categories (Y-axis): -1. Storage & File System Artifacts - -Static file system Analyse (encrypted/unencrypted) -Registry Analyse -Database forensics - -2. Memory & Runtime Artifacts - -Memory forensics of live systems -Process Analyse -Virtualization forensics - -3. Network & Communication Artifacts - -Webserver log Analyse -System log Analyse -PKI Auswertung -Radio signal Analyse -VoIP forensics -Network packet Analyse (PCAP) - -4. Application & Code Artifacts - -Malware Analyse -Darknet website source code Analyse -Browser forensics -Email forensics - -5. Multimedia & Content Artifacts - -Video/image/audio authenticity Analyse -Steganography detection -Content recovery - -6. Transaction & Financial Artifacts - -Blockchain payment Analyse -Cryptocurrency exchange Analyse -Financial transaction forensics - -7. Platform & Infrastructure Artifacts - -Mobile forensics -Cloud forensics -IoT device forensics -Social media/OSINT Analyse \ No newline at end of file diff --git a/src/components/Navigation.astro b/src/components/Navigation.astro index 7eb40f3..9754cb4 100644 --- a/src/components/Navigation.astro +++ b/src/components/Navigation.astro @@ -18,6 +18,11 @@ const currentPath = Astro.url.pathname; ~/ +
  • + + ~/knowledgebase + +
  • ~/status diff --git a/src/components/ToolCard.astro b/src/components/ToolCard.astro index 5f33c2b..60614d1 100644 --- a/src/components/ToolCard.astro +++ b/src/components/ToolCard.astro @@ -13,6 +13,7 @@ export interface Props { license: string; tags: string[]; statusUrl?: string; + knowledgebase?: boolean; }; } @@ -24,6 +25,9 @@ const hasValidProjectUrl = tool.projectUrl !== undefined && tool.projectUrl !== "" && tool.projectUrl.trim() !== ""; +// Check if tool has knowledgebase entry +const hasKnowledgebase = tool.knowledgebase === true; + // Determine card styling based on hosting status (derived from projectUrl) const cardClass = hasValidProjectUrl ? 'card card-hosted' : (tool.license !== 'Proprietary' ? 'card card-oss' : 'card'); --- @@ -31,9 +35,10 @@ const cardClass = hasValidProjectUrl ? 'card card-hosted' : (tool.license !== 'P

    {tool.name}

    -
    +
    {hasValidProjectUrl && Self-Hosted} {tool.license !== 'Proprietary' && Open Source} + {hasKnowledgebase && Infos 📖}
    diff --git a/src/components/ToolFilters.astro b/src/components/ToolFilters.astro index c487ded..a43d717 100644 --- a/src/components/ToolFilters.astro +++ b/src/components/ToolFilters.astro @@ -259,29 +259,34 @@ const sortedTags = Object.entries(tagFrequency) } } - // Filter function +// Filter function function filterTools() { const searchTerm = searchInput.value.toLowerCase(); const selectedDomain = domainSelect.value; const includeProprietary = proprietaryCheckbox.checked; const filtered = window.toolsData.filter(tool => { + // Ensure arrays exist with fallbacks + const domains = tool.domains || []; + const phases = tool.phases || []; + const tags = tool.tags || []; + // Search filter if (searchTerm && !( tool.name.toLowerCase().includes(searchTerm) || tool.description.toLowerCase().includes(searchTerm) || - tool.tags.some(tag => tag.toLowerCase().includes(searchTerm)) + tags.some(tag => tag.toLowerCase().includes(searchTerm)) )) { return false; } // Domain filter - if (selectedDomain && !tool.domains.includes(selectedDomain)) { + if (selectedDomain && !domains.includes(selectedDomain)) { return false; } // Phase filter - if (selectedPhase && !tool.phases.includes(selectedPhase)) { + if (selectedPhase && !phases.includes(selectedPhase)) { return false; } @@ -291,7 +296,7 @@ const sortedTags = Object.entries(tagFrequency) } // Tag filter - if (selectedTags.size > 0 && !Array.from(selectedTags).some(tag => tool.tags.includes(tag))) { + if (selectedTags.size > 0 && !Array.from(selectedTags).some(tag => tags.includes(tag))) { return false; } diff --git a/src/components/ToolMatrix.astro b/src/components/ToolMatrix.astro index 5a84ae5..182bf5c 100644 --- a/src/components/ToolMatrix.astro +++ b/src/components/ToolMatrix.astro @@ -14,11 +14,11 @@ const tools = data.tools; // Separate collaboration tools from domain-specific tools const collaborationTools = tools.filter((tool: any) => - tool.phases.includes('collaboration') + tool.phases && tool.phases.includes('collaboration') ); const domainTools = tools.filter((tool: any) => - !tool.phases.includes('collaboration') + !tool.phases || !tool.phases.includes('collaboration') ); // Create matrix structure for domain-specific tools only @@ -27,7 +27,7 @@ domains.forEach((domain: any) => { matrix[domain.id] = {}; phases.filter((phase: any) => phase.id !== 'collaboration').forEach((phase: any) => { matrix[domain.id][phase.id] = domainTools.filter((tool: any) => - tool.domains.includes(domain.id) && tool.phases.includes(phase.id) + tool.domains && tool.domains.includes(domain.id) && tool.phases && tool.phases.includes(phase.id) ); }); }); @@ -51,6 +51,7 @@ domains.forEach((domain: any) => {
    {hasValidProjectUrl && Self-Hosted} {tool.license !== 'Proprietary' && OSS} + {tool.knowledgebase === true && Infos 📖}

    @@ -95,8 +96,10 @@ domains.forEach((domain: any) => { class={`tool-chip ${hasValidProjectUrl ? 'tool-chip-hosted' : tool.license !== 'Proprietary' ? 'tool-chip-oss' : ''}`} data-tool-name={tool.name} onclick={`window.showToolDetails('${tool.name}')`} + title={`${tool.name}${tool.knowledgebase === true ? ' (KB verfügbar)' : ''}`} > {tool.name} + {tool.knowledgebase === true && 📖} ); })} @@ -131,7 +134,7 @@ domains.forEach((domain: any) => {

    - +
    \ No newline at end of file diff --git a/src/styles/global.css b/src/styles/global.css index 1c45e74..76dae54 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -389,6 +389,54 @@ input[type="checkbox"] { color: white; } +/* Knowledgebase entries styling */ +.kb-entry { + margin-bottom: 1rem; + position: relative; + transition: all 0.3s ease; +} + +.kb-entry:target { + animation: highlight-flash 2s ease-out; +} + +.kb-entry-collapsed { + /* Collapsed state - compact view with minimal spacing */ + margin-bottom: 1rem; +} + +.kb-entry-expanded { + margin-bottom: 2rem; +} + +.kb-entry-header { + padding: 1rem 0; + transition: all 0.2s ease; +} + +.kb-entry-header:hover { + background-color: var(--color-bg-secondary); + margin: -0.5rem; + padding: 1.5rem; + border-radius: 0.5rem; +} + +.kb-expand-icon { + transition: transform 0.3s ease; + color: var(--color-text-secondary); +} + +.kb-expand-icon svg { + transition: transform 0.3s ease; +} + +.kb-entry-content { + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid var(--color-border); + animation: slideDown 0.3s ease-out; +} + /* Tool Details Modal */ .tool-details { display: none; @@ -522,6 +570,69 @@ footer { to { opacity: 1; } } +@keyframes slideDown { + from { + opacity: 0; + max-height: 0; + padding-top: 0; + margin-top: 0; + } + to { + opacity: 1; + max-height: 1000px; + padding-top: 1rem; + margin-top: 1rem; + } +} + +@keyframes highlight-flash { + 0% { background-color: rgba(37, 99, 235, 0.1); } + 100% { background-color: transparent; } +} + +.kb-content { + line-height: 1.7; +} + +.kb-content h3 { + color: var(--color-text); + border-bottom: 2px solid var(--color-primary); + padding-bottom: 0.5rem; +} + +.kb-content p { + margin-bottom: 1rem; +} + +.kb-content ul, .kb-content ol { + margin-left: 1.5rem; + margin-bottom: 1rem; +} + +.kb-content code { + background-color: var(--color-bg-secondary); + padding: 0.125rem 0.25rem; + border-radius: 0.25rem; + font-family: 'Monaco', 'Courier New', monospace; + font-size: 0.875em; +} + +.kb-content pre { + background-color: var(--color-bg-secondary); + padding: 1rem; + border-radius: 0.5rem; + overflow-x: auto; + border: 1px solid var(--color-border); +} + +.kb-content blockquote { + border-left: 4px solid var(--color-primary); + padding-left: 1rem; + margin: 1rem 0; + font-style: italic; + color: var(--color-text-secondary); +} + .fade-in { animation: fadeIn 0.3s ease-in; }