node src dest display
This commit is contained in:
parent
2974312278
commit
41d556e2ce
@ -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 = []
|
||||||
|
@ -196,8 +196,11 @@ 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);
|
||||||
this.highlightNodeConnections(nodeId);
|
if (node) {
|
||||||
|
this.showNodeDetails(node);
|
||||||
|
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 }
|
||||||
|
@ -793,15 +793,37 @@ 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.
|
||||||
*/
|
*/
|
||||||
generateNodeDetailsHtml(node) {
|
generateNodeDetailsHtml(node) {
|
||||||
if(!node) return '<div class="detail-row"><span class="detail-value">Details not available.</span></div>';
|
if (!node) return '<div class="detail-row"><span class="detail-value">Details not available.</span></div>';
|
||||||
|
|
||||||
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';
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user