From 41d556e2ce335889bec00446e4cccda2131f35b4 Mon Sep 17 00:00:00 2001 From: overcuriousity Date: Sat, 13 Sep 2025 21:17:04 +0200 Subject: [PATCH] node src dest display --- core/graph_manager.py | 6 +++++ static/js/graph.js | 18 +++++++------ static/js/main.js | 63 ++++++++++++++++++++++++++++++++----------- 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/core/graph_manager.py b/core/graph_manager.py index 03d769d..8d4e743 100644 --- a/core/graph_manager.py +++ b/core/graph_manager.py @@ -282,6 +282,12 @@ class GraphManager: attributes = node_data['attributes'] if node_type == 'domain' and attributes.get('certificates', {}).get('has_valid_cert') is False: node_data['color'] = {'background': '#c7c7c7', 'border': '#999'} # Gray for invalid cert + + # Add incoming and outgoing edges to node data + if self.graph.has_node(node_id): + node_data['incoming_edges'] = [{'from': u, 'data': d} for u, _, d in self.graph.in_edges(node_id, data=True)] + node_data['outgoing_edges'] = [{'to': v, 'data': d} for _, v, d in self.graph.out_edges(node_id, data=True)] + nodes.append(node_data) edges = [] diff --git a/static/js/graph.js b/static/js/graph.js index b522a9d..99867f3 100644 --- a/static/js/graph.js +++ b/static/js/graph.js @@ -196,8 +196,11 @@ class GraphManager { if (this.network.isCluster(nodeId)) { this.network.openCluster(nodeId); } else { - this.showNodeDetails(nodeId); - this.highlightNodeConnections(nodeId); + const node = this.nodes.get(nodeId); + if (node) { + this.showNodeDetails(node); + this.highlightNodeConnections(nodeId); + } } } else { this.clearHighlights(); @@ -346,7 +349,9 @@ class GraphManager { attributes: node.attributes || {}, description: node.description || '', metadata: node.metadata || {}, - type: node.type + type: node.type, + incoming_edges: node.incoming_edges || [], + outgoing_edges: node.outgoing_edges || [] }; // Add confidence-based styling @@ -556,12 +561,9 @@ class GraphManager { /** * Show node details in modal - * @param {string} nodeId - Node identifier + * @param {Object} node - Node object */ - showNodeDetails(nodeId) { - const node = this.nodes.get(nodeId); - if (!node) return; - + showNodeDetails(node) { // Trigger custom event for main application to handle const event = new CustomEvent('nodeSelected', { detail: { node } diff --git a/static/js/main.js b/static/js/main.js index a498df4..27f0095 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -635,7 +635,7 @@ class DNSReconApp { break; } } - + /** * Update connection status indicator * @param {string} status - Connection status @@ -793,39 +793,61 @@ class DNSReconApp { } /** - * **FIX**: Generates the HTML for the node details view using the new data model. + * Generates the HTML for the node details view using the new data model. * @param {Object} node - The node object. * @returns {string} The HTML string for the node details. */ generateNodeDetailsHtml(node) { - if(!node) return '
Details not available.
'; - + if (!node) return '
Details not available.
'; + let detailsHtml = ''; return detailsHtml; } /** - * Recursively formats a JavaScript object into an HTML unordered list. + * Recursively formats a JavaScript object into an HTML unordered list with collapsible sections. * @param {Object} obj - The object to format. * @returns {string} - An HTML string representing the object. */ @@ -833,22 +855,20 @@ class DNSReconApp { if (!obj || Object.keys(obj).length === 0) { return '

No data available.

'; } - + let html = ''; @@ -889,6 +909,17 @@ class DNSReconApp { if (this.elements.modalDetails) { this.elements.modalDetails.innerHTML = detailsHtml; + this.elements.modalDetails.querySelectorAll('.node-link').forEach(link => { + link.addEventListener('click', (e) => { + e.preventDefault(); + const nodeId = e.target.dataset.nodeId; + const nextNode = this.graphManager.nodes.get(nodeId); + if (nextNode) { + this.hideModal(); + this.showNodeModal(nextNode); + } + }); + }); } this.elements.nodeModal.style.display = 'block'; }