/** * Background Service Worker for Hero Vault Extension * * Responsibilities: * - Maintain WebSocket connections * - Handle incoming script requests * - Manage session state when popup is closed * - Provide messaging interface for popup/content scripts * - Initialize WASM module when extension starts */ // Import WASM helper functions import { initWasm } from '../wasm/wasmHelper'; // Initialize WASM module when service worker starts initWasm().catch(error => { console.error('Failed to initialize WASM module:', error); }); // Store active WebSocket connection let activeWebSocket: WebSocket | null = null; let sessionActive = false; // Listen for messages from popup or content scripts chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { if (message.type === 'SESSION_STATUS') { sendResponse({ active: sessionActive }); return true; } if (message.type === 'SESSION_UNLOCK') { sessionActive = true; sendResponse({ success: true }); return true; } if (message.type === 'SESSION_LOCK') { sessionActive = false; if (activeWebSocket) { activeWebSocket.close(); activeWebSocket = null; } sendResponse({ success: true }); return true; } if (message.type === 'CONNECT_WEBSOCKET' && message.serverUrl && message.publicKey) { connectToWebSocket(message.serverUrl, message.publicKey) .then(success => sendResponse({ success })) .catch(error => sendResponse({ success: false, error: error.message })); return true; // Indicates we'll respond asynchronously } if (message.type === 'DISCONNECT_WEBSOCKET') { if (activeWebSocket) { activeWebSocket.close(); activeWebSocket = null; sendResponse({ success: true }); } else { sendResponse({ success: false, error: 'No active WebSocket connection' }); } return true; } }); /** * Connect to a WebSocket server with the user's public key */ async function connectToWebSocket(serverUrl: string, publicKey: string): Promise { if (activeWebSocket) { activeWebSocket.close(); } return new Promise((resolve, reject) => { try { const ws = new WebSocket(serverUrl); ws.onopen = () => { // Send authentication message with public key ws.send(JSON.stringify({ type: 'AUTH', publicKey })); activeWebSocket = ws; resolve(true); }; ws.onerror = (error) => { console.error('WebSocket error:', error); reject(new Error('Failed to connect to WebSocket server')); }; ws.onclose = () => { activeWebSocket = null; console.log('WebSocket connection closed'); }; ws.onmessage = async (event) => { try { const data = JSON.parse(event.data); // Handle incoming script requests if (data.type === 'SCRIPT_REQUEST') { // Notify the user of the script request chrome.notifications.create({ type: 'basic', iconUrl: 'icons/icon128.png', title: 'Script Request', message: `Received script request: ${data.title || 'Untitled Script'}`, priority: 2 }); // Store the script request for the popup to handle await chrome.storage.local.set({ pendingScripts: [ ...(await chrome.storage.local.get('pendingScripts')).pendingScripts || [], { id: data.id, title: data.title || 'Untitled Script', description: data.description || '', script: data.script, tags: data.tags || [], timestamp: Date.now() } ] }); } } catch (error) { console.error('Error processing WebSocket message:', error); } }; } catch (error) { reject(error); } }); } // Initialize notification setup chrome.notifications.onClicked.addListener((_notificationId) => { // Open the extension popup when a notification is clicked chrome.action.openPopup(); }); console.log('Hero Vault Extension background service worker initialized');