-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add encryption support and access privileges #2696
base: master
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 798995c The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 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 |
494459f
to
5d9a8e9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah, nice one! Looks good to me.
I wonder if we could have some tests for that. As long as #2633 repairs them 🥲
Also, changeset is missing. Can you please run yarn changeset
as explained in CONTRIBUTORS.md?
|
||
return Buffer.from(byteArray); | ||
}; | ||
import CryptoJS from 'crypto-js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder how this change affects bundle size and what was the original reason for selective import done like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I tried digging in revision history, but it was introduced with the selective import in #1894. Upstream never used the selective import and imported the whole library from the beginning: foliojs/pdfkit#820. I'm guessing it's because the full/upstream security.js
file uses extensively this library - CryptoJS.MD5
, CryptoJS.RC4
, CryptoJS.lib.WordArray
, CryptoJS.SHA256
, CryptoJS.AES
. Whereas the simplified version (not supporting password protection) indeed just used CryptoJS.MD5
, so the selective import might have made sense for that use case.
For completeness sake (so that the implications of this PR on the bundle size are known):
Current master
646,480 pdfkit.browser.cjs
644,160 pdfkit.browser.js
326,577 pdfkit.browser.min.cjs
325,782 pdfkit.browser.min.js
407,839 pdfkit.cjs
405,488 pdfkit.js
232,858 pdfkit.min.cjs
231,996 pdfkit.min.js
This branch/PR
683,846 pdfkit.browser.cjs
680,853 pdfkit.browser.js
343,476 pdfkit.browser.min.cjs
342,353 pdfkit.browser.min.js
445,176 pdfkit.cjs
442,171 pdfkit.js
249,962 pdfkit.min.cjs
248,604 pdfkit.min.js
So, 9% increase for pdfkit.js
and 7.2% for pdfkit.min.js
.
5d9a8e9
to
cb2d168
Compare
Thanks for looking at the PR, @wojtekmaj! Sorry for the late follow-up - private life got in the way, but now I'm back and determined to see this PR through. I've addressed your comments and generated the changeset 🙇 To be extra clear - I don't think this PR is ready to merge as-is. At the very least there's an issue with the fonts. There's links to generated PDF files in the description and my attempt at best describing the possible issue, but it might be best shown on screenshots: Production file, correct fontsPR file, missing fontsAnd there are indeed warnings from the Firefox internal PDF previewer:
My guess is that these attachments/resources are not correctly encoded or decoded with the passwords/security logic introduced in this PR. I've double-checked the differences between the |
0f4f988
to
858c779
Compare
Based on foliojs/pdfkit#820 upstream Fixes diegomura#672
Syncs up with the upstream version at: https://github.com/foliojs/pdfkit/blob/5635f8a02135acae1a6c1b904af55afe05d0ab7e/lib/security.js
Big props to @florianbepunkt for spotting this solution. See diegomura#2924 (comment)
99c8119
to
16f1475
Compare
From https://github.com/foliojs/pdfkit/tree/3a6977e813a886744a383efedd124ae661bcc96c/tests/unit Basically, just need small adjustments: - Adding `import { beforeEach, describe, expect, test } from 'vitest';` - Changing the relative imports from `import PDFMetadata from '../../lib/metadata';` to `import PDFMetadata from '../../src/metadata';`, since the source lives in `src` in this version, while the _output_ lives in `lib`. - `import matcher from './toContainChunk'; expect.extend(matcher);` if the file needs the `toContainChunk` matcher. This should be in a global vitest setup file, but that requires even more boilerplate.
PR updated - it should be good for a final/proper review. The font issues have been solved thanks to @florianbepunkt, see #2924 (comment). I've also ported some unit tests from |
Hi, @diegomura! Love your library - I've been using it extensively at https://github.com/klimeryk/recalendar.js/ (https://recalendar.me/). I stumbled upon #672 and figured it was a great chance to contribute back :)
I've tried my best to bring over the changes from the upstream pdfkit version. Encryption was originally added in foliojs/pdfkit#820 there. It was mostly a straightforward update... except changes in
reference.js
. Looks like that class has been fundamentally changed - upstream it uses internallyBuffer
, while in react-pdf, the class extendsWriteable
instead.I've tried first keeping the changes to
reference.js
minimal (see 4376bcb). Most of the changes were easy to port - basically copy and paste.The only part I did not know was the changes infinalize
inreference.js
here. As a result, this was a partial success - non-encrypted PDFs look as before (good), you can generate a PDF that requires a password, the password is properly validated... but then the opened PDF is missing content. See this file: recalendar-password.pdf (password:secret
)I've then tried just switching to upstream'sreference.js
, especially seeing your intention of doing that from #2613. See 5d9a8e9. That looks more promising - the decrypted PDF has the text and almost looks perfect... except, for some reason, the font seems to be missing, so it looks off. See this file: recalendar-password2.pdf (password:secret
)And this applies to both encrypted and non-encrypted generated PDFs. So I'm guessing there's some modification/customization, maybe in some other file that I missed that was done in this version of pdfkit that is not compatible with the upstream version of
reference.js
? Unfortunately, I could not find it. I've tried also going back in history ofreference.js
, but unfortunately these changes seems to be from before it was moved to monorepo and I cannot find the previous repository 😞I figured I'd create this PR for you to have a look, maybe something will spark a quick solution or hint from you. If not, I can continue digging 🙇
Everything should be working smoothly now, see #2924 (comment) 🎉
Testing
I'm guessing you have your preferred ways of testing different use cases :) Enabling password protection simply boils down to passing
userPassword
when creating a new instance ofPDFDocument
like so:To be on the safe side, I've also tried enabling all optional permissions, but that did not make a difference:
Additionally, I've ported some unit tests from
pdfkit
, see 798995c