From 381046a6b1f7be0ef3e36488d37180e4e32d1f18 Mon Sep 17 00:00:00 2001 From: Lhc_fl Date: Mon, 3 Mar 2025 18:17:13 +0800 Subject: [PATCH 1/2] fix: always clone the note before hideNote --- packages/backend/src/server/api/stream/channel.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts index 7a6193ccfc..b4a722e763 100644 --- a/packages/backend/src/server/api/stream/channel.ts +++ b/packages/backend/src/server/api/stream/channel.ts @@ -82,6 +82,12 @@ export default abstract class Channel { return false; } + /** + * Please make sure you did `assignMyReaction` before this function. + * See Dakker's comment regarding the same object will leading to wrong value. + * @param note The note to **CHANGE** + * @see assignMyReaction + */ protected async hideNote(note: Packed<'Note'>): Promise { if (note.renote) { await this.hideNote(note.renote); @@ -122,7 +128,6 @@ export default abstract class Channel { public onMessage?(type: string, body: JsonValue): void; public async assignMyReaction(note: Packed<'Note'>): Promise> { - let changed = false; // StreamingApiServerService creates a single EventEmitter per server process, // so a new note arriving from redis gets de-serialised once per server process, // and then that single object is passed to all active channels on each connection. @@ -133,7 +138,6 @@ export default abstract class Channel { if (note.renote && Object.keys(note.renote.reactions).length > 0) { const myReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); if (myReaction) { - changed = true; clonedNote.renote = { ...note.renote }; clonedNote.renote.myReaction = myReaction; } @@ -141,7 +145,6 @@ export default abstract class Channel { if (note.renote?.reply && Object.keys(note.renote.reply.reactions).length > 0) { const myReaction = await this.noteEntityService.populateMyReaction(note.renote.reply, this.user.id); if (myReaction) { - changed = true; clonedNote.renote = { ...note.renote }; clonedNote.renote.reply = { ...note.renote.reply }; clonedNote.renote.reply.myReaction = myReaction; @@ -151,12 +154,11 @@ export default abstract class Channel { if (this.user && note.reply && Object.keys(note.reply.reactions).length > 0) { const myReaction = await this.noteEntityService.populateMyReaction(note.reply, this.user.id); if (myReaction) { - changed = true; clonedNote.reply = { ...note.reply }; clonedNote.reply.myReaction = myReaction; } } - return changed ? clonedNote : note; + return clonedNote; } } From 8d487be4be368f2cf261746837862b945af990b8 Mon Sep 17 00:00:00 2001 From: Lhc_fl Date: Mon, 3 Mar 2025 23:46:31 +0800 Subject: [PATCH 2/2] small change to comment --- packages/backend/src/server/api/stream/channel.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts index b4a722e763..5189c86de8 100644 --- a/packages/backend/src/server/api/stream/channel.ts +++ b/packages/backend/src/server/api/stream/channel.ts @@ -83,10 +83,9 @@ export default abstract class Channel { } /** - * Please make sure you did `assignMyReaction` before this function. - * See Dakker's comment regarding the same object will leading to wrong value. - * @param note The note to **CHANGE** - * @see assignMyReaction + * This function modifies {@link note}, please make sure it has been shallow cloned. + * See Dakkar's comment of {@link assignMyReaction} for more + * @param note The note to change */ protected async hideNote(note: Packed<'Note'>): Promise { if (note.renote) {