Remove profiles and password proxy UI, simplify to cookie-only auth
Strip out User Profiles section, username/password proxy method, and related modals. Cookie proxy section is now always visible and renamed to just "Camera Proxy". Cookie key input hidden (auto-populated by Chrome extension). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+3
-86
@@ -37,21 +37,6 @@
|
|||||||
<h1>Alta Video Camera Proxy</h1>
|
<h1>Alta Video Camera Proxy</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- User Profiles Section -->
|
|
||||||
<section class="content-section profile-section">
|
|
||||||
<h2>User Profiles</h2>
|
|
||||||
<div class="profile-controls">
|
|
||||||
<div class="profile-row">
|
|
||||||
<label for="profileSelect">Select Profile:</label>
|
|
||||||
<select id="profileSelect">
|
|
||||||
<option value="">Select a profile...</option>
|
|
||||||
</select>
|
|
||||||
<button type="button" id="addProfileBtn" class="btn-primary">Add User</button>
|
|
||||||
<button type="button" id="manageProfilesBtn" class="btn-success">Manage Users</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- API Connection Section -->
|
<!-- API Connection Section -->
|
||||||
<section class="content-section">
|
<section class="content-section">
|
||||||
<h2>API Connection</h2>
|
<h2>API Connection</h2>
|
||||||
@@ -65,41 +50,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="connection-controls">
|
<div class="connection-controls">
|
||||||
<button type="button" id="connectBtn" class="btn-primary" disabled>Connect to API</button>
|
|
||||||
<button type="button" id="testConnectionBtn" class="btn-outline" disabled>Test Connection</button>
|
<button type="button" id="testConnectionBtn" class="btn-outline" disabled>Test Connection</button>
|
||||||
<button type="button" id="disconnectBtn" class="btn-outline" disabled>Disconnect</button>
|
<button type="button" id="disconnectBtn" class="btn-outline" disabled>Disconnect</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="connectionStatus" class="status-message"></div>
|
<div id="connectionStatus" class="status-message"></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Camera Proxy Section -->
|
<!-- Cookie-Based Camera Proxy Section -->
|
||||||
<section class="content-section">
|
<section class="content-section">
|
||||||
<h2>Camera Proxy (Username/Password Method)</h2>
|
<h2>Camera Proxy</h2>
|
||||||
<div class="proxy-controls">
|
<div class="proxy-controls">
|
||||||
<div class="input-row">
|
|
||||||
<label for="deviceUUID">Device UUID:</label>
|
|
||||||
<input type="text" id="deviceUUID" placeholder="(Auto-filled when you select a device from the list)" readonly>
|
|
||||||
</div>
|
|
||||||
<div class="proxy-buttons">
|
|
||||||
<button type="button" id="startProxyBtn" class="btn-primary" disabled>Start Camera Proxy</button>
|
|
||||||
<button type="button" id="checkVersionBtn" class="btn-outline" disabled>Check Version</button>
|
|
||||||
<button type="button" id="stopProxyBtn" class="btn-outline" disabled>Stop Proxy</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Cookie-Based Camera Proxy Section (Collapsible) -->
|
|
||||||
<section class="content-section">
|
|
||||||
<div class="collapsible-header" id="cookieSectionHeader">
|
|
||||||
<h2>Camera Proxy (Cookie Method)</h2>
|
|
||||||
<span class="collapse-icon" id="cookieCollapseIcon">▼</span>
|
|
||||||
</div>
|
|
||||||
<div class="proxy-controls collapsible-content" id="cookieProxyContent" style="display: none;">
|
|
||||||
<div class="input-row">
|
<div class="input-row">
|
||||||
<label for="cookieDeviceUUID">Device UUID:</label>
|
<label for="cookieDeviceUUID">Device UUID:</label>
|
||||||
<input type="text" id="cookieDeviceUUID" placeholder="(Auto-filled when you select a device from the list)" readonly>
|
<input type="text" id="cookieDeviceUUID" placeholder="(Auto-filled when you select a device from the list)" readonly>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-row">
|
<div class="input-row" style="display: none;">
|
||||||
<label for="cookieKey">Cookie Key:</label>
|
<label for="cookieKey">Cookie Key:</label>
|
||||||
<input type="text" id="cookieKey" placeholder="Paste your cookie key here">
|
<input type="text" id="cookieKey" placeholder="Paste your cookie key here">
|
||||||
</div>
|
</div>
|
||||||
@@ -119,54 +84,6 @@
|
|||||||
<div id="mainContent"></div>
|
<div id="mainContent"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Add Profile Modal -->
|
|
||||||
<div id="addProfileModal" class="modal">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h3>Add Connection Profile</h3>
|
|
||||||
<span class="close" id="closeAddProfile">×</span>
|
|
||||||
</div>
|
|
||||||
<form id="addProfileForm">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="profileName">Profile Name:</label>
|
|
||||||
<input type="text" id="profileName" placeholder="Enter profile name" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="profileUrl">Deployment URL:</label>
|
|
||||||
<input type="url" id="profileUrl" placeholder="https://your-deployment.eu1.aware.avasecurity.com" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="profileUsername">Username:</label>
|
|
||||||
<input type="text" id="profileUsername" placeholder="Enter username" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="profilePassword">Password:</label>
|
|
||||||
<input type="password" id="profilePassword" placeholder="Enter password" required>
|
|
||||||
</div>
|
|
||||||
<div class="modal-buttons">
|
|
||||||
<button type="submit" class="modal-btn primary">Save Profile</button>
|
|
||||||
<button type="button" class="modal-btn secondary" id="cancelAddProfile">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Manage Profiles Modal -->
|
|
||||||
<div id="manageProfilesModal" class="modal">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h3>Manage Connection Profiles</h3>
|
|
||||||
<span class="close" id="closeManageProfiles">×</span>
|
|
||||||
</div>
|
|
||||||
<div class="profiles-list" id="profilesList">
|
|
||||||
<!-- Profiles will be populated here -->
|
|
||||||
</div>
|
|
||||||
<div class="modal-buttons">
|
|
||||||
<button type="button" class="modal-btn secondary" id="closeManageProfilesBtn">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="renderer.js"></script>
|
<script src="renderer.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+12
-547
@@ -6,21 +6,16 @@ let sessionData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// DOM elements
|
// DOM elements
|
||||||
const connectBtn = document.getElementById('connectBtn');
|
|
||||||
const connectionStatus = document.getElementById('connectionStatus');
|
const connectionStatus = document.getElementById('connectionStatus');
|
||||||
const deviceStatus = document.getElementById('deviceStatus');
|
const deviceStatus = document.getElementById('deviceStatus');
|
||||||
const deviceList = document.getElementById('deviceList');
|
const deviceList = document.getElementById('deviceList');
|
||||||
const deviceDetails = document.getElementById('deviceDetails');
|
const deviceDetails = document.getElementById('deviceDetails');
|
||||||
const statusIndicator = document.getElementById('statusIndicator');
|
const statusIndicator = document.getElementById('statusIndicator');
|
||||||
const deviceUUID = document.getElementById('deviceUUID');
|
|
||||||
const deviceSearch = document.getElementById('deviceSearch');
|
const deviceSearch = document.getElementById('deviceSearch');
|
||||||
|
|
||||||
// New buttons for the layout
|
// Connection buttons
|
||||||
const testConnectionBtn = document.getElementById('testConnectionBtn');
|
const testConnectionBtn = document.getElementById('testConnectionBtn');
|
||||||
const disconnectBtn = document.getElementById('disconnectBtn');
|
const disconnectBtn = document.getElementById('disconnectBtn');
|
||||||
const startProxyBtn = document.getElementById('startProxyBtn');
|
|
||||||
const checkVersionBtn = document.getElementById('checkVersionBtn');
|
|
||||||
const stopProxyBtn = document.getElementById('stopProxyBtn');
|
|
||||||
|
|
||||||
// Cookie proxy elements
|
// Cookie proxy elements
|
||||||
const cookieDeviceUUID = document.getElementById('cookieDeviceUUID');
|
const cookieDeviceUUID = document.getElementById('cookieDeviceUUID');
|
||||||
@@ -28,31 +23,14 @@ const cookieKey = document.getElementById('cookieKey');
|
|||||||
const startCookieProxyBtn = document.getElementById('startCookieProxyBtn');
|
const startCookieProxyBtn = document.getElementById('startCookieProxyBtn');
|
||||||
const stopCookieProxyBtn = document.getElementById('stopCookieProxyBtn');
|
const stopCookieProxyBtn = document.getElementById('stopCookieProxyBtn');
|
||||||
|
|
||||||
// Profile management elements
|
// Track selected device
|
||||||
const profileSelect = document.getElementById('profileSelect');
|
|
||||||
const addProfileBtn = document.getElementById('addProfileBtn');
|
|
||||||
const manageProfilesBtn = document.getElementById('manageProfilesBtn');
|
|
||||||
const addProfileModal = document.getElementById('addProfileModal');
|
|
||||||
const manageProfilesModal = document.getElementById('manageProfilesModal');
|
|
||||||
const addProfileForm = document.getElementById('addProfileForm');
|
|
||||||
const profilesList = document.getElementById('profilesList');
|
|
||||||
|
|
||||||
// Track selected device and profiles
|
|
||||||
let selectedDevice = null;
|
let selectedDevice = null;
|
||||||
let currentProfiles = [];
|
|
||||||
let selectedProfile = null;
|
|
||||||
let activeProxyConnections = new Map(); // Track multiple active connections
|
|
||||||
let activeCookieProxyConnections = new Map(); // Track cookie-based proxy connections
|
let activeCookieProxyConnections = new Map(); // Track cookie-based proxy connections
|
||||||
const MAX_PROXY_CONNECTIONS = 2; // Limit to 2 simultaneous connections
|
|
||||||
let allDevices = []; // Store all devices for search functionality
|
let allDevices = []; // Store all devices for search functionality
|
||||||
|
|
||||||
// Event listeners
|
// Event listeners
|
||||||
connectBtn.addEventListener('click', handleConnection);
|
|
||||||
testConnectionBtn.addEventListener('click', handleTestConnection);
|
testConnectionBtn.addEventListener('click', handleTestConnection);
|
||||||
disconnectBtn.addEventListener('click', handleDisconnect);
|
disconnectBtn.addEventListener('click', handleDisconnect);
|
||||||
startProxyBtn.addEventListener('click', handleStartProxy);
|
|
||||||
checkVersionBtn.addEventListener('click', handleCheckVersion);
|
|
||||||
stopProxyBtn.addEventListener('click', handleStopProxy);
|
|
||||||
|
|
||||||
// Cookie proxy event listeners
|
// Cookie proxy event listeners
|
||||||
startCookieProxyBtn.addEventListener('click', handleStartCookieProxy);
|
startCookieProxyBtn.addEventListener('click', handleStartCookieProxy);
|
||||||
@@ -64,76 +42,6 @@ cookieKey.addEventListener('input', updateCookieProxyButtonStates);
|
|||||||
// Device search event listener
|
// Device search event listener
|
||||||
deviceSearch.addEventListener('input', handleDeviceSearch);
|
deviceSearch.addEventListener('input', handleDeviceSearch);
|
||||||
|
|
||||||
// Cookie section collapsible header
|
|
||||||
document.getElementById('cookieSectionHeader').addEventListener('click', toggleCookieSection);
|
|
||||||
|
|
||||||
// Profile management event listeners
|
|
||||||
profileSelect.addEventListener('change', handleProfileSelection);
|
|
||||||
addProfileBtn.addEventListener('click', showAddProfileModal);
|
|
||||||
manageProfilesBtn.addEventListener('click', showManageProfilesModal);
|
|
||||||
addProfileForm.addEventListener('submit', handleAddProfile);
|
|
||||||
|
|
||||||
// Modal event listeners
|
|
||||||
document.getElementById('closeAddProfile').addEventListener('click', hideAddProfileModal);
|
|
||||||
document.getElementById('cancelAddProfile').addEventListener('click', hideAddProfileModal);
|
|
||||||
document.getElementById('closeManageProfiles').addEventListener('click', hideManageProfilesModal);
|
|
||||||
document.getElementById('closeManageProfilesBtn').addEventListener('click', hideManageProfilesModal);
|
|
||||||
|
|
||||||
// Close modals when clicking outside
|
|
||||||
addProfileModal.addEventListener('click', (e) => {
|
|
||||||
if (e.target === addProfileModal) hideAddProfileModal();
|
|
||||||
});
|
|
||||||
manageProfilesModal.addEventListener('click', (e) => {
|
|
||||||
if (e.target === manageProfilesModal) hideManageProfilesModal();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Handle connection button click
|
|
||||||
async function handleConnection() {
|
|
||||||
if (!selectedProfile) {
|
|
||||||
showStatus(connectionStatus, 'Please select a profile to connect', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable button during connection
|
|
||||||
setConnectButtonEnabled(false);
|
|
||||||
showStatus(connectionStatus, 'Connecting to Alta API...', 'info');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.login({
|
|
||||||
deploymentUrl: selectedProfile.deploymentUrl,
|
|
||||||
username: selectedProfile.username,
|
|
||||||
password: selectedProfile.password
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
// Store session data
|
|
||||||
sessionData.deploymentUrl = selectedProfile.deploymentUrl;
|
|
||||||
sessionData.cookies = result.cookies;
|
|
||||||
sessionData.isConnected = true;
|
|
||||||
|
|
||||||
showStatus(connectionStatus, 'Connected successfully!', 'success');
|
|
||||||
updateConnectionStatus(true);
|
|
||||||
updateButtonStates();
|
|
||||||
|
|
||||||
// Auto-retrieve devices when connected
|
|
||||||
try {
|
|
||||||
await handleGetDevices();
|
|
||||||
} catch (deviceError) {
|
|
||||||
console.error('Failed to auto-fetch devices:', deviceError);
|
|
||||||
showStatus(deviceStatus, 'Connected, but failed to load devices. Try selecting a profile and reconnecting.', 'warning');
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
showStatus(connectionStatus, `Connection failed: ${result.message}`, 'error');
|
|
||||||
setConnectButtonEnabled(true);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Connection error:', error);
|
|
||||||
showStatus(connectionStatus, `Connection error: ${error.message}`, 'error');
|
|
||||||
setConnectButtonEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle test connection
|
// Handle test connection
|
||||||
async function handleTestConnection() {
|
async function handleTestConnection() {
|
||||||
if (!sessionData.isConnected) {
|
if (!sessionData.isConnected) {
|
||||||
@@ -166,14 +74,12 @@ function handleDisconnect() {
|
|||||||
sessionData.cookies = null;
|
sessionData.cookies = null;
|
||||||
sessionData.deploymentUrl = '';
|
sessionData.deploymentUrl = '';
|
||||||
selectedDevice = null;
|
selectedDevice = null;
|
||||||
activeProxyConnections.clear();
|
|
||||||
activeCookieProxyConnections.clear();
|
activeCookieProxyConnections.clear();
|
||||||
allDevices = []; // Clear stored devices
|
allDevices = []; // Clear stored devices
|
||||||
|
|
||||||
updateConnectionStatus(false);
|
updateConnectionStatus(false);
|
||||||
updateButtonStates();
|
updateButtonStates();
|
||||||
clearDeviceList();
|
clearDeviceList();
|
||||||
deviceUUID.value = '';
|
|
||||||
cookieDeviceUUID.value = '';
|
cookieDeviceUUID.value = '';
|
||||||
cookieKey.value = '';
|
cookieKey.value = '';
|
||||||
deviceSearch.value = ''; // Clear search input
|
deviceSearch.value = ''; // Clear search input
|
||||||
@@ -182,139 +88,9 @@ function handleDisconnect() {
|
|||||||
deviceStatus.style.display = 'none';
|
deviceStatus.style.display = 'none';
|
||||||
deviceStatus.textContent = '';
|
deviceStatus.textContent = '';
|
||||||
|
|
||||||
// Reset connect button text if it was stuck
|
|
||||||
connectBtn.textContent = 'Connect to API';
|
|
||||||
connectBtn.disabled = !selectedProfile;
|
|
||||||
|
|
||||||
// Reset proxy buttons
|
|
||||||
startProxyBtn.disabled = true;
|
|
||||||
stopProxyBtn.disabled = true;
|
|
||||||
|
|
||||||
showStatus(connectionStatus, 'Disconnected from API', 'info');
|
showStatus(connectionStatus, 'Disconnected from API', 'info');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle start proxy
|
|
||||||
async function handleStartProxy() {
|
|
||||||
if (!selectedDevice) {
|
|
||||||
showStatus(connectionStatus, 'Please select a device first', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selectedProfile) {
|
|
||||||
showStatus(connectionStatus, 'Please select a profile first', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check connection limit
|
|
||||||
if (activeProxyConnections.size >= MAX_PROXY_CONNECTIONS) {
|
|
||||||
showStatus(connectionStatus, `Maximum of ${MAX_PROXY_CONNECTIONS} camera proxy connections allowed. Stop an existing connection first.`, 'warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this device already has an active connection
|
|
||||||
const deviceId = selectedDevice.guid || selectedDevice.id;
|
|
||||||
if (activeProxyConnections.has(deviceId)) {
|
|
||||||
showStatus(connectionStatus, `Camera proxy already running for device ${selectedDevice.name}`, 'warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if camera proxy executable exists
|
|
||||||
try {
|
|
||||||
const checkResult = await window.electronAPI.checkCameraProxy();
|
|
||||||
if (!checkResult.exists) {
|
|
||||||
showStatus(connectionStatus, 'Camera proxy executable (aware-cam-proxy-win.exe) not found in application directory', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
showStatus(connectionStatus, 'Failed to check camera proxy executable', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable button during launch
|
|
||||||
startProxyBtn.disabled = true;
|
|
||||||
showStatus(connectionStatus, `Starting camera proxy for device ${selectedDevice.name}...`, 'info');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.launchCameraProxy({
|
|
||||||
deploymentUrl: selectedProfile.deploymentUrl,
|
|
||||||
username: selectedProfile.username,
|
|
||||||
password: selectedProfile.password,
|
|
||||||
deviceUuid: deviceId
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
// Track this connection
|
|
||||||
activeProxyConnections.set(deviceId, {
|
|
||||||
processId: result.processId,
|
|
||||||
deviceName: selectedDevice.name,
|
|
||||||
deviceId: deviceId,
|
|
||||||
startTime: Date.now()
|
|
||||||
});
|
|
||||||
|
|
||||||
updateProxyButtonStates();
|
|
||||||
showStatus(connectionStatus, `${result.message} (${activeProxyConnections.size}/${MAX_PROXY_CONNECTIONS} connections active)`, 'success');
|
|
||||||
} else {
|
|
||||||
showStatus(connectionStatus, `Failed to start camera proxy: ${result.message}`, 'error');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Camera proxy launch error:', error);
|
|
||||||
showStatus(connectionStatus, `Error launching camera proxy: ${error.message}`, 'error');
|
|
||||||
} finally {
|
|
||||||
startProxyBtn.disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle check version
|
|
||||||
async function handleCheckVersion() {
|
|
||||||
showStatus(connectionStatus, 'Checking camera proxy version...', 'info');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.getCameraProxyVersion();
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
showStatus(connectionStatus, `Camera Proxy Version: ${result.version}`, 'info');
|
|
||||||
} else {
|
|
||||||
showStatus(connectionStatus, `Failed to get version: ${result.message}`, 'error');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Version check error:', error);
|
|
||||||
showStatus(connectionStatus, `Error checking version: ${error.message}`, 'error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle stop proxy
|
|
||||||
async function handleStopProxy() {
|
|
||||||
if (activeProxyConnections.size === 0) {
|
|
||||||
showStatus(connectionStatus, 'No active camera proxy connections found', 'warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
showStatus(connectionStatus, 'Stopping all camera proxy connections...', 'info');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.stopCameraProxy(null); // Stop all processes
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
activeProxyConnections.clear();
|
|
||||||
showStatus(connectionStatus, 'All camera proxy connections stopped successfully', 'success');
|
|
||||||
|
|
||||||
// Update visual indicators for all devices
|
|
||||||
const deviceItems = deviceList.querySelectorAll('.device-item');
|
|
||||||
deviceItems.forEach(item => {
|
|
||||||
item.classList.remove('proxy-active');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
showStatus(connectionStatus, `Failed to stop camera proxy: ${result.message}`, 'warning');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Stop proxy error:', error);
|
|
||||||
showStatus(connectionStatus, 'Error stopping camera proxy', 'error');
|
|
||||||
}
|
|
||||||
|
|
||||||
updateProxyButtonStates();
|
|
||||||
updateCookieProxyButtonStates();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle start cookie proxy
|
// Handle start cookie proxy
|
||||||
async function handleStartCookieProxy() {
|
async function handleStartCookieProxy() {
|
||||||
if (!selectedDevice) {
|
if (!selectedDevice) {
|
||||||
@@ -441,19 +217,11 @@ function updateConnectionStatus(connected) {
|
|||||||
// Update button states based on connection status
|
// Update button states based on connection status
|
||||||
function updateButtonStates() {
|
function updateButtonStates() {
|
||||||
if (sessionData.isConnected) {
|
if (sessionData.isConnected) {
|
||||||
connectBtn.style.display = 'none'; // Hide connect button when connected
|
|
||||||
testConnectionBtn.disabled = false;
|
testConnectionBtn.disabled = false;
|
||||||
disconnectBtn.disabled = false;
|
disconnectBtn.disabled = false;
|
||||||
checkVersionBtn.disabled = false;
|
|
||||||
updateProxyButtonStates(); // Update proxy buttons when connected
|
|
||||||
} else {
|
} else {
|
||||||
connectBtn.style.display = 'inline-block'; // Show connect button when disconnected
|
|
||||||
connectBtn.disabled = !selectedProfile;
|
|
||||||
testConnectionBtn.disabled = true;
|
testConnectionBtn.disabled = true;
|
||||||
disconnectBtn.disabled = true;
|
disconnectBtn.disabled = true;
|
||||||
startProxyBtn.disabled = true;
|
|
||||||
checkVersionBtn.disabled = true;
|
|
||||||
stopProxyBtn.disabled = true;
|
|
||||||
startCookieProxyBtn.disabled = true;
|
startCookieProxyBtn.disabled = true;
|
||||||
stopCookieProxyBtn.disabled = true;
|
stopCookieProxyBtn.disabled = true;
|
||||||
}
|
}
|
||||||
@@ -628,11 +396,11 @@ function displayDevices(devices) {
|
|||||||
|
|
||||||
const deviceStatus = getDeviceStatus(device);
|
const deviceStatus = getDeviceStatus(device);
|
||||||
const deviceId = device.guid || device.id;
|
const deviceId = device.guid || device.id;
|
||||||
const isProxyActive = activeProxyConnections.has(deviceId);
|
const isCookieProxyActive = activeCookieProxyConnections.has(deviceId);
|
||||||
|
|
||||||
// Add proxy-active class if this device has an active connection
|
// Add cookie-proxy-active class if this device has an active cookie connection
|
||||||
if (isProxyActive) {
|
if (isCookieProxyActive) {
|
||||||
deviceItem.classList.add('proxy-active');
|
deviceItem.classList.add('cookie-proxy-active');
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceItem.innerHTML = `
|
deviceItem.innerHTML = `
|
||||||
@@ -646,8 +414,8 @@ function displayDevices(devices) {
|
|||||||
deviceList.appendChild(deviceItem);
|
deviceList.appendChild(deviceItem);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update proxy button states after displaying devices
|
// Update cookie proxy button states after displaying devices
|
||||||
updateProxyButtonStates();
|
updateCookieProxyButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle device selection
|
// Handle device selection
|
||||||
@@ -662,21 +430,17 @@ function selectDevice(device, deviceElement) {
|
|||||||
deviceElement.classList.add('selected');
|
deviceElement.classList.add('selected');
|
||||||
selectedDevice = device;
|
selectedDevice = device;
|
||||||
|
|
||||||
// Auto-populate device UUID fields
|
// Auto-populate cookie device UUID field
|
||||||
const uuid = device.guid || device.id || '';
|
const uuid = device.guid || device.id || '';
|
||||||
deviceUUID.value = uuid;
|
cookieDeviceUUID.value = uuid;
|
||||||
cookieDeviceUUID.value = uuid; // Also populate cookie proxy UUID field
|
|
||||||
|
|
||||||
// Show device selection feedback with connection status
|
// Show device selection feedback with connection status
|
||||||
if (uuid) {
|
if (uuid) {
|
||||||
const isActive = activeProxyConnections.has(uuid);
|
|
||||||
const isCookieActive = activeCookieProxyConnections.has(uuid);
|
const isCookieActive = activeCookieProxyConnections.has(uuid);
|
||||||
const statusText = isActive ? ' (PROXY ACTIVE)' : '';
|
|
||||||
const cookieStatusText = isCookieActive ? ' (COOKIE PROXY ACTIVE)' : '';
|
const cookieStatusText = isCookieActive ? ' (COOKIE PROXY ACTIVE)' : '';
|
||||||
showStatus(connectionStatus, `Selected device: ${device.name || 'Unnamed Device'} (UUID: ${uuid})${statusText}${cookieStatusText}`, 'info');
|
showStatus(connectionStatus, `Selected device: ${device.name || 'Unnamed Device'} (UUID: ${uuid})${cookieStatusText}`, 'info');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProxyButtonStates();
|
|
||||||
updateCookieProxyButtonStates();
|
updateCookieProxyButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,41 +511,9 @@ function showStatus(element, message, type) {
|
|||||||
element.style.display = 'block';
|
element.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
function setConnectButtonEnabled(enabled) {
|
|
||||||
connectBtn.disabled = !enabled;
|
|
||||||
connectBtn.textContent = enabled ? 'Connect to Alta API' : 'Connecting...';
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearDeviceList() {
|
function clearDeviceList() {
|
||||||
deviceList.innerHTML = '<p class="placeholder-text">Connect to API to load devices</p>';
|
deviceList.innerHTML = '<p class="placeholder-text">Connect to API to load devices</p>';
|
||||||
selectedDevice = null;
|
selectedDevice = null;
|
||||||
deviceUUID.value = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// New function to update proxy button states based on active connections
|
|
||||||
function updateProxyButtonStates() {
|
|
||||||
if (!sessionData.isConnected) {
|
|
||||||
startProxyBtn.disabled = true;
|
|
||||||
stopProxyBtn.disabled = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasActiveConnections = activeProxyConnections.size > 0;
|
|
||||||
const atMaxConnections = activeProxyConnections.size >= MAX_PROXY_CONNECTIONS;
|
|
||||||
const selectedDeviceActive = selectedDevice && activeProxyConnections.has(selectedDevice.guid || selectedDevice.id);
|
|
||||||
|
|
||||||
// Enable start button if: connected, device selected, not at max connections, and device not already active
|
|
||||||
startProxyBtn.disabled = !selectedDevice || atMaxConnections || selectedDeviceActive;
|
|
||||||
|
|
||||||
// Enable stop button if there are active connections
|
|
||||||
stopProxyBtn.disabled = !hasActiveConnections;
|
|
||||||
|
|
||||||
// Update button text to show connection count
|
|
||||||
if (hasActiveConnections) {
|
|
||||||
stopProxyBtn.textContent = `Stop All Proxies (${activeProxyConnections.size})`;
|
|
||||||
} else {
|
|
||||||
stopProxyBtn.textContent = 'Stop Proxy';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(text) {
|
function escapeHtml(text) {
|
||||||
@@ -791,211 +523,6 @@ function escapeHtml(text) {
|
|||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Profile Management Functions
|
|
||||||
async function loadProfiles() {
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.loadProfiles();
|
|
||||||
if (result.success) {
|
|
||||||
currentProfiles = result.profiles;
|
|
||||||
updateProfileDropdown();
|
|
||||||
} else {
|
|
||||||
console.error('Failed to load profiles:', result.message);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error loading profiles:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateProfileDropdown() {
|
|
||||||
// Clear existing options except the first one
|
|
||||||
profileSelect.innerHTML = '<option value="">Select a profile...</option>';
|
|
||||||
|
|
||||||
currentProfiles.forEach(profile => {
|
|
||||||
const option = document.createElement('option');
|
|
||||||
option.value = profile.id;
|
|
||||||
option.textContent = `${profile.name} (${profile.username})`;
|
|
||||||
profileSelect.appendChild(option);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleProfileSelection() {
|
|
||||||
const selectedProfileId = profileSelect.value;
|
|
||||||
if (!selectedProfileId) {
|
|
||||||
selectedProfile = null;
|
|
||||||
updateButtonStates();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.getProfile(selectedProfileId);
|
|
||||||
if (result.success) {
|
|
||||||
selectedProfile = result.profile;
|
|
||||||
updateButtonStates();
|
|
||||||
} else {
|
|
||||||
showStatus(connectionStatus, `Failed to load profile: ${result.message}`, 'error');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error loading profile:', error);
|
|
||||||
showStatus(connectionStatus, 'Error loading profile', 'error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showAddProfileModal() {
|
|
||||||
// Clear the form for new profile
|
|
||||||
addProfileForm.reset();
|
|
||||||
|
|
||||||
addProfileModal.style.display = 'block';
|
|
||||||
document.getElementById('profileName').focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideAddProfileModal() {
|
|
||||||
addProfileModal.style.display = 'none';
|
|
||||||
addProfileForm.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleAddProfile(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const name = document.getElementById('profileName').value.trim();
|
|
||||||
const deploymentUrl = document.getElementById('profileUrl').value.trim();
|
|
||||||
const username = document.getElementById('profileUsername').value.trim();
|
|
||||||
const password = document.getElementById('profilePassword').value;
|
|
||||||
|
|
||||||
if (!name || !deploymentUrl || !username || !password) {
|
|
||||||
alert('Please fill in all fields');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if profile name already exists
|
|
||||||
if (currentProfiles.some(p => p.name.toLowerCase() === name.toLowerCase())) {
|
|
||||||
alert('A profile with this name already exists');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.saveProfile({
|
|
||||||
name: name,
|
|
||||||
deploymentUrl: deploymentUrl.replace(/\/$/, ''), // Remove trailing slash
|
|
||||||
username: username,
|
|
||||||
password: password
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
hideAddProfileModal();
|
|
||||||
await loadProfiles(); // Reload profiles
|
|
||||||
|
|
||||||
// Select the newly created profile
|
|
||||||
profileSelect.value = result.profile.id;
|
|
||||||
await handleProfileSelection();
|
|
||||||
|
|
||||||
showStatus(connectionStatus, 'Profile saved successfully!', 'success');
|
|
||||||
} else {
|
|
||||||
alert(`Failed to save profile: ${result.message}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error saving profile:', error);
|
|
||||||
alert('Error saving profile');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showManageProfilesModal() {
|
|
||||||
updateProfilesList();
|
|
||||||
manageProfilesModal.style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideManageProfilesModal() {
|
|
||||||
manageProfilesModal.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateProfilesList() {
|
|
||||||
profilesList.innerHTML = '';
|
|
||||||
|
|
||||||
if (currentProfiles.length === 0) {
|
|
||||||
profilesList.innerHTML = '<div class="no-profiles">No profiles saved</div>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentProfiles.forEach(profile => {
|
|
||||||
const profileItem = document.createElement('div');
|
|
||||||
profileItem.className = 'profile-item';
|
|
||||||
|
|
||||||
profileItem.innerHTML = `
|
|
||||||
<div class="profile-info">
|
|
||||||
<h4>${escapeHtml(profile.name)}</h4>
|
|
||||||
<p>${escapeHtml(profile.username)} @ ${escapeHtml(profile.deploymentUrl)}</p>
|
|
||||||
</div>
|
|
||||||
<div class="profile-actions">
|
|
||||||
<button class="profile-action-btn edit">Edit</button>
|
|
||||||
<button class="profile-action-btn delete">Delete</button>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
profileItem.querySelector('.edit').addEventListener('click', () => editProfile(profile.id));
|
|
||||||
profileItem.querySelector('.delete').addEventListener('click', () => deleteProfile(profile.id));
|
|
||||||
|
|
||||||
profilesList.appendChild(profileItem);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function editProfile(profileId) {
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.getProfile(profileId);
|
|
||||||
if (result.success) {
|
|
||||||
const profile = result.profile;
|
|
||||||
const newName = prompt('Enter new profile name:', profile.name);
|
|
||||||
if (newName && newName.trim() !== profile.name) {
|
|
||||||
const updateResult = await window.electronAPI.updateProfile(profileId, {
|
|
||||||
name: newName.trim(),
|
|
||||||
deploymentUrl: profile.deploymentUrl,
|
|
||||||
username: profile.username,
|
|
||||||
password: profile.password
|
|
||||||
});
|
|
||||||
|
|
||||||
if (updateResult.success) {
|
|
||||||
await loadProfiles();
|
|
||||||
updateProfilesList();
|
|
||||||
showStatus(connectionStatus, 'Profile updated successfully!', 'success');
|
|
||||||
} else {
|
|
||||||
alert(`Failed to update profile: ${updateResult.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error editing profile:', error);
|
|
||||||
alert('Error editing profile');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteProfile(profileId) {
|
|
||||||
const profile = currentProfiles.find(p => p.id === profileId);
|
|
||||||
if (!profile) return;
|
|
||||||
|
|
||||||
if (confirm(`Are you sure you want to delete the profile "${profile.name}"?`)) {
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.deleteProfile(profileId);
|
|
||||||
if (result.success) {
|
|
||||||
await loadProfiles();
|
|
||||||
updateProfilesList();
|
|
||||||
|
|
||||||
// Clear selection if deleted profile was selected
|
|
||||||
if (profileSelect.value === profileId) {
|
|
||||||
profileSelect.value = '';
|
|
||||||
await handleProfileSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
showStatus(connectionStatus, 'Profile deleted successfully!', 'success');
|
|
||||||
} else {
|
|
||||||
alert(`Failed to delete profile: ${result.message}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error deleting profile:', error);
|
|
||||||
alert('Error deleting profile');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// toggleCookieSection is attached via addEventListener in the event listeners section above
|
|
||||||
|
|
||||||
// Handle cookie received from Chrome extension via local HTTP bridge
|
// Handle cookie received from Chrome extension via local HTTP bridge
|
||||||
async function handleExtensionCookie(data) {
|
async function handleExtensionCookie(data) {
|
||||||
const { deploymentUrl, cookies, cookieValue } = data;
|
const { deploymentUrl, cookies, cookieValue } = data;
|
||||||
@@ -1014,15 +541,8 @@ async function handleExtensionCookie(data) {
|
|||||||
updateConnectionStatus(true);
|
updateConnectionStatus(true);
|
||||||
updateButtonStates();
|
updateButtonStates();
|
||||||
|
|
||||||
// Auto-populate cookie key and expand cookie proxy section
|
// Auto-populate cookie key
|
||||||
cookieKey.value = cookieValue;
|
cookieKey.value = cookieValue;
|
||||||
const cookieContent = document.getElementById('cookieProxyContent');
|
|
||||||
const cookieIcon = document.getElementById('cookieCollapseIcon');
|
|
||||||
if (cookieContent.style.display === 'none') {
|
|
||||||
cookieContent.style.display = 'block';
|
|
||||||
cookieIcon.textContent = '\u25B2';
|
|
||||||
cookieIcon.classList.add('expanded');
|
|
||||||
}
|
|
||||||
updateCookieProxyButtonStates();
|
updateCookieProxyButtonStates();
|
||||||
|
|
||||||
// Fetch devices
|
// Fetch devices
|
||||||
@@ -1044,59 +564,4 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
|
|
||||||
// Listen for cookies pushed from Chrome extension
|
// Listen for cookies pushed from Chrome extension
|
||||||
window.electronAPI.onExtensionCookie(handleExtensionCookie);
|
window.electronAPI.onExtensionCookie(handleExtensionCookie);
|
||||||
|
|
||||||
// Load saved profiles
|
|
||||||
await loadProfiles();
|
|
||||||
|
|
||||||
// Check camera proxy executable availability
|
|
||||||
await checkCameraProxyAvailability();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if camera proxy executable is available
|
|
||||||
async function checkCameraProxyAvailability() {
|
|
||||||
try {
|
|
||||||
const result = await window.electronAPI.checkCameraProxy();
|
|
||||||
|
|
||||||
if (!result.exists) {
|
|
||||||
showStatus(connectionStatus, 'Warning: aware-cam-proxy-win.exe not found. Camera proxy functionality will not work.', 'warning');
|
|
||||||
// Disable proxy-related buttons
|
|
||||||
startProxyBtn.disabled = true;
|
|
||||||
checkVersionBtn.disabled = true;
|
|
||||||
|
|
||||||
// Add a tooltip or visual indicator
|
|
||||||
startProxyBtn.title = 'Camera proxy executable not found';
|
|
||||||
checkVersionBtn.title = 'Camera proxy executable not found';
|
|
||||||
} else {
|
|
||||||
console.log('Camera proxy executable found at:', result.path);
|
|
||||||
|
|
||||||
// Optionally get version info
|
|
||||||
try {
|
|
||||||
const versionResult = await window.electronAPI.getCameraProxyVersion();
|
|
||||||
if (versionResult.success) {
|
|
||||||
console.log('Camera proxy version:', versionResult.version);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log('Could not get camera proxy version:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error checking camera proxy availability:', error);
|
|
||||||
showStatus(connectionStatus, 'Error checking camera proxy availability', 'warning');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle cookie section visibility
|
|
||||||
function toggleCookieSection() {
|
|
||||||
const content = document.getElementById('cookieProxyContent');
|
|
||||||
const icon = document.getElementById('cookieCollapseIcon');
|
|
||||||
|
|
||||||
if (content.style.display === 'none') {
|
|
||||||
content.style.display = 'block';
|
|
||||||
icon.textContent = '▲';
|
|
||||||
icon.classList.add('expanded');
|
|
||||||
} else {
|
|
||||||
content.style.display = 'none';
|
|
||||||
icon.textContent = '▼';
|
|
||||||
icon.classList.remove('expanded');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user