// MacroPad login page logic (externalized so the CSP can drop 'unsafe-inline' // for scripts). const sessionId = window.location.pathname.split('/')[1]; const form = document.getElementById('loginForm'); const passwordInput = document.getElementById('password'); const rememberCheckbox = document.getElementById('remember'); const submitBtn = document.getElementById('submitBtn'); const errorDiv = document.getElementById('error'); const statusDiv = document.getElementById('status'); let desktopConnected = false; // Check for saved password (session first, then "remembered" store) const savedPassword = sessionStorage.getItem(`macropad_${sessionId}`) || localStorage.getItem(`macropad_${sessionId}`); if (savedPassword) { passwordInput.value = savedPassword; } // Connect to WebSocket to check desktop status function checkStatus() { const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const ws = new WebSocket(`${protocol}//${window.location.host}/${sessionId}/ws`); ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'desktop_status') { desktopConnected = data.status === 'connected'; updateStatus(); } }; ws.onerror = () => { statusDiv.textContent = 'Connection error'; statusDiv.className = 'status disconnected'; }; ws.onclose = () => { setTimeout(checkStatus, 5000); }; } function updateStatus() { if (desktopConnected) { statusDiv.textContent = 'Desktop connected'; statusDiv.className = 'status connected'; submitBtn.disabled = false; } else { statusDiv.textContent = 'Desktop not connected'; statusDiv.className = 'status disconnected'; submitBtn.disabled = true; } } form.addEventListener('submit', async (e) => { e.preventDefault(); errorDiv.style.display = 'none'; const password = passwordInput.value; try { // Test password with a simple API call const response = await fetch(`/${sessionId}/api/tabs`, { headers: { 'X-MacroPad-Password': password } }); if (response.ok) { // Hand the credential to the app via storage (never the URL). sessionStorage.setItem(`macropad_${sessionId}`, password); if (rememberCheckbox.checked) { localStorage.setItem(`macropad_${sessionId}`, password); } else { localStorage.removeItem(`macropad_${sessionId}`); } // Redirect to the PWA (credential is read from storage). window.location.href = `/${sessionId}/app`; } else { const data = await response.json(); errorDiv.textContent = data.error || 'Invalid password'; errorDiv.style.display = 'block'; } } catch (error) { errorDiv.textContent = 'Connection failed'; errorDiv.style.display = 'block'; } }); checkStatus();