import * as vscode from 'vscode'; import * as iDeviceDeps from './iDeviceConnections'; import { LKutils } from './Utils'; import { ToolboxNodeProvider } from './iDeviceToolbox'; import { iDeviceNodeProvider } from './iDeviceConnections'; import { ApplicationNodeProvider } from './iDeviceApplications'; import { FileSystemNodeProvider, FileItem } from './iDeviceFileSystem'; import { writeFileSync } from 'fs'; import { execSync, exec, ChildProcess } from 'child_process'; // tslint:disable-next-line: class-name export class iDevices { public static shared: iDevices = new iDevices(); private selectedDevice: iDeviceDeps.iDeviceItem | null = null; constructor() { } public setDevice(devObject: iDeviceDeps.iDeviceItem | null) { if (this.selectedDevice === devObject) { console.log("[i] this.selectedDevice === devObject"); return; } if (this.selectedDevice?.udid === devObject?.udid) { console.log("[i] this.selectedDevice?.udid === devObject?.udid"); this.bootstrapDeviceConfig(); return; } if (devObject?.udid === undefined || devObject.udid === null || devObject.udid === "") { return; } this.selectedDevice = devObject; this.bootstrapDeviceConfig(); this.reloadDevice(); const vdev = devObject as iDeviceDeps.iDeviceItem; if (devObject === null) { console.log("[E] iDevice Selection Invalid"); vscode.window.showErrorMessage("setDevice (null)"); return; } console.log("[*] User selected device: " + devObject.udid); vscode.window.showInformationMessage("Selected device: " + devObject.udid.substring(0, 16).toUpperCase() + " +"); } public getDevice(): iDeviceDeps.iDeviceItem | null { return this.selectedDevice; } public bootstrapDeviceConfig() { let device = this.selectedDevice; if (device === undefined || device === null) { return; } device.iSSH_devicePort = Number(LKutils.shared.readKeyPairValue(device.udid + "iSSH_devicePort")); device.iSSH_mappedPort = Number(LKutils.shared.readKeyPairValue(device.udid + "iSSH_mappedPort")); device.iSSH_password = LKutils.shared.readKeyPairValue(device.udid + "iSSH_password"); // VAILD THIS CONFIG FIRST if (isNaN(device.iSSH_devicePort) || device.iSSH_devicePort < 1 || device.iSSH_devicePort > 65533) { device.iSSH_devicePort = 22; LKutils.shared.saveKeyPairValue(device.udid + "iSSH_devicePort", "22"); } if (isNaN(device.iSSH_mappedPort) || device.iSSH_mappedPort < 1 || device.iSSH_mappedPort > 65533) { device.iSSH_mappedPort = 2222; LKutils.shared.saveKeyPairValue(device.udid + "iSSH_mappedPort", "2222"); } if (device.iSSH_password === "") { device.iSSH_password = "alpine"; LKutils.shared.saveKeyPairValue(device.udid + "iSSH_password", "alpine"); } } private reloadDevice() { ApplicationNodeProvider.nodeProvider.refresh(); ToolboxNodeProvider.nodeProvider.refresh(); FileSystemNodeProvider.nodeProvider.refresh(); } public executeOnDevice(cmd: string): string { if (this.selectedDevice === undefined) { vscode.window.showErrorMessage("No device selected"); return ""; } let selection = this.selectedDevice as iDeviceDeps.iDeviceItem; iDeviceNodeProvider.nodeProvider.ensureiProxy(selection); let passpath = LKutils.shared.storagePath + "/" + LKutils.shared.makeid(10); writeFileSync(passpath, selection.iSSH_password); let terminalCommands: Array<string> = []; terminalCommands.push(" export SSHPASSWORD=$(cat \'" + passpath + "\')"); terminalCommands.push(" rm -f \'" + passpath + "\'"); terminalCommands.push(" ssh-keygen -R \"[127.0.0.1]:" + selection.iSSH_mappedPort + "\" &> /dev/null"); terminalCommands.push(" sshpass -p $SSHPASSWORD ssh -oStrictHostKeyChecking=no -p " + String(selection.iSSH_mappedPort) + " [email protected] \'" + cmd + "\'"); let bashScript = ""; let bashpath = LKutils.shared.storagePath + "/" + LKutils.shared.makeid(10); terminalCommands.forEach((cmd) => { bashScript += "\n"; bashScript += cmd; }); writeFileSync(bashpath, bashScript, 'utf8'); let realCmd = "/bin/bash -C \'" + bashpath + "\' && exit"; let executeObject = execSync(realCmd); return executeObject.toString(); } public executeOnDeviceAsync(cmd: string): ChildProcess | undefined { // console.log("[W] executeOnDeviceAsync may cause executionLock errors!"); if (this.selectedDevice === undefined) { vscode.window.showErrorMessage("No device selected"); return; } // while (iDevices.executionLock) { } // iDevices.executionLock = true; let selection = this.selectedDevice as iDeviceDeps.iDeviceItem; iDeviceNodeProvider.nodeProvider.ensureiProxy(selection); let passpath = LKutils.shared.storagePath + "/" + LKutils.shared.makeid(10); writeFileSync(passpath, selection.iSSH_password); let terminalCommands: Array<string> = []; terminalCommands.push(" export SSHPASSWORD=$(cat \'" + passpath + "\')"); // terminalCommands.push(" rm -f \'" + passpath + "\'"); terminalCommands.push(" ssh-keygen -R \"[127.0.0.1]:" + selection.iSSH_mappedPort + "\" &> /dev/null"); terminalCommands.push(" sshpass -p $SSHPASSWORD ssh -oStrictHostKeyChecking=no -p " + String(selection.iSSH_mappedPort) + " [email protected] \'" + cmd + "\'"); let bashScript = ""; let bashpath = LKutils.shared.storagePath + "/" + LKutils.shared.makeid(10); terminalCommands.forEach((cmd) => { bashScript += "\n"; bashScript += cmd; }); writeFileSync(bashpath, bashScript, 'utf8'); let realCmd = "/bin/bash -C \'" + bashpath + "\'"; let executeObject = exec(realCmd); // iDevices.executionLock = false; return executeObject; } }