iterating on fixes
This commit is contained in:
@@ -377,6 +377,21 @@ class GraphManager {
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
// Check if we have actual data to display
|
||||
const hasData = graphData.nodes.length > 0 || graphData.edges.length > 0;
|
||||
|
||||
// Handle placeholder visibility
|
||||
const placeholder = this.container.querySelector('.graph-placeholder');
|
||||
if (placeholder) {
|
||||
if (hasData) {
|
||||
placeholder.style.display = 'none';
|
||||
} else {
|
||||
placeholder.style.display = 'flex';
|
||||
// Early return if no data to process
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.largeEntityMembers.clear();
|
||||
const largeEntityMap = new Map();
|
||||
|
||||
@@ -398,11 +413,11 @@ class GraphManager {
|
||||
|
||||
console.log(`Filtered ${graphData.nodes.length - filteredNodes.length} large entity member nodes from visualization`);
|
||||
|
||||
// FIXED: Process nodes with proper certificate coloring
|
||||
// Process nodes with proper certificate coloring
|
||||
const processedNodes = filteredNodes.map(node => {
|
||||
const processed = this.processNode(node);
|
||||
|
||||
// FIXED: Apply certificate-based coloring here in frontend
|
||||
// Apply certificate-based coloring here in frontend
|
||||
if (node.type === 'domain' && Array.isArray(node.attributes)) {
|
||||
const certInfo = this.analyzeCertificateInfo(node.attributes);
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ class DNSReconApp {
|
||||
this.loadProviders();
|
||||
this.initializeEnhancedModals();
|
||||
|
||||
// FIXED: Force initial graph update to handle empty sessions properly
|
||||
this.updateGraph();
|
||||
|
||||
console.log('DNSRecon application initialized successfully');
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize DNSRecon application:', error);
|
||||
@@ -42,7 +45,7 @@ class DNSReconApp {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize DOM element references
|
||||
*/
|
||||
@@ -484,9 +487,8 @@ class DNSReconApp {
|
||||
console.log('- Nodes:', graphData.nodes ? graphData.nodes.length : 0);
|
||||
console.log('- Edges:', graphData.edges ? graphData.edges.length : 0);
|
||||
|
||||
// Only update if data has changed
|
||||
if (this.hasGraphChanged(graphData)) {
|
||||
console.log('*** GRAPH DATA CHANGED - UPDATING VISUALIZATION ***');
|
||||
// FIXED: Always update graph, even if empty - let GraphManager handle placeholder
|
||||
if (this.graphManager) {
|
||||
this.graphManager.updateGraph(graphData);
|
||||
this.lastGraphUpdate = Date.now();
|
||||
|
||||
@@ -495,18 +497,30 @@ class DNSReconApp {
|
||||
if (this.elements.relationshipsDisplay) {
|
||||
this.elements.relationshipsDisplay.textContent = edgeCount;
|
||||
}
|
||||
} else {
|
||||
console.log('Graph data unchanged, skipping update');
|
||||
}
|
||||
} else {
|
||||
console.error('Graph update failed:', response);
|
||||
// FIXED: Show placeholder when graph update fails
|
||||
if (this.graphManager && this.graphManager.container) {
|
||||
const placeholder = this.graphManager.container.querySelector('.graph-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to update graph:', error);
|
||||
// Don't show error for graph updates to avoid spam
|
||||
// FIXED: Show placeholder on error
|
||||
if (this.graphManager && this.graphManager.container) {
|
||||
const placeholder = this.graphManager.container.querySelector('.graph-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update status display elements
|
||||
@@ -925,18 +939,32 @@ class DNSReconApp {
|
||||
return 'Empty Array';
|
||||
}
|
||||
|
||||
// Special handling for DNS records and similar arrays
|
||||
if (name === 'dns_records' || name.includes('record') || name.includes('hostname')) {
|
||||
// Show DNS records as a readable list
|
||||
// ENHANCED: Special handling for specific DNS record types
|
||||
if (name.endsWith('_records') || name.includes('record')) {
|
||||
const recordType = name.replace('_records', '').toUpperCase();
|
||||
|
||||
// Format nicely for DNS records
|
||||
if (value.length <= 5) {
|
||||
return this.escapeHtml(value.join(', '));
|
||||
const formattedRecords = value.map(record => {
|
||||
// Add record type prefix if not already present
|
||||
if (recordType !== 'DNS' && !record.includes(':')) {
|
||||
return `${recordType}: ${record}`;
|
||||
}
|
||||
return record;
|
||||
});
|
||||
return this.escapeHtml(formattedRecords.join('\n'));
|
||||
} else {
|
||||
const preview = value.slice(0, 3).join(', ');
|
||||
return this.escapeHtml(`${preview} ... (+${value.length - 3} more)`);
|
||||
const preview = value.slice(0, 3).map(record => {
|
||||
if (recordType !== 'DNS' && !record.includes(':')) {
|
||||
return `${recordType}: ${record}`;
|
||||
}
|
||||
return record;
|
||||
}).join('\n');
|
||||
return this.escapeHtml(`${preview}\n... (+${value.length - 3} more ${recordType} records)`);
|
||||
}
|
||||
}
|
||||
|
||||
// For other arrays
|
||||
// For other arrays (existing logic)
|
||||
if (value.length <= 3) {
|
||||
return this.escapeHtml(value.join(', '));
|
||||
} else {
|
||||
@@ -953,6 +981,10 @@ class DNSReconApp {
|
||||
}
|
||||
|
||||
groupAttributesByProviderAndType(attributes, nodeType) {
|
||||
if (!Array.isArray(attributes) || attributes.length === 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const groups = {
|
||||
'DNS Records': { icon: '📋', priority: 'high', attributes: [] },
|
||||
'Certificate Information': { icon: '🔒', priority: 'high', attributes: [] },
|
||||
@@ -968,11 +1000,11 @@ class DNSReconApp {
|
||||
|
||||
let assigned = false;
|
||||
|
||||
// DNS-related attributes (better detection)
|
||||
// ENHANCED: Better DNS record detection for specific record types
|
||||
if (provider === 'dns' ||
|
||||
name === 'dns_records' ||
|
||||
name.endsWith('_records') || // Catches a_records, mx_records, txt_records, etc.
|
||||
name.includes('record') ||
|
||||
['ptr', 'mx', 'cname', 'ns', 'txt', 'soa'].some(keyword => name.includes(keyword))) {
|
||||
['ptr', 'mx', 'cname', 'ns', 'txt', 'soa', 'srv', 'caa', 'a_records', 'aaaa_records'].some(keyword => name.includes(keyword))) {
|
||||
groups['DNS Records'].attributes.push(attr);
|
||||
assigned = true;
|
||||
}
|
||||
@@ -1013,7 +1045,6 @@ class DNSReconApp {
|
||||
formatEdgeLabel(relationshipType, confidence) {
|
||||
if (!relationshipType) return '';
|
||||
|
||||
// UPDATED: No formatting of relationship type - use raw values
|
||||
const confidenceText = confidence >= 0.8 ? '●' : confidence >= 0.6 ? '◐' : '○';
|
||||
return `${relationshipType} ${confidenceText}`;
|
||||
}
|
||||
@@ -1695,13 +1726,18 @@ class DNSReconApp {
|
||||
const newNodeCount = graphData.nodes ? graphData.nodes.length : 0;
|
||||
const newEdgeCount = graphData.edges ? graphData.edges.length : 0;
|
||||
|
||||
// FIXED: Always update if we currently have no data (ensures placeholder is handled correctly)
|
||||
if (currentStats.nodeCount === 0 && currentStats.edgeCount === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if counts changed
|
||||
const countsChanged = currentStats.nodeCount !== newNodeCount || currentStats.edgeCount !== newEdgeCount;
|
||||
|
||||
// Also check if we have new timestamp data
|
||||
const hasNewTimestamp = graphData.statistics &&
|
||||
graphData.statistics.last_modified &&
|
||||
graphData.statistics.last_modified !== this.lastGraphTimestamp;
|
||||
graphData.statistics.last_modified &&
|
||||
graphData.statistics.last_modified !== this.lastGraphTimestamp;
|
||||
|
||||
if (hasNewTimestamp) {
|
||||
this.lastGraphTimestamp = graphData.statistics.last_modified;
|
||||
@@ -1713,7 +1749,7 @@ class DNSReconApp {
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make API call to server
|
||||
* @param {string} endpoint - API endpoint
|
||||
|
||||
Reference in New Issue
Block a user