CrowdProof-Observe-Chrome/background/background.js

145 lines
3.7 KiB
JavaScript

// CrowdProof Observe - Chrome Background Service Worker
// Handles side panel toggle and context menus
// Create context menus on install
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: "send-url-to-crowdproof",
title: "Send URL to CrowdProof",
contexts: ["link"]
});
chrome.contextMenus.create({
id: "send-image-to-crowdproof",
title: "Send Image to CrowdProof",
contexts: ["image"]
});
});
// Open side panel when action button is clicked
chrome.action.onClicked.addListener((tab) => {
chrome.sidePanel.open({ windowId: tab.windowId });
});
// Handle context menu click
chrome.contextMenus.onClicked.addListener((info, tab) => {
// Open side panel
chrome.sidePanel.open({ windowId: tab.windowId });
if (info.menuItemId === "send-url-to-crowdproof") {
chrome.storage.local.set({ pendingUrl: info.linkUrl });
} else if (info.menuItemId === "send-image-to-crowdproof") {
// Store the image source URL - sidepanel will fetch it
chrome.storage.local.set({
pendingImage: {
sourceUrl: info.srcUrl
}
});
}
});
// API helper
const API = {
async getServerUrl() {
const result = await chrome.storage.local.get('serverUrl');
return result.serverUrl || null;
},
async request(endpoint, options = {}) {
const serverUrl = await this.getServerUrl();
if (!serverUrl) {
throw new Error('Server URL not configured. Please set it in extension options.');
}
const url = `${serverUrl}${endpoint}`;
const fetchOptions = {
credentials: 'include',
...options
};
const response = await fetch(url, fetchOptions);
return response;
},
async login(username, password) {
const formData = new FormData();
formData.append('username', username);
formData.append('password', password);
const response = await this.request('/login', {
method: 'POST',
body: formData
});
return {
success: response.ok && !response.url.includes('/login'),
response
};
},
async logout() {
const response = await this.request('/logout', {
method: 'GET'
});
return response.ok;
},
async checkAuth() {
const response = await this.request('/profile', {
method: 'GET'
});
return !response.url.includes('/login');
},
async createObservation(type, formData) {
const response = await this.request(`/create_observation/${type}`, {
method: 'POST',
body: formData
});
return {
success: response.ok,
response
};
}
};
// Handle messages from sidepanel
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
(async () => {
try {
switch (message.action) {
case 'getServerUrl':
sendResponse({ serverUrl: await API.getServerUrl() });
break;
case 'checkAuth':
const isAuthenticated = await API.checkAuth();
sendResponse({ authenticated: isAuthenticated });
break;
case 'login':
const loginResult = await API.login(message.username, message.password);
sendResponse({ success: loginResult.success });
break;
case 'logout':
const logoutSuccess = await API.logout();
sendResponse({ success: logoutSuccess });
break;
case 'createObservation':
const obsResult = await API.createObservation(message.type, message.formData);
sendResponse({ success: obsResult.success });
break;
default:
sendResponse({ error: 'Unknown action' });
}
} catch (error) {
sendResponse({ error: error.message });
}
})();
return true; // Keep message channel open for async response
});