added S3 file deletion

pull/18/head
tycrek 4 years ago
parent f525cc2f13
commit 3bda2c0cb4
No known key found for this signature in database
GPG Key ID: 25D74F3943625263

@ -23,7 +23,7 @@ const Thumbnail = require('./thumbnails');
const Vibrant = require('./vibrant');
const Hash = require('./hash');
const Path = require('path');
const { uploadLocal, uploadS3 } = require('./storage');
const { uploadLocal, uploadS3, deleteS3 } = require('./storage');
const { path, saveData, log, verify, generateToken, generateId, formatBytes, arrayEquals, getS3url, downloadTempS3 } = require('./utils');
//#endregion
@ -74,7 +74,9 @@ function startup() {
app.set('view engine', 'pug');
app.use(useragent.express());
// Generate ID's to use for other functions
app.use((req, _res, next) => (req.randomId = generateId('random', 32, null, null), next()));
app.use((req, _res, next) => (req.deleteId = generateId('random', 32, null, null), next()));
// Don't process favicon requests
app.use((req, res, next) => req.url.includes('favicon.ico') ? res.sendStatus(204) : next());
@ -105,6 +107,7 @@ function startup() {
// Pre-response operations
app.post('/', (req, _res, next) => {
req.file.randomId = req.randomId;
req.file.deleteId = req.deleteId;
// Download a temp copy to work with if using S3 storage
(s3enabled ? downloadTempS3(req.file) : new Promise((resolve) => resolve()))
@ -175,7 +178,7 @@ function startup() {
// Build the URLs
let resourceUrl = `${getTrueHttp()}${trueDomain}/${resourceId}`;
let thumbnailUrl = `${getTrueHttp()}${trueDomain}/${resourceId}/thumbnail`;
let deleteUrl = `${getTrueHttp()}${trueDomain}/delete/${req.file.filename}`;
let deleteUrl = `${getTrueHttp()}${trueDomain}/${resourceId}/delete/${req.file.deleteId}`;
// Send the response
res.type('json').send({ resource: resourceUrl, thumbnail: thumbnailUrl, delete: deleteUrl })
@ -267,22 +270,28 @@ function startup() {
});
// Delete file
app.get('/delete/:filename', (req, res) => {
let filename = req.params.filename;
let resourceId = Object.keys(data)[Object.values(data).indexOf(Object.values(data).find((d) => d.filename == filename))];
app.get('/:resourceId/delete/:deleteId', (req, res) => {
let resourceId = req.params.resourceId;
let deleteId = req.params.deleteId;
let fileData = data[resourceId];
// If the delete ID doesn't match, don't delete the file
if (deleteId !== fileData.deleteId) return res.sendStatus(401);
// If the ID is invalid, return 400 because we are unable to process the resource
if (!resourceId || !data[resourceId]) return res.sendStatus(400);
if (!resourceId || !fileData) return res.sendStatus(400);
log(`Deleted: ${data[resourceId].originalname} (${data[resourceId].mimetype})`);
log(`Deleted: ${fileData.originalname} (${fileData.mimetype})`);
// Save the file information
fs.rmSync(path(data[resourceId].path));
delete data[resourceId];
saveData(data);
res.type('text').send('File has been deleted!');
})
Promise.all([s3enabled ? deleteS3(fileData) : fs.rmSync(path(fileData.path)), fs.rmSync(path('uploads/thumbnails/', fileData.thumbnail))])
.then(() => {
delete data[resourceId];
saveData(data);
res.type('text').send('File has been deleted!');
})
.catch(console.error);
});
app.listen(port, host, () => log(`Server started on [${host}:${port}]\nAuthorized users: ${Object.keys(users).length}\nAvailable files: ${Object.keys(data).length}`));
}

@ -2,7 +2,7 @@ const Mustache = require('mustache');
const DateTime = require('luxon').DateTime;
const { homepage, version } = require('./package.json');
const { s3enabled } = require('./config.json');
const { formatBytes, randomHexColour, getS3url } = require('./utils');
const { formatBytes, randomHexColour, getS3url, getSafeExt } = require('./utils');
// https://ogp.me/
class OpenGraph {
@ -41,7 +41,7 @@ class OpenGraph {
}
build() {
let resourceUrl = !s3enabled ? (this.http + this.domain + "/" + this.resourceId + (this.type.includes('video') ? '.mp4' : this.type.includes('gif') ? '.gif' : '')) : getS3url(this.randomId, this.type);
let resourceUrl = !s3enabled ? (this.http + this.domain + "/" + this.resourceId + getSafeExt(this.type)) : getS3url(this.randomId, this.type);
return Mustache.render(html, {
homepage,
version,

@ -5,6 +5,7 @@ const fs = require('fs-extra');
const aws = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');
const { getSafeExt } = require('./utils');
const { diskFilePath, saveWithDate, s3endpoint, s3bucket, s3accessKey, s3secretKey } = require('./config.json');
const s3 = new aws.S3({
@ -17,11 +18,15 @@ const uploadS3 = multer({
s3: s3,
bucket: s3bucket,
acl: 'public-read',
key: (req, file, cb) => cb(null, req.randomId.concat(file.mimetype.includes('video') ? '.mp4' : file.mimetype.includes('gif') ? '.gif' : '')),
key: (req, file, cb) => cb(null, req.randomId.concat(getSafeExt(file.mimetype))),
contentType: (_req, file, cb) => cb(null, file.mimetype)
})
}).single('file');
const deleteS3 = (file) =>
new Promise((resolve, reject) =>
s3.deleteObject({ Bucket: s3bucket, Key: file.randomId.concat(getSafeExt(file.mimetype)) }).promise().then(resolve).catch(reject));
const uploadLocal = multer({
storage: multer.diskStorage({
destination: !saveWithDate ? diskFilePath : (_req, _file, cb) => {
@ -39,7 +44,4 @@ const uploadLocal = multer({
})
}).single('file');
module.exports = { uploadLocal, uploadS3 };
// This deletes everything from the Bucket
//s3.listObjects({ Bucket: s3bucket }, (err, data) => err ? console.error(err) : data['Contents'].forEach((obj) => s3.deleteObject({ Bucket: s3bucket, Key: obj['Key'] }, (err, data) => err ? console.log(err) : console.log(data))));
module.exports = { uploadLocal, uploadS3, deleteS3 };

@ -45,8 +45,13 @@ module.exports = {
.then((f2) => f2.body.pipe(fs.createWriteStream(Path.join(__dirname, 'uploads/', file.originalname)).on('close', () => resolve())))
.catch(reject)),
getS3url,
getSafeExt
}
function getS3url(s3key, type) {
return `https://${s3bucket}.${s3endpoint}/${s3key}${type.includes('video') ? '.mp4' : type.includes('gif') ? '.gif' : ''}`;
return `https://${s3bucket}.${s3endpoint}/${s3key}${getSafeExt(type)}`;
}
function getSafeExt(type) {
return type.includes('video') ? '.mp4' : type.includes('gif') ? '.gif' : '';
}

Loading…
Cancel
Save