# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Alta Proxy Tool (APT) — an Electron desktop app that authenticates with Avigilon Alta Video deployments via a companion Chrome extension, discovers cameras, and launches `aware-cam-proxy.exe` to establish camera connections. Authentication uses cookie import from Chrome — no username/password login flow. Windows-only due to the proxy executable. ## Repository - **GitHub**: https://github.com/PageZ948/Alta-Proxy-Tool (private) - **Branch**: master - **Git identity**: Zac (repo-local config) ## Commands ```bash npm start # Run the app npm run dev # Run with DevTools open (--dev flag) npm run build # Build portable Windows .exe (output: dist/) npm run build-test # Build to directory without packaging ``` No test framework is configured. No linter is configured. ## Architecture This is a vanilla Electron app (no React/Vue/framework). Core files: ``` main.js → Electron main process: IPC handlers, API calls (axios), cookie proxy process spawning, local HTTP cookie server preload.js → contextBridge exposing window.electronAPI with IPC wrappers renderer.js → All UI logic: DOM manipulation, state management, event handlers index.html → Static HTML shell, no inline scripts (CSP enforced) styles.css → Dark theme using CSS custom properties ``` A companion Chrome extension lives in `chrome-extension/`: ``` chrome-extension/ manifest.json → Manifest V3, cookies + activeTab permissions popup.html → Extension popup UI popup.css → Dark theme matching the Electron app popup.js → Tab detection, cookie retrieval, POST to localhost icon*.png → Placeholder icons ``` ### Authentication Flow There is no login form or profile system. Authentication works exclusively through the Chrome extension cookie bridge: 1. User logs into Alta deployment in Chrome 2. Clicks the Chrome extension popup → "Send Cookie to APT" 3. Extension POSTs `{deploymentUrl, cookieValue}` to `http://127.0.0.1:18247/cookie` with `X-APT-Token` header 4. `main.js` HTTP server validates and forwards via IPC push to renderer 5. `renderer.js` `handleExtensionCookie()` sets session state, auto-populates cookie key, fetches devices The extension is loaded unpacked via `chrome://extensions/` → Developer mode → Load unpacked → select `chrome-extension/`. ### IPC Communication Pattern Most cross-process communication follows the request/response pattern: 1. `main.js` registers handler: `ipcMain.handle('channel-name', async (event, params) => { ... })` 2. `preload.js` exposes it: `channelName: (params) => ipcRenderer.invoke('channel-name', params)` 3. `renderer.js` calls it: `const result = await window.electronAPI.channelName(params)` All handlers return `{ success: boolean, message?: string, ...data }`. There is one **push-pattern** channel for the Chrome extension cookie bridge: - `main.js` sends: `mainWindow.webContents.send('extension-cookie-received', data)` - `preload.js` bridges: `ipcRenderer.on('extension-cookie-received', callback)` - `renderer.js` listens via `window.electronAPI.onExtensionCookie(callback)` ### IPC Channels | Channel | Purpose | |---------|---------| | `api-get-devices` | GET /api/v1/devices with cookie auth | | `api-get-auth-info` | GET /api/v1/auth to verify session | | `camera-proxy-cookie-launch` | Spawns aware-cam-proxy.exe (cookie method) | | `camera-proxy-stop` | Kills all proxy processes via taskkill/powershell | | `extension-cookie-received` | Push channel: cookie data from Chrome extension → renderer | ### State Management (renderer.js) All connection state lives in the `sessionData` object (deploymentUrl, cookies, isConnected). There is no separate `isConnected` flag — always use `sessionData.isConnected`. Active cookie proxy processes are tracked in `activeCookieProxyConnections` Map, keyed by device GUID. ### Security Model - Context isolation enabled, nodeIntegration disabled - CSP meta tag: `script-src 'self'` — no inline scripts or onclick handlers allowed - Batch file inputs are sanitized via `sanitizeBatchInput()` to prevent command injection - Local HTTP cookie server (port 18247) bound to `127.0.0.1` only - Cookie server validates: shared token header, CORS restricted to `chrome-extension://` origins, deployment URL must be `*.avasecurity.com` or `*.avigilon.com` over HTTPS, type/length limits on all inputs, 64KB body size limit ## Key Conventions - No inline event handlers in HTML — all use `addEventListener` in renderer.js - All user-provided content rendered to DOM must go through `escapeHtml()` (XSS prevention) - External processes spawned with `detached: true` + `unref()` so they survive if the app closes - Device list filters out cloud cameras (`capabilities.localStorage === false` only) - `clearDeviceList()` must NOT clear proxy connection Maps (proxies may still be running) ## External Executable - `aware-cam-proxy.exe` — cookie-based auth proxy (required) Not bundled via npm. Must be in the app root directory. Gitignored along with `*.pdf`, `node_modules/`, and `dist/`.