From 92be236251833cc66f644ffb0aec4441b57bf713 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Thu, 26 Mar 2026 18:41:18 +0100 Subject: [PATCH] fix(federation): use canonical message identity in reaction outbox payloads Resolves canonical messageId (sourceMessageId for replicated messages, local ID for originated messages) and includes messageHomeInstance so the receiver can deterministically find the target message regardless of which instance created it. --- packages/server/src/ws/events.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/server/src/ws/events.ts b/packages/server/src/ws/events.ts index ed39ccfb..ccd757d6 100644 --- a/packages/server/src/ws/events.ts +++ b/packages/server/src/ws/events.ts @@ -12,6 +12,7 @@ import { sanitizeUser } from '../utils/sanitize.js'; import { deleteAttachmentFiles } from '../utils/fileCleanup.js'; import { resolveEmbeds, reResolveEmbeds, embedRowToEmbed } from '../utils/embedResolver.js'; import { appendMutationLog, queueOutboxEvent, queueDmRelay } from '../utils/federationOutbox.js'; +import { getOurOrigin } from '../utils/federationAuth.js'; /** * Re-evaluate SPEAK permission for all participants in voice channels @@ -1127,6 +1128,8 @@ function handleReactionAdd(event: Record, userId: string): void }); // Federation: log reaction mutation and queue for relay + const canonicalMessageId = dmMsg.sourceMessageId || messageId; + const messageHomeInstance = dmMsg.sourceInstance || getOurOrigin(); appendMutationLog(messageId, dmMsg.dmChannelId, 'reaction_add', JSON.stringify({ userId, homeUserId: reactionUser?.homeUserId || userId, @@ -1135,7 +1138,8 @@ function handleReactionAdd(event: Record, userId: string): void })); queueOutboxEvent(reactionId, dmMsg.dmChannelId, 'reaction_add', JSON.stringify({ reaction: { - messageId, + messageId: canonicalMessageId, + messageHomeInstance, userId, homeUserId: reactionUser?.homeUserId || userId, emoji, @@ -1202,6 +1206,8 @@ function handleReactionRemove(event: Record, userId: string): v // Federation: log reaction removal and queue for relay const removingUser = db.select().from(schema.users).where(eq(schema.users.id, userId)).get(); + const canonicalMessageId = dmMsg.sourceMessageId || messageId; + const messageHomeInstance = dmMsg.sourceInstance || getOurOrigin(); appendMutationLog(messageId, dmMsg.dmChannelId, 'reaction_remove', JSON.stringify({ userId, homeUserId: removingUser?.homeUserId || userId, @@ -1213,7 +1219,8 @@ function handleReactionRemove(event: Record, userId: string): v 'reaction_remove', JSON.stringify({ reaction: { - messageId, + messageId: canonicalMessageId, + messageHomeInstance, userId, homeUserId: removingUser?.homeUserId || userId, emoji,