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
229 stars 46 forks source link

Allow Anyone to View, Only Those with Owner Password to edit/copy/etc #306

Closed mhmooreht closed 1 year ago

mhmooreht commented 1 year ago

Hello,

I'm trying to encrypt a file so that anyone who receives it can print it without a password, but only those who have the ownerPassword can edit it.

Here's what I've tried:

 await pdfDoc
      .encrypt({
        ownerPassword: password,
        userProtectionFlag: (1 << 3),
      })
      .endPDF();

Here's an example PDF I'm trying to secure:

EPAM_Systems_Audit_Certifications (1).pdf

Expected Outcome: Users should only be able to view content and not edit, copy, delete pages, etc.

Actual Outcome: Any user is able to open the file in an editor and make changes

Let me know if this is possible with this library or if I should be looking for alternatives.

Thank you so much for your work on this library.

julianhille commented 1 year ago

currently working on an ubuntu issue will come back at it

julianhille commented 1 year ago

How do you check afterwards if it editable?

mhmooreht commented 1 year ago

Opening in Adobe online or trying to convert to Word. My team that does this work manually right now uses Adobe Acrobat Pro and uses these settings to produce the desired effect: afc3997c-b09c-4921-a960-344f94d7a346

huvanile commented 1 year ago

hi, any update on this one? This would be very, very help, thanks! I just dropped a tip in the sponsorship jar in GitHub as a thanks for your eyes on this and for the excellent repo.

julianhille commented 1 year ago

Haven't had the time. Probably by tomorrow I'll have a deeper look.

Thanks for the tip

julianhille commented 1 year ago

had a surgery on wednesda, now i feel like i could work a bit on this.

julianhille commented 1 year ago

please try: userPassword: '' as option.

This only works if you do not use recipe but use recrypt. need to find why that is the case.

julianhille commented 1 year ago

yes recipe has a bug it checks for truthines of userPassword and if falsy removes it. This makes it impossible to set the userPassword to an empty string. Which seems to be needed for your case.

You could try that locally by editing node_modules/muhammara/lib/recipe/encryption.js round about line 57

and replace if (options.userPassword) ... with if (options.userPassword !== undefined) {

please let me know if that helps.

mhmooreht commented 1 year ago

@julianhille Thanks for the guidance here. Changing lines 52-62 in encrypt.cs worked for my use case:

  if (password) {
    encryptOptions.userPassword = "";
    encryptOptions.password = password;
    encryptOptions.ownerPassword = password;
  }

  if (options.userPassword !== undefined) {  
    encryptOptions.userPassword = options.userPassword;
    if (!encryptOptions.password) {
      encryptOptions.password = options.userPassword;
    }
  }

I'm setting the password to an empty string first. Then, setting it is handled in the the case it is not undefined which produces the desired behavior.

julianhille commented 1 year ago

i think the whole logic is a bit off.

If i set a password AND an ownerPassword which differ, the password is ignored and ownerPassword is used everywhere even though they seem to be used for different things.

If i set a password and an leave ownerPassword out, the same applies but the other way around.

Why having two different member/keys/properties of that options object which lead essentially to the same.

  if (password) {
    encryptOptions.userPassword = "";
    encryptOptions.password = password;
    encryptOptions.ownerPassword = password;
  }

  if (options.userPassword !== undefined) {  
    encryptOptions.userPassword = options.userPassword;
    if (!encryptOptions.password) {
      encryptOptions.password = options.userPassword;
    }
  }

Recrypt function states:

julianhille commented 1 year ago

Could you solve it?

julianhille commented 1 year ago

I guess it is solved