[FEATURE] Initial File Manager
This commit is contained in:
parent
e66e685903
commit
22bf905415
10 changed files with 356 additions and 85 deletions
|
@ -1,4 +1,10 @@
|
|||
import { listServerFiles } from "../k8s/server-files.js";
|
||||
import {
|
||||
createServerFolder,
|
||||
getServerItem,
|
||||
listServerFiles,
|
||||
removeServerItem,
|
||||
uploadServerItem,
|
||||
} from "../k8s/server-files.js";
|
||||
import { sendError } from "../util/ExpressClientError.js";
|
||||
|
||||
export async function listFiles(req, res) {
|
||||
|
@ -15,10 +21,50 @@ export async function listFiles(req, res) {
|
|||
isSymLink: !!fi.link,
|
||||
size: fi.size,
|
||||
}));
|
||||
console.log(fileData);
|
||||
res.json(fileData);
|
||||
})
|
||||
.catch(sendError(res));
|
||||
}
|
||||
|
||||
export async function uploadFile(req, res) {}
|
||||
export async function createFolder(req, res) {
|
||||
const serverSpec = req.body;
|
||||
if (!serverSpec) return res.sendStatus(400);
|
||||
if (!serverSpec.name) return res.status(400).send("Server name required!");
|
||||
if (!serverSpec.path) return res.status(400).send("Path required!");
|
||||
createServerFolder(serverSpec)
|
||||
.then(() => res.sendStatus(200))
|
||||
.catch(sendError(res));
|
||||
}
|
||||
|
||||
export async function deleteItem(req, res) {
|
||||
const serverSpec = req.body;
|
||||
if (!serverSpec) return res.sendStatus(400);
|
||||
if (!serverSpec.name) return res.status(400).send("Server name required!");
|
||||
if (!serverSpec.path) return res.status(400).send("Path required!");
|
||||
if (serverSpec.isDir === undefined || serverSpec.isDir === null)
|
||||
return res.status(400).send("IsDIr required!");
|
||||
removeServerItem(serverSpec)
|
||||
.then(() => res.sendStatus(200))
|
||||
.catch(sendError(res));
|
||||
}
|
||||
|
||||
export async function uploadItem(req, res) {
|
||||
const serverSpec = req.body;
|
||||
if (!serverSpec.name) return res.status(400).send("Server name required!");
|
||||
if (!serverSpec.path) return res.status(400).send("Path required!");
|
||||
uploadServerItem(serverSpec, req.file)
|
||||
.then(() => res.sendStatus(200))
|
||||
.catch(sendError(res));
|
||||
}
|
||||
|
||||
export async function getItem(req, res) {
|
||||
const serverSpec = req.body;
|
||||
if (!serverSpec.name) return res.status(400).send("Server name required!");
|
||||
if (!serverSpec.path) return res.status(400).send("Path required!");
|
||||
getServerItem(serverSpec, res)
|
||||
.then(({ ds, ftpTransfer }) => {
|
||||
ds.pipe(res).on("error", sendError(res));
|
||||
return ftpTransfer;
|
||||
})
|
||||
.catch(sendError(res));
|
||||
}
|
||||
|
|
|
@ -2,10 +2,27 @@ import ftp from "basic-ftp";
|
|||
import { ERR } from "../util/logging.js";
|
||||
import { getServerAssets } from "./k8s-server-control.js";
|
||||
import ExpressClientError from "../util/ExpressClientError.js";
|
||||
import { Readable, Writable, Transform } from "node:stream";
|
||||
|
||||
const namespace = process.env.MCL_SERVER_NAMESPACE;
|
||||
|
||||
export async function useFtp(serverService) {
|
||||
const pathSecurityCheck = (path) => {
|
||||
if (!path.startsWith("."))
|
||||
throw new ExpressClientError({
|
||||
m: "Only relative directories can be created",
|
||||
c: 409,
|
||||
});
|
||||
};
|
||||
|
||||
const handleError = (e) => {
|
||||
ERR("SERVER FILES", "Error occurred while preforming FTP operation!", e);
|
||||
throw new ExpressClientError({
|
||||
c: 500,
|
||||
m: "Error occurred while performing FTP operation!",
|
||||
});
|
||||
};
|
||||
|
||||
export async function getFtpClient(serverService) {
|
||||
const { name } = serverService.metadata;
|
||||
const client = new ftp.Client();
|
||||
await client.access({
|
||||
|
@ -16,16 +33,8 @@ export async function useFtp(serverService) {
|
|||
return client;
|
||||
}
|
||||
|
||||
const handleError = (e) => {
|
||||
ERR("SERVER FILES", "Error occurred while preforming FTP operation!", e);
|
||||
throw new ExpressClientError({
|
||||
c: 500,
|
||||
m: "Error occurred while performing FTP operation!",
|
||||
});
|
||||
};
|
||||
|
||||
export async function listServerFiles(serverSpec) {
|
||||
const { name, dir } = serverSpec;
|
||||
export async function useServerFtp(serverSpec, fn) {
|
||||
const { name } = serverSpec;
|
||||
const server = await getServerAssets(name);
|
||||
if (!server)
|
||||
throw new ExpressClientError({
|
||||
|
@ -37,15 +46,52 @@ export async function listServerFiles(serverSpec) {
|
|||
c: 409,
|
||||
m: "Service doesn't exist, please contact your hosting provider!",
|
||||
});
|
||||
const client = await getFtpClient(server.service);
|
||||
const result = await fn(client);
|
||||
client.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
// FTP Operations;
|
||||
const client = await useFtp(server.service).catch(handleError);
|
||||
const files = client
|
||||
.list(dir)
|
||||
.then((f) => {
|
||||
client.close();
|
||||
return f;
|
||||
})
|
||||
.catch(handleError);
|
||||
export async function listServerFiles(serverSpec) {
|
||||
const { path } = serverSpec;
|
||||
const files = useServerFtp(serverSpec, async (c) => await c.list(path)).catch(
|
||||
handleError,
|
||||
);
|
||||
return files;
|
||||
}
|
||||
|
||||
export async function createServerFolder(serverSpec) {
|
||||
const { path } = serverSpec;
|
||||
pathSecurityCheck(path);
|
||||
await useServerFtp(serverSpec, async (c) => c.ensureDir(path)).catch(
|
||||
handleError,
|
||||
);
|
||||
}
|
||||
|
||||
export async function removeServerItem(serverSpec) {
|
||||
const { path, isDir } = serverSpec;
|
||||
pathSecurityCheck(path);
|
||||
await useServerFtp(serverSpec, async (c) => {
|
||||
if (isDir) await c.removeDir(path);
|
||||
else await c.remove(path);
|
||||
}).catch(handleError);
|
||||
}
|
||||
|
||||
export async function uploadServerItem(serverSpec, file) {
|
||||
const fileStream = Readable.from(file.buffer);
|
||||
const { path } = serverSpec;
|
||||
pathSecurityCheck(path);
|
||||
await useServerFtp(serverSpec, async (c) => {
|
||||
await c.uploadFrom(fileStream, `${path}/${file.originalname}`);
|
||||
}).catch(handleError);
|
||||
}
|
||||
|
||||
export async function getServerItem(serverSpec, writableStream) {
|
||||
const { path } = serverSpec;
|
||||
const ds = new Transform({ transform: (c, e, cb) => cb(null, c) });
|
||||
pathSecurityCheck(path);
|
||||
const ftpTransfer = useServerFtp(serverSpec, async (c) => {
|
||||
await c.downloadTo(ds, path);
|
||||
}).catch(handleError);
|
||||
return { ds, ftpTransfer };
|
||||
}
|
||||
|
|
|
@ -1,7 +1,21 @@
|
|||
import { Router, json as jsonMiddleware } from "express";
|
||||
import { listFiles } from "../controllers/file-controller.js";
|
||||
import multer from "multer";
|
||||
import {
|
||||
createFolder,
|
||||
deleteItem,
|
||||
listFiles,
|
||||
uploadItem,
|
||||
getItem,
|
||||
} from "../controllers/file-controller.js";
|
||||
|
||||
const router = Router();
|
||||
router.use(jsonMiddleware());
|
||||
const multerMiddleware = multer();
|
||||
|
||||
router.post("/list", listFiles);
|
||||
router.post("/folder", createFolder);
|
||||
router.delete("/item", deleteItem);
|
||||
router.post("/item", getItem);
|
||||
router.post("/upload", multerMiddleware.single("file"), uploadItem);
|
||||
|
||||
export default router;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue