1import express from 'express';
2import * as nodes from '../controller/node.js';
3import password from '../middlewares/password.js';
4import { passwordHeaderNames, writePasswordHeaders } from '../util/passwordHeader.js';
5
6const app = express.Router();
7
8app.get("/", password(false), async (req, res) => {
9 return res.json(await nodes.listAll());
10});
11
12app.put("/", password(false), async (req, res) => {
13 if (process.env.PREVIEW_MODE === "true")
14 return res.status(403).json({message: "For security reasons, you can't create nodes in preview mode"});
15
16 if (!req.body.name || !req.body.url) return res.status(400).json({message: "Missing parameters", type: "MISSING_PARAMETERS"});
17
18 const url = req.body.url.replace(/\/+$/, "");
19
20 nodes.checkStatus(url, req.body.password).then(async (result) => {
21 if (result === "INVALID_URL")
22 return res.status(400).json({message: "Invalid URL", type: "INVALID_URL"});
23
24 if (result === "PASSWORD_REQUIRED")
25 return res.status(400).json({message: "Invalid password", type: "PASSWORD_REQUIRED"});
26
27 res.json({id: (await nodes.create(req.body.name, url, req.body.password)).id, type: "NODE_CREATED"});
28 });
29});
30
31app.delete("/:nodeId", password(false), async (req, res) => {
32 if (process.env.PREVIEW_MODE === "true")
33 return res.status(403).json({message: "For security reasons, you can't delete nodes in preview mode"});
34
35 const node = await nodes.getOne(req.params.nodeId);
36 if (node === null) return res.status(404).json({message: "Node not found"});
37
38 await nodes.deleteNode(req.params.nodeId);
39 res.json({message: "Node successfully deleted"});
40});
41
42app.patch("/:nodeId/name", password(false), async (req, res) => {
43 if (process.env.PREVIEW_MODE === "true")
44 return res.status(403).json({message: "For security reasons, you can't update nodes in preview mode"});
45
46 if (!req.body.name) return res.status(400).json({message: "Missing parameters", type: "MISSING_PARAMETERS"});
47
48 const node = await nodes.getOne(req.params.nodeId);
49 if (node === null) return res.status(404).json({message: "Node not found"});
50
51 await nodes.updateName(req.params.nodeId, req.body.name);
52 res.json({message: "Node name successfully updated"});
53});
54
55app.patch("/:nodeId/password", password(false), async (req, res) => {
56 if (process.env.PREVIEW_MODE === "true")
57 return res.status(403).json({message: "For security reasons, you can't update nodes in preview mode"});
58
59 if (!req.body.password) return res.status(400).json({message: "Missing parameters", type: "MISSING_PARAMETERS"});
60
61 const node = await nodes.getOne(req.params.nodeId);
62 if (node === null) return res.status(404).json({message: "Node not found"});
63
64 nodes.checkStatus(node.url, req.body.password).then(async (result) => {
65 if (result === "INVALID_URL")
66 return res.status(400).json({message: "Invalid URL", type: "INVALID_URL"});
67
68 if (result === "PASSWORD_REQUIRED")
69 return res.status(400).json({message: "Invalid password", type: "PASSWORD_REQUIRED"});
70
71 await nodes.updatePassword(req.params.nodeId, req.body.password === "none" ? null : req.body.password);
72 res.json({message: "Node password successfully updated", type: "PASSWORD_UPDATED"});
73 });
74});
75
76app.all("/:nodeId/*route", password(false), async (req, res) => {
77 const node = await nodes.getOne(req.params.nodeId);
78 if (node === null) return res.status(404).json({message: "Node not found"});
79
80 const url = node.url + req.originalUrl.replace("/api/nodes/" + req.params.nodeId, "/api");
81
82 passwordHeaderNames.forEach(name => delete req.headers[name]);
83 Object.assign(req.headers, writePasswordHeaders(node.password));
84 delete req.headers['host'];
85
86 await nodes.proxyRequest(url, req, res);
87});
88
89export default app;