it
This commit is contained in:
@@ -724,29 +724,82 @@ class DNSReconApp {
|
||||
*/
|
||||
showNodeModal(nodeId, node) {
|
||||
if (!this.elements.nodeModal) return;
|
||||
|
||||
|
||||
if (this.elements.modalTitle) {
|
||||
this.elements.modalTitle.textContent = `Node Details: ${nodeId}`;
|
||||
}
|
||||
|
||||
|
||||
let detailsHtml = '';
|
||||
detailsHtml += `<div class="detail-row"><span class="detail-label">Identifier:</span><span class="detail-value">${nodeId}</span></div>`;
|
||||
detailsHtml += `<div class="detail-row"><span class="detail-label">Type:</span><span class="detail-value">${node.metadata.type || node.type || 'Unknown'}</span></div>`;
|
||||
|
||||
if (node.metadata) {
|
||||
for (const [key, value] of Object.entries(node.metadata)) {
|
||||
if (key !== 'type') {
|
||||
detailsHtml += `<div class="detail-row"><span class="detail-label">${this.formatLabel(key)}:</span><span class="detail-value">${this.formatValue(value)}</span></div>`;
|
||||
}
|
||||
const createDetailRow = (label, value) => {
|
||||
const baseId = `detail-${label.replace(/[^a-zA-Z0-9]/g, '-')}`;
|
||||
|
||||
// Handle empty or undefined values by showing N/A
|
||||
if (value === null || value === undefined || (Array.isArray(value) && value.length === 0)) {
|
||||
return `
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">${label} <span class="status-icon text-warning">✗</span></span>
|
||||
<span class="detail-value">N/A</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// If value is an array, create a row for each item
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item, index) => {
|
||||
const itemId = `${baseId}-${index}`;
|
||||
// Only show the label for the first item in the list
|
||||
const itemLabel = index === 0 ? label : '';
|
||||
return `
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">${itemLabel}</span>
|
||||
<span class="detail-value" id="${itemId}">${this.formatValue(item)}</span>
|
||||
<button class="copy-btn" onclick="copyToClipboard('${itemId}')" title="Copy">📋</button>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
// Handle objects and other primitive values in a single row
|
||||
else {
|
||||
const valueId = `${baseId}-0`;
|
||||
return `
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">${label} <span class="status-icon text-success">✓</span></span>
|
||||
<span class="detail-value" id="${valueId}">${this.formatValue(value)}</span>
|
||||
<button class="copy-btn" onclick="copyToClipboard('${valueId}')" title="Copy">📋</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
const metadata = node.metadata || {};
|
||||
|
||||
switch (node.type) {
|
||||
case 'domain':
|
||||
detailsHtml += createDetailRow('DNS Records', metadata.dns_records);
|
||||
detailsHtml += createDetailRow('Related Domains (SAN)', metadata.related_domains_san);
|
||||
detailsHtml += createDetailRow('Shodan Data', metadata.shodan);
|
||||
detailsHtml += createDetailRow('VirusTotal Data', metadata.virustotal);
|
||||
break;
|
||||
case 'ip':
|
||||
detailsHtml += createDetailRow('DNS Records', metadata.dns_records);
|
||||
detailsHtml += createDetailRow('Shodan Data', metadata.shodan);
|
||||
detailsHtml += createDetailRow('VirusTotal Data', metadata.virustotal);
|
||||
break;
|
||||
case 'certificate':
|
||||
detailsHtml += createDetailRow('Certificate Hash', metadata.hash);
|
||||
detailsHtml += createDetailRow('SANs', metadata.sans);
|
||||
detailsHtml += createDetailRow('Issuer', metadata.issuer);
|
||||
detailsHtml += createDetailRow('Validity', `From: ${metadata.not_before || 'N/A'} To: ${metadata.not_after || 'N/A'}`);
|
||||
break;
|
||||
case 'asn':
|
||||
detailsHtml += createDetailRow('ASN', metadata.asn);
|
||||
detailsHtml += createDetailRow('Description', metadata.description);
|
||||
break;
|
||||
case 'large_entity':
|
||||
detailsHtml += createDetailRow('Discovered Domains', metadata.domains);
|
||||
break;
|
||||
}
|
||||
|
||||
// Add timestamps if available
|
||||
if (node.added_timestamp) {
|
||||
const addedDate = new Date(node.added_timestamp);
|
||||
detailsHtml += `<div class="detail-row"><span class="detail-label">Added:</span><span class="detail-value">${addedDate.toLocaleString()}</span></div>`;
|
||||
}
|
||||
|
||||
|
||||
if (this.elements.modalDetails) {
|
||||
this.elements.modalDetails.innerHTML = detailsHtml;
|
||||
}
|
||||
@@ -982,12 +1035,13 @@ class DNSReconApp {
|
||||
* @returns {string} Formatted value
|
||||
*/
|
||||
formatValue(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(', ');
|
||||
} else if (typeof value === 'object') {
|
||||
return JSON.stringify(value, null, 2);
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
// Use <pre> for nicely formatted JSON
|
||||
return `<pre>${JSON.stringify(value, null, 2)}</pre>`;
|
||||
} else {
|
||||
return String(value);
|
||||
// Escape HTML to prevent XSS issues with string values
|
||||
const strValue = String(value);
|
||||
return strValue.replace(/</g, "<").replace(/>/g, ">");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user