node src dest display

This commit is contained in:
overcuriousity 2025-09-13 21:17:04 +02:00
parent 2974312278
commit 41d556e2ce
3 changed files with 63 additions and 24 deletions

View File

@ -282,6 +282,12 @@ class GraphManager:
attributes = node_data['attributes'] attributes = node_data['attributes']
if node_type == 'domain' and attributes.get('certificates', {}).get('has_valid_cert') is False: 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 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) nodes.append(node_data)
edges = [] edges = []

View File

@ -196,9 +196,12 @@ class GraphManager {
if (this.network.isCluster(nodeId)) { if (this.network.isCluster(nodeId)) {
this.network.openCluster(nodeId); this.network.openCluster(nodeId);
} else { } else {
this.showNodeDetails(nodeId); const node = this.nodes.get(nodeId);
if (node) {
this.showNodeDetails(node);
this.highlightNodeConnections(nodeId); this.highlightNodeConnections(nodeId);
} }
}
} else { } else {
this.clearHighlights(); this.clearHighlights();
} }
@ -346,7 +349,9 @@ class GraphManager {
attributes: node.attributes || {}, attributes: node.attributes || {},
description: node.description || '', description: node.description || '',
metadata: node.metadata || {}, metadata: node.metadata || {},
type: node.type type: node.type,
incoming_edges: node.incoming_edges || [],
outgoing_edges: node.outgoing_edges || []
}; };
// Add confidence-based styling // Add confidence-based styling
@ -556,12 +561,9 @@ class GraphManager {
/** /**
* Show node details in modal * Show node details in modal
* @param {string} nodeId - Node identifier * @param {Object} node - Node object
*/ */
showNodeDetails(nodeId) { showNodeDetails(node) {
const node = this.nodes.get(nodeId);
if (!node) return;
// Trigger custom event for main application to handle // Trigger custom event for main application to handle
const event = new CustomEvent('nodeSelected', { const event = new CustomEvent('nodeSelected', {
detail: { node } detail: { node }

View File

@ -793,7 +793,7 @@ 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. * @param {Object} node - The node object.
* @returns {string} The HTML string for the node details. * @returns {string} The HTML string for the node details.
*/ */
@ -802,6 +802,28 @@ class DNSReconApp {
let detailsHtml = '<div class="modal-details-grid">'; let detailsHtml = '<div class="modal-details-grid">';
// Section for Incoming Edges (Source Nodes)
if (node.incoming_edges && node.incoming_edges.length > 0) {
detailsHtml += '<div class="modal-section">';
detailsHtml += '<h4>Source Nodes (Incoming)</h4>';
detailsHtml += '<ul>';
node.incoming_edges.forEach(edge => {
detailsHtml += `<li><a href="#" class="node-link" data-node-id="${edge.from}">${edge.from}</a> (${edge.data.relationship_type})</li>`;
});
detailsHtml += '</ul></div>';
}
// Section for Outgoing Edges (Destination Nodes)
if (node.outgoing_edges && node.outgoing_edges.length > 0) {
detailsHtml += '<div class="modal-section">';
detailsHtml += '<h4>Destination Nodes (Outgoing)</h4>';
detailsHtml += '<ul>';
node.outgoing_edges.forEach(edge => {
detailsHtml += `<li><a href="#" class="node-link" data-node-id="${edge.to}">${edge.to}</a> (${edge.data.relationship_type})</li>`;
});
detailsHtml += '</ul></div>';
}
// Section for Attributes // Section for Attributes
detailsHtml += '<div class="modal-section">'; detailsHtml += '<div class="modal-section">';
detailsHtml += '<h4>Attributes</h4>'; detailsHtml += '<h4>Attributes</h4>';
@ -825,7 +847,7 @@ class DNSReconApp {
} }
/** /**
* 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. * @param {Object} obj - The object to format.
* @returns {string} - An HTML string representing the object. * @returns {string} - An HTML string representing the object.
*/ */
@ -839,16 +861,14 @@ class DNSReconApp {
if (Object.hasOwnProperty.call(obj, key)) { if (Object.hasOwnProperty.call(obj, key)) {
const value = obj[key]; const value = obj[key];
const formattedKey = key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); const formattedKey = key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
html += `<li><strong>${formattedKey}:</strong>`;
if (Array.isArray(value)) { if (typeof value === 'object' && value !== null) {
html += `<ul>${value.map(item => `<li>${this.formatValue(item)}</li>`).join('')}</ul>`; html += `<li><details><summary><strong>${formattedKey}</strong></summary>`;
} else if (typeof value === 'object' && value !== null) {
html += this.formatObjectToHtml(value); html += this.formatObjectToHtml(value);
html += `</details></li>`;
} else { } else {
html += ` ${this.formatValue(value)}`; html += `<li><strong>${formattedKey}:</strong> ${this.formatValue(value)}</li>`;
} }
html += '</li>';
} }
} }
html += '</ul>'; html += '</ul>';
@ -889,6 +909,17 @@ class DNSReconApp {
if (this.elements.modalDetails) { if (this.elements.modalDetails) {
this.elements.modalDetails.innerHTML = detailsHtml; 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'; this.elements.nodeModal.style.display = 'block';
} }