完成扩展

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,208 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 350px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: #1a1a1a;
color: #e0e0e0;
}
.container {
padding: 16px;
}
/* Header */
header {
text-align: center;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #333;
}
header h1 {
font-size: 18px;
font-weight: 600;
color: #fff;
margin-bottom: 4px;
}
.subtitle {
font-size: 11px;
color: #888;
}
/* Master Control */
.master-control {
background: #252525;
border-radius: 8px;
padding: 12px;
margin-bottom: 16px;
}
.control-row {
display: flex;
justify-content: space-between;
align-items: center;
}
.control-label {
font-weight: 600;
font-size: 14px;
color: #fff;
}
/* Switch Component */
.switch {
position: relative;
display: inline-block;
width: 44px;
height: 24px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #444;
transition: 0.3s;
border-radius: 24px;
}
.slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
transition: 0.3s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #4CAF50;
}
input:checked + .slider:before {
transform: translateX(20px);
}
/* Modules Section */
.modules {
margin-bottom: 16px;
}
.modules h2 {
font-size: 13px;
font-weight: 600;
color: #aaa;
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.module-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 12px;
background: #252525;
border-radius: 6px;
margin-bottom: 6px;
transition: background 0.2s;
}
.module-item:hover {
background: #2a2a2a;
}
.module-info {
display: flex;
align-items: center;
gap: 8px;
}
.module-name {
font-size: 13px;
font-weight: 500;
}
.module-status {
font-size: 16px;
line-height: 1;
}
.module-status.active {
color: #4CAF50;
}
.module-status.inactive {
color: #666;
}
/* Stats Section */
.stats {
background: #252525;
border-radius: 8px;
padding: 12px;
margin-bottom: 16px;
}
.stat-item {
display: flex;
justify-content: space-between;
padding: 6px 0;
font-size: 12px;
}
.stat-label {
color: #aaa;
}
.stat-value {
color: #4CAF50;
font-weight: 600;
}
/* Footer */
footer {
text-align: center;
}
.btn-secondary {
width: 100%;
padding: 10px;
background: #333;
border: none;
border-radius: 6px;
color: #fff;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
margin-bottom: 8px;
}
.btn-secondary:hover {
background: #3a3a3a;
}
.warning {
font-size: 10px;
color: #ff9800;
margin-top: 8px;
}

View File

@@ -0,0 +1,135 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Automation Suite</title>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<div class="container">
<!-- Header -->
<header>
<h1>🔧 Payment Automation Suite</h1>
<p class="subtitle">Authorized Testing Tools</p>
</header>
<!-- Master Control -->
<section class="master-control">
<div class="control-row">
<span class="control-label">Master Control</span>
<label class="switch">
<input type="checkbox" id="masterSwitch">
<span class="slider"></span>
</label>
</div>
</section>
<!-- Module List -->
<section class="modules">
<h2>Modules</h2>
<div class="module-item">
<div class="module-info">
<span class="module-name">Captcha Solver</span>
<span class="module-status" id="status-captchaSolver"></span>
</div>
<label class="switch">
<input type="checkbox" class="module-toggle" data-module="captchaSolver">
<span class="slider"></span>
</label>
</div>
<div class="module-item">
<div class="module-info">
<span class="module-name">hCaptcha Bypass</span>
<span class="module-status" id="status-hcaptchaBypass"></span>
</div>
<label class="switch">
<input type="checkbox" class="module-toggle" data-module="hcaptchaBypass">
<span class="slider"></span>
</label>
</div>
<div class="module-item">
<div class="module-info">
<span class="module-name">3DS Handler</span>
<span class="module-status" id="status-threeDSecure"></span>
</div>
<label class="switch">
<input type="checkbox" class="module-toggle" data-module="threeDSecure">
<span class="slider"></span>
</label>
</div>
<div class="module-item">
<div class="module-info">
<span class="module-name">GOG Payment</span>
<span class="module-status" id="status-gogPayment"></span>
</div>
<label class="switch">
<input type="checkbox" class="module-toggle" data-module="gogPayment">
<span class="slider"></span>
</label>
</div>
<div class="module-item">
<div class="module-info">
<span class="module-name">Auto Fill</span>
<span class="module-status" id="status-autoFill"></span>
</div>
<label class="switch">
<input type="checkbox" class="module-toggle" data-module="autoFill">
<span class="slider"></span>
</label>
</div>
<div class="module-item">
<div class="module-info">
<span class="module-name">Fetch Spy</span>
<span class="module-status" id="status-fetchSpy"></span>
</div>
<label class="switch">
<input type="checkbox" class="module-toggle" data-module="fetchSpy">
<span class="slider"></span>
</label>
</div>
<div class="module-item">
<div class="module-info">
<span class="module-name">Payment Capture</span>
<span class="module-status" id="status-paymentHandler"></span>
</div>
<label class="switch">
<input type="checkbox" class="module-toggle" data-module="paymentHandler">
<span class="slider"></span>
</label>
</div>
</section>
<!-- Stats -->
<section class="stats">
<div class="stat-item">
<span class="stat-label">Captchas Solved:</span>
<span class="stat-value" id="stat-captchas">0</span>
</div>
<div class="stat-item">
<span class="stat-label">Forms Filled:</span>
<span class="stat-value" id="stat-forms">0</span>
</div>
<div class="stat-item">
<span class="stat-label">Cards Generated:</span>
<span class="stat-value" id="stat-cards">0</span>
</div>
</section>
<!-- Footer -->
<footer>
<button id="openOptions" class="btn-secondary">⚙️ Advanced Settings</button>
<p class="warning">⚠️ For authorized testing only</p>
</footer>
</div>
<script src="popup.js"></script>
</body>
</html>

188
extension/ui/popup/popup.js Normal file
View File

@@ -0,0 +1,188 @@
/**
* Popup UI Logic
*/
// Debug mode flag (set to true to enable verbose logging)
const DEBUG = true;
function debugLog(...args) {
if (DEBUG) {
console.log('[Popup DEBUG]', new Date().toISOString(), ...args);
}
}
// DOM elements
const masterSwitch = document.getElementById('masterSwitch');
const moduleToggles = document.querySelectorAll('.module-toggle');
const openOptionsBtn = document.getElementById('openOptions');
// Stats elements
const statCaptchas = document.getElementById('stat-captchas');
const statForms = document.getElementById('stat-forms');
const statCards = document.getElementById('stat-cards');
// Initialize popup
document.addEventListener('DOMContentLoaded', async () => {
debugLog('=== Popup DOMContentLoaded ===');
debugLog('DOM elements found:', {
masterSwitch: !!masterSwitch,
moduleToggles: moduleToggles.length,
openOptionsBtn: !!openOptionsBtn
});
await loadConfig();
await loadStats();
// Set up event listeners
masterSwitch.addEventListener('change', handleMasterToggle);
moduleToggles.forEach(toggle => {
toggle.addEventListener('change', handleModuleToggle);
});
openOptionsBtn.addEventListener('click', () => {
debugLog('Options button clicked');
chrome.runtime.openOptionsPage();
});
// Refresh stats every 2 seconds
setInterval(loadStats, 2000);
debugLog('=== Popup initialization complete ===');
});
/**
* Load configuration from storage
*/
async function loadConfig() {
debugLog('loadConfig: Starting to load configuration');
try {
const config = await chrome.storage.sync.get(['modules', 'globalSettings']);
debugLog('loadConfig: Received config from storage:', config);
// Set master switch
if (config.globalSettings) {
masterSwitch.checked = config.globalSettings.masterEnabled || false;
debugLog('loadConfig: Master switch set to', masterSwitch.checked);
}
// Set module toggles
if (config.modules) {
moduleToggles.forEach(toggle => {
const moduleName = toggle.dataset.module;
const moduleConfig = config.modules[moduleName];
if (moduleConfig) {
toggle.checked = moduleConfig.enabled || false;
updateModuleStatus(moduleName, moduleConfig.enabled);
debugLog(`loadConfig: Module ${moduleName} set to`, toggle.checked);
}
});
}
debugLog('loadConfig: Configuration loaded successfully');
} catch (error) {
console.error('[Popup] Failed to load config:', error);
debugLog('loadConfig: ERROR -', error);
}
}
/**
* Load statistics from storage
*/
async function loadStats() {
try {
const response = await chrome.runtime.sendMessage({ type: 'GET_STATS' });
if (response && response.success) {
const stats = response.stats;
statCaptchas.textContent = stats.captchasSolved || 0;
statForms.textContent = stats.formsFilled || 0;
statCards.textContent = stats.cardsGenerated || 0;
}
} catch (error) {
console.error('[Popup] Failed to load stats:', error);
}
}
/**
* Handle master switch toggle
*/
async function handleMasterToggle(event) {
const enabled = event.target.checked;
debugLog('handleMasterToggle: User toggled master switch to', enabled);
try {
debugLog('handleMasterToggle: Sending TOGGLE_MASTER message');
const response = await chrome.runtime.sendMessage({
type: 'TOGGLE_MASTER',
enabled
});
debugLog('handleMasterToggle: Received response:', response);
if (response && response.success) {
// Update all module toggles
moduleToggles.forEach(toggle => {
toggle.checked = enabled;
const moduleName = toggle.dataset.module;
updateModuleStatus(moduleName, enabled);
});
console.log('[Popup] Master switch:', enabled ? 'ON' : 'OFF');
debugLog('handleMasterToggle: All modules updated in UI');
} else {
debugLog('handleMasterToggle: Response indicated failure:', response);
event.target.checked = !enabled; // Revert on error
}
} catch (error) {
console.error('[Popup] Failed to toggle master:', error);
debugLog('handleMasterToggle: ERROR -', error);
event.target.checked = !enabled; // Revert on error
}
}
/**
* Handle individual module toggle
*/
async function handleModuleToggle(event) {
const moduleName = event.target.dataset.module;
const enabled = event.target.checked;
debugLog(`handleModuleToggle: User toggled ${moduleName} to`, enabled);
try {
debugLog('handleModuleToggle: Sending TOGGLE_MODULE message');
const response = await chrome.runtime.sendMessage({
type: 'TOGGLE_MODULE',
moduleName,
enabled
});
debugLog('handleModuleToggle: Received response:', response);
if (response && response.success) {
updateModuleStatus(moduleName, enabled);
console.log(`[Popup] Module ${moduleName}:`, enabled ? 'ON' : 'OFF');
debugLog('handleModuleToggle: Module status updated in UI');
} else {
debugLog('handleModuleToggle: Response indicated failure:', response);
event.target.checked = !enabled; // Revert on error
}
} catch (error) {
console.error(`[Popup] Failed to toggle ${moduleName}:`, error);
debugLog('handleModuleToggle: ERROR -', error);
event.target.checked = !enabled; // Revert on error
}
}
/**
* Update module status indicator
*/
function updateModuleStatus(moduleName, enabled) {
debugLog(`updateModuleStatus: ${moduleName} = ${enabled}`);
const statusElement = document.getElementById(`status-${moduleName}`);
if (statusElement) {
statusElement.textContent = enabled ? '●' : '○';
statusElement.className = enabled ? 'module-status active' : 'module-status inactive';
}
}