301 lines
7.3 KiB
JavaScript
301 lines
7.3 KiB
JavaScript
import { rmSync } from 'fs';
|
|
import { copyFile, mkdir, readdir, rm } from 'fs/promises';
|
|
import { Collection, Db, ObjectId } from 'mongodb';
|
|
import multer from 'multer';
|
|
|
|
const dataPath = process.env.JEOPARDY_CDN_DATA_PATH;
|
|
const upload = multer({ dest: dataPath });
|
|
|
|
/**
|
|
* @type {Collection}
|
|
*/
|
|
let ressources;
|
|
|
|
function buildPath(userid, path) {
|
|
return `${dataPath}/${userid}${path.length === '/' ? '' : path}`;
|
|
}
|
|
|
|
function ressourcePath(res) {
|
|
return `${res.fullpath}/${res.filename}`;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {*} app
|
|
* @param {Db} db
|
|
*/
|
|
export function initCdn(app, db) {
|
|
ressources = db.collection('ressources');
|
|
app.post('/upload', upload.single('file'), uploadFile);
|
|
app.get('/cdn/:userid/:resid', fetchFile);
|
|
app.put('/cdn/:userid/:resid', renameFile);
|
|
app.delete('/cdn/:userid/:resid', deleteFile);
|
|
app.post('/directory', fetchDirectory);
|
|
app.put('/directory', addDirectory);
|
|
app.delete('/directory', deleteDirectory);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {import('express').Request} req
|
|
* @param {import('express').Response} res
|
|
* @param {import('express').NextFunction} next
|
|
*/
|
|
function uploadFile(req, res, next) {
|
|
console.log(req.file, req.body);
|
|
|
|
/**
|
|
* @type {string | undefined}
|
|
*/
|
|
const path = req.body.path;
|
|
|
|
if (path !== undefined && path.startsWith('/') && !path.includes('.')) {
|
|
let destinationPath = buildPath(req.user._id, req.body.path);
|
|
mkdir(destinationPath, {
|
|
recursive: true,
|
|
})
|
|
.then(() => {
|
|
return copyFile(
|
|
req.file.path,
|
|
`${destinationPath}/${req.file.filename}`,
|
|
);
|
|
})
|
|
.then(async () => {
|
|
rmSync(req.file.path);
|
|
|
|
await ressources.insertOne({
|
|
fullpath: destinationPath,
|
|
path: path,
|
|
user: req.user._id,
|
|
mimetype: req.file.mimetype,
|
|
name: req.file.originalname,
|
|
filename: req.file.filename,
|
|
});
|
|
|
|
res.sendStatus(200);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
rmSync(req.file.path);
|
|
res.sendStatus(500);
|
|
});
|
|
} else {
|
|
rmSync(req.file.path);
|
|
res.sendStatus(400);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {import('express').Request} req
|
|
* @param {import('express').Response} res
|
|
*/
|
|
async function fetchFile(req, res) {
|
|
let ressource = await ressources.findOne({
|
|
user: new ObjectId(req.params.userid),
|
|
filename: req.params.resid,
|
|
});
|
|
|
|
if (ressource) {
|
|
res.sendFile(ressourcePath(ressource));
|
|
} else {
|
|
res.sendStatus(404);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {import('express').Request} req
|
|
* @param {import('express').Response} res
|
|
*/
|
|
async function renameFile(req, res) {
|
|
if (req.user._id.toString() !== req.params.userid) {
|
|
res.sendStatus(403);
|
|
return;
|
|
}
|
|
if (
|
|
req.body === undefined ||
|
|
req.body.name === undefined ||
|
|
req.body.name.length <= 0 ||
|
|
/\.{2}|\/|\\/.test(req.body.name)
|
|
) {
|
|
res.sendStatus(400);
|
|
return;
|
|
}
|
|
|
|
const name = req.body.name;
|
|
|
|
let ressource = await ressources.findOne({
|
|
user: new ObjectId(req.params.userid),
|
|
filename: req.params.resid,
|
|
});
|
|
|
|
if (!ressource) {
|
|
console.log('Ressource could not be found');
|
|
res.sendStatus(400);
|
|
return;
|
|
}
|
|
|
|
ressources
|
|
.updateOne(
|
|
{
|
|
_id: ressource._id,
|
|
},
|
|
{
|
|
$set: {
|
|
name,
|
|
},
|
|
},
|
|
)
|
|
.then(() => {
|
|
res.sendStatus(200);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.sendStatus(500);
|
|
});
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {import('express').Request} req
|
|
* @param {import('express').Response} res
|
|
*/
|
|
async function deleteFile(req, res) {
|
|
if (req.user._id.toString() !== req.params.userid) {
|
|
res.sendStatus(403);
|
|
return;
|
|
}
|
|
let ressource = await ressources.findOne({
|
|
user: new ObjectId(req.params.userid),
|
|
filename: req.params.resid,
|
|
});
|
|
|
|
if (!ressource) {
|
|
console.log('Ressource could not be found');
|
|
res.sendStatus(400);
|
|
return;
|
|
}
|
|
|
|
rm(ressourcePath(ressource))
|
|
.then(() => {
|
|
return ressources.deleteOne({ _id: ressource._id });
|
|
})
|
|
.then(() => {
|
|
res.sendStatus(200);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.sendStatus(500);
|
|
});
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {import('express').Request} req
|
|
* @param {import('express').Response} res
|
|
*/
|
|
async function fetchDirectory(req, res) {
|
|
if (!req.body) {
|
|
res.sendStatus(400);
|
|
return;
|
|
}
|
|
const path = req.body.path;
|
|
if (!path) {
|
|
res.sendStatus(400);
|
|
return;
|
|
}
|
|
|
|
const files = ressources.find({
|
|
path,
|
|
});
|
|
|
|
readdir(buildPath(req.user._id, path), {
|
|
withFileTypes: true,
|
|
})
|
|
.then(async (value) => {
|
|
let directories = value
|
|
.filter((dir) => dir.isDirectory())
|
|
.map((dir) => {
|
|
return {
|
|
name: dir.name,
|
|
isDir: true,
|
|
};
|
|
});
|
|
|
|
res.status(200).send([...directories, ...(await files.toArray())]);
|
|
})
|
|
.catch(async (err) => {
|
|
console.error(err);
|
|
res.status(200).send(await files.toArray());
|
|
});
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {import('express').Request} req
|
|
* @param {import('express').Response} res
|
|
*/
|
|
async function addDirectory(req, res) {
|
|
if (!req.body) {
|
|
res.sendStatus(400);
|
|
return;
|
|
}
|
|
const name = req.body.name;
|
|
const path = req.body.path;
|
|
if (!name || !path || !/^[a-zA-Z0-9-_]+$/.test(name)) {
|
|
res.sendStatus(400);
|
|
return;
|
|
}
|
|
|
|
mkdir(buildPath(req.user._id, path + '/' + name))
|
|
.then(() => {
|
|
res.sendStatus(200);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.sendStatus(500);
|
|
});
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {import('express').Request} req
|
|
* @param {import('express').Response} res
|
|
*/
|
|
async function deleteDirectory(req, res) {
|
|
console.log(req.body);
|
|
if (
|
|
req.body === undefined ||
|
|
req.body.path === undefined ||
|
|
req.body.path.length <= 0
|
|
) {
|
|
res.sendStatus(400);
|
|
return;
|
|
}
|
|
|
|
console.log(req.body);
|
|
|
|
const path = req.body.path;
|
|
|
|
rm(buildPath(req.user._id, path), {
|
|
force: true,
|
|
recursive: true,
|
|
})
|
|
.then(() => {
|
|
return ressources.deleteMany({
|
|
user: req.user._id,
|
|
path: {
|
|
$regex: '^' + path + '($|\\/.*)',
|
|
},
|
|
});
|
|
})
|
|
.then(() => {
|
|
res.sendStatus(200);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.sendStatus(500);
|
|
});
|
|
}
|