diff --git a/src/modules/api/api.ts b/src/modules/api/api.ts index 4a854d2..eed8e73 100644 --- a/src/modules/api/api.ts +++ b/src/modules/api/api.ts @@ -54,6 +54,8 @@ function GetApp(): ModuleType { domain = domain.join('.') // "frylabs.net" logger.DebugLog(`Cookie domain: ${domain}`, 'cookie', 1) + // ------------------------------------------------------------------------------------------- + app.use( bodyParser.urlencoded({ limit: '10mb', @@ -81,15 +83,7 @@ function GetApp(): ModuleType { ], }) ) - publicdirs.forEach((pdir) => { - logger.Log(`Using public dir: ${pdir}`) - app.use(express.static(pdir)) - }) - app.use( - fileUpload({ - limits: { fileSize: 50 * 1024 * 1024 }, - }) - ) + // ------------------------------------------------------------------------------------------- let rootRedirectURL = '' @@ -128,7 +122,7 @@ function GetApp(): ModuleType { // -------------------------------------------------------------- - app.get('/', function(req: Request, res: any) { + app.get('/', function (req: Request, res: any) { logger.LogReq(req) if (reloadRootRedirectURL) { res.redirect(rootRedirectURL) @@ -143,11 +137,23 @@ function GetApp(): ModuleType { // ------------------------------------------------------------------------------------------- - app.get('*', function(req: Request, res: any) { + publicdirs.forEach((pdir) => { + logger.Log(`Using public dir: ${pdir}`) + app.use(express.static(pdir)) + }) + app.use( + fileUpload({ + limits: { fileSize: 50 * 1024 * 1024 }, + }) + ) + + // ------------------------------------------------------------------------------------------- + + app.get('*', function (req: Request, res: any) { res.status(404).render('404') }) - app.post('*', function(req: Request, res: any) { + app.post('*', function (req: Request, res: any) { res.status(404).render('404') }) diff --git a/src/modules/api/submodules/userFiles.ts b/src/modules/api/submodules/userFiles.ts index d2f1029..34e66b0 100644 --- a/src/modules/api/submodules/userFiles.ts +++ b/src/modules/api/submodules/userFiles.ts @@ -4,11 +4,102 @@ import logger from '../../../utils/logger' import utils from '../../../utils/utils' import { Request, SubmoduleData, User } from '../../../types/basicTypes' -const usersFileName = '.users.json' +const dataFileName = '.data.json' + +function listDir(publicDir, subdir, userFilesDir) { + const safeSubdir = subdir.replace(/\.+/g, '').replace(/\/+/g, '') + const dir = userFilesDir + '/' + safeSubdir + const usersFile = dir + '/' + dataFileName + + if (!utils.FileExists(dir)) { + return { + success: false, + msg: `Directory ${subdir} does not exists`, + } + return + } + if (!utils.FileExists(usersFile)) { + utils.WriteFile('{}', usersFile) + } + const users = utils.ReadJSON(usersFile) + + if (!utils.FileExists(dir)) { + return { + success: false, + msg: `Path '${safeSubdir}' does not exists`, + } + return + } + + return { + 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, + date: stat.mtime.getTime(), + user: users && users[file] ? users[file].uid : -1, + views: + users && users[file] && users[file].views ? users[file].views : 0, + upvotes: + users && users[file] && users[file].upvotes + ? users[file].upvotes + : [], + downvotes: + users && users[file] && users[file].downvotes + ? users[file].downvotes + : [], + }) + return acc + }, []), + } +} function setup(data: SubmoduleData): void { const { app, /* userDB, url, */ publicdirs /* moduleSpecificData */ } = data + app.use((req: Request, res, next) => { + // /userFiles/test/2021-04-28_10-59.png + try { + if (req.url.includes('/userFiles/')) { + logger.LogReq(req) + const safePath = decodeURIComponent(req.url) + .split('?')[0] + .replace(/\.+/g, '.') + .replace(/\/+/g, '/') + const x = safePath.split('/') + const dir = x[2] + const fname = x.pop() + const dataFilePath = userFilesDir + '/' + dir + '/' + dataFileName + + const data = utils.ReadJSON(dataFilePath) + + if (data[fname]) { + if (!data[fname].views) { + data[fname].views = 0 + } + data[fname].views = data[fname].views + 1 + + utils.WriteFile(JSON.stringify(data), dataFilePath) + } + } + } catch (e) { + console.error(e) + logger.Log( + `Error trying to update view count on ${req.url}`, + logger.GetColor('redbg') + ) + } + next() + }) + const publicDir = publicdirs[0] const userFilesDir = publicDir + 'userFiles' @@ -26,49 +117,8 @@ function setup(data: SubmoduleData): void { const subdir: any = req.query.subdir if (subdir) { - 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) - } - const users = utils.ReadJSON(usersFile) - - if (!utils.FileExists(dir)) { - res.json({ - success: false, - msg: `Path '${safeSubdir}' does not exists`, - }) - return - } - - 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, - date: stat.mtime.getTime(), - user: users[file] || -1, - }) - return acc - }, []), - }) + const result = listDir(publicDir, subdir, userFilesDir) + res.json(result) } else { res.json({ success: true, @@ -113,7 +163,7 @@ function setup(data: SubmoduleData): void { return } utils.deleteFile(filePath) - const usersFile = userFilesDir + '/' + safeDir + '/' + usersFileName + const usersFile = userFilesDir + '/' + safeDir + '/' + dataFileName const users = utils.ReadJSON(usersFile) delete users[safeFname] utils.WriteFile(JSON.stringify(users), usersFile) @@ -179,9 +229,9 @@ function setup(data: SubmoduleData): void { logger.GetColor('blue') ) - const usersFile = userFilesDir + '/' + safeDir + '/' + usersFileName + const usersFile = userFilesDir + '/' + safeDir + '/' + dataFileName const users = utils.ReadJSON(usersFile) - users[body.fileName] = user.id + users[body.fileName] = { uid: user.id } utils.WriteFile(JSON.stringify(users), usersFile) res.json({ @@ -192,6 +242,57 @@ function setup(data: SubmoduleData): void { res.end('something bad happened :s') }) }) + + app.post('/voteFile', (req: Request, res) => { + logger.LogReq(req) + const user: User = req.session.user + // { path: 'userFiles/test/2021-04-28_10-59.png', to: 'up' } 19 + const { path, to } = req.body + const safePath = path.replace(/\.+/g, '.').replace(/\/+/g, '/') + const x = safePath.split('/') + const dir = x[1] + const fname = x.pop() + const dataFilePath = userFilesDir + '/' + dir + '/' + dataFileName + + const data = utils.ReadJSON(dataFilePath) + + if (data[fname]) { + if (!data[fname].upvotes) { + data[fname].upvotes = [] + } + if (!data[fname].downvotes) { + data[fname].downvotes = [] + } + + const removeVote = (from, uid) => { + if (!from.includes(uid)) { + return from + } + return from.reduce((acc, id) => { + if (id !== uid) { + acc = [...acc, id] + } + return acc + }, []) + } + + data[fname].downvotes = removeVote(data[fname].downvotes, user.id) + data[fname].upvotes = removeVote(data[fname].upvotes, user.id) + + if (to === 'up') { + data[fname].upvotes = [...data[fname].upvotes, user.id] + } else if (to === 'down') { + data[fname].downvotes = [...data[fname].downvotes, user.id] + } else if (to === 'clear') { + // ... already cleared + } + + utils.WriteFile(JSON.stringify(data), dataFilePath) + } + + const result = listDir(publicDir, dir, userFilesDir) + res.json(result) + }) } export default {