mirror of
https://gitlab.com/MrFry/mrfrys-node-server
synced 2026-04-28 03:07:38 +02:00
299 lines
7.6 KiB
TypeScript
299 lines
7.6 KiB
TypeScript
import fs from 'fs'
|
|
|
|
import logger from '../../../utils/logger'
|
|
import utils from '../../../utils/utils'
|
|
import { Request, SubmoduleData, User } from '../../../types/basicTypes'
|
|
|
|
const dataFileName = '.data.json'
|
|
|
|
function listDir(publicDir: string, subdir: string, userFilesDir: string) {
|
|
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`,
|
|
}
|
|
}
|
|
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 {
|
|
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'
|
|
if (!utils.FileExists(userFilesDir)) {
|
|
utils.CreatePath(userFilesDir, true)
|
|
}
|
|
|
|
app.get('/listUserDir', (req: Request, res) => {
|
|
logger.LogReq(req)
|
|
|
|
if (!utils.FileExists(userFilesDir)) {
|
|
utils.CreatePath(userFilesDir, true)
|
|
}
|
|
|
|
const subdir: any = req.query.subdir
|
|
|
|
if (subdir) {
|
|
const result = listDir(publicDir, subdir, userFilesDir)
|
|
res.json(result)
|
|
} else {
|
|
res.json({
|
|
success: true,
|
|
dirs: utils.ReadDir(userFilesDir).reduce((acc, file) => {
|
|
const stat = fs.lstatSync(userFilesDir + '/' + file)
|
|
|
|
if (!stat.isDirectory()) {
|
|
return acc
|
|
}
|
|
|
|
acc.push({
|
|
name: file,
|
|
date: stat.mtime.getTime(),
|
|
size: utils.ReadDir(userFilesDir + '/' + file).length,
|
|
})
|
|
return acc
|
|
}, []),
|
|
})
|
|
}
|
|
})
|
|
|
|
app.post('/deleteUserFile', (req: Request, res) => {
|
|
logger.LogReq(req)
|
|
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 + '/' + dataFileName
|
|
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 + '/' + dataFileName
|
|
const users = utils.ReadJSON(usersFile)
|
|
users[body.fileName] = { uid: user.id }
|
|
utils.WriteFile(JSON.stringify(users), usersFile)
|
|
|
|
res.json({
|
|
success: true,
|
|
})
|
|
})
|
|
.catch(() => {
|
|
res.json({ success: false, msg: '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: number[], uid: number) => {
|
|
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 {
|
|
setup: setup,
|
|
}
|