完成扩展

This commit is contained in:
dela
2026-01-10 16:53:02 +08:00
parent 9eba656dbd
commit 97b162939e
31 changed files with 8436 additions and 0 deletions

View 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 ===');