209 lines
6.6 KiB
JavaScript
Raw Normal View History

// Listen for messages from the devtools panel
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === "CAPTURE_SCREENSHOT" && message.tabId) {
// First get the server settings
chrome.storage.local.get(["browserConnectorSettings"], (result) => {
const settings = result.browserConnectorSettings || {
serverHost: "localhost",
serverPort: 3025,
};
// Validate server identity first
validateServerIdentity(settings.serverHost, settings.serverPort)
.then((isValid) => {
if (!isValid) {
console.error(
"Cannot capture screenshot: Not connected to a valid browser tools server"
);
sendResponse({
success: false,
error:
"Not connected to a valid browser tools server. Please check your connection settings.",
});
return;
}
// Continue with screenshot capture
captureAndSendScreenshot(message, settings, sendResponse);
})
.catch((error) => {
console.error("Error validating server:", error);
sendResponse({
success: false,
error: "Failed to validate server identity: " + error.message,
});
});
});
return true; // Required to use sendResponse asynchronously
}
});
// Validate server identity
async function validateServerIdentity(host, port) {
try {
const response = await fetch(`http://${host}:${port}/.identity`, {
signal: AbortSignal.timeout(3000), // 3 second timeout
});
if (!response.ok) {
console.error(`Invalid server response: ${response.status}`);
return false;
}
const identity = await response.json();
// Validate the server signature
if (identity.signature !== "mcp-browser-connector-24x7") {
console.error("Invalid server signature - not the browser tools server");
return false;
}
return true;
} catch (error) {
console.error("Error validating server identity:", error);
return false;
}
}
// Listen for tab updates to detect page refreshes
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
// Check if this is a page refresh (status becoming "complete")
if (changeInfo.status === "complete") {
retestConnectionOnRefresh(tabId);
}
});
// Function to retest connection when a page is refreshed
async function retestConnectionOnRefresh(tabId) {
console.log(`Page refreshed in tab ${tabId}, retesting connection...`);
// Get the saved settings
chrome.storage.local.get(["browserConnectorSettings"], async (result) => {
const settings = result.browserConnectorSettings || {
serverHost: "localhost",
serverPort: 3025,
};
// Test the connection with the last known host and port
const isConnected = await validateServerIdentity(
settings.serverHost,
settings.serverPort
);
// Notify all devtools instances about the connection status
chrome.runtime.sendMessage({
type: "CONNECTION_STATUS_UPDATE",
isConnected: isConnected,
tabId: tabId,
});
// Always notify for page refresh, whether connected or not
// This ensures any ongoing discovery is cancelled and restarted
chrome.runtime.sendMessage({
type: "INITIATE_AUTO_DISCOVERY",
reason: "page_refresh",
tabId: tabId,
forceRestart: true, // Add a flag to indicate this should force restart any ongoing processes
});
if (!isConnected) {
console.log(
"Connection test failed after page refresh, initiating auto-discovery..."
);
} else {
console.log("Connection test successful after page refresh");
}
});
}
// Function to capture and send screenshot
function captureAndSendScreenshot(message, settings, sendResponse) {
// Get the inspected window's tab
chrome.tabs.get(message.tabId, (tab) => {
if (chrome.runtime.lastError) {
console.error("Error getting tab:", chrome.runtime.lastError);
sendResponse({
success: false,
error: chrome.runtime.lastError.message,
});
return;
}
// Get all windows to find the one containing our tab
chrome.windows.getAll({ populate: true }, (windows) => {
const targetWindow = windows.find((w) =>
w.tabs.some((t) => t.id === message.tabId)
);
if (!targetWindow) {
console.error("Could not find window containing the inspected tab");
sendResponse({
success: false,
error: "Could not find window containing the inspected tab",
});
return;
}
// Capture screenshot of the window containing our tab
chrome.tabs.captureVisibleTab(
targetWindow.id,
{ format: "png" },
(dataUrl) => {
// Ignore DevTools panel capture error if it occurs
if (
chrome.runtime.lastError &&
!chrome.runtime.lastError.message.includes("devtools://")
) {
console.error(
"Error capturing screenshot:",
chrome.runtime.lastError
);
sendResponse({
success: false,
error: chrome.runtime.lastError.message,
});
return;
}
// Send screenshot data to browser connector using configured settings
const serverUrl = `http://${settings.serverHost}:${settings.serverPort}/screenshot`;
console.log(`Sending screenshot to ${serverUrl}`);
fetch(serverUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
data: dataUrl,
path: message.screenshotPath,
}),
})
.then((response) => response.json())
.then((result) => {
if (result.error) {
console.error("Error from server:", result.error);
sendResponse({ success: false, error: result.error });
} else {
console.log("Screenshot saved successfully:", result.path);
// Send success response even if DevTools capture failed
sendResponse({
success: true,
path: result.path,
title: tab.title || "Current Tab",
});
}
})
.catch((error) => {
console.error("Error sending screenshot data:", error);
sendResponse({
success: false,
error: error.message || "Failed to save screenshot",
});
});
}
);
});
});
}