From fb2afbd9d62532be3952118adafff3972c63f3bc Mon Sep 17 00:00:00 2001 From: Asher Date: Tue, 16 Apr 2024 11:13:36 -0800 Subject: [PATCH] Handle undefined body In the latest Express it seems the body is undefined when no data is passed (instead of being empty). --- src/node/http.ts | 4 +- src/node/routes/login.ts | 4 +- src/node/vscodeSocket.ts | 59 ++++++++++++++++------------- test/unit/node/routes/login.test.ts | 7 +--- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/node/http.ts b/src/node/http.ts index 837e12acf..e0fb3a4ca 100644 --- a/src/node/http.ts +++ b/src/node/http.ts @@ -319,8 +319,8 @@ export const getCookieOptions = (req: express.Request): express.CookieOptions => // URL of that page) and the relative path to the root as given to it by the // backend. Using these two we can determine the true absolute root. const url = new URL( - req.query.base || req.body.base || "/", - req.query.href || req.body.href || "http://" + (req.headers.host || "localhost"), + req.query.base || req.body?.base || "/", + req.query.href || req.body?.href || "http://" + (req.headers.host || "localhost"), ) return { domain: getCookieDomain(url.host, req.args["proxy-domain"]), diff --git a/src/node/routes/login.ts b/src/node/routes/login.ts index 73575e8ac..29d51a59d 100644 --- a/src/node/routes/login.ts +++ b/src/node/routes/login.ts @@ -68,8 +68,8 @@ router.get("/", async (req, res) => { res.send(await getRoot(req)) }) -router.post<{}, string, { password: string; base?: string }, { to?: string }>("/", async (req, res) => { - const password = sanitizeString(req.body.password) +router.post<{}, string, { password?: string; base?: string } | undefined, { to?: string }>("/", async (req, res) => { + const password = sanitizeString(req.body?.password) const hashedPasswordFromArgs = req.args["hashed-password"] try { diff --git a/src/node/vscodeSocket.ts b/src/node/vscodeSocket.ts index 68625028b..619a764b0 100644 --- a/src/node/vscodeSocket.ts +++ b/src/node/vscodeSocket.ts @@ -20,11 +20,11 @@ export interface EditorSessionEntry { } interface DeleteSessionRequest { - socketPath: string + socketPath?: string } interface AddSessionRequest { - entry: EditorSessionEntry + entry?: EditorSessionEntry } interface GetSessionResponse { @@ -40,37 +40,42 @@ export async function makeEditorSessionManagerServer( // eslint-disable-next-line import/no-named-as-default-member router.use(express.json()) - router.get("/session", async (req, res) => { - const filePath = req.query.filePath as string - if (!filePath) { - res.status(HttpCode.BadRequest).send("filePath is required") + router.get<{}, GetSessionResponse | string | unknown, undefined, { filePath?: string }>( + "/session", + async (req, res) => { + const filePath = req.query.filePath + if (!filePath) { + res.status(HttpCode.BadRequest).send("filePath is required") + return + } + try { + const socketPath = await editorSessionManager.getConnectedSocketPath(filePath) + const response: GetSessionResponse = { socketPath } + res.json(response) + } catch (error: unknown) { + res.status(HttpCode.ServerError).send(error) + } + }, + ) + + router.post<{}, string, AddSessionRequest | undefined>("/add-session", async (req, res) => { + const entry = req.body?.entry + if (!entry) { + res.status(400).send("entry is required") return } - try { - const socketPath = await editorSessionManager.getConnectedSocketPath(filePath) - const response: GetSessionResponse = { socketPath } - res.json(response) - } catch (error: unknown) { - res.status(HttpCode.ServerError).send(error) - } + editorSessionManager.addSession(entry) + res.status(200).send("session added") }) - router.post("/add-session", async (req, res) => { - const request = req.body as AddSessionRequest - if (!request.entry) { - res.status(400).send("entry is required") - } - editorSessionManager.addSession(request.entry) - res.status(200).send() - }) - - router.post("/delete-session", async (req, res) => { - const request = req.body as DeleteSessionRequest - if (!request.socketPath) { + router.post<{}, string, DeleteSessionRequest | undefined>("/delete-session", async (req, res) => { + const socketPath = req.body?.socketPath + if (!socketPath) { res.status(400).send("socketPath is required") + return } - editorSessionManager.deleteSession(request.socketPath) - res.status(200).send() + editorSessionManager.deleteSession(socketPath) + res.status(200).send("session deleted") }) const server = http.createServer(router) diff --git a/test/unit/node/routes/login.test.ts b/test/unit/node/routes/login.test.ts index f2f38fedc..2835bad82 100644 --- a/test/unit/node/routes/login.test.ts +++ b/test/unit/node/routes/login.test.ts @@ -68,13 +68,10 @@ describe("login", () => { } }) - it("should return HTML with 'Missing password' message", async () => { + it("should return 'Missing password' without body", async () => { const resp = await codeServer().fetch("/login", { method: "POST" }) - - expect(resp.status).toBe(200) - const htmlContent = await resp.text() - + expect(resp.status).toBe(200) expect(htmlContent).toContain("Missing password") })