diff --git a/electron/api-server.js b/electron/api-server.js index 3a9f06bca..971922b71 100644 --- a/electron/api-server.js +++ b/electron/api-server.js @@ -12,11 +12,13 @@ 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", () => { + + req.on("end", async () => { const providedToken = req.headers?.authorization?.replace('Bearer ', '') ?? ''; const isValid = providedToken === getAuthenticationToken(); if (isValid) { @@ -24,8 +26,11 @@ async function initialize(win) { } else { log.log('Invalid authentication token'); res.writeHead(401); - res.write('Invalid authentication token'); - res.end(); + + res.end(JSON.stringify({ + success: false, + msg: 'Invalid authentication token' + })); return; } @@ -35,17 +40,56 @@ async function initialize(win) { } catch (error) { log.warn(`Invalid body data`); res.writeHead(400); - res.write('Invalid body data'); - res.end(); + res.end(JSON.stringify({ + success: false, + msg: 'Invalid body data' + })); + return; } - if (data) { - window.webContents.executeJavaScript(`document.saveFile("${data.filename}", "${data.code}")`).then((result) => { - res.write(result); - res.end(); - }); + 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 + })); + }); }); diff --git a/src/Electron.tsx b/src/Electron.tsx index b4f4ba684..50811ded7 100644 --- a/src/Electron.tsx +++ b/src/Electron.tsx @@ -1,11 +1,10 @@ import { Player } from "./Player"; -import { isScriptFilename } from "./Script/isScriptFilename"; -import { Script } from "./Script/Script"; import { removeLeadingSlash } from "./Terminal/DirectoryHelpers"; import { Terminal } from "./Terminal"; import { SnackbarEvents } from "./ui/React/Snackbar"; -import { IMap } from "./types"; +import { IMap, IReturnStatus } from "./types"; import { GetServer } from "./Server/AllServers"; +import { resolve } from "cypress/types/bluebird"; export function initElectron(): void { const userAgent = navigator.userAgent.toLowerCase(); @@ -18,32 +17,77 @@ export function initElectron(): void { } function initWebserver(): void { - (document as any).saveFile = function (filename: string, code: string): string { + interface IReturnWebStatus extends IReturnStatus { + data?: { + [propName: string]: any; + }; + } + function normalizeFileName(filename: string): string { filename = filename.replace(/\/\/+/g, "/"); filename = removeLeadingSlash(filename); if (filename.includes("/")) { filename = "/" + removeLeadingSlash(filename); } + return filename; + } + + (document as any).getFiles = function (): IReturnWebStatus { + const home = GetServer("home"); + if (home === null) { + return { + res: false, + msg: "Home server does not exist." + } + } + return { + res: true, + data: { + files: home.scripts.map((script) => ({ + filename: script.filename, + code: script.code, + hash: script.hash(), + ramUsage: script.ramUsage + })) + } + } + }; + + (document as any).deleteFile = function (filename: string): IReturnWebStatus { + filename = normalizeFileName(filename); + const home = GetServer("home"); + if (home === null) { + return { + res: false, + msg: "Home server does not exist." + } + } + return home.removeFile(filename); + }; + + (document as any).saveFile = function (filename: string, code: string): IReturnWebStatus { + filename = normalizeFileName(filename); + code = Buffer.from(code, "base64").toString(); const home = GetServer("home"); - if (home === null) return "'home' server not found."; - if (isScriptFilename(filename)) { - //If the current script already exists on the server, overwrite it - for (let i = 0; i < home.scripts.length; i++) { - if (filename == home.scripts[i].filename) { - home.scripts[i].saveScript(Player, filename, code, "home", home.scripts); - return "written"; - } + if (home === null) { + return { + res: false, + msg: "Home server does not exist." } - - //If the current script does NOT exist, create a new one - const script = new Script(); - script.saveScript(Player, filename, code, "home", home.scripts); - home.scripts.push(script); - return "written"; } - - return "not a script file"; + const {success, overwritten} = home.writeToScriptFile(Player, filename, code); + let script; + if (success) { + script = home.getScript(filename); + } + return { + res: success, + data: { + overwritten, + hash: script?.hash() || undefined, + ramUsage: script?.ramUsage + } + }; }; }