import {WiFiNetwork} from "./RawConstants"; import {spawn, exec} from 'node:child_process'; import * as dns from "dns"; import * as process from "process"; import * as path from "path"; import * as fs from "fs"; const wifiScan = require("node-wifi-scanner"); export default class OSHandler { static scriptPath = path.resolve(process.cwd(), "scripts"); static async enableAllWifis() { return this.overwriteWifis(await this.getKnownWifis()); } static getKnownWifis(): Promise { return new Promise((resolve, reject) => { exec("sudo touch /etc/wpa_supplicant/wpa_supplicant-monopoly.conf && sudo cat /etc/wpa_supplicant/wpa_supplicant-monopoly.conf", (err, stdout) => { if (err) return reject(err); let lines = stdout.split("\n"); let wifis: WiFiNetwork[] = []; let inBlock = false; let currentNetwork: WiFiNetwork = {ssid: "", psk: "", isSecured: false}; for (let line of lines) { if (line.includes("network={")) inBlock = true; if (line.includes("}")) { inBlock = false; //currentNetwork.isSecured = !!currentNetwork.psk; if (currentNetwork.ssid) wifis.push({...currentNetwork}); currentNetwork.ssid = ""; currentNetwork.psk = ""; currentNetwork.isSecured = false; } if (inBlock && line.includes("ssid")) currentNetwork.ssid = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"')); if (inBlock && line.includes("psk")) currentNetwork.psk = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"')); if (inBlock && line.includes("key_mgmt")) currentNetwork.isSecured = line.includes("WPA-PSK"); } resolve(wifis); }) }); } /** * Adds a new wifi to the known networks * @param ssid * @param passkey */ static addWifi(ssid: string, passkey: string) { return new Promise(async (resolve, reject) => { try { let knownWifis = await this.getKnownWifis(); let found = false; for (let wifi of knownWifis) { if (wifi.ssid == wifi.ssid) { // We know this wifi! - Refresh it! found = true; wifi.psk = passkey; wifi.isSecured = !!passkey; } } if (!found) { knownWifis.push({ssid: ssid, psk: passkey, isSecured: !!passkey}); } await this.overwriteWifis(knownWifis); return resolve(); } catch (e) { return reject(e); } }); } /** * Overwrites the custom wpa_supplicant file * @param wifis * @param ssid */ static overwriteWifis(wifis: WiFiNetwork[], ssid = "") { return new Promise((resolve, reject) => { let wifi_str = `ctrl_interface=/run/wpa_supplicant \nupdate_config=0\n\n`; for (let wifi of wifis) { wifi_str += "network={\n"; wifi_str += ` ssid="${wifi.ssid}"\n` wifi_str += ` key_mgmt="${wifi.isSecured ? "WPA-PSK" : "NONE"}"\n` if (ssid && ssid != wifi.ssid) wifi_str += ` disabled=1\n` if (wifi.psk) wifi_str += ` psk="${wifi.psk}"\n` wifi_str += `}\n\n` } fs.writeFileSync("/tmp/wpa_supplicant.conf", wifi_str); exec("sudo mv -f /tmp/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-monopoly.conf", (err, stdout) => { if (err) return reject(err); resolve(); }); }) } /** * Connects to a specific wifi * @param ssid */ static connectToWifi(ssid: string) { return new Promise((resolve, reject) => { this.getKnownWifis().then((wifis) => { this.overwriteWifis(wifis, ssid).then(() => { let p = path.resolve(this.scriptPath, "connectToWifi.sh"); exec(p, (error, stdout, stderr) => { if (!error) return resolve(stdout.includes("!!ok")); reject(error); }); }).catch(reject); }).catch(reject); }); } static removeWifi(ssid: string) { return new Promise((resolve, reject) => { this.getKnownWifis().then(wifis => { wifis.filter((ele) => { return ele.ssid != ssid; }); this.overwriteWifis(wifis).then(resolve).catch(reject); }).catch(reject); }); } static scanWifis() { return new Promise((resolve, reject) => { wifiScan.scan(true).then((result: { ssid: string, mac: string, channel: number, rssi: number, encrypted: boolean }[]) => { if (!result) return {status: false}; let networks: WiFiNetwork[] = []; for (let wifi of result) { networks.push({ ssid: wifi.ssid, isKnown: true, isSecured: wifi.encrypted, rssi: wifi.rssi }) } // Sort best rssi to top networks.sort((a, b) => { return b.rssi - a.rssi; }); // Sort best rssi to top networks.sort((a, b) => { if (b.isSecured && !a.isSecured) return 1; else if (b.isSecured == a.isSecured) return 0; else return -1; }); networks = networks.filter((ele, index) => { // If empty ssid if (!ele.ssid || ele.ssid == "") return false; // Remove duplicates let i = 0; for (let x of networks) { if (x.ssid == ele.ssid) { return i == index; } i++; } return true; }); resolve(networks); }).catch(reject); }) } static checkForSudo() { return new Promise((resolve) => { const test = spawn("sudo", ["-v"], {detached: true, stdio: ["ignore", "pipe", "pipe"]}); test.on("close", (code: number) => { if (code != 0) resolve(false); else resolve(true); }); test.on("error", (err) => { resolve(false); }) }) } static checkForInternet() { return new Promise((resolve) => { dns.lookup("google.de", 4, (err, address, family) => { if (err) resolve(false); else resolve(true); }) }); } }