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 43 forks source link

Feature: Encryption is not supported in Buffer Mode yet. #326

Closed EmmanDizon closed 9 months ago

EmmanDizon commented 10 months ago

Is there another way to add password on pdf buffer ? i don't want to create an output file.

console.time();

const htmlPdf = require("pdf-creator-node");
const HummusRecipe = require("muhammara").Recipe;
const AWS = require("aws-sdk");

const s3 = new AWS.S3();

const fs = require("fs");

const data = require("./utils/data");

async function uploadToS3(buffer) {
  const htmlParams = {
    Bucket: "test-test-test-dev",
    Key: `test/test/test-sample.pdf`,
    Body: buffer,
    ServerSideEncryption: "AES256",
  };

  await s3.upload(htmlParams).promise();
}

const htmlTemplate = fs.readFileSync("TDC-template.html", "utf-8");
const options = {
  format: "A3",
  orientation: "portrait",
};

const document = {
  html: htmlTemplate,
  data,
  type: "buffer",
};

htmlPdf.create(document, options).then((buffer) => {
  const recipe = new HummusRecipe(Buffer.from(buffer));
  recipe
    .encrypt({
      userPassword: "123456",
    })
    .endPDF(async (outputBuffer) => {
      await uploadToS3(outputBuffer);
      console.timeEnd();
    });
});
julianhille commented 10 months ago

please add code highlighting and by using three backticks and reformat the code. thank you

julianhille commented 10 months ago

but as far as i understand you might try this:

  const existingPdfBytes = fs.readFileSync(INPUT_FILE_NAME)
  const inputStream = new muhammara.PDFRStreamForBuffer( existingPdfBytes );
  const outputStream = new muhammara.PDFWStreamForBuffer();
  muhammara.recrypt( inputStream, outputStream, options);
EmmanDizon commented 10 months ago

Hi @julianhille , did not work:

console.time();

const htmlPdf = require("pdf-creator-node");
const HummusRecipe = require("muhammara").Recipe;
const muhammara = require("muhammara");
const AWS = require("aws-sdk");

const s3 = new AWS.S3();

const fs = require("fs");

async function uploadToS3(buffer) {
  const htmlParams = {
    Bucket: "test-test-test-dev",
    Key: `test/test/emman-sample.pdf`,
    Body: buffer,
    ServerSideEncryption: "AES256",
  };

  await s3.upload(htmlParams).promise();
}
const data = require("./utils/data");

const htmlTemplate = fs.readFileSync("TDC-template.html", "utf-8");
const options = {
  format: "A3",
  orientation: "portrait",
};

const document = {
  html: htmlTemplate,
  data,
  type: "buffer",
};

const beforeMemoryUsage = process.memoryUsage();
console.log("Memory Usage (Before PDF Generation):", beforeMemoryUsage);

htmlPdf.create(document, options).then(async (output) => {
    const inputStream = new muhammara.PDFRStreamForBuffer(output);
  const outputStream = new muhammara.PDFWStreamForBuffer();
  muhammara.recrypt(inputStream, outputStream, {
    password: "12345",
  });

  await uploadToS3(outputStream);

  const afterMemoryUsage = process.memoryUsage();
  console.log("Memory Usage (After PDF Generation):", afterMemoryUsage);
  console.timeEnd();
});

Please migrate your code to use AWS SDK for JavaScript (v3). For more information, check the migration guide at https://a.co/7PzMCcy (Use node --trace-warnings ... to show where the warning was created) C:\node pdf practice\node_modules\aws-sdk\lib\s3\managed_upload.js:92 self.callback(new Error('Unsupported body payload ' + typeof self.body)); ^

Error: Unsupported body payload object
    at ManagedUpload.self.fillQueue (C:\node pdf practice\node_modules\aws-sdk\lib\s3\managed_upload.js:92:21)
    at ManagedUpload.send (C:\node pdf practice\node_modules\aws-sdk\lib\s3\managed_upload.js:201:33)
    at C:\node pdf practice\node_modules\aws-sdk\lib\util.js:865:26
    at new Promise (<anonymous>)
    at ManagedUpload.promise (C:\node pdf practice\node_modules\aws-sdk\lib\util.js:857:14)
    at uploadToS3 (C:\node pdf practice\last-try.js:20:31)
    at C:\node pdf practice\last-try.js:46:9
EmmanDizon commented 10 months ago

My very first code given above works fine. but it does not have a password since i receive on terminal logs:

Feature: Encryption is not supported in Buffer Mode yet.

Tried migrating to your provided code above, it gives me an error.

recrypt function returns void, that's why i pass the outputStream

julianhille commented 10 months ago

maybe this works for s3 upload:

this needs further elaboration as where res is an object with at least a write method maybe that helps

var pdfWriter = muhammara.createWriter(new muhammara.PDFStreamForResponse(res));
EmmanDizon commented 10 months ago

sorry @julianhille i don't get much.

assuming:

const pdfBuffer = "let say this variable contains PDF buffer";

const inputStream = new muhammara.PDFRStreamForBuffer(pdfBuffer );
const outputStream = new muhammara.PDFWStreamForBuffer();
  muhammara.recrypt(inputStream, outputStream, {
    password: "12345",
  });

  await uploadToS3(muhammara.createWriter(new muhammara.PDFStreamForResponse(outputStream )));

is this what you meant ?

EmmanDizon commented 10 months ago

Hi @julianhille

julianhille commented 10 months ago

will get back to it this evening, but basically the idea was:

const pdfBuffer = "let say this variable contains PDF buffer";

const muhammaraWriteStream = new muhammara.PDFStreamForResponse(outputStream );
  muhammara.recrypt(inputStream, muhammaraWriteStream, {
    password: "12345",
  });

  await uploadToS3(muhammaraWriteStream);

not sure if that works, just typed from memory.

EmmanDizon commented 9 months ago

Hi @julianhille , it works but don't have a password. I open my PDF with expected content but it is not password protected

here is the code:

 const inputStream = new muhammara.PDFRStreamForBuffer(pdfBuffer);
  const outputStream = new muhammara.PDFWStreamForBuffer();
  const muhammaraWriteStream = new muhammara.PDFStreamForResponse(outputStream);
  muhammara.recrypt(inputStream, muhammaraWriteStream, {
    password: "12345",
  });

  await uploadToS3(muhammaraWriteStream);
julianhille commented 9 months ago

Try setting the userPassword

EmmanDizon commented 9 months ago

thanks julian it worked !

julianhille commented 9 months ago

Happy to help. Thanks you for reporting back. You could always buy me a coffee to support the work. 😉

EmmanDizon commented 9 months ago

sure, i'll give some soon just wait :)

EmmanDizon commented 9 months ago

Last question @julianhille , is this code could potentialy caused memory leak or something like abundant increase in memory size ?

const inputStream = new muhammara.PDFRStreamForBuffer(pdfBuffer);
 const outputStream = new muhammara.PDFWStreamForBuffer();
 const muhammaraWriteStream = new muhammara.PDFStreamForResponse(outputStream);
 muhammara.recrypt(inputStream, muhammaraWriteStream, {
   userPassword: "12345",
 });
julianhille commented 9 months ago

I'm not aware of any memory leak here. If you await all and close every thing up and wait for the next gc it should be the same (or close to) memory usage as before these calls.