mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-10 16:05:49 +01:00
updated post association code to only associate files that exist, closes #6455
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
var db = require('../database');
|
var db = require('../database');
|
||||||
|
|
||||||
@@ -9,6 +11,7 @@ module.exports = function (Posts) {
|
|||||||
Posts.uploads = {};
|
Posts.uploads = {};
|
||||||
|
|
||||||
const md5 = filename => crypto.createHash('md5').update(filename).digest('hex');
|
const md5 = filename => crypto.createHash('md5').update(filename).digest('hex');
|
||||||
|
const pathPrefix = path.join(__dirname, '../../public/uploads/files');
|
||||||
|
|
||||||
Posts.uploads.sync = function (pid, callback) {
|
Posts.uploads.sync = function (pid, callback) {
|
||||||
// Scans a post and updates sorted set of uploads
|
// Scans a post and updates sorted set of uploads
|
||||||
@@ -73,13 +76,24 @@ module.exports = function (Posts) {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
filePaths = !Array.isArray(filePaths) ? [filePaths] : filePaths;
|
filePaths = !Array.isArray(filePaths) ? [filePaths] : filePaths;
|
||||||
const scores = filePaths.map(() => now);
|
const scores = filePaths.map(() => now);
|
||||||
let methods = [async.apply(db.sortedSetAdd.bind(db), 'post:' + pid + ':uploads', scores, filePaths)];
|
|
||||||
methods = methods.concat(filePaths.map(path => async.apply(db.sortedSetAdd.bind(db), 'upload:' + md5(path) + ':pids', now, pid)));
|
|
||||||
|
|
||||||
|
async.filter(filePaths, function (filePath, next) {
|
||||||
|
// Only process files that exist
|
||||||
|
fs.access(path.join(pathPrefix, filePath), fs.constants.F_OK | fs.constants.R_OK, function (err) {
|
||||||
|
next(null, !err);
|
||||||
|
});
|
||||||
|
}, function (err, filePaths) {
|
||||||
|
let methods = [async.apply(db.sortedSetAdd.bind(db), 'post:' + pid + ':uploads', scores, filePaths)];
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
methods = methods.concat(filePaths.map(path => async.apply(db.sortedSetAdd.bind(db), 'upload:' + md5(path) + ':pids', now, pid)));
|
||||||
async.parallel(methods, function (err) {
|
async.parallel(methods, function (err) {
|
||||||
// Strictly return only err
|
// Strictly return only err
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Posts.uploads.dissociate = function (pid, filePaths, callback) {
|
Posts.uploads.dissociate = function (pid, filePaths, callback) {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ var async = require('async');
|
|||||||
var request = require('request');
|
var request = require('request');
|
||||||
var nconf = require('nconf');
|
var nconf = require('nconf');
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
var db = require('./mocks/databasemock');
|
var db = require('./mocks/databasemock');
|
||||||
var topics = require('../src/topics');
|
var topics = require('../src/topics');
|
||||||
@@ -883,6 +885,10 @@ describe('Post\'s', function () {
|
|||||||
var pid;
|
var pid;
|
||||||
|
|
||||||
before(function (done) {
|
before(function (done) {
|
||||||
|
// Create stub files for testing
|
||||||
|
['abracadabra.png', 'shazam.jpg', 'whoa.gif', 'amazeballs.jpg', 'wut.txt', 'test.bmp']
|
||||||
|
.forEach(filename => fs.closeSync(fs.openSync(path.join(__dirname, '../public/uploads/files', filename), 'w')));
|
||||||
|
|
||||||
topics.post({
|
topics.post({
|
||||||
uid: 1,
|
uid: 1,
|
||||||
cid: 1,
|
cid: 1,
|
||||||
@@ -1001,6 +1007,18 @@ describe('Post\'s', function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not associate a file that does not exist on the local disk', function (done) {
|
||||||
|
async.waterfall([
|
||||||
|
async.apply(posts.uploads.associate, pid, ['nonexistant.xls']),
|
||||||
|
async.apply(posts.uploads.list, pid),
|
||||||
|
], function (err, uploads) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(uploads.length, 5);
|
||||||
|
assert.strictEqual(false, uploads.includes('nonexistant.xls'));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('.dissociate()', function () {
|
describe('.dissociate()', function () {
|
||||||
@@ -1046,7 +1064,7 @@ describe('Post\'s', function () {
|
|||||||
uid: 1,
|
uid: 1,
|
||||||
tid: topicPostData.topicData.tid,
|
tid: topicPostData.topicData.tid,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
content: '[abcdef](/assets/uploads/files/shazam.png)',
|
content: '[abcdef](/assets/uploads/files/shazam.jpg)',
|
||||||
}, function (err, replyData) {
|
}, function (err, replyData) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
topic = topicPostData;
|
topic = topicPostData;
|
||||||
|
|||||||
Reference in New Issue
Block a user