Open Sparticuz opened 2 years ago
is this resolve ? i want also an input buffer. @Sparticuz
what i want is, i will generate an HTML template to PDF using pdf-creator-node, then thaat result buffer i will transfer to node-qpdf2 library to set a password. is that possible ?
This is what I use in my app, outside of this package. I will probably add it next time I allocate some time to this package.
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import type { Readable } from "node:stream";
/** Writes a Readable to a File in tmpdir() */
export const writeTemporaryFile = async (file: Readable): Promise<string> => {
const filePath = join(tmpdir(), `${randomUUID().replaceAll("-", "")}.pdf`);
await writeFile(filePath, file);
return filePath;
};
So I'll take my buffer or stream or whatever, and put it in this function which outputs a file path that I can use in node-qpdf2
.
is the tmpdir automatically deletes after execution ? @Sparticuz
aint working for me. this is my code:
generatePDF.js: ` console.time(); const fs = require("fs"); const pdf = require("pdf-creator-node"); const data = require("./utils/data"); const { secure } = require("./pdf");
const generatePdf = async () => {
// Read HTML Template
const html = fs.readFileSync("./template.html", "utf8");
const options = {
format: "A3",
orientation: "portrait",
};
const document = {
html: html,
data,
type: "buffer",
};
const pdfBuffer = await pdf.create(document, options);
await secure(pdfBuffer);
console.timeEnd();
}; generatePdf();`
secure.js: ` const { S3 } = require("aws-sdk"); const fs = require("fs"); const { writeTemporaryFile } = require("./temp"); const s3 = new S3();
const secure = async (file) => {
try {
const { encrypt } = await import("node-qpdf2");
const pdf = {
input: await writeTemporaryFile(file),
password: "1234emman",
};
const encryptedPdf = await encrypt(pdf);
const htmlParams = {
Bucket: "certificate",
Key: `documents/emman/test.pdf`,
Body: encryptedPdf,
ServerSideEncryption: "AES256",
ContentDisposition: "inline",
ContentType: "application/pdf",
};
await s3.upload(htmlParams).promise();
} catch (error) {
console.error(error);
}
};
module.exports = { secure };
`
temp.js:
` const { randomUUID } = require("crypto"); const { writeFile } = require("fs/promises"); const { tmpdir } = require("os"); const { join } = require("path");
/** Writes a Readable to a File in tmpdir() */
const writeTemporaryFile = async (file) => {
const filePath = join(tmpdir(), `${randomUUID().replaceAll("-", "")}.pdf`);
await writeFile(filePath, file);
return filePath;
};
module.exports = { writeTemporaryFile };
`
When i open the file on s3 bucket, it contains nothing
here is the screenshot:
I've never used pdf-creator-node before. Does the file display properly before attempting to encrypt it?
@Sparticuz yes it works when creating an output like this:
const pdf = { input: await writeTemporaryFile(file), password: "1234emman", output: "./tmp/secure.pdf", };
await encrypt(pdf);
when i open the pdf on tmp/secure.pdf, inputs a password then open the pdf then boom, i see my html template,
that "file" parameter on const secure = async (file) => {
is a buffer from pdf-creator-node.
it works fine when passing like code above. but what if i dont want to create "./tmp/secure.pdf", pass the pdfbuffer to s3 bucket, it aint working like the previous code above our conversations i mentioned:
` const encryptedPdf = await encrypt(pdf);
const htmlParams = {
Bucket: "certificate",
Key: `documents/emman/test.pdf`,
Body: encryptedPdf,
ServerSideEncryption: "AES256",
ContentDisposition: "inline",
ContentType: "application/pdf",
};
await s3.upload(htmlParams).promise();`
I don't think qpdf supports that. I guess you could then read the file into a buffer then pass it to s3, but that seems redundant. Again, this Feature Request will probably just 'fake it' by just taking the buffer and throwing it into a file, then taking the file and throwing it in a buffer.
EDIT:
Actually, This is in my tests, it should work:
test.serial("Should encrypt File -> Buffer", async (t) => {
const BufferFromFile = await encrypt({
input,
password: "1234",
});
t.true(Buffer.isBuffer(BufferFromFile));
});
Not work for me when i open the PDF file the content is missing.
Hi! Thanks for your work! I also faced with issue that after encryption my PDF was blank. I save the document locally not in any clouds. In the result document, I have the same number of pages, but they are white. During testing before the encryption, the pdf has content.
Found one interesting thing, if I save data to a file and then read it all works fine. But if I operate with the buffer that returns from encrypt
method - the document is white.
@EmmanDizon maybe my case will help you.
According to https://github.com/qpdf/qpdf/issues/54, we can't use stdin as input. Build a helper function that will take in a buffer as input and output it to /tmp before passing it to
qpdf