progress
This commit is contained in:
107
static/script.js
107
static/script.js
@@ -1,4 +1,4 @@
|
||||
// DNS Reconnaissance Tool - Enhanced Frontend JavaScript with Real-time Updates
|
||||
// DNS Reconnaissance Tool - Enhanced Frontend JavaScript with Debug Output
|
||||
|
||||
class ReconTool {
|
||||
constructor() {
|
||||
@@ -6,9 +6,20 @@ class ReconTool {
|
||||
this.pollInterval = null;
|
||||
this.liveDataInterval = null;
|
||||
this.currentReport = null;
|
||||
this.debugMode = true; // Enable debug logging
|
||||
this.init();
|
||||
}
|
||||
|
||||
debug(message, data = null) {
|
||||
if (this.debugMode) {
|
||||
if (data) {
|
||||
console.log(`🔍 DEBUG: ${message}`, data);
|
||||
} else {
|
||||
console.log(`🔍 DEBUG: ${message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
this.bindEvents();
|
||||
this.setupRealtimeElements();
|
||||
@@ -67,6 +78,7 @@ class ReconTool {
|
||||
</div>
|
||||
`;
|
||||
progressSection.appendChild(liveDiv);
|
||||
this.debug("Live discoveries container created");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +139,7 @@ class ReconTool {
|
||||
this.showProgressSection();
|
||||
this.updateProgress(0, 'Starting scan...');
|
||||
|
||||
console.log('🚀 Starting scan with data:', scanData);
|
||||
this.debug('Starting scan with data:', scanData);
|
||||
|
||||
const response = await fetch('/api/scan', {
|
||||
method: 'POST',
|
||||
@@ -148,7 +160,7 @@ class ReconTool {
|
||||
}
|
||||
|
||||
this.currentScanId = result.scan_id;
|
||||
console.log('✅ Scan started with ID:', this.currentScanId);
|
||||
this.debug('Scan started with ID:', this.currentScanId);
|
||||
|
||||
this.startPolling();
|
||||
this.startLiveDataPolling();
|
||||
@@ -160,6 +172,7 @@ class ReconTool {
|
||||
}
|
||||
|
||||
startPolling() {
|
||||
this.debug('Starting status polling...');
|
||||
// Poll every 2 seconds for status updates
|
||||
this.pollInterval = setInterval(() => {
|
||||
this.checkScanStatus();
|
||||
@@ -170,6 +183,7 @@ class ReconTool {
|
||||
}
|
||||
|
||||
startLiveDataPolling() {
|
||||
this.debug('Starting live data polling...');
|
||||
// Poll every 3 seconds for live data updates
|
||||
this.liveDataInterval = setInterval(() => {
|
||||
this.updateLiveData();
|
||||
@@ -179,6 +193,9 @@ class ReconTool {
|
||||
const liveSection = document.querySelector('.live-discoveries');
|
||||
if (liveSection) {
|
||||
liveSection.style.display = 'block';
|
||||
this.debug('Live discoveries section made visible');
|
||||
} else {
|
||||
this.debug('ERROR: Live discoveries section not found!');
|
||||
}
|
||||
|
||||
// Also update immediately
|
||||
@@ -208,12 +225,13 @@ class ReconTool {
|
||||
|
||||
// Update live stats
|
||||
if (status.live_stats) {
|
||||
this.debug('Received live stats:', status.live_stats);
|
||||
this.updateLiveStats(status.live_stats);
|
||||
}
|
||||
|
||||
// Check if completed
|
||||
if (status.status === 'completed') {
|
||||
console.log('✅ Scan completed');
|
||||
this.debug('Scan completed, loading report...');
|
||||
this.stopPolling();
|
||||
await this.loadScanReport();
|
||||
} else if (status.status === 'error') {
|
||||
@@ -233,29 +251,37 @@ class ReconTool {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(`Fetching live data for scan: ${this.currentScanId}`);
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/scan/${this.currentScanId}/live-data`);
|
||||
|
||||
if (!response.ok) {
|
||||
this.debug(`Live data request failed: HTTP ${response.status}`);
|
||||
return; // Silently fail for live data
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.error) {
|
||||
this.debug('Live data error:', data.error);
|
||||
return; // Silently fail for live data
|
||||
}
|
||||
|
||||
this.debug('Received live data:', data);
|
||||
|
||||
// Update live discoveries
|
||||
this.updateLiveDiscoveries(data);
|
||||
|
||||
} catch (error) {
|
||||
// Silently fail for live data updates
|
||||
console.debug('Live data update failed:', error);
|
||||
this.debug('Live data update failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
updateLiveStats(stats) {
|
||||
this.debug('Updating live stats:', stats);
|
||||
|
||||
// Update the live statistics counters
|
||||
const statElements = {
|
||||
'liveHostnames': stats.hostnames || 0,
|
||||
@@ -269,54 +295,69 @@ class ReconTool {
|
||||
Object.entries(statElements).forEach(([elementId, value]) => {
|
||||
const element = document.getElementById(elementId);
|
||||
if (element) {
|
||||
const currentValue = element.textContent;
|
||||
element.textContent = value;
|
||||
|
||||
// Add a brief highlight effect when value changes
|
||||
if (element.textContent !== value.toString()) {
|
||||
if (currentValue !== value.toString()) {
|
||||
this.debug(`Updated ${elementId}: ${currentValue} -> ${value}`);
|
||||
// Add a brief highlight effect when value changes
|
||||
element.style.backgroundColor = '#ff9900';
|
||||
setTimeout(() => {
|
||||
element.style.backgroundColor = '';
|
||||
}, 1000);
|
||||
}
|
||||
} else {
|
||||
this.debug(`ERROR: Element ${elementId} not found!`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateLiveDiscoveries(data) {
|
||||
this.debug('Updating live discoveries with data:', data);
|
||||
|
||||
// Update hostnames list
|
||||
const hostnameList = document.querySelector('#recentHostnames .hostname-list');
|
||||
if (hostnameList && data.hostnames) {
|
||||
if (hostnameList && data.hostnames && data.hostnames.length > 0) {
|
||||
// Show last 10 hostnames
|
||||
const recentHostnames = data.hostnames.slice(-10);
|
||||
hostnameList.innerHTML = recentHostnames.map(hostname =>
|
||||
`<span class="discovery-item">${hostname}</span>`
|
||||
).join('');
|
||||
this.debug(`Updated hostname list with ${recentHostnames.length} items`);
|
||||
} else if (hostnameList) {
|
||||
this.debug(`No hostnames to display (${data.hostnames ? data.hostnames.length : 0} total)`);
|
||||
}
|
||||
|
||||
// Update IP addresses list
|
||||
const ipList = document.querySelector('#recentIPs .ip-list');
|
||||
if (ipList && data.ip_addresses) {
|
||||
if (ipList && data.ip_addresses && data.ip_addresses.length > 0) {
|
||||
// Show last 10 IPs
|
||||
const recentIPs = data.ip_addresses.slice(-10);
|
||||
ipList.innerHTML = recentIPs.map(ip =>
|
||||
`<span class="discovery-item">${ip}</span>`
|
||||
).join('');
|
||||
this.debug(`Updated IP list with ${recentIPs.length} items`);
|
||||
} else if (ipList) {
|
||||
this.debug(`No IPs to display (${data.ip_addresses ? data.ip_addresses.length : 0} total)`);
|
||||
}
|
||||
|
||||
// Update activity log
|
||||
const activityList = document.querySelector('#activityLog .activity-list');
|
||||
if (activityList && data.latest_discoveries) {
|
||||
if (activityList && data.latest_discoveries && data.latest_discoveries.length > 0) {
|
||||
const activities = data.latest_discoveries.slice(-5); // Last 5 activities
|
||||
activityList.innerHTML = activities.map(activity => {
|
||||
const time = new Date(activity.timestamp * 1000).toLocaleTimeString();
|
||||
return `<div class="activity-item">[${time}] ${activity.message}</div>`;
|
||||
}).join('');
|
||||
this.debug(`Updated activity log with ${activities.length} items`);
|
||||
} else if (activityList) {
|
||||
this.debug(`No activities to display (${data.latest_discoveries ? data.latest_discoveries.length : 0} total)`);
|
||||
}
|
||||
}
|
||||
|
||||
async loadScanReport() {
|
||||
try {
|
||||
console.log('📄 Loading scan report...');
|
||||
this.debug('Loading scan report...');
|
||||
const response = await fetch(`/api/scan/${this.currentScanId}/report`);
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -330,7 +371,7 @@ class ReconTool {
|
||||
}
|
||||
|
||||
this.currentReport = report;
|
||||
console.log('✅ Report loaded successfully');
|
||||
this.debug('Report loaded successfully');
|
||||
this.showResultsSection();
|
||||
this.showReport('text'); // Default to text view
|
||||
|
||||
@@ -341,6 +382,7 @@ class ReconTool {
|
||||
}
|
||||
|
||||
stopPolling() {
|
||||
this.debug('Stopping polling intervals...');
|
||||
if (this.pollInterval) {
|
||||
clearInterval(this.pollInterval);
|
||||
this.pollInterval = null;
|
||||
@@ -355,18 +397,34 @@ class ReconTool {
|
||||
document.getElementById('scanForm').style.display = 'none';
|
||||
document.getElementById('progressSection').style.display = 'block';
|
||||
document.getElementById('resultsSection').style.display = 'none';
|
||||
this.debug('Showing progress section');
|
||||
}
|
||||
|
||||
showResultsSection() {
|
||||
document.getElementById('scanForm').style.display = 'none';
|
||||
document.getElementById('progressSection').style.display = 'none';
|
||||
document.getElementById('progressSection').style.display = 'block'; // Keep visible
|
||||
document.getElementById('resultsSection').style.display = 'block';
|
||||
|
||||
// Hide live discoveries in results section
|
||||
// Change the title to show it's the final summary
|
||||
const liveSection = document.querySelector('.live-discoveries');
|
||||
if (liveSection) {
|
||||
liveSection.style.display = 'none';
|
||||
const title = liveSection.querySelector('h3');
|
||||
if (title) {
|
||||
title.textContent = '📊 Final Discovery Summary';
|
||||
}
|
||||
liveSection.style.display = 'block';
|
||||
}
|
||||
|
||||
// Hide just the progress bar and scan controls
|
||||
const progressBar = document.querySelector('.progress-bar');
|
||||
const progressMessage = document.getElementById('progressMessage');
|
||||
const scanControls = document.querySelector('.scan-controls');
|
||||
|
||||
if (progressBar) progressBar.style.display = 'none';
|
||||
if (progressMessage) progressMessage.style.display = 'none';
|
||||
if (scanControls) scanControls.style.display = 'none';
|
||||
|
||||
this.debug('Showing results section with live discoveries');
|
||||
}
|
||||
|
||||
resetToForm() {
|
||||
@@ -378,10 +436,23 @@ class ReconTool {
|
||||
document.getElementById('progressSection').style.display = 'none';
|
||||
document.getElementById('resultsSection').style.display = 'none';
|
||||
|
||||
// Hide live discoveries
|
||||
// Show progress elements again
|
||||
const progressBar = document.querySelector('.progress-bar');
|
||||
const progressMessage = document.getElementById('progressMessage');
|
||||
const scanControls = document.querySelector('.scan-controls');
|
||||
|
||||
if (progressBar) progressBar.style.display = 'block';
|
||||
if (progressMessage) progressMessage.style.display = 'block';
|
||||
if (scanControls) scanControls.style.display = 'block';
|
||||
|
||||
// Hide live discoveries and reset title
|
||||
const liveSection = document.querySelector('.live-discoveries');
|
||||
if (liveSection) {
|
||||
liveSection.style.display = 'none';
|
||||
const title = liveSection.querySelector('h3');
|
||||
if (title) {
|
||||
title.textContent = '🔍 Live Discoveries';
|
||||
}
|
||||
}
|
||||
|
||||
// Clear form
|
||||
@@ -389,6 +460,8 @@ class ReconTool {
|
||||
document.getElementById('shodanKey').value = '';
|
||||
document.getElementById('virustotalKey').value = '';
|
||||
document.getElementById('maxDepth').value = '2';
|
||||
|
||||
this.debug('Reset to form view');
|
||||
}
|
||||
|
||||
updateProgress(percentage, message) {
|
||||
@@ -477,6 +550,6 @@ class ReconTool {
|
||||
|
||||
// Initialize the application when DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log('🌐 DNS Reconnaissance Tool initialized');
|
||||
console.log('🌐 DNS Reconnaissance Tool initialized with debug mode');
|
||||
new ReconTool();
|
||||
});
|
||||
181
static/style.css
181
static/style.css
@@ -211,7 +211,6 @@ header p {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
|
||||
.hostname-list, .ip-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -245,65 +244,7 @@ header p {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Responsive design adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.scan-form, .progress-section, .results-section {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.btn-primary, .btn-secondary {
|
||||
width: 100%;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.results-controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.results-controls button {
|
||||
flex: 1;
|
||||
min-width: 120px;
|
||||
}
|
||||
.stats-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.stat-label, .stat-value {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.hostname-list, .ip-list {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tactical loading spinner */
|
||||
.loading {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 3px solid rgba(199, 199, 199, 0.3);
|
||||
border-radius: 50%;
|
||||
border-top-color: #00ff41; /* Night-vision green spinner */
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
/* Live Discoveries Base Styling */
|
||||
.live-discoveries {
|
||||
background: rgba(0, 20, 0, 0.6);
|
||||
border: 1px solid #00ff41;
|
||||
@@ -319,6 +260,44 @@ header p {
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* Enhanced styling for live discoveries when shown in results view */
|
||||
.results-section .live-discoveries {
|
||||
background: rgba(0, 40, 0, 0.8);
|
||||
border: 2px solid #00ff41;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0 0 10px rgba(0, 255, 65, 0.3);
|
||||
}
|
||||
|
||||
.results-section .live-discoveries h3 {
|
||||
color: #00ff41;
|
||||
text-shadow: 0 0 3px rgba(0, 255, 65, 0.5);
|
||||
}
|
||||
|
||||
/* Ensure the progress section flows nicely when showing both progress and results */
|
||||
.progress-section.with-results {
|
||||
margin-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.results-section.with-live-data {
|
||||
border-top: 1px solid #444;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
/* Better spacing for the combined view */
|
||||
.progress-section + .results-section {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Hide specific progress elements while keeping the section visible */
|
||||
.progress-section .progress-bar.hidden,
|
||||
.progress-section #progressMessage.hidden,
|
||||
.progress-section .scan-controls.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
@@ -348,6 +327,16 @@ header p {
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
/* Animation for final stats highlight */
|
||||
@keyframes finalHighlight {
|
||||
0% { background-color: #ff9900; }
|
||||
100% { background-color: transparent; }
|
||||
}
|
||||
|
||||
.stat-value.final {
|
||||
animation: finalHighlight 2s ease-in-out;
|
||||
}
|
||||
|
||||
.discoveries-list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
@@ -374,9 +363,77 @@ header p {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Tactical loading spinner */
|
||||
.loading {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 3px solid rgba(199, 199, 199, 0.3);
|
||||
border-radius: 50%;
|
||||
border-top-color: #00ff41; /* Night-vision green spinner */
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* Responsive design adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.scan-form, .progress-section, .results-section {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.btn-primary, .btn-secondary {
|
||||
width: 100%;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.results-controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.results-controls button {
|
||||
flex: 1;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.stat-label, .stat-value {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.hostname-list, .ip-list {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* Responsive adjustments for the combined view */
|
||||
.results-section .live-discoveries {
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.results-section .live-discoveries .stats-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user