fix: inability to download encrypted pdfs from pdf preview#40517
fix: inability to download encrypted pdfs from pdf preview#40517nazabucciarelli wants to merge 4 commits into
Conversation
|
Looks like this PR is not ready to merge, because of the following issues:
Please fix the issues and try again If you have any trouble, please check the PR guidelines |
🦋 Changeset detectedLatest commit: 78225b7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 42 packages
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 |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
WalkthroughGenericFileAttachment detects encrypted ChangesEncrypted PDF Viewing on Desktop
🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #40517 +/- ##
===========================================
- Coverage 69.63% 69.59% -0.05%
===========================================
Files 3318 3325 +7
Lines 121981 122853 +872
Branches 21813 21876 +63
===========================================
+ Hits 84947 85499 +552
- Misses 33701 34007 +306
- Partials 3333 3347 +14
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR updates file attachment handling so PDF attachments—especially encrypted PDFs—can be previewed inline and downloaded from the PDF viewer instead of failing through the previous encrypted download path.
Changes:
- Adds a helper to request decrypted attachment bytes from the service worker.
- Routes PDF title clicks through browser/native PDF preview or Electron document viewer.
- Preserves the existing service-worker download path for encrypted non-PDF files.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
apps/meteor/client/hooks/useDownloadFromServiceWorker.ts |
Adds getDecryptedBuffer for retrieving decrypted attachment data from the service worker. |
apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx |
Splits PDF handling into encrypted blob-preview and non-encrypted inline-preview flows. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
3d105f4 to
77b5b46
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx`:
- Around line 38-45: The cleanup effect currently revokes blobUrlRef.current on
unmount but doesn’t prevent a concurrent fetch from later assigning a new blob
URL, causing a leak; update the component to add a mounted flag (e.g., let
isMounted = true in useEffect and set false on cleanup) and/or use an
AbortController to cancel the in-flight fetch, and only set blobUrlRef.current
(and call URL.createObjectURL) if isMounted is true and the fetch was not
aborted; apply the same guard to the fetch logic referenced around the
download/fetch function (the code that assigns blobUrlRef.current, lines ~66-71)
so any newly created blob URL is only stored while mounted and revoked on
cleanup (and abort the fetch on unmount).
- Around line 63-71: The blob URL leak happens when multiple clicks start
overlapping fetches because only blobUrlRef.current is tracked; fix by
introducing an AbortController stored (e.g., in a ref like fetchAbortRef) and
before starting a new fetch abort any in-flight request and revoke any
previously created blob URL (blobUrlRef.current) to ensure cleanup; then create
a new AbortController for the new fetch, pass its signal to fetch(getURL(link)),
await response.blob(), create the new object URL, set blobUrlRef.current and
openDocumentViewer(blobUrl, format, title ?? ''), and ensure you handle
AbortError (skip revoke if already revoked) and always revoke old blob URLs when
replacing them to prevent leaks.
- Around line 66-71: Wrap the fetch/get blob sequence in a try-catch around the
code that calls fetch(getURL(link)), response.blob(), URL.createObjectURL and
openDocumentViewer so network or blob errors are caught; on success set
blobUrlRef.current and call openDocumentViewer(blobUrl, format, title ?? ''), on
failure log the error (console.error) and surface a user-facing error (e.g.,
show a toast/alert or call a provided notification helper) so clicking gives
feedback; also ensure any created object URL is revoked on error/cleanup (use
URL.revokeObjectURL) so resources aren’t leaked and blobUrlRef.current is only
assigned after successful creation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6ad6eb8c-d3d7-4ff1-a1fa-efdb623d2af3
📒 Files selected for processing (2)
.changeset/fine-jokes-trade.mdapps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)
**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation
Files:
apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx
🧠 Learnings (3)
📚 Learning: 2026-03-16T21:50:37.589Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: .changeset/migrate-users-register-openapi.md:3-3
Timestamp: 2026-03-16T21:50:37.589Z
Learning: For changes related to OpenAPI migrations in Rocket.Chat/OpenAPI, when removing endpoint types and validators from rocket.chat/rest-typings (e.g., UserRegisterParamsPOST, /v1/users.register) document this as a minor changeset (not breaking) per RocketChat/Rocket.Chat-Open-API#150 Rule 7. Note that the endpoint type is re-exposed via a module augmentation .d.ts in the consuming package (e.g., packages/web-ui-registration/src/users-register.d.ts). In reviews, ensure the changeset clearly states: this is a non-breaking change, the major version should not be bumped, and the changeset reflects a minor version bump. Do not treat this as a breaking change during OpenAPI migrations.
Applied to files:
.changeset/fine-jokes-trade.md
📚 Learning: 2026-03-27T14:52:56.865Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39892
File: apps/meteor/client/views/room/contextualBar/Threads/Thread.tsx:150-155
Timestamp: 2026-03-27T14:52:56.865Z
Learning: In Rocket.Chat, there are two different `ModalBackdrop` components with different prop APIs. During review, confirm the import source: (1) `rocket.chat/fuselage` `ModalBackdrop` uses `ModalBackdropProps` based on `BoxProps` (so it supports `onClick` and other Box/DOM props) and does not have an `onDismiss` prop; (2) `rocket.chat/ui-client` `ModalBackdrop` uses a narrower props interface like `{ children?: ReactNode; onDismiss?: () => void }` and handles Escape keypress and outside mouse-up, and it does not forward arbitrary DOM props such as `onClick`. Flag mismatched props (e.g., `onDismiss` passed to the fuselage component or `onClick` passed to the ui-client component) and ensure the usage matches the correct component being imported.
Applied to files:
apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.
Applied to files:
apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx
🔇 Additional comments (1)
.changeset/fine-jokes-trade.md (1)
1-5: LGTM!
There was a problem hiding this comment.
1 issue found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx">
<violation number="1" location="apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx:79">
P2: Check `response.ok` before converting to blob; HTTP error responses currently get opened in the PDF viewer as if they were valid files.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Re-trigger cubic
Proposed changes (including videos or screenshots)
I’ll divide the fix in 2 steps:
1- Rocket.Chat Electron Repo: I’ll need to add ‘blob:’ as a supported protocol in src/documentViewer/ipc.ts so that the sent blob is served by the PDF viewer in Electron. This one-line PR was raised for that.
2- Rocket.Chat Main Repo: In the
GenericFileAttachmentcomponent (the one that renders attachments), I've added two different flows for the electron path:MAX_FILE_SIZE_PREVIEWconst, it won't be converted to blob but downloaded, otherwise it would be very resource consuming. To avoid memory leaks, blob urls are properly revoked.No tests will be implemented since we can't test the PDF viewer from the Electron app.
Issue(s)
SUP-1022 Download fail on Encrypted rooms PDF Viewer
Steps to test or reproduce
Steps to reproduce on Electron and Browser:
Further comments
Summary by CodeRabbit