modularize, shodan qs
This commit is contained in:
@@ -13,7 +13,6 @@ class GraphManager {
|
||||
this.currentLayout = 'physics';
|
||||
this.nodeInfoPopup = null;
|
||||
|
||||
// Enhanced graph options for Phase 2
|
||||
this.options = {
|
||||
nodes: {
|
||||
shape: 'dot',
|
||||
@@ -214,20 +213,7 @@ class GraphManager {
|
||||
}
|
||||
});
|
||||
|
||||
this.network.on('blurNode', (params) => {
|
||||
this.hideNodeInfoPopup();
|
||||
this.clearHoverHighlights();
|
||||
});
|
||||
|
||||
// Double-click to focus on node
|
||||
this.network.on('doubleClick', (params) => {
|
||||
if (params.nodes.length > 0) {
|
||||
const nodeId = params.nodes[0];
|
||||
this.focusOnNode(nodeId);
|
||||
}
|
||||
});
|
||||
|
||||
// Context menu (right-click)
|
||||
// TODO Context menu (right-click)
|
||||
this.network.on('oncontext', (params) => {
|
||||
params.event.preventDefault();
|
||||
if (params.nodes.length > 0) {
|
||||
|
||||
@@ -12,10 +12,8 @@ class DNSReconApp {
|
||||
this.pollInterval = null;
|
||||
this.currentSessionId = null;
|
||||
|
||||
// UI Elements
|
||||
this.elements = {};
|
||||
|
||||
// Application state
|
||||
this.isScanning = false;
|
||||
this.lastGraphUpdate = null;
|
||||
|
||||
@@ -80,7 +78,7 @@ class DNSReconApp {
|
||||
// API Key Modal elements
|
||||
apiKeyModal: document.getElementById('api-key-modal'),
|
||||
apiKeyModalClose: document.getElementById('api-key-modal-close'),
|
||||
shodanApiKey: document.getElementById('shodan-api-key'),
|
||||
apiKeyInputs: document.getElementById('api-key-inputs'),
|
||||
saveApiKeys: document.getElementById('save-api-keys'),
|
||||
resetApiKeys: document.getElementById('reset-api-keys'),
|
||||
|
||||
@@ -732,6 +730,7 @@ class DNSReconApp {
|
||||
|
||||
if (response.success) {
|
||||
this.updateProviderDisplay(response.providers);
|
||||
this.buildApiKeyModal(response.providers);
|
||||
console.log('Providers loaded successfully');
|
||||
}
|
||||
|
||||
@@ -766,7 +765,7 @@ class DNSReconApp {
|
||||
|
||||
providerItem.innerHTML = `
|
||||
<div class="provider-header">
|
||||
<div class="provider-name">${name.toUpperCase()}</div>
|
||||
<div class="provider-name">${info.display_name}</div>
|
||||
<div class="provider-status ${statusClass}">${statusText}</div>
|
||||
</div>
|
||||
<div class="provider-stats">
|
||||
@@ -970,10 +969,15 @@ class DNSReconApp {
|
||||
* Save API Keys
|
||||
*/
|
||||
async saveApiKeys() {
|
||||
const shodanKey = this.elements.shodanApiKey.value.trim();
|
||||
|
||||
const inputs = this.elements.apiKeyInputs.querySelectorAll('input');
|
||||
const keys = {};
|
||||
if (shodanKey) keys.shodan = shodanKey;
|
||||
inputs.forEach(input => {
|
||||
const provider = input.dataset.provider;
|
||||
const value = input.value.trim();
|
||||
if (provider && value) {
|
||||
keys[provider] = value;
|
||||
}
|
||||
});
|
||||
|
||||
if (Object.keys(keys).length === 0) {
|
||||
this.showWarning('No API keys were entered.');
|
||||
@@ -998,7 +1002,10 @@ class DNSReconApp {
|
||||
* Reset API Key fields
|
||||
*/
|
||||
resetApiKeys() {
|
||||
this.elements.shodanApiKey.value = '';
|
||||
const inputs = this.elements.apiKeyInputs.querySelectorAll('input');
|
||||
inputs.forEach(input => {
|
||||
input.value = '';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1295,6 +1302,74 @@ class DNSReconApp {
|
||||
};
|
||||
return colors[type] || colors.info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the API key modal dynamically
|
||||
* @param {Object} providers - Provider information
|
||||
*/
|
||||
buildApiKeyModal(providers) {
|
||||
if (!this.elements.apiKeyInputs) return;
|
||||
this.elements.apiKeyInputs.innerHTML = ''; // Clear existing inputs
|
||||
let hasApiKeyProviders = false;
|
||||
|
||||
for (const [name, info] of Object.entries(providers)) {
|
||||
if (info.requires_api_key) {
|
||||
hasApiKeyProviders = true;
|
||||
const inputGroup = document.createElement('div');
|
||||
inputGroup.className = 'apikey-section';
|
||||
|
||||
if (info.enabled) {
|
||||
// If the API key is set and the provider is enabled
|
||||
inputGroup.innerHTML = `
|
||||
<label for="${name}-api-key">${info.display_name} API Key</label>
|
||||
<div class="api-key-set-message">
|
||||
<span class="api-key-set-text">API Key is set</span>
|
||||
<button class="clear-api-key-btn" data-provider="${name}">Clear</button>
|
||||
</div>
|
||||
<p class="apikey-help">Provides infrastructure context and service information.</p>
|
||||
`;
|
||||
} else {
|
||||
// If the API key is not set
|
||||
inputGroup.innerHTML = `
|
||||
<label for="${name}-api-key">${info.display_name} API Key</label>
|
||||
<input type="password" id="${name}-api-key" data-provider="${name}" placeholder="Enter ${info.display_name} API Key">
|
||||
<p class="apikey-help">Provides infrastructure context and service information.</p>
|
||||
`;
|
||||
}
|
||||
this.elements.apiKeyInputs.appendChild(inputGroup);
|
||||
}
|
||||
}
|
||||
|
||||
// Add event listeners for the new clear buttons
|
||||
this.elements.apiKeyInputs.querySelectorAll('.clear-api-key-btn').forEach(button => {
|
||||
button.addEventListener('click', (e) => {
|
||||
const provider = e.target.dataset.provider;
|
||||
this.clearApiKey(provider);
|
||||
});
|
||||
});
|
||||
|
||||
if (!hasApiKeyProviders) {
|
||||
this.elements.apiKeyInputs.innerHTML = '<p>No providers require API keys.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear an API key for a specific provider
|
||||
* @param {string} provider The name of the provider to clear the API key for
|
||||
*/
|
||||
async clearApiKey(provider) {
|
||||
try {
|
||||
const response = await this.apiCall('/api/config/api-keys', 'POST', { [provider]: '' });
|
||||
if (response.success) {
|
||||
this.showSuccess(`API key for ${provider} has been cleared.`);
|
||||
this.loadProviders(); // This will rebuild the modal with the updated state
|
||||
} else {
|
||||
throw new Error(response.error || 'Failed to clear API key');
|
||||
}
|
||||
} catch (error) {
|
||||
this.showError(`Error clearing API key: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add CSS animations for message toasts
|
||||
|
||||
Reference in New Issue
Block a user