Files
smart-monopoly/src/OSHandler.ts
2024-04-02 01:41:51 +02:00

234 lines
7.7 KiB
TypeScript

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<WiFiNetwork[]> {
return new Promise<WiFiNetwork[]>((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<void>(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<void>((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<boolean>((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<void>((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<WiFiNetwork[]>((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<boolean>((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<boolean>((resolve) => {
dns.lookup("google.de", 4, (err, address, family) => {
if (err)
resolve(false);
else
resolve(true);
})
});
}
}