mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-01-01 21:30:30 +01:00
* feat: move all user profile pics to folder
get rid of glob delete and just delete the uid-{uid} folder when deleting user images
* when exporting user uploads add all profile uploads
* uid check
This commit is contained in:
committed by
GitHub
parent
aef3ea18cf
commit
8f9ac5c17a
@@ -18,8 +18,7 @@ const plugins = require('../plugins');
|
||||
const events = require('../events');
|
||||
const translator = require('../translator');
|
||||
const sockets = require('../socket.io');
|
||||
|
||||
// const api = require('.');
|
||||
const utils = require('../utils');
|
||||
|
||||
const usersAPI = module.exports;
|
||||
|
||||
@@ -686,6 +685,9 @@ usersAPI.generateExport = async (caller, { uid, type }) => {
|
||||
if (!validTypes.includes(type)) {
|
||||
throw new Error('[[error:invalid-data]]');
|
||||
}
|
||||
if (!utils.isNumber(uid) || !(parseInt(uid, 10) > 0)) {
|
||||
throw new Error('[[error:invalid-uid]]');
|
||||
}
|
||||
const count = await db.incrObjectField('locks', `export:${uid}${type}`);
|
||||
if (count > 1) {
|
||||
throw new Error('[[error:already-exporting]]');
|
||||
|
||||
86
src/upgrades/3.8.0/user-upload-folders.js
Normal file
86
src/upgrades/3.8.0/user-upload-folders.js
Normal file
@@ -0,0 +1,86 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const fs = require('fs');
|
||||
const nconf = require('nconf');
|
||||
const path = require('path');
|
||||
const { mkdirp } = require('mkdirp');
|
||||
|
||||
const db = require('../../database');
|
||||
const batch = require('../../batch');
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'Create user upload folders',
|
||||
timestamp: Date.UTC(2024, 4, 28),
|
||||
method: async function () {
|
||||
const { progress } = this;
|
||||
|
||||
const folder = path.join(nconf.get('upload_path'), 'profile');
|
||||
|
||||
const userPicRegex = /^\d+-profile/;
|
||||
const files = (await fs.promises.readdir(folder, { withFileTypes: true }))
|
||||
.filter(item => !item.isDirectory() && String(item.name).match(userPicRegex))
|
||||
.map(item => item.name);
|
||||
|
||||
progress.total = files.length;
|
||||
await batch.processArray(files, async (files) => {
|
||||
progress.incr(files.length);
|
||||
await Promise.all(files.map(async (file) => {
|
||||
const uid = file.split('-')[0];
|
||||
if (parseInt(uid, 10) > 0) {
|
||||
await mkdirp(path.join(folder, `uid-${uid}`));
|
||||
await fs.promises.rename(
|
||||
path.join(folder, file),
|
||||
path.join(folder, `uid-${uid}`, file),
|
||||
);
|
||||
}
|
||||
}));
|
||||
}, {
|
||||
batch: 500,
|
||||
});
|
||||
|
||||
await batch.processSortedSet('users:joindate', async (uids) => {
|
||||
progress.incr(uids.length);
|
||||
const usersData = await db.getObjects(uids.map(uid => `user:${uid}`));
|
||||
const bulkSet = [];
|
||||
usersData.forEach((userData) => {
|
||||
const setObj = {};
|
||||
if (userData && userData.picture &&
|
||||
userData.picture.includes(`/uploads/profile/${userData.uid}-`) &&
|
||||
!userData.picture.includes(`/uploads/profile/uid-${userData.uid}/${userData.uid}-`)) {
|
||||
setObj.picture = userData.picture.replace(
|
||||
`/uploads/profile/${userData.uid}-`,
|
||||
`/uploads/profile/uid-${userData.uid}/${userData.uid}-`
|
||||
);
|
||||
}
|
||||
|
||||
if (userData && userData.uploadedpicture &&
|
||||
userData.uploadedpicture.includes(`/uploads/profile/${userData.uid}-`) &&
|
||||
!userData.uploadedpicture.includes(`/uploads/profile/uid-${userData.uid}/${userData.uid}-`)) {
|
||||
setObj.uploadedpicture = userData.uploadedpicture.replace(
|
||||
`/uploads/profile/${userData.uid}-`,
|
||||
`/uploads/profile/uid-${userData.uid}/${userData.uid}-`
|
||||
);
|
||||
}
|
||||
|
||||
if (userData && userData['cover:url'] &&
|
||||
userData['cover:url'].includes(`/uploads/profile/${userData.uid}-`) &&
|
||||
!userData['cover:url'].includes(`/uploads/profile/uid-${userData.uid}/${userData.uid}-`)) {
|
||||
setObj['cover:url'] = userData['cover:url'].replace(
|
||||
`/uploads/profile/${userData.uid}-`,
|
||||
`/uploads/profile/uid-${userData.uid}/${userData.uid}-`
|
||||
);
|
||||
}
|
||||
|
||||
if (Object.keys(setObj).length) {
|
||||
bulkSet.push([`user:${userData.uid}`, setObj]);
|
||||
}
|
||||
});
|
||||
await db.setObjectBulk(bulkSet);
|
||||
}, {
|
||||
batch: 500,
|
||||
progress: progress,
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -227,7 +227,7 @@ module.exports = function (User) {
|
||||
}
|
||||
|
||||
async function deleteImages(uid) {
|
||||
const folder = path.join(nconf.get('upload_path'), 'profile');
|
||||
await rimraf(`${uid}-profile{avatar,cover}*`, { glob: { cwd: folder } });
|
||||
const folder = path.join(nconf.get('upload_path'), 'profile', `uid-${uid}`);
|
||||
await rimraf(folder);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -74,14 +74,8 @@ process.on('message', async (msg) => {
|
||||
winston.verbose(`[user/export/uploads] Collating uploads for uid ${targetUid}`);
|
||||
await user.collateUploads(targetUid, archive);
|
||||
|
||||
const uploadedPicture = await user.getUserField(targetUid, 'uploadedpicture');
|
||||
if (uploadedPicture) {
|
||||
const filePath = uploadedPicture.replace(nconf.get('upload_url'), '');
|
||||
archive.file(path.join(nconf.get('upload_path'), filePath), {
|
||||
name: path.basename(filePath),
|
||||
});
|
||||
}
|
||||
|
||||
const profileUploadPath = path.join(nconf.get('upload_path'), `profile/uid-${targetUid}`);
|
||||
archive.directory(profileUploadPath, 'profile');
|
||||
archive.finalize();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ module.exports = function (User) {
|
||||
|
||||
const extension = file.typeToExtension(image.mimeFromBase64(data.imageData));
|
||||
const filename = `${data.uid}-profilecover-${Date.now()}${extension}`;
|
||||
const uploadData = await image.uploadImage(filename, 'profile', picture);
|
||||
const uploadData = await image.uploadImage(filename, `profile/uid-${data.uid}`, picture);
|
||||
|
||||
await deleteCurrentPicture(data.uid, 'cover:url');
|
||||
await User.setUserField(data.uid, 'cover:url', uploadData.url);
|
||||
@@ -96,7 +96,7 @@ module.exports = function (User) {
|
||||
});
|
||||
|
||||
const filename = generateProfileImageFilename(data.uid, extension);
|
||||
const uploadedImage = await image.uploadImage(filename, 'profile', {
|
||||
const uploadedImage = await image.uploadImage(filename, `profile/uid-${data.uid}`, {
|
||||
uid: data.uid,
|
||||
path: newPath,
|
||||
name: 'profileAvatar',
|
||||
@@ -140,7 +140,7 @@ module.exports = function (User) {
|
||||
});
|
||||
|
||||
const filename = generateProfileImageFilename(data.uid, extension);
|
||||
const uploadedImage = await image.uploadImage(filename, 'profile', picture);
|
||||
const uploadedImage = await image.uploadImage(filename, `profile/uid-${data.uid}`, picture);
|
||||
|
||||
await deleteCurrentPicture(data.uid, 'uploadedpicture');
|
||||
await User.updateProfile(data.callerUid, {
|
||||
@@ -224,10 +224,10 @@ module.exports = function (User) {
|
||||
|
||||
async function getPicturePath(uid, field) {
|
||||
const value = await User.getUserField(uid, field);
|
||||
if (!value || !value.startsWith(`${nconf.get('relative_path')}/assets/uploads/profile/`)) {
|
||||
if (!value || !value.startsWith(`${nconf.get('relative_path')}/assets/uploads/profile/uid-${uid}`)) {
|
||||
return false;
|
||||
}
|
||||
const filename = value.split('/').pop();
|
||||
return path.join(nconf.get('upload_path'), 'profile', filename);
|
||||
return path.join(nconf.get('upload_path'), `profile/uid-${uid}`, filename);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user