Fixed unable to delete Avatar, with Meteor 3 compatible avatar and attachments fixes.

Thanks to inDane and xet7 !

Fixes #6160
This commit is contained in:
Lauri Ojansivu 2026-03-05 17:27:33 +02:00
parent 326f9bed84
commit 274f1309c3
3 changed files with 83 additions and 6 deletions

View file

@ -267,10 +267,9 @@ BlazeComponent.extendComponent({
event.stopPropagation();
this.setAvatar('');
},
'click .js-delete-avatar': Popup.afterConfirm('deleteAvatar', function(event) {
'click .js-delete-avatar': Popup.afterConfirm('deleteAvatar', function() {
Avatars.remove(this._id);
Popup.back();
event.stopPropagation();
}),
},
];

View file

@ -169,8 +169,14 @@ Attachments = new FilesCollection({
const ret = fileStoreStrategyFactory.getFileStrategy(fileObj, versionName).interceptDownload(http, this.cacheControl);
return ret;
},
onAfterRemove(files) {
onAfterRemove(filesInput) {
const files = normalizeRemovedFiles(filesInput);
files.forEach(fileObj => {
if (!fileObj || !fileObj.versions) {
return;
}
Object.keys(fileObj.versions).forEach(versionName => {
fileStoreStrategyFactory.getFileStrategy(fileObj, versionName).onAfterRemove();
});
@ -194,6 +200,38 @@ Attachments = new FilesCollection({
},
});
function normalizeRemovedFiles(filesInput) {
if (!filesInput) {
return [];
}
if (Array.isArray(filesInput)) {
return filesInput;
}
if (typeof filesInput.fetch === 'function') {
return filesInput.fetch();
}
if (Array.isArray(filesInput.files)) {
return filesInput.files;
}
if (typeof filesInput === 'string') {
return Attachments.find({ _id: filesInput }).fetch();
}
if (filesInput && typeof filesInput === 'object') {
if (filesInput._id && (filesInput.versions || filesInput.meta)) {
return [filesInput];
}
return Attachments.find(filesInput).fetch();
}
return [];
}
if (Meteor.isServer) {
Attachments.allow({
insert(userId, fileObj) {

View file

@ -129,9 +129,11 @@ Avatars = new FilesCollection({
const ret = fileStoreStrategyFactory.getFileStrategy(fileObj, versionName).interceptDownload(http, this.cacheControl);
return ret;
},
async onBeforeRemove(files) {
async onBeforeRemove(filesInput) {
const files = normalizeRemovedFiles(filesInput);
for (const fileObj of files) {
if (fileObj.userId) {
if (fileObj && fileObj.userId) {
const user = await ReactiveCache.getUser(fileObj.userId);
user.setAvatarUrl('');
}
@ -139,8 +141,14 @@ Avatars = new FilesCollection({
return true;
},
onAfterRemove(files) {
onAfterRemove(filesInput) {
const files = normalizeRemovedFiles(filesInput);
files.forEach(fileObj => {
if (!fileObj || !fileObj.versions) {
return;
}
Object.keys(fileObj.versions).forEach(versionName => {
fileStoreStrategyFactory.getFileStrategy(fileObj, versionName).onAfterRemove();
});
@ -148,6 +156,38 @@ Avatars = new FilesCollection({
},
});
function normalizeRemovedFiles(filesInput) {
if (!filesInput) {
return [];
}
if (Array.isArray(filesInput)) {
return filesInput;
}
if (typeof filesInput.fetch === 'function') {
return filesInput.fetch();
}
if (Array.isArray(filesInput.files)) {
return filesInput.files;
}
if (typeof filesInput === 'string') {
return Avatars.find({ _id: filesInput }).fetch();
}
if (filesInput && typeof filesInput === 'object') {
if (filesInput._id && (filesInput.versions || filesInput.userId)) {
return [filesInput];
}
return Avatars.find(filesInput).fetch();
}
return [];
}
function isOwner(userId, doc) {
return userId && userId === doc.userId;
}