mirror of
https://git.sr.ht/~coasteen/webui
synced 2025-11-04 11:37:34 +01:00
Compare commits
4 commits
243ba4d1c7
...
7fa4f8fc9d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fa4f8fc9d | ||
|
|
09269b3b72 | ||
|
|
75942458d9 | ||
|
|
36345026a7 |
6 changed files with 215 additions and 177 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
node_modules
|
||||
node_modules/
|
||||
uploads/
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
logs = enable
|
||||
log_to_file = false
|
||||
|
|
|
|||
164
package-lock.json
generated
164
package-lock.json
generated
|
|
@ -7,10 +7,15 @@
|
|||
"": {
|
||||
"name": "webui",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"license": "GPLv2",
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"multer": "^1.4.5-lts.1"
|
||||
"chalk": "^5.3.0",
|
||||
"express": "^4.19.2",
|
||||
"morgan": "^1.10.0",
|
||||
"multer": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
|
|
@ -38,6 +43,24 @@
|
|||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/basic-auth": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
|
||||
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/basic-auth/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||
|
|
@ -117,18 +140,30 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
|
||||
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||
"engines": [
|
||||
"node >= 0.8"
|
||||
"node >= 6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"readable-stream": "^3.0.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
|
|
@ -168,12 +203,6 @@
|
|||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
|
|
@ -483,12 +512,6 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
|
|
@ -579,6 +602,34 @@
|
|||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/morgan": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz",
|
||||
"integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"basic-auth": "~2.0.1",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~2.0.0",
|
||||
"on-finished": "~2.3.0",
|
||||
"on-headers": "~1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/morgan/node_modules/on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
|
|
@ -586,22 +637,21 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/multer": {
|
||||
"version": "1.4.5-lts.2",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.2.tgz",
|
||||
"integrity": "sha512-VzGiVigcG9zUAoCNU+xShztrlr1auZOlurXynNvO9GiWD1/mTBbUljOKY+qMeazBqXgRnjzeEgJI/wyjJUHg9A==",
|
||||
"deprecated": "Multer 1.x is impacted by a number of vulnerabilities, which have been patched in 2.x. You should upgrade to the latest 2.x version.",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz",
|
||||
"integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^1.0.0",
|
||||
"concat-stream": "^1.5.2",
|
||||
"mkdirp": "^0.5.4",
|
||||
"busboy": "^1.6.0",
|
||||
"concat-stream": "^2.0.0",
|
||||
"mkdirp": "^0.5.6",
|
||||
"object-assign": "^4.1.1",
|
||||
"type-is": "^1.6.4",
|
||||
"xtend": "^4.0.0"
|
||||
"type-is": "^1.6.18",
|
||||
"xtend": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
"node": ">= 10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
|
|
@ -646,6 +696,15 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/on-headers": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
|
||||
"integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
|
|
@ -661,12 +720,6 @@
|
|||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
|
@ -720,26 +773,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
|
@ -916,20 +962,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
|
|
|
|||
24
package.json
24
package.json
|
|
@ -1,20 +1,20 @@
|
|||
{
|
||||
"name": "webui",
|
||||
"version": "1.0.0",
|
||||
"description": "WebUI is a lightweight and easy-to-use web application for managing files on your server. It provides a simple interface to upload, download, delete, and preview files.",
|
||||
"main": "script.js",
|
||||
"description": "WebUI for managing server files",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/Soccera/webui.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"multer": "^1.4.5-lts.1"
|
||||
}
|
||||
"chalk": "^5.3.0",
|
||||
"express": "^4.19.2",
|
||||
"morgan": "^1.10.0",
|
||||
"multer": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"author": "Coasteen",
|
||||
"license": "GPLv2"
|
||||
}
|
||||
|
|
|
|||
198
server.js
198
server.js
|
|
@ -1,122 +1,116 @@
|
|||
const express = require('express');
|
||||
const multer = require('multer');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const express = require('express')
|
||||
const multer = require('multer')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const morgan = require('morgan')
|
||||
const chalk = require('chalk').default
|
||||
|
||||
const app = express();
|
||||
const app = express()
|
||||
const uploadDir = path.join(__dirname, 'uploads')
|
||||
if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir, { recursive: true })
|
||||
|
||||
function loadConfig() {
|
||||
try {
|
||||
const configPath = path.join(__dirname, 'config.conf');
|
||||
const content = fs.readFileSync(configPath, 'utf8');
|
||||
const match = content.match(/^logs\s*=\s*(.*)$/m);
|
||||
if (match && match[1].trim().toLowerCase() === 'disable') {
|
||||
return { loggingEnabled: false };
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
return { loggingEnabled: true };
|
||||
try {
|
||||
const content = fs.readFileSync(path.join(__dirname, 'config.conf'), 'utf8')
|
||||
const match = content.match(/^logs\s*=\s*(.*)$/m)
|
||||
if (match && match[1].trim().toLowerCase() === 'disable') return { loggingEnabled: false }
|
||||
} catch {}
|
||||
return { loggingEnabled: true }
|
||||
}
|
||||
|
||||
const config = loadConfig();
|
||||
const config = loadConfig()
|
||||
|
||||
function logAction(message) {
|
||||
if (config.loggingEnabled) {
|
||||
console.log(`[ACTION] ${message}`);
|
||||
}
|
||||
const colors = {
|
||||
info: chalk.cyanBright,
|
||||
warn: chalk.yellowBright,
|
||||
error: chalk.redBright,
|
||||
action: chalk.greenBright,
|
||||
sys: chalk.magentaBright
|
||||
}
|
||||
|
||||
const storage = multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
cb(null, 'uploads/');
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
|
||||
cb(null, uniqueSuffix + '-' + file.originalname);
|
||||
}
|
||||
});
|
||||
function log(level, msg) {
|
||||
if (!config.loggingEnabled) return
|
||||
const time = new Date().toISOString().replace('T', ' ').split('.')[0]
|
||||
const colorFn = colors[level.toLowerCase()] || chalk.white
|
||||
console.log(`[${time}] [${level.toUpperCase()}] ${colorFn(msg)}`)
|
||||
}
|
||||
|
||||
const upload = multer({ storage: storage });
|
||||
const storage = multer.diskStorage({
|
||||
destination: (req, file, cb) => cb(null, uploadDir),
|
||||
filename: (req, file, cb) => cb(null, `${Date.now()}-${Math.round(Math.random() * 1e9)}-${file.originalname}`)
|
||||
})
|
||||
const upload = multer({ storage }).array('files')
|
||||
|
||||
app.use(express.static(__dirname));
|
||||
app.use(express.static(__dirname))
|
||||
if (config.loggingEnabled) app.use(morgan('dev'))
|
||||
|
||||
app.post('/upload', upload.array('files'), (req, res) => {
|
||||
if (!req.files || req.files.length === 0) {
|
||||
logAction(`FAILED upload attempt: No files received.`);
|
||||
return res.status(400).send('No files were uploaded.');
|
||||
}
|
||||
const uploadedNames = req.files.map(f => f.filename).join(', ');
|
||||
logAction(`UPLOADED ${req.files.length} file(s): ${uploadedNames}`);
|
||||
res.send(`Successfully uploaded ${req.files.length} file(s)!`);
|
||||
});
|
||||
app.post('/upload', (req, res) => {
|
||||
upload(req, res, err => {
|
||||
if (err) {
|
||||
log('error', `UPLOAD ERROR: ${err.message}`)
|
||||
return res.status(500).send('Upload error')
|
||||
}
|
||||
if (!req.files?.length) {
|
||||
log('warn', `UPLOAD FAILED: No files received`)
|
||||
return res.status(400).send('No files uploaded')
|
||||
}
|
||||
const names = req.files.map(f => f.filename).join(', ')
|
||||
log('action', `UPLOADED ${req.files.length} file(s): ${names}`)
|
||||
res.send(`Uploaded ${req.files.length} file(s)!`)
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/files', (req, res) => {
|
||||
logAction(`LIST files requested.`);
|
||||
const directoryPath = path.join(__dirname, 'uploads');
|
||||
fs.readdir(directoryPath, (err, files) => {
|
||||
if (err) {
|
||||
return res.status(500).send('Unable to scan directory: ' + err);
|
||||
}
|
||||
const fileListPromises = files.map(file => {
|
||||
return new Promise((resolve) => {
|
||||
const filePath = path.join(directoryPath, file);
|
||||
fs.stat(filePath, (err, stats) => {
|
||||
if (err) {
|
||||
return resolve(null);
|
||||
}
|
||||
resolve({
|
||||
name: file,
|
||||
path: `/uploads/${file}`,
|
||||
size: stats.size,
|
||||
date: stats.mtime
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Promise.all(fileListPromises).then(fileList => {
|
||||
res.json(fileList.filter(file => file !== null));
|
||||
});
|
||||
});
|
||||
});
|
||||
log('info', 'Listing all files')
|
||||
fs.readdir(uploadDir, (err, files) => {
|
||||
if (err) {
|
||||
log('error', `Unable to read uploads directory: ${err.message}`)
|
||||
return res.status(500).send('Unable to scan directory')
|
||||
}
|
||||
const fileList = files.map(file => {
|
||||
const stat = fs.statSync(path.join(uploadDir, file))
|
||||
return { name: file, path: `/uploads/${file}`, size: stat.size, date: stat.mtime }
|
||||
})
|
||||
res.json(fileList)
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/uploads/:filename', (req, res) => {
|
||||
const filename = req.params.filename;
|
||||
logAction(`PREVIEW/ACCESS file: ${filename}`);
|
||||
const filePath = path.join(__dirname, 'uploads', filename);
|
||||
res.sendFile(filePath, err => {
|
||||
if (err) {
|
||||
res.status(404).send(`File not found: ${filename}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
const filename = req.params.filename
|
||||
const filePath = path.join(uploadDir, filename)
|
||||
log('info', `Serving file: ${filename}`)
|
||||
res.sendFile(filePath, err => {
|
||||
if (err) {
|
||||
log('error', `File not found: ${filename}`)
|
||||
res.status(404).send('File not found')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/download/:filename', (req, res) => {
|
||||
const filename = req.params.filename;
|
||||
logAction(`DOWNLOAD file: ${filename}`);
|
||||
const filePath = path.join(__dirname, 'uploads', filename);
|
||||
res.download(filePath, err => {
|
||||
if (err) {
|
||||
res.status(404).send(`File not found for download: ${filename}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
const filename = req.params.filename
|
||||
const filePath = path.join(uploadDir, filename)
|
||||
log('action', `Downloading file: ${filename}`)
|
||||
res.download(filePath, err => {
|
||||
if (err) {
|
||||
log('error', `Download failed for: ${filename}`)
|
||||
res.status(404).send('File not found')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
app.delete('/delete/:filename', (req, res) => {
|
||||
const filename = req.params.filename;
|
||||
const filePath = path.join(__dirname, 'uploads', filename);
|
||||
fs.unlink(filePath, err => {
|
||||
if (err) {
|
||||
logAction(`FAILED deletion of file: ${filename}`);
|
||||
return res.status(404).send('File not found');
|
||||
}
|
||||
logAction(`DELETED file: ${filename}`);
|
||||
res.send('File deleted successfully');
|
||||
});
|
||||
});
|
||||
const filename = req.params.filename
|
||||
const filePath = path.join(uploadDir, filename)
|
||||
fs.unlink(filePath, err => {
|
||||
if (err) {
|
||||
log('error', `Failed to delete: ${filename}`)
|
||||
return res.status(404).send('File not found')
|
||||
}
|
||||
log('action', `Deleted file: ${filename}`)
|
||||
res.send('File deleted successfully')
|
||||
})
|
||||
})
|
||||
|
||||
app.listen(3000, () => {
|
||||
if (config.loggingEnabled) {
|
||||
console.log('[*] Server is running on http://localhost:3000');
|
||||
}
|
||||
});
|
||||
const PORT = 3000
|
||||
app.listen(PORT, () => log('sys', `Server running on http://localhost:${PORT}`))
|
||||
|
|
|
|||
2
start.sh
Executable file
2
start.sh
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env sh
|
||||
node server.js
|
||||
Loading…
Add table
Reference in a new issue