it
This commit is contained in:
		
							parent
							
								
									72f7056bc7
								
							
						
					
					
						commit
						3511f18f9a
					
				
							
								
								
									
										117
									
								
								app.py
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								app.py
									
									
									
									
									
								
							@ -1,3 +1,5 @@
 | 
			
		||||
# dnsrecon-reduced/app.py
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
Flask application entry point for DNSRecon web interface.
 | 
			
		||||
Provides REST API endpoints and serves the web interface with user session support.
 | 
			
		||||
@ -321,12 +323,18 @@ def export_results():
 | 
			
		||||
@app.route('/api/providers', methods=['GET'])
 | 
			
		||||
def get_providers():
 | 
			
		||||
    """Get information about available providers for the user session."""
 | 
			
		||||
    print("=== API: /api/providers called ===")
 | 
			
		||||
    
 | 
			
		||||
    try:
 | 
			
		||||
        # Get user-specific scanner
 | 
			
		||||
        user_session_id, scanner = get_user_scanner()
 | 
			
		||||
        
 | 
			
		||||
        if scanner:
 | 
			
		||||
            completed_tasks = scanner.indicators_completed
 | 
			
		||||
            enqueued_tasks = len(scanner.task_queue)
 | 
			
		||||
            print(f"DEBUG: Tasks - Completed: {completed_tasks}, Enqueued: {enqueued_tasks}")
 | 
			
		||||
        else:
 | 
			
		||||
            print("DEBUG: No active scanner session found.")
 | 
			
		||||
 | 
			
		||||
        provider_info = scanner.get_provider_info()
 | 
			
		||||
        
 | 
			
		||||
        return jsonify({
 | 
			
		||||
@ -401,113 +409,6 @@ def set_api_keys():
 | 
			
		||||
            'error': f'Internal server error: {str(e)}'
 | 
			
		||||
        }), 500
 | 
			
		||||
 | 
			
		||||
# TODO buggy, remove
 | 
			
		||||
@app.route('/api/session/info', methods=['GET'])
 | 
			
		||||
def get_session_info():
 | 
			
		||||
    """Get information about the current user session."""
 | 
			
		||||
    try:
 | 
			
		||||
        user_session_id, scanner = get_user_scanner()
 | 
			
		||||
        session_info = session_manager.get_session_info(user_session_id)
 | 
			
		||||
        
 | 
			
		||||
        return jsonify({
 | 
			
		||||
            'success': True,
 | 
			
		||||
            'session_info': session_info
 | 
			
		||||
        })
 | 
			
		||||
    
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(f"ERROR: Exception in get_session_info endpoint: {e}")
 | 
			
		||||
        traceback.print_exc()
 | 
			
		||||
        return jsonify({
 | 
			
		||||
            'success': False,
 | 
			
		||||
            'error': f'Internal server error: {str(e)}'
 | 
			
		||||
        }), 500
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route('/api/session/terminate', methods=['POST'])
 | 
			
		||||
def terminate_session():
 | 
			
		||||
    """Terminate the current user session."""
 | 
			
		||||
    try:
 | 
			
		||||
        user_session_id = session.get('dnsrecon_session_id')
 | 
			
		||||
        
 | 
			
		||||
        if user_session_id:
 | 
			
		||||
            success = session_manager.terminate_session(user_session_id)
 | 
			
		||||
            # Clear Flask session
 | 
			
		||||
            session.pop('dnsrecon_session_id', None)
 | 
			
		||||
            
 | 
			
		||||
            return jsonify({
 | 
			
		||||
                'success': success,
 | 
			
		||||
                'message': 'Session terminated' if success else 'Session not found'
 | 
			
		||||
            })
 | 
			
		||||
        else:
 | 
			
		||||
            return jsonify({
 | 
			
		||||
                'success': False,
 | 
			
		||||
                'error': 'No active session to terminate'
 | 
			
		||||
            }), 400
 | 
			
		||||
    
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(f"ERROR: Exception in terminate_session endpoint: {e}")
 | 
			
		||||
        traceback.print_exc()
 | 
			
		||||
        return jsonify({
 | 
			
		||||
            'success': False,
 | 
			
		||||
            'error': f'Internal server error: {str(e)}'
 | 
			
		||||
        }), 500
 | 
			
		||||
 | 
			
		||||
# TODO remove
 | 
			
		||||
@app.route('/api/admin/sessions', methods=['GET'])
 | 
			
		||||
def list_sessions():
 | 
			
		||||
    """Admin endpoint to list all active sessions."""
 | 
			
		||||
    try:
 | 
			
		||||
        sessions = session_manager.list_active_sessions()
 | 
			
		||||
        stats = session_manager.get_statistics()
 | 
			
		||||
        
 | 
			
		||||
        return jsonify({
 | 
			
		||||
            'success': True,
 | 
			
		||||
            'sessions': sessions,
 | 
			
		||||
            'statistics': stats
 | 
			
		||||
        })
 | 
			
		||||
    
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(f"ERROR: Exception in list_sessions endpoint: {e}")
 | 
			
		||||
        traceback.print_exc()
 | 
			
		||||
        return jsonify({
 | 
			
		||||
            'success': False,
 | 
			
		||||
            'error': f'Internal server error: {str(e)}'
 | 
			
		||||
        }), 500
 | 
			
		||||
 | 
			
		||||
# TODO remove
 | 
			
		||||
@app.route('/api/health', methods=['GET'])
 | 
			
		||||
def health_check():
 | 
			
		||||
    """Health check endpoint."""
 | 
			
		||||
    try:
 | 
			
		||||
        # Get session stats
 | 
			
		||||
        session_stats = session_manager.get_statistics()
 | 
			
		||||
        
 | 
			
		||||
        return jsonify({
 | 
			
		||||
            'success': True,
 | 
			
		||||
            'status': 'healthy',
 | 
			
		||||
            'timestamp': datetime.now(timezone.utc).isoformat(),
 | 
			
		||||
            'version': '1.0.0-phase2',
 | 
			
		||||
            'phase': 2,
 | 
			
		||||
            'features': {
 | 
			
		||||
                'multi_provider': True,
 | 
			
		||||
                'concurrent_processing': True,
 | 
			
		||||
                'real_time_updates': True,
 | 
			
		||||
                'api_key_management': True,
 | 
			
		||||
                'visualization': True,
 | 
			
		||||
                'retry_logic': True,
 | 
			
		||||
                'user_sessions': True,
 | 
			
		||||
                'session_isolation': True
 | 
			
		||||
            },
 | 
			
		||||
            'session_statistics': session_stats
 | 
			
		||||
        })
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(f"ERROR: Exception in health_check endpoint: {e}")
 | 
			
		||||
        return jsonify({
 | 
			
		||||
            'success': False,
 | 
			
		||||
            'error': f'Health check failed: {str(e)}'
 | 
			
		||||
        }), 500
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.errorhandler(404)
 | 
			
		||||
def not_found(error):
 | 
			
		||||
    """Handle 404 errors."""
 | 
			
		||||
 | 
			
		||||
@ -703,7 +703,6 @@ class Scanner:
 | 
			
		||||
                'current_depth': self.current_depth,
 | 
			
		||||
                'max_depth': self.max_depth,
 | 
			
		||||
                'current_indicator': self.current_indicator,
 | 
			
		||||
                'total_indicators_found': self.total_indicators_found,
 | 
			
		||||
                'indicators_processed': self.indicators_processed,
 | 
			
		||||
                'indicators_completed': self.indicators_completed,
 | 
			
		||||
                'tasks_re_enqueued': self.tasks_re_enqueued,
 | 
			
		||||
@ -721,7 +720,6 @@ class Scanner:
 | 
			
		||||
                'current_depth': 0,
 | 
			
		||||
                'max_depth': 0,
 | 
			
		||||
                'current_indicator': '',
 | 
			
		||||
                'total_indicators_found': 0,
 | 
			
		||||
                'indicators_processed': 0,
 | 
			
		||||
                'indicators_completed': 0,
 | 
			
		||||
                'tasks_re_enqueued': 0,
 | 
			
		||||
@ -732,10 +730,11 @@ class Scanner:
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
    def _calculate_progress(self) -> float:
 | 
			
		||||
        """Calculate scan progress percentage."""
 | 
			
		||||
        if self.total_indicators_found == 0:
 | 
			
		||||
        """Calculate scan progress percentage based on task completion."""
 | 
			
		||||
        total_tasks = self.indicators_completed + len(self.task_queue)
 | 
			
		||||
        if total_tasks == 0:
 | 
			
		||||
            return 0.0
 | 
			
		||||
        return min(100.0, (self.indicators_processed / self.total_indicators_found) * 100)
 | 
			
		||||
        return min(100.0, (self.indicators_completed / total_tasks) * 100)
 | 
			
		||||
 | 
			
		||||
    def get_graph_data(self) -> Dict[str, Any]:
 | 
			
		||||
        """Get current graph data for visualization."""
 | 
			
		||||
@ -798,9 +797,6 @@ class Scanner:
 | 
			
		||||
                                'statistics': live_provider.get_statistics() if live_provider else temp_provider.get_statistics(),
 | 
			
		||||
                                'enabled': self.config.is_provider_enabled(provider_name),
 | 
			
		||||
                                'rate_limit': self.config.get_rate_limit(provider_name),
 | 
			
		||||
                                'task_queue_size': len(self.task_queue),
 | 
			
		||||
                                'tasks_completed': self.indicators_completed,
 | 
			
		||||
                                'tasks_re_enqueued': self.tasks_re_enqueued,
 | 
			
		||||
                            }
 | 
			
		||||
                except Exception as e:
 | 
			
		||||
                    print(f"✗ Failed to get info for provider from {filename}: {e}")
 | 
			
		||||
 | 
			
		||||
@ -355,31 +355,6 @@ class SessionManager:
 | 
			
		||||
            
 | 
			
		||||
            time.sleep(300)  # Sleep for 5 minutes
 | 
			
		||||
 | 
			
		||||
    def list_active_sessions(self) -> List[Dict[str, Any]]:
 | 
			
		||||
        """List all active sessions for admin purposes."""
 | 
			
		||||
        try:
 | 
			
		||||
            session_keys = self.redis_client.keys("dnsrecon:session:*")
 | 
			
		||||
            sessions = []
 | 
			
		||||
            
 | 
			
		||||
            for session_key in session_keys:
 | 
			
		||||
                session_id = session_key.decode('utf-8').split(':')[-1]
 | 
			
		||||
                session_data = self._get_session_data(session_id)
 | 
			
		||||
                
 | 
			
		||||
                if session_data:
 | 
			
		||||
                    scanner = session_data.get('scanner')
 | 
			
		||||
                    sessions.append({
 | 
			
		||||
                        'session_id': session_id,
 | 
			
		||||
                        'created_at': session_data.get('created_at'),
 | 
			
		||||
                        'last_activity': session_data.get('last_activity'),
 | 
			
		||||
                        'scanner_status': scanner.status if scanner else 'unknown',
 | 
			
		||||
                        'current_target': scanner.current_target if scanner else None
 | 
			
		||||
                    })
 | 
			
		||||
            
 | 
			
		||||
            return sessions
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            print(f"ERROR: Failed to list active sessions: {e}")
 | 
			
		||||
            return []
 | 
			
		||||
 | 
			
		||||
    def get_statistics(self) -> Dict[str, Any]:
 | 
			
		||||
        """Get session manager statistics."""
 | 
			
		||||
        try:
 | 
			
		||||
 | 
			
		||||
@ -272,8 +272,24 @@ input[type="text"]:focus, select:focus {
 | 
			
		||||
    text-shadow: 0 0 3px rgba(0, 255, 65, 0.3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.progress-container {
 | 
			
		||||
    padding: 0 1.5rem 1.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.progress-info {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    font-size: 0.8rem;
 | 
			
		||||
    color: #999;
 | 
			
		||||
    margin-bottom: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#progress-compact {
 | 
			
		||||
    color: #00ff41;
 | 
			
		||||
    font-weight: 500;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.progress-bar {
 | 
			
		||||
    margin: 1rem 1.5rem;
 | 
			
		||||
    height: 8px;
 | 
			
		||||
    background-color: #1a1a1a;
 | 
			
		||||
    border: 1px solid #444;
 | 
			
		||||
 | 
			
		||||
@ -216,12 +216,8 @@ class GraphManager {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // FIX: Comment out the problematic context menu handler
 | 
			
		||||
        this.network.on('oncontext', (params) => {
 | 
			
		||||
            params.event.preventDefault();
 | 
			
		||||
            // if (params.nodes.length > 0) {
 | 
			
		||||
            //     this.showNodeContextMenu(params.pointer.DOM, params.nodes[0]);
 | 
			
		||||
            // }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Stabilization events with progress
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Main application logic for DNSRecon web interface
 | 
			
		||||
 * Handles UI interactions, API communication, and data flow
 | 
			
		||||
 * DEBUG VERSION WITH EXTRA LOGGING
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class DNSReconApp {
 | 
			
		||||
@ -61,12 +60,8 @@ class DNSReconApp {
 | 
			
		||||
            scanStatus: document.getElementById('scan-status'),
 | 
			
		||||
            targetDisplay: document.getElementById('target-display'),
 | 
			
		||||
            depthDisplay: document.getElementById('depth-display'),
 | 
			
		||||
            progressDisplay: document.getElementById('progress-display'),
 | 
			
		||||
            indicatorsDisplay: document.getElementById('indicators-display'),
 | 
			
		||||
            relationshipsDisplay: document.getElementById('relationships-display'),
 | 
			
		||||
            taskQueueDisplay: document.getElementById('task-queue-display'),
 | 
			
		||||
            tasksCompletedDisplay: document.getElementById('tasks-completed-display'),
 | 
			
		||||
            tasksReEnqueuedDisplay: document.getElementById('tasks-re-enqueued-display'),
 | 
			
		||||
            progressCompact: document.getElementById('progress-compact'),
 | 
			
		||||
            progressFill: document.getElementById('progress-fill'),
 | 
			
		||||
            
 | 
			
		||||
            // Provider elements
 | 
			
		||||
@ -545,26 +540,19 @@ class DNSReconApp {
 | 
			
		||||
            if (this.elements.depthDisplay) {
 | 
			
		||||
                this.elements.depthDisplay.textContent = `${status.current_depth}/${status.max_depth}`;
 | 
			
		||||
            }
 | 
			
		||||
            if (this.elements.progressDisplay) {
 | 
			
		||||
                this.elements.progressDisplay.textContent = `${status.progress_percentage.toFixed(1)}%`;
 | 
			
		||||
            }
 | 
			
		||||
            if (this.elements.indicatorsDisplay) {
 | 
			
		||||
                this.elements.indicatorsDisplay.textContent = status.indicators_processed || 0;
 | 
			
		||||
            }
 | 
			
		||||
            if (this.elements.taskQueueDisplay) {
 | 
			
		||||
                this.elements.taskQueueDisplay.textContent = status.task_queue_size || 0;
 | 
			
		||||
            }
 | 
			
		||||
            if (this.elements.tasksCompletedDisplay) {
 | 
			
		||||
                this.elements.tasksCompletedDisplay.textContent = status.indicators_completed || 0;
 | 
			
		||||
            }
 | 
			
		||||
            if (this.elements.tasksReEnqueuedDisplay) {
 | 
			
		||||
                this.elements.tasksReEnqueuedDisplay.textContent = status.tasks_re_enqueued || 0;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            // Update progress bar with smooth animation
 | 
			
		||||
            // Update progress bar and compact display
 | 
			
		||||
            if (this.elements.progressFill) {
 | 
			
		||||
                this.elements.progressFill.style.width = `${status.progress_percentage}%`;
 | 
			
		||||
                
 | 
			
		||||
                const completed = status.indicators_completed || 0;
 | 
			
		||||
                const enqueued = status.task_queue_size || 0;
 | 
			
		||||
                const totalTasks = completed + enqueued;
 | 
			
		||||
                const progressPercentage = totalTasks > 0 ? (completed / totalTasks) * 100 : 0;
 | 
			
		||||
 | 
			
		||||
                this.elements.progressFill.style.width = `${progressPercentage}%`;
 | 
			
		||||
                if (this.elements.progressCompact) {
 | 
			
		||||
                    this.elements.progressCompact.textContent = `${completed}/${totalTasks} - ${Math.round(progressPercentage)}%`;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Add pulsing animation for active scans
 | 
			
		||||
                if (status.status === 'running') {
 | 
			
		||||
                    this.elements.progressFill.parentElement.classList.add('scanning');
 | 
			
		||||
@ -802,20 +790,6 @@ class DNSReconApp {
 | 
			
		||||
                        <span class="provider-stat-value">${info.rate_limit}/min</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="provider-task-stats">
 | 
			
		||||
                    <div class="provider-stat">
 | 
			
		||||
                        <span class="provider-stat-label">Task Queue:</span>
 | 
			
		||||
                        <span class="provider-stat-value">${info.task_queue_size || 0}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="provider-stat">
 | 
			
		||||
                        <span class="provider-stat-label">Tasks Completed:</span>
 | 
			
		||||
                        <span class="provider-stat-value">${info.tasks_completed || 0}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                     <div class="provider-stat">
 | 
			
		||||
                        <span class="provider-stat-label">Tasks Re-enqueued:</span>
 | 
			
		||||
                        <span class="provider-stat-value">${info.tasks_re_enqueued || 0}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            `;
 | 
			
		||||
            
 | 
			
		||||
            this.elements.providerList.appendChild(providerItem);
 | 
			
		||||
 | 
			
		||||
@ -90,34 +90,20 @@
 | 
			
		||||
                        <span class="status-label">Depth:</span>
 | 
			
		||||
                        <span id="depth-display" class="status-value">0/0</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="status-row">
 | 
			
		||||
                        <span class="status-label">Progress:</span>
 | 
			
		||||
                        <span id="progress-display" class="status-value">0%</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="status-row">
 | 
			
		||||
                        <span class="status-label">Indicators:</span>
 | 
			
		||||
                        <span id="indicators-display" class="status-value">0</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="status-row">
 | 
			
		||||
                        <span class="status-label">Relationships:</span>
 | 
			
		||||
                        <span id="relationships-display" class="status-value">0</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="status-row">
 | 
			
		||||
                        <span class="status-label">Task Queue:</span>
 | 
			
		||||
                        <span id="task-queue-display" class="status-value">0</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="status-row">
 | 
			
		||||
                        <span class="status-label">Tasks Completed:</span>
 | 
			
		||||
                        <span id="tasks-completed-display" class="status-value">0</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="status-row">
 | 
			
		||||
                        <span class="status-label">Tasks Re-enqueued:</span>
 | 
			
		||||
                        <span id="tasks-re-enqueued-display" class="status-value">0</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                
 | 
			
		||||
                <div class="progress-bar">
 | 
			
		||||
                    <div id="progress-fill" class="progress-fill"></div>
 | 
			
		||||
                <div class="progress-container">
 | 
			
		||||
                    <div class="progress-info">
 | 
			
		||||
                        <span id="progress-label">Progress:</span>
 | 
			
		||||
                        <span id="progress-compact">0/0</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="progress-bar">
 | 
			
		||||
                        <div id="progress-fill" class="progress-fill"></div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user