329 lines
11 KiB
JavaScript
Raw Normal View History

2025-02-10 04:21:21 -05:00
// Store settings
let settings = {
logLimit: 50,
queryLimit: 30000,
stringSizeLimit: 500,
showRequestHeaders: false,
showResponseHeaders: false,
maxLogSize: 20000,
screenshotPath: "",
// Add server connection settings
serverHost: "localhost",
serverPort: 3025,
2025-02-10 04:21:21 -05:00
};
// Load saved settings on startup
chrome.storage.local.get(["browserConnectorSettings"], (result) => {
if (result.browserConnectorSettings) {
settings = { ...settings, ...result.browserConnectorSettings };
updateUIFromSettings();
}
});
// Initialize UI elements
const logLimitInput = document.getElementById("log-limit");
const queryLimitInput = document.getElementById("query-limit");
const stringSizeLimitInput = document.getElementById("string-size-limit");
const showRequestHeadersCheckbox = document.getElementById(
"show-request-headers"
);
const showResponseHeadersCheckbox = document.getElementById(
"show-response-headers"
);
const maxLogSizeInput = document.getElementById("max-log-size");
const screenshotPathInput = document.getElementById("screenshot-path");
2025-02-14 04:18:43 -05:00
const captureScreenshotButton = document.getElementById("capture-screenshot");
// Server connection UI elements
const serverHostInput = document.getElementById("server-host");
const serverPortInput = document.getElementById("server-port");
const discoverServerButton = document.getElementById("discover-server");
const testConnectionButton = document.getElementById("test-connection");
const connectionStatusDiv = document.getElementById("connection-status");
const statusIcon = document.getElementById("status-icon");
const statusText = document.getElementById("status-text");
2025-02-14 04:18:43 -05:00
// Initialize collapsible advanced settings
const advancedSettingsHeader = document.getElementById(
"advanced-settings-header"
);
const advancedSettingsContent = document.getElementById(
"advanced-settings-content"
);
const chevronIcon = advancedSettingsHeader.querySelector(".chevron");
advancedSettingsHeader.addEventListener("click", () => {
advancedSettingsContent.classList.toggle("visible");
chevronIcon.classList.toggle("open");
});
2025-02-10 04:21:21 -05:00
// Update UI from settings
function updateUIFromSettings() {
logLimitInput.value = settings.logLimit;
queryLimitInput.value = settings.queryLimit;
stringSizeLimitInput.value = settings.stringSizeLimit;
showRequestHeadersCheckbox.checked = settings.showRequestHeaders;
showResponseHeadersCheckbox.checked = settings.showResponseHeaders;
maxLogSizeInput.value = settings.maxLogSize;
screenshotPathInput.value = settings.screenshotPath;
serverHostInput.value = settings.serverHost;
serverPortInput.value = settings.serverPort;
2025-02-10 04:21:21 -05:00
}
// Save settings
function saveSettings() {
chrome.storage.local.set({ browserConnectorSettings: settings });
// Notify devtools.js about settings change
chrome.runtime.sendMessage({
type: "SETTINGS_UPDATED",
settings,
});
}
// Add event listeners for all inputs
logLimitInput.addEventListener("change", (e) => {
settings.logLimit = parseInt(e.target.value, 10);
saveSettings();
});
queryLimitInput.addEventListener("change", (e) => {
settings.queryLimit = parseInt(e.target.value, 10);
saveSettings();
});
stringSizeLimitInput.addEventListener("change", (e) => {
settings.stringSizeLimit = parseInt(e.target.value, 10);
saveSettings();
});
showRequestHeadersCheckbox.addEventListener("change", (e) => {
settings.showRequestHeaders = e.target.checked;
saveSettings();
});
showResponseHeadersCheckbox.addEventListener("change", (e) => {
settings.showResponseHeaders = e.target.checked;
saveSettings();
});
maxLogSizeInput.addEventListener("change", (e) => {
settings.maxLogSize = parseInt(e.target.value, 10);
saveSettings();
});
screenshotPathInput.addEventListener("change", (e) => {
settings.screenshotPath = e.target.value;
saveSettings();
});
2025-02-14 04:18:43 -05:00
// Add event listeners for server settings
serverHostInput.addEventListener("change", (e) => {
settings.serverHost = e.target.value;
saveSettings();
});
serverPortInput.addEventListener("change", (e) => {
settings.serverPort = parseInt(e.target.value, 10);
saveSettings();
});
// Test server connection
testConnectionButton.addEventListener("click", async () => {
await testConnection(settings.serverHost, settings.serverPort);
});
// Function to test server connection
async function testConnection(host, port) {
connectionStatusDiv.style.display = "block";
statusIcon.className = "status-indicator";
statusText.textContent = "Testing connection...";
try {
// Use the identity endpoint instead of .port for more reliable validation
const response = await fetch(`http://${host}:${port}/.identity`, {
signal: AbortSignal.timeout(5000), // 5 second timeout
});
if (response.ok) {
const identity = await response.json();
// Verify this is actually our server by checking the signature
if (identity.signature !== "mcp-browser-connector-24x7") {
statusIcon.className = "status-indicator status-disconnected";
statusText.textContent = `Connection failed: Found a server at ${host}:${port} but it's not the Browser Tools server`;
return;
}
statusIcon.className = "status-indicator status-connected";
statusText.textContent = `Connected successfully to ${identity.name} v${identity.version} at ${host}:${port}`;
// Update settings if different port was discovered
if (parseInt(identity.port, 10) !== port) {
console.log(`Detected different port: ${identity.port}`);
settings.serverPort = parseInt(identity.port, 10);
serverPortInput.value = settings.serverPort;
saveSettings();
}
} else {
statusIcon.className = "status-indicator status-disconnected";
statusText.textContent = `Connection failed: Server returned ${response.status}`;
}
} catch (error) {
statusIcon.className = "status-indicator status-disconnected";
statusText.textContent = `Connection failed: ${error.message}`;
}
}
// Server discovery function
discoverServerButton.addEventListener("click", async () => {
connectionStatusDiv.style.display = "block";
statusIcon.className = "status-indicator";
statusText.textContent = "Discovering server...";
// Common IPs to try
const hosts = ["localhost", "127.0.0.1", "0.0.0.0"];
// Get local IP addresses on common networks
const commonLocalIps = ["192.168.0.", "192.168.1.", "10.0.0.", "10.0.1."];
// Add common local networks with last octet from 1 to 10
for (const prefix of commonLocalIps) {
for (let i = 1; i <= 10; i++) {
hosts.push(`${prefix}${i}`);
}
}
// Common ports to try
const ports = [3025, parseInt(settings.serverPort, 10)];
// Ensure the current port is in the list
if (!ports.includes(parseInt(settings.serverPort, 10))) {
ports.push(parseInt(settings.serverPort, 10));
}
// Create a progress indicator
let progress = 0;
const totalAttempts = hosts.length * ports.length;
statusText.textContent = `Discovering server... (0/${totalAttempts})`;
// Try each host:port combination
for (const host of hosts) {
for (const port of ports) {
try {
// Skip duplicates if current port is in the ports list multiple times
if (
port === parseInt(settings.serverPort, 10) &&
host === settings.serverHost
) {
progress++;
statusText.textContent = `Discovering server... (${progress}/${totalAttempts})`;
continue;
}
// Update progress
progress++;
statusText.textContent = `Discovering server... (${progress}/${totalAttempts}) - Trying ${host}:${port}`;
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 1000); // 1 second timeout per attempt
// Use identity endpoint instead of .port for more reliable server validation
const response = await fetch(`http://${host}:${port}/.identity`, {
signal: controller.signal,
});
clearTimeout(timeoutId);
if (response.ok) {
const identity = await response.json();
// Verify this is actually our server by checking the signature
if (identity.signature !== "mcp-browser-connector-24x7") {
console.log(
`Found a server at ${host}:${port} but it's not the Browser Tools server`
);
continue;
}
// Update settings with discovered server
settings.serverHost = host;
settings.serverPort = parseInt(identity.port, 10);
serverHostInput.value = settings.serverHost;
serverPortInput.value = settings.serverPort;
saveSettings();
statusIcon.className = "status-indicator status-connected";
statusText.textContent = `Discovered ${identity.name} v${identity.version} at ${host}:${identity.port}`;
// Stop searching once found
return;
}
} catch (error) {
// Ignore connection errors during discovery
}
}
}
// If we get here, no server was found
statusIcon.className = "status-indicator status-disconnected";
statusText.textContent =
"No server found. Please check server is running and try again.";
});
// Screenshot capture functionality
2025-02-14 04:18:43 -05:00
captureScreenshotButton.addEventListener("click", () => {
captureScreenshotButton.textContent = "Capturing...";
// Send message to background script to capture screenshot
chrome.runtime.sendMessage(
{
type: "CAPTURE_SCREENSHOT",
tabId: chrome.devtools.inspectedWindow.tabId,
screenshotPath: settings.screenshotPath,
},
(response) => {
console.log("Screenshot capture response:", response);
if (!response) {
captureScreenshotButton.textContent = "Failed to capture!";
console.error("Screenshot capture failed: No response received");
} else if (!response.success) {
captureScreenshotButton.textContent = "Failed to capture!";
console.error("Screenshot capture failed:", response.error);
} else {
captureScreenshotButton.textContent = `Captured: ${response.title}`;
console.log("Screenshot captured successfully:", response.path);
}
setTimeout(() => {
captureScreenshotButton.textContent = "Capture Screenshot";
}, 2000);
2025-02-14 04:18:43 -05:00
}
);
2025-02-14 04:18:43 -05:00
});
// Add wipe logs functionality
const wipeLogsButton = document.getElementById("wipe-logs");
wipeLogsButton.addEventListener("click", () => {
const serverUrl = `http://${settings.serverHost}:${settings.serverPort}/wipelogs`;
console.log(`Sending wipe request to ${serverUrl}`);
fetch(serverUrl, {
2025-02-14 04:18:43 -05:00
method: "POST",
headers: { "Content-Type": "application/json" },
})
.then((response) => response.json())
.then((result) => {
console.log("Logs wiped successfully:", result.message);
wipeLogsButton.textContent = "Logs Wiped!";
setTimeout(() => {
wipeLogsButton.textContent = "Wipe All Logs";
}, 2000);
})
.catch((error) => {
console.error("Failed to wipe logs:", error);
wipeLogsButton.textContent = "Failed to Wipe Logs";
setTimeout(() => {
wipeLogsButton.textContent = "Wipe All Logs";
}, 2000);
});
});