218 lines
9.0 KiB
JavaScript
218 lines
9.0 KiB
JavaScript
const fs = require("fs");
|
|
const route = require("express").Router()
|
|
const { exec } = require("child_process")
|
|
const { verifyToken } = require("../checkToken")
|
|
const { addRouteToScope, compareScopes, getRequiredScopes } = require("../scopes")
|
|
const { join } = require("path");
|
|
const { addScopeEntry, implicitAllowScopes, getExtSharePath } = require("../arangodb");
|
|
const { get } = require("https")
|
|
const multer = require("multer");
|
|
const path = require("path");
|
|
const storage = multer.diskStorage({
|
|
destination: (req, file, cb) => {
|
|
cb(null, req.body.path)
|
|
},
|
|
filename: (req, file, cb) => {
|
|
cb(null, req.body.name)
|
|
}
|
|
})
|
|
const upload = multer({ storage })
|
|
addRouteToScope("/files/foldercontent", "files")
|
|
addRouteToScope("/files/text", "files")
|
|
addRouteToScope("/files/", "files")
|
|
addRouteToScope("/files/hls", "hls")
|
|
addRouteToScope("/files/hlscheck", "hls")
|
|
addRouteToScope("/files/hls", "files")
|
|
addRouteToScope("/files/hlscheck", "files")
|
|
addRouteToScope("/", "files")
|
|
//addRouteToScope("/files/upload", "upload")
|
|
addRouteToScope("/files/upload", "files")
|
|
route.post("/foldercontent", verifyToken, (req, res) => {
|
|
const { path } = req.body;
|
|
// console.log(req.tokendata)
|
|
implicitAllowScopes(path).then((implicitscopes) => {
|
|
if (implicitscopes.find((scope) => req.tokendata.scopes.includes(scope)) || compareScopes(path, req.tokendata.scopes)) {
|
|
fs.readdir(path, (err, files) => {
|
|
if (err) {
|
|
res.status(500).json(`can't get content of ${path}`)
|
|
} else {
|
|
const returnObj = { Files: [], Folders: [] }
|
|
Promise.all(files.map((file) => implicitAllowScopes(join(path, file)))).then((implicitscopes) => {
|
|
files.forEach((file, i) => {
|
|
try {
|
|
if (fs.statSync(join(path, file)).isDirectory() && (implicitscopes[i].find((scope) => req.tokendata.scopes.includes(scope)) || compareScopes(join(path, file), req.tokendata.scopes))) {
|
|
returnObj.Folders.push({ name: file, requiredScopes: getRequiredScopes(join(path, file)) })
|
|
} else if (compareScopes(join(path, file), req.tokendata.scopes)) {
|
|
returnObj.Files.push({ name: file, requiredScopes: getRequiredScopes(join(path, file)) })
|
|
}
|
|
} catch (e) {
|
|
|
|
}
|
|
})
|
|
res.json(returnObj)
|
|
})
|
|
}
|
|
})
|
|
} else {
|
|
res.status("403").json("you lack the required scopes to access this directory")
|
|
}
|
|
})
|
|
|
|
})
|
|
route.get("/text/:path", verifyToken, (req, res) => {
|
|
const route = req.params.path.replace(/%2f/gi, "/")
|
|
if (!compareScopes(route, req.tokendata.scopes)) {
|
|
res.status(403).json("you lack required scopes for this content")
|
|
} else {
|
|
res.sendFile(req.params.path.replace(/%2f/gi, "/"))
|
|
}
|
|
})
|
|
route.post("/scope", verifyToken, (req, res) => {
|
|
const { path, scope } = req.body;
|
|
// console.log(path, scope)
|
|
addScopeEntry({ scope, content: path }).then(() => {
|
|
addRouteToScope(path, scope)
|
|
res.end()
|
|
}, ({ error, message }) => {
|
|
res.status(error).json(message)
|
|
})
|
|
})
|
|
route.get("/video/:path", verifyToken, (req, res) => {
|
|
const route = req.params.path.replace(/%2f/gi, "/")
|
|
// console.log("getting video", req.tokendata.scopes, req.params.path)
|
|
if (req.tokendata.scopes.find((scope) => scope.replace(/%2f/g, "/").match(new RegExp(req.params.path))) || compareScopes(route, req.tokendata.scopes)) {
|
|
if (fs.existsSync(route)) {
|
|
const { size } = fs.statSync(route);
|
|
const { range } = req.headers;
|
|
if (range) {
|
|
const [start, end] = range.replace(/bytes=/, "").split("-").map((num) => parseInt(num, 10));
|
|
if (start >= size) {
|
|
res.statusCode = 416;
|
|
res.end();
|
|
return;
|
|
}
|
|
const chunksize = (end ? end : size - 1) - start + 1
|
|
const file = fs.createReadStream(route, { start, end: end ? end : size - 1 });
|
|
const head = {
|
|
"Content-Range": `bytes ${start}-${end ? end : size - 1}/${size}`,
|
|
"Accept-Ranges": "bytes",
|
|
"Content-Length": chunksize,
|
|
"Content-Type": "video/mp4"
|
|
}
|
|
res.writeHead(206, head);
|
|
file.pipe(res)
|
|
} else {
|
|
const head = {
|
|
"Content-Length": size,
|
|
"Content-Type": "video/mp4"
|
|
}
|
|
res.writeHead(200, head);
|
|
fs.createReadStream(route).pipe(res);
|
|
}
|
|
} else {
|
|
res.status(404).json("not found")
|
|
}
|
|
}
|
|
})
|
|
route.get("/extshare/:id", (req, res) => {
|
|
getExtSharePath(req.params.id).then(({ path }) => {
|
|
if (path.endsWith(".mp4")) {
|
|
if (fs.existsSync(path)) {
|
|
const { size } = fs.statSync(path);
|
|
const { range } = req.headers;
|
|
if (range) {
|
|
const [start, end] = range.replace(/bytes=/, "").split("-").map((num) => parseInt(num, 10));
|
|
if (start >= size) {
|
|
res.statusCode = 416;
|
|
res.end();
|
|
return;
|
|
}
|
|
const chunksize = (end ? end : size - 1) - start + 1
|
|
const file = fs.createReadStream(route, { start, end: end ? end : size - 1 });
|
|
const head = {
|
|
"Content-Range": `bytes ${start}-${end ? end : size - 1}/${size}`,
|
|
"Accept-Ranges": "bytes",
|
|
"Content-Length": chunksize,
|
|
"Content-Type": "video/mp4"
|
|
}
|
|
res.writeHead(206, head);
|
|
file.pipe(res)
|
|
} else {
|
|
const head = {
|
|
"Content-Length": size,
|
|
"Content-Type": "video/mp4"
|
|
}
|
|
res.writeHead(200, head);
|
|
fs.createReadStream(path).pipe(res);
|
|
}
|
|
} else {
|
|
res.status(404).json("not found")
|
|
}
|
|
} else {
|
|
res.sendFile(path)
|
|
}
|
|
}, () => {
|
|
res.status(404).json("not found")
|
|
})
|
|
})
|
|
route.post("/upload", verifyToken, upload.single("data"), (req, res) => {
|
|
//console.log(req.file)
|
|
// let prevprog = 0;
|
|
// res.writeHead(200, "ok", {"content-length":"100000"})
|
|
// const writeStream = fs.createWriteStream(path.join(req.body.path, req.body.name))
|
|
// const readStream = fs.createReadStream(req.file.path)
|
|
// const inter = setInterval(()=>{
|
|
// const curprog = Math.round((writeStream.bytesWritten+readStream.bytesRead)/req.file.size*50000)
|
|
// console.log(curprog, prevprog)
|
|
// if(curprog>prevprog){
|
|
// res.write(new Array(curprog-prevprog).fill("0").join(""))
|
|
// }
|
|
// prevprog=curprog
|
|
// }, 100)
|
|
// readStream.pipe(writeStream)
|
|
// writeStream.on("close", ()=>{
|
|
// clearInterval(inter)
|
|
// fs.unlink(req.file.path, ()=>{
|
|
// res.end()
|
|
// })
|
|
// // console.log(writeStream.bytesWritten)
|
|
// // fs.access(path.join(req.body.path, req.body.name), (err)=>{
|
|
// // console.log(err, path.join(req.body.path, req.body.name))
|
|
// // })
|
|
// })
|
|
res.end()
|
|
|
|
|
|
})
|
|
route.post("/hls", verifyToken, (req, res) => {
|
|
const { program, output, hls } = req.body;
|
|
if (program == undefined|| !output || !hls) {
|
|
res.status(406).json("missing hls, program or output fields")
|
|
} else {
|
|
exec(`ffmpeg -i ${hls} -map p:${program} -c copy -f segment -segment_list "${path.basename(output)}.list" "${path.basename(output)}%03d.ts"`, { cwd: path.dirname(output) }, (error) => {
|
|
if (error) {
|
|
res.status(500).json(error)
|
|
} else {
|
|
exec(`ffmpeg -f concat -safe 0 -i <(for f in "${path.dirname(output)}/${path.basename(output)}"*.ts; do echo "file '$f'"; done) -c copy "${output}"`, {shell:"/bin/bash"}, (error) => {
|
|
if (error) {
|
|
res.status(500).json(error)
|
|
} else {
|
|
res.end()
|
|
exec(`rm "${path.basename(output)}"*.ts "${path.basename(output)}.list"`, {cwd:path.dirname(output)}, (error)=>{
|
|
if(error){
|
|
console.log(error)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
})
|
|
route.get("/hlscheck", verifyToken, (req, res) => {
|
|
get(req.query.url, (response)=>{
|
|
response.pipe(res)
|
|
})
|
|
})
|
|
module.exports = route
|