integrate checkbox filters
This commit is contained in:
		
							parent
							
								
									2658bd148b
								
							
						
					
					
						commit
						62470673fe
					
				
							
								
								
									
										1
									
								
								cache/crtsh/raptor_cc24_dev.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								cache/crtsh/raptor_cc24_dev.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -328,41 +328,6 @@ input[type="text"]:focus, select:focus {
 | 
			
		||||
    min-height: 500px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.view-controls {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    gap: 1.5rem;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-group {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-group label {
 | 
			
		||||
    font-size: 0.9rem;
 | 
			
		||||
    color: #999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-group select,
 | 
			
		||||
.filter-group input[type="range"] {
 | 
			
		||||
    background-color: #1a1a1a;
 | 
			
		||||
    border: 1px solid #555;
 | 
			
		||||
    color: #c7c7c7;
 | 
			
		||||
    padding: 0.25rem 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-group select {
 | 
			
		||||
    max-width: 150px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#confidence-value {
 | 
			
		||||
    min-width: 30px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    color: #00ff41;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-container {
 | 
			
		||||
    height: 800px;
 | 
			
		||||
    position: relative;
 | 
			
		||||
@ -397,6 +362,79 @@ input[type="text"]:focus, select:focus {
 | 
			
		||||
    background: rgba(42, 42, 42, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graph-filter-panel {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    bottom: 10px;
 | 
			
		||||
    left: 10px;
 | 
			
		||||
    z-index: 10;
 | 
			
		||||
    background: rgba(42, 42, 42, 0.9);
 | 
			
		||||
    border: 1px solid #555;
 | 
			
		||||
    color: #c7c7c7;
 | 
			
		||||
    padding: 0.75rem;
 | 
			
		||||
    font-family: 'Roboto Mono', monospace;
 | 
			
		||||
    font-size: 0.8rem;
 | 
			
		||||
    max-height: 40%;
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    gap: 1.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-column {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-column h4 {
 | 
			
		||||
    color: #00ff41;
 | 
			
		||||
    margin-bottom: 0.5rem;
 | 
			
		||||
    font-size: 0.9rem;
 | 
			
		||||
    border-bottom: 1px solid #444;
 | 
			
		||||
    padding-bottom: 0.25rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-column .checkbox-group {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 0.25rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-column label {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 0.5rem;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    transition: color 0.2s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-column label:hover {
 | 
			
		||||
    color: #00ff41;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-column input[type="checkbox"] {
 | 
			
		||||
    appearance: none;
 | 
			
		||||
    width: 12px;
 | 
			
		||||
    height: 12px;
 | 
			
		||||
    border: 1px solid #555;
 | 
			
		||||
    background-color: #1a1a1a;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-column input[type="checkbox"]:checked {
 | 
			
		||||
    background-color: #00ff41;
 | 
			
		||||
    border-color: #00ff41;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-column input[type="checkbox"]:checked::after {
 | 
			
		||||
    content: '✓';
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: -3px;
 | 
			
		||||
    left: 1px;
 | 
			
		||||
    color: #1a1a1a;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.graph-context-menu {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    z-index: 1000;
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ class GraphManager {
 | 
			
		||||
        this.nodeInfoPopup = null;
 | 
			
		||||
        this.contextMenu = null;
 | 
			
		||||
        this.history = [];
 | 
			
		||||
        this.filterPanel = null;
 | 
			
		||||
 | 
			
		||||
        this.options = {
 | 
			
		||||
            nodes: {
 | 
			
		||||
@ -177,6 +178,8 @@ class GraphManager {
 | 
			
		||||
 | 
			
		||||
            // Add graph controls
 | 
			
		||||
            this.addGraphControls();
 | 
			
		||||
            this.addFilterPanel();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            console.log('Graph initialized successfully');
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
@ -209,6 +212,12 @@ class GraphManager {
 | 
			
		||||
        document.getElementById('graph-revert').addEventListener('click', () => this.revertLastAction());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    addFilterPanel() {
 | 
			
		||||
        this.filterPanel = document.createElement('div');
 | 
			
		||||
        this.filterPanel.className = 'graph-filter-panel';
 | 
			
		||||
        this.container.appendChild(this.filterPanel);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Setup network event handlers
 | 
			
		||||
     */
 | 
			
		||||
@ -354,6 +363,10 @@ class GraphManager {
 | 
			
		||||
            this.nodes.update(processedNodes);
 | 
			
		||||
            this.edges.update(processedEdges);
 | 
			
		||||
 | 
			
		||||
            this.updateFilterControls();
 | 
			
		||||
            this.applyAllFilters();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // Highlight new additions briefly
 | 
			
		||||
            if (newNodes.length > 0 || newEdges.length > 0) {
 | 
			
		||||
                setTimeout(() => this.highlightNewElements(newNodes, newEdges), 100);
 | 
			
		||||
@ -922,48 +935,73 @@ class GraphManager {
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Apply filters to the graph
 | 
			
		||||
     * @param {string} nodeType - The type of node to show ('all' for no filter)
 | 
			
		||||
     * @param {number} minConfidence - The minimum confidence score for edges to be visible
 | 
			
		||||
     */
 | 
			
		||||
    applyFilters(nodeType, minConfidence) {
 | 
			
		||||
        console.log(`Applying filters: nodeType=${nodeType}, minConfidence=${minConfidence}`);
 | 
			
		||||
    updateFilterControls() {
 | 
			
		||||
        if (!this.filterPanel) return;
 | 
			
		||||
 | 
			
		||||
        const nodeTypes = new Set(this.nodes.get().map(n => n.type));
 | 
			
		||||
        const edgeTypes = new Set(this.edges.get().map(e => e.metadata.relationship_type));
 | 
			
		||||
 | 
			
		||||
        let nodeCheckboxes = '<div class="filter-column"><h4>Nodes</h4><div class="checkbox-group">';
 | 
			
		||||
        nodeTypes.forEach(type => {
 | 
			
		||||
            const label = type === 'correlation_object' ? 'latent correlations' : type;
 | 
			
		||||
            const isChecked = type !== 'correlation_object';
 | 
			
		||||
            nodeCheckboxes += `<label><input type="checkbox" data-filter-type="node" value="${type}" ${isChecked ? 'checked' : ''}> ${label}</label>`;
 | 
			
		||||
        });
 | 
			
		||||
        nodeCheckboxes += '</div></div>';
 | 
			
		||||
 | 
			
		||||
        let edgeCheckboxes = '<div class="filter-column"><h4>Edges</h4><div class="checkbox-group">';
 | 
			
		||||
        edgeTypes.forEach(type => {
 | 
			
		||||
            edgeCheckboxes += `<label><input type="checkbox" data-filter-type="edge" value="${type}" checked> ${type}</label>`;
 | 
			
		||||
        });
 | 
			
		||||
        edgeCheckboxes += '</div></div>';
 | 
			
		||||
 | 
			
		||||
        this.filterPanel.innerHTML = nodeCheckboxes + edgeCheckboxes;
 | 
			
		||||
 | 
			
		||||
        this.filterPanel.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
 | 
			
		||||
            checkbox.addEventListener('change', () => this.applyAllFilters());
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    applyAllFilters() {
 | 
			
		||||
        const hiddenNodeTypes = new Set();
 | 
			
		||||
        this.filterPanel.querySelectorAll('input[data-filter-type="node"]:not(:checked)').forEach(cb => {
 | 
			
		||||
            hiddenNodeTypes.add(cb.value);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        const hiddenEdgeTypes = new Set();
 | 
			
		||||
        this.filterPanel.querySelectorAll('input[data-filter-type="edge"]:not(:checked)').forEach(cb => {
 | 
			
		||||
            hiddenEdgeTypes.add(cb.value);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        const nodeUpdates = [];
 | 
			
		||||
        const edgeUpdates = [];
 | 
			
		||||
        const visibleEdges = new Set();
 | 
			
		||||
 | 
			
		||||
        const allNodes = this.nodes.get({ returnType: 'Object' });
 | 
			
		||||
        const allEdges = this.edges.get();
 | 
			
		||||
 | 
			
		||||
        // Determine which nodes are visible based on the nodeType filter
 | 
			
		||||
        for (const nodeId in allNodes) {
 | 
			
		||||
            const node = allNodes[nodeId];
 | 
			
		||||
            const isVisible = (nodeType === 'all' || node.type === nodeType);
 | 
			
		||||
            nodeUpdates.push({ id: nodeId, hidden: !isVisible });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Update nodes first to determine edge visibility
 | 
			
		||||
        this.nodes.update(nodeUpdates);
 | 
			
		||||
 | 
			
		||||
        // Determine which edges are visible based on confidence and connected nodes
 | 
			
		||||
        for (const edge of allEdges) {
 | 
			
		||||
            const sourceNode = this.nodes.get(edge.from);
 | 
			
		||||
            const targetNode = this.nodes.get(edge.to);
 | 
			
		||||
            const confidence = edge.metadata ? edge.metadata.confidence_score : 0;
 | 
			
		||||
 | 
			
		||||
            const isVisible = confidence >= minConfidence &&
 | 
			
		||||
                              sourceNode && !sourceNode.hidden &&
 | 
			
		||||
                              targetNode && !targetNode.hidden;
 | 
			
		||||
            
 | 
			
		||||
        this.edges.get().forEach(edge => {
 | 
			
		||||
            const isVisible = !hiddenEdgeTypes.has(edge.metadata.relationship_type);
 | 
			
		||||
            edgeUpdates.push({ id: edge.id, hidden: !isVisible });
 | 
			
		||||
            if (isVisible) {
 | 
			
		||||
                visibleEdges.add(edge.id);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.nodes.get().forEach(node => {
 | 
			
		||||
            let isVisible = !hiddenNodeTypes.has(node.type);
 | 
			
		||||
            if (isVisible) {
 | 
			
		||||
                const connectedEdges = this.network.getConnectedEdges(node.id);
 | 
			
		||||
                const hasVisibleConnection = connectedEdges.some(edgeId => visibleEdges.has(edgeId));
 | 
			
		||||
                if (!hasVisibleConnection && connectedEdges.length > 0) {
 | 
			
		||||
                    isVisible = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            nodeUpdates.push({ id: node.id, hidden: !isVisible });
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        this.edges.update(edgeUpdates);
 | 
			
		||||
 | 
			
		||||
        console.log('Filters applied.');
 | 
			
		||||
        this.nodes.update(nodeUpdates);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Show context menu for a node
 | 
			
		||||
     * @param {string} nodeId - The ID of the node
 | 
			
		||||
 | 
			
		||||
@ -83,11 +83,6 @@ class DNSReconApp {
 | 
			
		||||
            // Other elements
 | 
			
		||||
            sessionId: document.getElementById('session-id'),
 | 
			
		||||
            connectionStatus: document.getElementById('connection-status'),
 | 
			
		||||
            
 | 
			
		||||
            // Filter elements
 | 
			
		||||
            nodeTypeFilter: document.getElementById('node-type-filter'),
 | 
			
		||||
            confidenceFilter: document.getElementById('confidence-filter'),
 | 
			
		||||
            confidenceValue: document.getElementById('confidence-value')
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Verify critical elements exist
 | 
			
		||||
@ -211,13 +206,6 @@ class DNSReconApp {
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
             // Filter events
 | 
			
		||||
            this.elements.nodeTypeFilter.addEventListener('change', () => this.applyFilters());
 | 
			
		||||
            this.elements.confidenceFilter.addEventListener('input', () => {
 | 
			
		||||
                this.elements.confidenceValue.textContent = this.elements.confidenceFilter.value;
 | 
			
		||||
                this.applyFilters();
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            console.log('Event handlers set up successfully');
 | 
			
		||||
            
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
@ -1043,18 +1031,6 @@ class DNSReconApp {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Apply graph filters
 | 
			
		||||
     */
 | 
			
		||||
    applyFilters() {
 | 
			
		||||
        if (this.graphManager) {
 | 
			
		||||
            const nodeType = this.elements.nodeTypeFilter.value;
 | 
			
		||||
            const minConfidence = parseFloat(this.elements.confidenceFilter.value);
 | 
			
		||||
            this.graphManager.applyFilters(nodeType, minConfidence);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if graph data has changed
 | 
			
		||||
     * @param {Object} graphData - New graph data
 | 
			
		||||
 | 
			
		||||
@ -110,24 +110,6 @@
 | 
			
		||||
            <section class="visualization-panel">
 | 
			
		||||
                <div class="panel-header">
 | 
			
		||||
                    <h2>Infrastructure Map</h2>
 | 
			
		||||
                    <div class="view-controls">
 | 
			
		||||
                        <div class="filter-group">
 | 
			
		||||
                            <label for="node-type-filter">Node Type:</label>
 | 
			
		||||
                            <select id="node-type-filter">
 | 
			
		||||
                                <option value="all">All</option>
 | 
			
		||||
                                <option value="domain">Domain</option>
 | 
			
		||||
                                <option value="ip">IP</option>
 | 
			
		||||
                                <option value="asn">ASN</option>
 | 
			
		||||
                                <option value="correlation_object">Correlation Object</option>
 | 
			
		||||
                                <option value="large_entity">Large Entity</option>
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="filter-group">
 | 
			
		||||
                            <label for="confidence-filter">Min Confidence:</label>
 | 
			
		||||
                            <input type="range" id="confidence-filter" min="0" max="1" step="0.1" value="0">
 | 
			
		||||
                            <span id="confidence-value">0</span>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                
 | 
			
		||||
                <div id="network-graph" class="graph-container">
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user