346 lines
9.9 KiB
JavaScript
346 lines
9.9 KiB
JavaScript
/**
|
|
* 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 ===');
|