// make the export accessible from inline js import * as main from "./main"; // for some reason doing the same with the window object doesn't work (globalThis as any).main = main; import { backButton, clicksLog, homeButton, socket, screen, adid_priv_info_table, lat_priv_info_table, lon_priv_info_table, recentButton, } from "./shared"; import { start_notifications } from "./notifications"; import { start_traffic_log } from "./traffic_log"; export { download_har, inspect_har } from "./traffic_log"; export function reset_adid_handler(_: Event) { socket.emit("reset_adid"); } export function coords_handler(e: FormDataEvent) { e.preventDefault(); const form_data = new FormData(e.target as HTMLFormElement); socket.emit("setcoord", { lon: Number.parseFloat(form_data.get("lon") as string), lat: Number.parseFloat(form_data.get("lat") as string), }); } export function open_tab(evt: Event, tab_name: string) { let i, tabcontent, tablinks; // Get all elements with class="tabcontent" and hide them tabcontent = document.getElementsByClassName("tabcontent"); for (i = 0; i < tabcontent.length; i++) { if (tabcontent[i].id != tab_name) { tabcontent[i].classList.remove("active"); } else { tabcontent[i].classList.add("active"); } } // Get all elements with class="tablinks" and remove the class "active" tablinks = document.getElementsByClassName("tablinks"); for (i = 0; i < tablinks.length; i++) { tablinks[i].classList.remove("active"); } // Show the current tab, and add an "active" class to the button that opened the tab (evt.currentTarget as HTMLElement).classList.add("active"); } let lastTouch = new Date().getTime(); export const calculateElapsedTime = () => { const currentTouch = new Date().getTime(); const elapsedTime = currentTouch - lastTouch; const elapsedSec = Math.round(elapsedTime / 1000); lastTouch = currentTouch; return elapsedSec; }; export const waitToLog = (clickInfoText: string) => { const clickInfo = document.createElement("span"); const waitInfo = document.createElement("span"); waitInfo.textContent = `await wait(${calculateElapsedTime()});`; clicksLog.appendChild(waitInfo); clickInfo.textContent = clickInfoText; clicksLog.appendChild(clickInfo); }; export const registerClick = ({ path, logText, body, }: { path: string; logText: string; body?: any; }) => { waitToLog(logText); socket.emit(path, body ? body : {}); }; homeButton.addEventListener("click", () => registerClick({ path: "home", logText: "await homeButton();" }) ); backButton.addEventListener("click", () => registerClick({ path: "back", logText: "await backButton();" }) ); recentButton.addEventListener("click", () => registerClick({ path: "recent", logText: "await recentButton();" }) ); socket.on("screenshot_data", (data) => { try { const blob = new Blob([data]); screen.src = URL.createObjectURL(blob); } catch (error) { console.error("Error fetching image: ", error); } }); socket.on("private_info", (data) => { console.log("private_info"); adid_priv_info_table.textContent = data.adid; lat_priv_info_table.textContent = data.latitude; lon_priv_info_table.textContent = data.longitude; }); socket.emit("private_info_req"); socket.onAny((ev, ...args) => { console.log("ev: ", ev, args); }); async function displayImage() { socket.emit("screenshot"); } let isDragging = false; const screenSize = [320, 640]; export function calcMousePos(event: MouseEvent) { let rect = screen.getBoundingClientRect(); let x = ((event.clientX - rect.left) / rect.width) * screenSize[0]; let y = ((event.clientY - rect.top) / rect.height) * screenSize[1]; x = Math.min(Math.max(x, 0), screenSize[0]); y = Math.min(Math.max(y, 0), screenSize[1]); return { x, y }; } screen.addEventListener( "mousemove", (event) => { if (!isDragging) return; let pos = calcMousePos(event); if (isDragging) { registerClick({ path: "motionevent", logText: `await motionevent({motionType: "MOVE", x:${pos.x},y:${pos.y}}});`, body: { motionType: "MOVE", x: pos.x, y: pos.y, }, }); } }, false ); export const handleDraggStart = (event: MouseEvent) => { isDragging = true; let pos = calcMousePos(event); registerClick({ path: "motionevent", logText: `await motionevent({motionType: "DOWN", x:${pos.x},y:${pos.y}}});`, body: { motionType: "DOWN", x: pos.x, y: pos.y, }, }); }; screen.addEventListener("mousedown", handleDraggStart); document.addEventListener("mouseup", (e) => { if (!isDragging) return; isDragging = false; let pos = calcMousePos(e); registerClick({ path: "motionevent", logText: `await motionevent({motionType: "MOVE", x:${pos.x},y:${pos.y}}});`, body: { motionType: "MOVE", x: pos.x, y: pos.y, }, }); registerClick({ path: "motionevent", logText: `await motionevent({motionType: "UP", x:${pos.x},y:${pos.y}}});`, body: { motionType: "UP", x: pos.x, y: pos.y, }, }); }); window.addEventListener("keydown", (event) => { let key = event.key; if (key === "Space") key = " "; else if (key !== "Enter" && key !== "Backspace" && key.length !== 1) return; console.log(event.key, key); if (screen.matches(":hover")) { registerClick({ path: "key", logText: `await key(${event.key});`, body: { key }, }); } }); export async function sleep(time: number) { return new Promise((resolve) => setTimeout(resolve, time)); } async function screenshot_loop() { var before; while (true) { before = performance.now(); await displayImage(); // TODO: Make this dynamic again while (performance.now() - before < 100) await sleep(50); } } screenshot_loop(); start_notifications(); start_traffic_log();