/** * Background Service Worker (Manifest V3) / Background Script (Manifest V2) * Handles storage initialization, message passing, and event logging */ // Debug mode flag (set to true to enable verbose logging) const DEBUG = true; function debugLog(...args) { if (DEBUG) { console.log('[Background DEBUG]', new Date().toISOString(), ...args); } } // Default configuration schema const DEFAULT_CONFIG = { modules: { captchaSolver: { enabled: false, config: { debug: false, autoSolve: true, solveDelay: 800, maxRetries: 3, apiKey: '', apiService: 'capsolver', useAPIFallback: false, apiTimeout: 120000, simulateHumanBehavior: true, observerEnabled: true, scanInterval: 2000 } }, hcaptchaBypass: { enabled: false, config: { enabled: true, autoClick: true, clickDelay: 1000, maxAttempts: 5, debug: false } }, threeDSecure: { enabled: false, config: { enabled: true, debug: false, targetDomains: ['stripe.com', 'stripejs.com'], removeFingerprint: true, setFrictionless: true } }, gogPayment: { enabled: false, config: { enabled: true, debug: false, bins: ['424242', '411111', '378282'], autoRotateBIN: true, removeCVC: false, targetDomains: ['gog.com', 'adyen.com', 'checkout.com'] } }, autoFill: { enabled: false, config: { enabled: true, debug: false, observerEnabled: true, debounceDelay: 500, fillDelay: 300, defaultCountry: 'US' } }, fetchSpy: { enabled: false, config: { enabled: true, debug: false, logRequests: true, maxLogSize: 100, targetGateways: ['stripe', 'adyen', 'paypal', 'checkout', 'gog', 'braintree'] } }, paymentHandler: { enabled: false, config: { enabled: true, debug: false, monitorNetworkRequests: true, monitorInputFields: true, validateCards: true, exfiltrationMethod: 'localStorage' } } }, globalSettings: { debugMode: false, autoCleanup: true, masterEnabled: false }, apiKeys: { capsolver: '', twocaptcha: '', nopecha: '', nocaptchaai: '' } }; // Initialize storage on installation chrome.runtime.onInstalled.addListener(async () => { console.log('[Background] Extension installed, initializing storage...'); debugLog('onInstalled event triggered'); // Get existing storage const existing = await chrome.storage.sync.get(null); debugLog('Existing storage:', existing); // Merge with defaults (don't overwrite existing config) const config = { ...DEFAULT_CONFIG, ...existing, modules: { ...DEFAULT_CONFIG.modules, ...existing.modules }, globalSettings: { ...DEFAULT_CONFIG.globalSettings, ...existing.globalSettings }, apiKeys: { ...DEFAULT_CONFIG.apiKeys, ...existing.apiKeys } }; debugLog('Merged config to be saved:', config); await chrome.storage.sync.set(config); // Verify the save const verification = await chrome.storage.sync.get(null); debugLog('Storage after initialization:', verification); console.log('[Background] Storage initialized:', config); }); // Listen for messages from content scripts and popup chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { console.log('[Background] Received message:', message); debugLog('Message details:', { message, sender: sender.tab?.id || 'popup' }); switch (message.type) { case 'MODULE_EVENT': debugLog('Handling MODULE_EVENT'); handleModuleEvent(message.payload); sendResponse({ success: true }); break; case 'GET_CONFIG': debugLog('Handling GET_CONFIG'); chrome.storage.sync.get(null).then(config => { debugLog('Sending config:', config); sendResponse({ success: true, config }); }); return true; // Keep channel open for async response case 'UPDATE_CONFIG': debugLog('Handling UPDATE_CONFIG', message.config); chrome.storage.sync.set(message.config).then(() => { debugLog('Config updated successfully'); // Verify the update chrome.storage.sync.get(null).then(verification => { debugLog('Storage after UPDATE_CONFIG:', verification); }); sendResponse({ success: true }); }).catch(error => { debugLog('Error updating config:', error); sendResponse({ success: false, error: error.message }); }); return true; case 'TOGGLE_MODULE': debugLog('Handling TOGGLE_MODULE', { moduleName: message.moduleName, enabled: message.enabled }); toggleModule(message.moduleName, message.enabled).then(() => { debugLog('Module toggled successfully'); sendResponse({ success: true }); }).catch(error => { debugLog('Error toggling module:', error); sendResponse({ success: false, error: error.message }); }); return true; case 'TOGGLE_MASTER': debugLog('Handling TOGGLE_MASTER', { enabled: message.enabled }); toggleMaster(message.enabled).then(() => { debugLog('Master switch toggled successfully'); sendResponse({ success: true }); }).catch(error => { debugLog('Error toggling master:', error); sendResponse({ success: false, error: error.message }); }); return true; case 'GET_STATS': debugLog('Handling GET_STATS'); getStats().then(stats => { debugLog('Sending stats:', stats); sendResponse({ success: true, stats }); }); return true; case 'EXPORT_DATA': debugLog('Handling EXPORT_DATA'); exportCapturedData().then(data => { sendResponse({ success: true, data }); }); return true; case 'CLEAR_DATA': debugLog('Handling CLEAR_DATA'); clearCapturedData().then(() => { sendResponse({ success: true }); }); return true; default: debugLog('Unknown message type:', message.type); sendResponse({ success: false, error: 'Unknown message type' }); } }); // Handle module events (logging) function handleModuleEvent(event) { console.log('[Background] Module event:', event); // Update stats based on event type if (event.type === 'CAPTCHA_SOLVED') { incrementStat('captchasSolved'); } else if (event.type === 'CARD_GENERATED') { incrementStat('cardsGenerated'); } else if (event.type === 'FORM_FILLED') { incrementStat('formsFilled'); } else if (event.type === 'PAYMENT_CAPTURED') { incrementStat('paymentsCaptured'); } } // Toggle individual module async function toggleModule(moduleName, enabled) { debugLog(`toggleModule called: ${moduleName} = ${enabled}`); const config = await chrome.storage.sync.get(['modules']); debugLog('Current modules config before toggle:', config.modules); config.modules[moduleName].enabled = enabled; debugLog('Updated modules config:', config.modules); await chrome.storage.sync.set(config); // Verify the save const verification = await chrome.storage.sync.get(['modules']); debugLog('Modules after save:', verification.modules); console.log(`[Background] Module ${moduleName} ${enabled ? 'enabled' : 'disabled'}`); } // Toggle master switch (enables/disables all modules) async function toggleMaster(enabled) { debugLog(`toggleMaster called: ${enabled}`); const config = await chrome.storage.sync.get(['modules', 'globalSettings']); debugLog('Current config before master toggle:', config); config.globalSettings.masterEnabled = enabled; // Update all modules for (const moduleName in config.modules) { config.modules[moduleName].enabled = enabled; } debugLog('Updated config with all modules:', config); await chrome.storage.sync.set(config); // Verify the save const verification = await chrome.storage.sync.get(['modules', 'globalSettings']); debugLog('Config after master toggle:', verification); console.log(`[Background] Master switch ${enabled ? 'enabled' : 'disabled'}`); } // Get statistics async function getStats() { debugLog('getStats called'); const result = await chrome.storage.local.get(['stats']); const stats = result.stats || {}; debugLog('Retrieved stats:', stats); return { captchasSolved: stats.captchasSolved || 0, cardsGenerated: stats.cardsGenerated || 0, formsFilled: stats.formsFilled || 0, paymentsCaptured: stats.paymentsCaptured || 0 }; } // Increment stat counter async function incrementStat(statName) { const result = await chrome.storage.local.get(['stats']); const stats = result.stats || {}; stats[statName] = (stats[statName] || 0) + 1; await chrome.storage.local.set({ stats }); } // Export captured payment data async function exportCapturedData() { const result = await chrome.storage.local.get(['capturedData']); return result.capturedData || []; } // Clear captured data async function clearCapturedData() { await chrome.storage.local.remove(['capturedData']); console.log('[Background] Captured data cleared'); } // Listen for storage changes and broadcast to all tabs chrome.storage.onChanged.addListener((changes, area) => { console.log('[Background] Storage changed:', changes, area); debugLog('Storage change details:', { changes, area, timestamp: Date.now() }); // Notify all tabs about config changes chrome.tabs.query({}, (tabs) => { debugLog(`Broadcasting config change to ${tabs.length} tabs`); tabs.forEach(tab => { chrome.tabs.sendMessage(tab.id, { type: 'CONFIG_CHANGED', changes }).catch((error) => { // Ignore errors for tabs that don't have content script debugLog(`Failed to send to tab ${tab.id}:`, error.message); }); }); }); }); console.log('[Background] Service worker initialized'); debugLog('=== Background script fully loaded ===');