feat: deleting a user upload dissociates from posts, and vice versa

isekai-main
Julian Lam 3 years ago
parent 8c2752bab1
commit d5ed8736aa

@ -9,6 +9,7 @@ const validator = require('validator');
const db = require('../database');
const image = require('../image');
const user = require('../user');
const topics = require('../topics');
const file = require('../file');
const meta = require('../meta');
@ -123,14 +124,19 @@ module.exports = function (Posts) {
db.sortedSetRemoveBulk(bulkRemove),
];
await Promise.all(promises);
if (!meta.config.preserveOrphanedUploads) {
const deletePaths = (await Promise.all(
filePaths.map(async filePath => (await Posts.uploads.isOrphan(filePath) ? filePath : false))
)).filter(Boolean);
promises.push(Posts.uploads.deleteFromDisk(deletePaths));
}
await Promise.all(promises);
const uploaderUids = (await db.getObjectsFields(deletePaths.map(path => `upload:${md5(path)}`, ['uid']))).map(o => (o ? o.uid || null : null));
await Promise.all(uploaderUids.map((uid, idx) => (
uid && isFinite(uid) ? user.deleteUpload(uid, uid, deletePaths[idx]) : null
)).filter(Boolean));
await Posts.uploads.deleteFromDisk(deletePaths);
}
};
Posts.uploads.dissociateAll = async (pid) => {

@ -6,6 +6,7 @@ const winston = require('winston');
const crypto = require('crypto');
const db = require('../database');
const posts = require('../posts');
const file = require('../file');
const batch = require('../batch');
@ -66,6 +67,12 @@ module.exports = function (User) {
db.delete(`upload:${md5(uploadNames[idx])}`),
]);
}));
// Dissociate the upload from pids, if any
const pids = await db.getSortedSetsMembers(uploadNames.map(relativePath => `upload:${md5(relativePath)}:pids`));
await Promise.all(pids.map(async (pids, idx) => Promise.all(
pids.map(async pid => posts.uploads.dissociate(pid, uploadNames[idx]))
)));
}, { batch: 50 });
};

@ -207,6 +207,16 @@ describe('upload methods', () => {
done();
});
});
it('should remove the image\'s user association, if present', async () => {
_recreateFiles();
await posts.uploads.associate(pid, 'files/wut.txt');
await user.associateUpload(uid, 'files/wut.txt');
await posts.uploads.dissociate(pid, 'files/wut.txt');
const userUploads = await db.getSortedSetMembers(`uid:${uid}:uploads`);
assert.strictEqual(userUploads.includes('files/wut.txt'), false);
});
});
describe('.dissociateAll()', () => {

@ -9,6 +9,8 @@ const nconf = require('nconf');
const db = require('../mocks/databasemock');
const user = require('../../src/user');
const topics = require('../../src/topics');
const categories = require('../../src/categories');
const file = require('../../src/file');
const utils = require('../../public/src/utils');
@ -144,5 +146,21 @@ describe('uploads.js', () => {
assert.strictEqual(e.message, '[[error:invalid-path]]');
}
});
it('should remove the post association as well, if present', async () => {
const { cid } = await categories.create({ name: utils.generateUUID() });
const { postData } = await topics.post({
uid,
cid,
title: utils.generateUUID(),
content: `[an upload](/assets/uploads/${relativePath})`,
});
assert.deepStrictEqual(await db.getSortedSetMembers(`upload:${md5(relativePath)}:pids`), [postData.pid.toString()]);
await user.deleteUpload(uid, uid, relativePath);
assert.strictEqual(await db.exists(`upload:${md5(relativePath)}:pids`), false);
});
});
});

Loading…
Cancel
Save