From f08079ba84221cd830b39ea0489a0750a04596b7 Mon Sep 17 00:00:00 2001 From: mrfry Date: Tue, 6 Apr 2021 10:30:32 +0200 Subject: [PATCH] File upload fixes --- src/modules/api/api.ts | 8 +- src/modules/api/submodules/feedback.ts | 45 +------- src/modules/api/submodules/userFiles.ts | 132 ++++++++++++++++++++++-- src/types/basicTypes.ts | 1 + src/utils/utils.ts | 46 +++++++++ submodules/qmining-page | 2 +- 6 files changed, 178 insertions(+), 56 deletions(-) diff --git a/src/modules/api/api.ts b/src/modules/api/api.ts index a2377d0..16034b5 100644 --- a/src/modules/api/api.ts +++ b/src/modules/api/api.ts @@ -21,7 +21,7 @@ // package requires import express from 'express' import bodyParser from 'body-parser' -import busboy from 'connect-busboy' +import fileUpload from 'express-fileupload' // other requires import logger from '../../utils/logger' @@ -86,10 +86,8 @@ function GetApp(): ModuleType { app.use(express.static(pdir)) }) app.use( - busboy({ - limits: { - fileSize: 50000 * 1024 * 1024, - }, + fileUpload({ + limits: { fileSize: 50 * 1024 * 1024 }, }) ) diff --git a/src/modules/api/submodules/feedback.ts b/src/modules/api/submodules/feedback.ts index 2908bae..2020f81 100644 --- a/src/modules/api/submodules/feedback.ts +++ b/src/modules/api/submodules/feedback.ts @@ -1,5 +1,3 @@ -import fs from 'fs' - import logger from '../../../utils/logger' import utils from '../../../utils/utils' import { Request, SubmoduleData, User } from '../../../types/basicTypes' @@ -11,7 +9,7 @@ function setup(data: SubmoduleData): void { const { app /* userDB, url, publicdirs, moduleSpecificData */ } = data app.post('/postfeedbackfile', function(req: Request, res: any) { - UploadFile(req, res, uloadFiles, () => { + utils.uploadFile(req, uloadFiles).then(() => { res.json({ success: true }) }) @@ -53,46 +51,9 @@ function setup(data: SubmoduleData): void { res.json({ success: true }) }) - function UploadFile(req: Request, res: any, path: string, next) { - try { - req.pipe(req.busboy) - req.busboy.on('file', function(fieldname, file, filename) { - logger.Log('Uploading: ' + filename, logger.GetColor('blue')) - - utils.CreatePath(path, true) - const date = new Date() - const fn = - date.getHours() + - '' + - date.getMinutes() + - '' + - date.getSeconds() + - '_' + - filename - - const fstream = fs.createWriteStream(path + '/' + fn) - file.pipe(fstream) - fstream.on('close', function() { - logger.Log( - 'Upload Finished of ' + path + '/' + fn, - logger.GetColor('blue') - ) - next(fn) - }) - fstream.on('error', function(err) { - console.error(err) - res.end('something bad happened :s') - }) - }) - } catch (err) { - logger.Log(`Unable to upload file!`, logger.GetColor('redbg')) - console.error(err) - } - } - app.route('/fosuploader').post(function(req: Request, res: any) { - UploadFile(req, res, uloadFiles, (fn) => { - res.redirect('/f/' + fn) + utils.uploadFile(req, uloadFiles).then(({ fileName }) => { + res.redirect('/f/' + fileName) }) }) } diff --git a/src/modules/api/submodules/userFiles.ts b/src/modules/api/submodules/userFiles.ts index c5aa9e4..f1486eb 100644 --- a/src/modules/api/submodules/userFiles.ts +++ b/src/modules/api/submodules/userFiles.ts @@ -2,7 +2,7 @@ import fs from 'fs' import logger from '../../../utils/logger' import utils from '../../../utils/utils' -import { Request, SubmoduleData } from '../../../types/basicTypes' +import { Request, SubmoduleData, User } from '../../../types/basicTypes' const usersFileName = '.users.json' @@ -13,16 +13,27 @@ function setup(data: SubmoduleData): void { const userFilesDir = publicDir + 'userFiles' + if (!utils.FileExists(userFilesDir)) { + utils.CreatePath(userFilesDir, true) + } + app.get('/listUserDir', (req: Request, res) => { logger.LogReq(req) const subdir: any = req.query.subdir if (subdir) { - const safeSubdir = subdir.replace(/\./g, '').replace(/\/+/g, '') + const safeSubdir = subdir.replace(/\.+/g, '').replace(/\/+/g, '') const dir = userFilesDir + '/' + safeSubdir const usersFile = dir + '/' + usersFileName + if (!utils.FileExists(dir)) { + res.json({ + success: false, + msg: `Directory ${subdir} does not exists`, + }) + return + } if (!utils.FileExists(usersFile)) { utils.WriteFile('{}', usersFile) } @@ -37,25 +48,27 @@ function setup(data: SubmoduleData): void { } res.json({ + success: true, files: utils.ReadDir(dir).reduce((acc, file) => { const stat = fs.lstatSync(dir + '/' + file) + if (stat.isDirectory()) { + return acc + } + acc.push({ name: file, path: dir.replace(publicDir, '') + '/' + file, size: stat.size, - uploadDate: stat.mtime.getTime(), - user: users[file], + date: stat.mtime.getTime(), + user: users[file] || -1, }) return acc }, []), }) } else { - if (!utils.FileExists(userFilesDir)) { - utils.CreatePath(userFilesDir, true) - } - res.json({ + success: true, dirs: utils.ReadDir(userFilesDir).reduce((acc, file) => { const stat = fs.lstatSync(userFilesDir + '/' + file) @@ -66,12 +79,115 @@ function setup(data: SubmoduleData): void { acc.push({ name: file, date: stat.mtime.getTime(), + size: utils.ReadDir(userFilesDir + '/' + file).length, }) return acc }, []), }) } }) + + app.post('/deleteUserFile', (req: Request, res) => { + const dir: any = req.body.dir + const fname: any = req.body.fname + if (!dir || !fname) { + res.json({ + success: false, + msg: `'dir' or 'fname' is undefined!`, + }) + return + } + const safeDir = dir.replace(/\.+/g, '').replace(/\/+/g, '') + const safeFname = fname.replace(/\.+/g, '.').replace(/\/+/g, '') + const filePath = userFilesDir + '/' + safeDir + '/' + safeFname + + if (!utils.FileExists(filePath)) { + res.json({ + success: false, + msg: `path does not exists!`, + }) + return + } + utils.deleteFile(filePath) + const usersFile = userFilesDir + '/' + safeDir + '/' + usersFileName + const users = utils.ReadJSON(usersFile) + delete users[safeFname] + utils.WriteFile(JSON.stringify(users), usersFile) + + res.json({ + success: true, + }) + }) + + app.post('/newUserDir', (req: Request, res) => { + logger.LogReq(req) + + const name: any = req.body.name + if (!name) { + res.json({ + success: false, + msg: `name is undefined!`, + }) + return + } + const safeName = name.replace(/\.+/g, '').replace(/\/+/g, '') + + if (utils.FileExists(userFilesDir + '/' + safeName)) { + res.json({ + success: false, + msg: `Dir ${name} already exists`, + }) + return + } + utils.CreatePath(userFilesDir + '/' + safeName, true) + + res.json({ + success: true, + }) + }) + + app.post('/uploadUserFile', (req: Request, res) => { + logger.LogReq(req) + + const user: User = req.session.user + const dir = req.body.dir + if (!dir) { + res.json({ + success: false, + msg: `dir '${dir}' is undefined!`, + }) + return + } + const safeDir = dir.replace(/\.+/g, '.').replace(/\/+/g, '/') + if (!utils.FileExists(userFilesDir + '/' + safeDir)) { + res.json({ + success: false, + msg: `dir '${dir}' does not exists!`, + }) + return + } + + utils + .uploadFile(req, userFilesDir + '/' + safeDir) + .then((body) => { + logger.Log( + `Successfull upload ${body.filePath}`, + logger.GetColor('blue') + ) + + const usersFile = userFilesDir + '/' + safeDir + '/' + usersFileName + const users = utils.ReadJSON(usersFile) + users[body.fileName] = user.id + utils.WriteFile(JSON.stringify(users), usersFile) + + res.json({ + success: true, + }) + }) + .catch(() => { + res.end('something bad happened :s') + }) + }) } export default { diff --git a/src/types/basicTypes.ts b/src/types/basicTypes.ts index 3364435..4a050df 100644 --- a/src/types/basicTypes.ts +++ b/src/types/basicTypes.ts @@ -72,6 +72,7 @@ export interface Request extends express.Request { cookies: any session: any busboy: any + files: any } export interface SubmoduleData { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 5bec6f3..df4e776 100755 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -12,11 +12,14 @@ export default { GetDateString: GetDateString, formatUrl: formatUrl, deleteFile: deleteFile, + uploadFile: uploadFile, } import fs from 'fs' import logger from '../utils/logger' +import { Request } from '../types/basicTypes' + interface URLFormatOptions { pathname?: string query?: any @@ -177,3 +180,46 @@ function deleteFile(fname: string): Boolean { } return false } + +function uploadFile(req: Request, path: string): Promise { + return new Promise((resolve, reject) => { + try { + const file = req.files.file + // FIXME: Object.keys(req.files).forEach((file) => { saveFile() }) + logger.Log('Uploading: ' + file.name, logger.GetColor('blue')) + + CreatePath(path, true) + + let fileName = file.name.replace(/\.+/g, '.').replace(/\/+/g, '/') + let fileDestination = path + '/' + fileName + if (FileExists(fileDestination)) { + const date = new Date() + const id = date.getHours() + date.getMinutes() + date.getSeconds() + + const temp = file.name.split('.') + const extension = temp.pop() + fileName = temp.join('.') + '_' + id + '.' + extension + console.log(fileName) + fileDestination = path + '/' + fileName + } + + file.mv(fileDestination, (err) => { + if (err) { + logger.Log(`Unable to upload file!`, logger.GetColor('redbg')) + console.error(err) + reject(err) + } else { + resolve({ + body: req.body, + fileName: fileName, + filePath: fileDestination, + }) + } + }) + } catch (err) { + logger.Log(`Unable to upload file!`, logger.GetColor('redbg')) + console.error(err) + reject(err) + } + }) +} diff --git a/submodules/qmining-page b/submodules/qmining-page index 47a2227..4f9a41d 160000 --- a/submodules/qmining-page +++ b/submodules/qmining-page @@ -1 +1 @@ -Subproject commit 47a2227f87f4f2ca726c16328006de174fa04aac +Subproject commit 4f9a41dea854de5d0e14a6acb06d2c6accd5cebf