julianhille / MuhammaraJS

Muhammara a node module with c/cpp bindings to modify PDF with js for node or electron (based/replacement on/of galkhana/hummusjs)
Other
205 stars 41 forks source link

Encrypt is not working and recrypt cleans pdf metadata #350

Open luicfrr opened 8 months ago

luicfrr commented 8 months ago

I'm trying to encrypt a pdf file but the following code is not working:

const pdfBuffer = Buffer.from( 'base64string', 'base64')
const encryptedBuffer = await new Promise<Buffer>(( res ) => {
    const recipe = new Recipe( pdfBuffer, undefined, {
        title: 'test title',
        author: 'test author',
        subject: 'test subject'
    } )
    recipe.encrypt( {
        userPassword: '123abc',
        ownerPassword: 'abc123',
        userProtectionFlag: 4
    } ).endPDF( buffer => res(buffer) )
} )
return res.send( encryptedBuffer )

If I save/open returned pdf on Adobe reader I can see all metada (title, author, subject, etc...) but no password is required to open the pdf and on file properties Adobe says the pdf is not password protected.

Then I tryed to move to recrypt, this is working and my pdf is now password protected but the problem is all metadata are cleared. All fields (title, subject, author, etc..) are empty. I've tryed recrypt using encryptedBuffer, also tryed adding metadata with other library and every metadata is present if I don't recrypt the pdf.

Here's my recrypt code:

const pdfBuffer = Buffer.from( 'base64string', 'base64')
const encryptedBuffer = await new Promise<Buffer>(( res ) => {
    const recipe = new Recipe( pdfBuffer, undefined, {
        title: 'test title',
        author: 'test author',
        subject: 'test subject'
    } )
    recipe.endPDF( buffer => {
          const readed = new PDFRStreamForBuffer( buffer )
          const encrypted = new PDFWStreamForBuffer()
          recrypt( readed, encrypted, {
              userPassword: '123abc',
              ownerPassword: 'abc123',
              userProtectionFlag: 4
          } )
          res( encrypted.buffer )
    } )
} )
return res.send( encryptedBuffer )

How can I have both

julianhille commented 7 months ago

That should not happen, encrypting should not remove metadata.

Have you tried in the first code to remove the protectionFlag and see what happens on default? 4 means allow printing if i remember right?

luicfrr commented 7 months ago

Yes, I've tryed removing protectionFlag but doesn't work.

I've created this codesanbox returning pdf's metadata logs. I'm using pdf-lib to add and read metadata from pdfs and as you can see on console logs, all metadata are cleared after encryption.

I also noticed that endPDF callback event is returning undefined(you'll see that encryptedBuffer variable is undefined and it's section is not even called) after encrypting pdf. Maybe this is another issue too.

EDIT: Another test I've made is removing everything from recrypt with only read/write streams and, like before, all metadata are cleared:

// tryed running this code
recrypt( pdfRStream, pdfWStream )
julianhille commented 7 months ago

Currently my laptop is broken and so I'm unable tohelp or investigate.

negaxsender commented 7 months ago

when will it be fixed sir?

luicfrr commented 7 months ago

@negaxsender I'm now using this package instead.

In my case I needed to use a custom qpdf binary so I opened this pull request.

Hope this helps you.

polesapart commented 7 months ago

I can confirm it strips the original metadata.

xuakson commented 7 months ago

i use PyPDF2 library python for the backend to create the rest api gateway then use it in my node js application, everything is fine and working perfectly, using only buffer so nothing saves on the disk. Only issue is that i get errors or fails when the request is too high

julianhille commented 6 months ago

Added a test receipt really throws stuff away. Will get to it.