Skip to content

Conversation

@pierre-lehnen-rc
Copy link
Contributor

@pierre-lehnen-rc pierre-lehnen-rc commented Jan 27, 2026

Proposed changes (including videos or screenshots)

On e2ee messages, the link between the message and the file is also being encrypted. This makes the server unable to delete files based on messages and also unable to delete messages based on files.
This PR changes the backend to save the metadata of the encrypted file on the message (just like it does for non-encrypted messages), so that any code that checks for links between files and messages can still find it.
It also changes the message to keep a list of files that have been deleted on the server so that the client may ignore any references to those files on decrypted data.

The only thing being saved to the message is related to the encrypted version of the file, so attributes like name, format and size will not reflect the real file - as the server doesn't have any info about it.

Issue(s)

CORE-1776

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • Bug Fixes

    • Removing an encrypted file now also removes its associated encrypted message and displays a consistent "removed file" indicator.
  • Improvements

    • Decryption and message rendering better handle deleted attachments, preserving removed-file placeholders.
    • Email notifications and message pending status now consistently treat end-to-end encrypted messages.
    • Uploaded encrypted files now include improved attachment linkage for clearer display.

✏️ Tip: You can customize this high-level summary in your review settings.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Jan 27, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is targeting the wrong base branch. It should target 8.2.0, but it targets 8.1.0

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Jan 27, 2026

🦋 Changeset detected

Latest commit: 25b152c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 40 packages
Name Type
@rocket.chat/core-typings Patch
@rocket.chat/meteor Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/abac Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/models Patch
@rocket.chat/ui-video-conf Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 27, 2026

Walkthrough

This PR ensures removed attachments from encrypted messages are consistently represented and handled: adds a removed-file attachment type (with optional fileId), makes attachment parsing unconditional for E2E sends, updates deletion/update paths to emit removed-file, and adjusts client-side decryption to map deleted attachments into placeholders.

Changes

Cohort / File(s) Summary
Type Definitions & Exports
packages/core-typings/src/IMessage/MessageAttachment/Files/RemovedFileAttachmentProps.ts, packages/core-typings/src/IMessage/MessageAttachment/Files/index.ts, packages/core-typings/src/IMessage/MessageAttachment/MessageAttachment.ts
Add RemovedFileAttachmentProps type (type: 'removed-file', optional fileId) and isRemovedFileAttachment guard; re-export and include in MessageAttachment union.
File Upload & Attachment Handling
apps/meteor/app/file-upload/server/methods/sendFileMessage.ts, apps/meteor/server/services/upload/service.ts, apps/meteor/client/lib/chats/flows/uploadFiles.ts
Remove parseAttachmentsForE2EE parameter; always parse attachments for sends; construct removed-file attachments (with type, color, text, optional fileId) when marking files removed; propagate fileId in upload flow.
E2E Decryption & Message Handling
apps/meteor/client/lib/e2ee/rocketchat.e2e.room.ts
Add decryptMessageContent and helpers (isFileAttachment, isRemovedFileAttachment); decrypt flow replaces deleted attachments with removed-attachment placeholders.
Room History & Message Deletion
apps/meteor/app/lib/server/functions/cleanRoomHistory.ts
Mark pruned message attachments with explicit type: 'removed-file' (retain color/text).
API & Notifications
apps/meteor/app/api/server/v1/rooms.ts, apps/meteor/app/lib/server/functions/notifications/email.js
Remove explicit parseAttachmentsForE2EE: false when calling sendFileMessage; broaden E2E email guard to apply for all t === 'e2e' messages (short-circuit email content building).
Client UI Utils
apps/meteor/app/ui-utils/client/lib/RoomHistoryManager.ts
Mark all E2E messages as pending (t === 'e2e') regardless of msg.file presence.
Changeset
.changeset/flat-tables-applaud.md
Add changeset documenting patch to @rocket.chat/core-typings and @rocket.chat/meteor for removed E2E message file deletion fix.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant UploadService
    participant MessagesDB
    participant Decryptor

    Note over Client,MessagesDB: Removal flow for encrypted message with file

    Client->>UploadService: Request remove message / file
    activate UploadService
    UploadService->>MessagesDB: Update message attachments -> `removed-file` (type, color, text, fileId?)
    deactivate UploadService

    Note over Client,Decryptor: Client receives updated message

    Client->>Decryptor: Decrypt message content
    activate Decryptor
    Decryptor->>Decryptor: Detect `removed-file` attachments (isRemovedFileAttachment)
    Decryptor->>Client: Return decrypted message with removed-file placeholders
    deactivate Decryptor
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • cardoso
  • tassoevan

Poem

🐰 I hopped through bytes and keys all night,
Replaced lost files with a gentle light.
A removed-file flag and a tiny trace,
Now encrypted leaves find their rightful place.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: preventing file removal issues in E2EE rooms by ensuring encrypted messages and their files are properly linked for deletion.
Linked Issues check ✅ Passed The PR comprehensively addresses CORE-1776 by storing encrypted-file metadata on messages for server-side file discovery, implementing client-side deletion tracking, and ensuring consistent message-file deletion behavior.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing E2EE message-file linkage issues, including type definitions, attachment handling, decryption logic, and file removal mechanisms.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/e2ee-uploads

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Jan 27, 2026

Codecov Report

❌ Patch coverage is 36.00000% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.85%. Comparing base (e57f158) to head (25b152c).
⚠️ Report is 9 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #38379      +/-   ##
===========================================
+ Coverage    70.78%   70.85%   +0.07%     
===========================================
  Files         3159     3160       +1     
  Lines       109401   109788     +387     
  Branches     19700    19709       +9     
===========================================
+ Hits         77435    77786     +351     
- Misses       29929    29975      +46     
+ Partials      2037     2027      -10     
Flag Coverage Δ
e2e 60.33% <36.36%> (-0.02%) ⬇️
e2e-api 47.79% <0.00%> (-0.07%) ⬇️
unit 72.07% <100.00%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 27, 2026

📦 Docker Image Size Report

➡️ Changes

Service Current Baseline Change Percent
sum of all images 0B 0B 0B
account-service 0B 0B 0B
authorization-service 0B 0B 0B
ddp-streamer-service 0B 0B 0B
omnichannel-transcript-service 0B 0B 0B
presence-service 0B 0B 0B
queue-worker-service 0B 0B 0B
rocketchat 0B 0B 0B

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 18:17", "12/05 21:56", "12/08 20:15", "12/09 22:17", "12/10 23:26", "12/11 21:56", "12/12 22:45", "12/13 01:34", "12/15 22:31", "12/16 22:18", "12/17 21:04", "12/18 23:12", "12/19 23:27", "12/20 21:03", "12/22 18:54", "12/23 16:16", "12/24 19:38", "12/25 17:51", "12/26 13:18", "12/29 19:01", "12/30 20:52", "01/28 16:41 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.00]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.00]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "queue-worker-service" [0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.00]
  line "rocketchat" [0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.00]
Loading

Statistics (last 30 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.4GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 0B
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-38379
  • Baseline: develop
  • Timestamp: 2026-01-28 16:41:34 UTC
  • Historical data points: 30

Updated: Wed, 28 Jan 2026 16:41:34 GMT

@pierre-lehnen-rc pierre-lehnen-rc added this to the 8.2.0 milestone Jan 28, 2026
@pierre-lehnen-rc pierre-lehnen-rc marked this pull request as ready for review January 28, 2026 16:15
@pierre-lehnen-rc pierre-lehnen-rc requested review from a team as code owners January 28, 2026 16:15
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 12 files

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@apps/meteor/client/lib/e2ee/rocketchat.e2e.room.ts`:
- Around line 672-678: The second early-return check "if
(!deletedAttachments.length) { return message; }" is redundant because
"!deletedAttachments.length" is already part of the earlier compound condition;
remove the duplicate if-block and keep only the initial guard that checks
deletedAttachments, message.attachments, and content.attachments so the function
returns once when there are no deleted attachments or missing attachments (refer
to the variables deletedAttachments, message.attachments, and
content.attachments to locate the redundant check).
🧹 Nitpick comments (1)
apps/meteor/client/lib/e2ee/rocketchat.e2e.room.ts (1)

680-701: Consider using .find() instead of manual loop for cleaner code.

The manual for...of loop can be simplified.

♻️ Suggested refactor
 		message.attachments = message.attachments.map((att) => {
 			if (!isFileAttachment(att)) {
 				return att;
 			}
 
 			if (deletedAllAttachment) {
 				return deletedAllAttachment;
 			}
 
 			const fileId = att.fileId || message.file?._id;
 			if (!fileId) {
 				return att;
 			}
 
-			for (const removedAttachment of deletedAttachments) {
-				if (removedAttachment.fileId === fileId) {
-					return removedAttachment;
-				}
-			}
-
-			return att;
+			return deletedAttachments.find((removed) => removed.fileId === fileId) ?? att;
 		});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants