mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 14:42:28 +01:00
200 lines
4.5 KiB
JavaScript
200 lines
4.5 KiB
JavaScript
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
const http = require("http");
|
|
const crypto = require("crypto");
|
|
const log = require("electron-log");
|
|
const Store = require("electron-store");
|
|
const store = new Store();
|
|
|
|
let server;
|
|
let window;
|
|
|
|
async function initialize(win) {
|
|
window = win;
|
|
server = http.createServer(async function (req, res) {
|
|
let body = "";
|
|
res.setHeader("Content-Type", "application/json");
|
|
|
|
req.on("data", (chunk) => {
|
|
body += chunk.toString(); // convert Buffer to string
|
|
});
|
|
|
|
req.on("end", async () => {
|
|
const providedToken = req.headers?.authorization?.replace("Bearer ", "") ?? "";
|
|
const isValid = providedToken === getAuthenticationToken();
|
|
if (isValid) {
|
|
log.debug("Valid authentication token");
|
|
} else {
|
|
log.log("Invalid authentication token");
|
|
res.writeHead(401);
|
|
|
|
res.end(
|
|
JSON.stringify({
|
|
success: false,
|
|
msg: "Invalid authentication token",
|
|
}),
|
|
);
|
|
return;
|
|
}
|
|
|
|
let data;
|
|
try {
|
|
data = JSON.parse(body);
|
|
} catch (error) {
|
|
log.warn(`Invalid body data`);
|
|
res.writeHead(400);
|
|
res.end(
|
|
JSON.stringify({
|
|
success: false,
|
|
msg: "Invalid body data",
|
|
}),
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
let result;
|
|
switch (req.method) {
|
|
// Request files
|
|
case "GET":
|
|
result = await window.webContents.executeJavaScript(`document.getFiles()`);
|
|
break;
|
|
|
|
// Create or update files
|
|
// Support POST for VScode implementation
|
|
case "POST":
|
|
case "PUT":
|
|
if (!data) {
|
|
log.warn(`Invalid script update request - No data`);
|
|
res.writeHead(400);
|
|
res.end(
|
|
JSON.stringify({
|
|
success: false,
|
|
msg: "Invalid script update request - No data",
|
|
}),
|
|
);
|
|
return;
|
|
}
|
|
|
|
result = await window.webContents.executeJavaScript(`document.saveFile("${data.filename}", "${data.code}")`);
|
|
break;
|
|
|
|
// Delete files
|
|
case "DELETE":
|
|
result = await window.webContents.executeJavaScript(`document.deleteFile("${data.filename}")`);
|
|
break;
|
|
}
|
|
|
|
if (!result.res) {
|
|
//We've encountered an error
|
|
res.writeHead(400);
|
|
log.warn(`Api Server Error`, result.msg);
|
|
}
|
|
|
|
res.end(
|
|
JSON.stringify({
|
|
success: result.res,
|
|
msg: result.msg,
|
|
data: result.data,
|
|
}),
|
|
);
|
|
});
|
|
});
|
|
|
|
const autostart = store.get("autostart", false);
|
|
if (autostart) {
|
|
try {
|
|
await enable();
|
|
} catch (error) {
|
|
return Promise.reject(error);
|
|
}
|
|
}
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
function enable() {
|
|
if (isListening()) {
|
|
log.warn("API server already listening");
|
|
return Promise.resolve();
|
|
}
|
|
|
|
const port = store.get("port", 9990);
|
|
const host = store.get("host", "127.0.0.1");
|
|
log.log(`Starting http server on port ${port} - listening on ${host}`);
|
|
|
|
// https://stackoverflow.com/a/62289870
|
|
let startFinished = false;
|
|
return new Promise((resolve, reject) => {
|
|
server.listen(port, host, () => {
|
|
if (!startFinished) {
|
|
startFinished = true;
|
|
resolve();
|
|
}
|
|
});
|
|
server.once("error", (err) => {
|
|
if (!startFinished) {
|
|
startFinished = true;
|
|
console.log("There was an error starting the server in the error listener:", err);
|
|
reject(err);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function disable() {
|
|
if (!isListening()) {
|
|
log.warn("API server not listening");
|
|
return Promise.resolve();
|
|
}
|
|
|
|
log.log("Stopping http server");
|
|
return server.close();
|
|
}
|
|
|
|
function toggleServer() {
|
|
if (isListening()) {
|
|
return disable();
|
|
} else {
|
|
return enable();
|
|
}
|
|
}
|
|
|
|
function isListening() {
|
|
return server?.listening ?? false;
|
|
}
|
|
|
|
function toggleAutostart() {
|
|
const newValue = !isAutostart();
|
|
store.set("autostart", newValue);
|
|
log.log(`New autostart value is '${newValue}'`);
|
|
}
|
|
|
|
function isAutostart() {
|
|
return store.get("autostart");
|
|
}
|
|
|
|
function getAuthenticationToken() {
|
|
const token = store.get("token");
|
|
if (token) return token;
|
|
|
|
const newToken = generateToken();
|
|
store.set("token", newToken);
|
|
return newToken;
|
|
}
|
|
|
|
function generateToken() {
|
|
const buffer = crypto.randomBytes(48);
|
|
return buffer.toString("base64");
|
|
}
|
|
|
|
module.exports = {
|
|
initialize,
|
|
enable,
|
|
disable,
|
|
toggleServer,
|
|
toggleAutostart,
|
|
isAutostart,
|
|
getAuthenticationToken,
|
|
isListening,
|
|
};
|