From 97f0ad7c3bd3a5a1583cf2d3f8ca8c43adbd8a33 Mon Sep 17 00:00:00 2001 From: Doug Lauder Date: Thu, 7 May 2026 21:04:10 -0400 Subject: [PATCH] [MM-68697] Preserve sender file ID in plugin-relayed shared channel attachments (#36468) Set ReqFileId on the UploadSession created in ReceiveSharedChannelAttachmentSyncMsg so the attachment is persisted under the sender's file ID. Without this, the receiving server stored the bytes under a freshly generated ID while the synced post's FileIds still referenced the sender's ID, leaving the attachment invisible in the UI even though the file and FileInfo row existed on disk. Mirrors the existing cluster-to-cluster path in platform/services/sharedchannel/attachment.go. Also tightens TestPluginAPIReceiveSharedChannelAttachmentSyncMsg to pass a sender-side fi.Id and assert the saved FileInfo keeps it. The prior assertion only checked that some ID was assigned, which the buggy code also satisfied. --- server/channels/app/shared_channel.go | 1 + server/channels/app/shared_channel_test.go | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/server/channels/app/shared_channel.go b/server/channels/app/shared_channel.go index c25f03e3071..f861265c789 100644 --- a/server/channels/app/shared_channel.go +++ b/server/channels/app/shared_channel.go @@ -339,6 +339,7 @@ func (a *App) ReceiveSharedChannelAttachmentSyncMsg(rctx request.CTX, pluginID, Filename: fi.Name, FileSize: fi.Size, RemoteId: rc.RemoteId, + ReqFileId: fi.Id, } us, appErr := a.CreateUploadSession(rctx, us) diff --git a/server/channels/app/shared_channel_test.go b/server/channels/app/shared_channel_test.go index 73adac0c1b3..5acdc384fc1 100644 --- a/server/channels/app/shared_channel_test.go +++ b/server/channels/app/shared_channel_test.go @@ -1360,7 +1360,11 @@ func TestPluginAPIReceiveSharedChannelAttachmentSyncMsg(t *testing.T) { remoteUser, appErr := th.App.CreateUser(th.Context, remoteUser) require.Nil(t, appErr) + // The sender-side file ID must be preserved on the receiving server so the + // post's FileIds (which reference the sender ID) resolve to the saved file. + senderFileID := model.NewId() fi := &model.FileInfo{ + Id: senderFileID, CreatorId: remoteUser.Id, Name: "hello.txt", Size: 13, @@ -1369,12 +1373,13 @@ func TestPluginAPIReceiveSharedChannelAttachmentSyncMsg(t *testing.T) { saved, err := api.ReceiveSharedChannelAttachmentSyncMsg(rc.RemoteId, channel.Id, fi, bytes.NewReader([]byte("hello, world!"))) require.NoError(t, err) require.NotNil(t, saved) - assert.NotEmpty(t, saved.Id) + assert.Equal(t, senderFileID, saved.Id, "saved FileInfo must keep the sender's file ID") assert.Equal(t, rc.RemoteId, *saved.RemoteId) // Verify the FileInfo was persisted with a server-constructed path storedFI, appErr := th.App.GetFileInfo(th.Context, saved.Id) require.Nil(t, appErr) + assert.Equal(t, senderFileID, storedFI.Id) assert.Equal(t, "hello.txt", storedFI.Name) assert.NotEmpty(t, storedFI.Path) assert.Contains(t, storedFI.Path, "hello.txt")