Skip to content
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

placeholder-pdfkit stops the pdf stream emitting the "end" event #240

Open
Dmitrijs-Sakovics opened this issue Mar 21, 2024 · 5 comments
Open

Comments

@Dmitrijs-Sakovics
Copy link

Dmitrijs-Sakovics commented Mar 21, 2024

Describe the bug and the expected behaviour
Using a very slightly modified example based on packages\examples\src\pdfkit010.js to create a signed pdf (code below, calling the function from an external file)

The program is not throwing any errors, but gets stuck waiting for the pdfReady promise to resolve. the pdf stream emits the "data" event 59 times, but does not emit the "end" event (hence the promise not resolving). The "error" event does not get emitted either.

Commenting out the call to pdfkitAddPlaceholder (and the .end()-ing of the new refs) resolves the problem (but the signing process fails because the placeholder is missing)

Tried with pdfkit 0.11.0 and 0.14.0; under nodeJS 18.17.0 and 20.11.1

Is it a bug in signing or in the helpers?
Helper: placeholder-pdfkit

To Reproduce

var fs = require("fs");
const PDFDocument = require("pdfkit").default;
var signpdf = require("@signpdf/signpdf").default;
var P12Signer = require("@signpdf/signer-p12").P12Signer;
var pdfkitAddPlaceholder = require("@signpdf/placeholder-pdfkit").pdfkitAddPlaceholder;

export const work = () => {
    console.log("generating example pdf");

    let pdf = new PDFDocument({
        autoFirstPage: false,
        size: "A4",
        layout: "portrait",
        bufferPages: true,
    });
    pdf.info.CreationDate = "";

    var pdfReady = new Promise(function (resolve) {
        var pdfChunks = [];
        pdf.on("data", function (data) {
            // ---------------------------------------------------gets triggered 59 times
            console.log("---data chunk #" + pdfChunks.length);
            pdfChunks.push(data);
        });
        pdf.on("error", () => {
            console.log("error emitted");
        });
        pdf.on("end", function () {
            // ----------------------------------------------------Never gets triggered
            console.log("data end");
            resolve(Buffer.concat(pdfChunks));
        });
    });

    pdf.addPage().fillColor("#333").fontSize(25).moveDown().text("@signpdf").save();

    var refs = pdfkitAddPlaceholder({
        pdf: pdf,
        pdfBuffer: Buffer.from([pdf]), // FIXME: This shouldn't be needed.
        reason: "Showing off.",
        contactInfo: "[email protected]",
        name: "Sign PDF",
        location: "The digital world.",
    });
    Object.keys(refs).forEach(function (key) {
        console.log(`---ending ${key}`);
        refs[key].end();
    });

    var certificatePath = "./certificates/client-identity.p12";
    var certificateBuffer = fs.readFileSync(certificatePath);
    var signer = new P12Signer(certificateBuffer);

    console.log("setting up promise");
    pdfReady
        .then(function (pdfWithPlaceholder) {
            console.log("signing");
            return signpdf.sign(pdfWithPlaceholder, signer);
        })
        .then(function (signedPdf) {
            console.log("saving");
            var targetPath = "./pdfkit010.pdf";
            console.log("writing file");
            fs.writeFileSync(targetPath, signedPdf);
        });

    console.log("---ending pdfDocument stream");
    pdf.end();
};
@vbuch
Copy link
Owner

vbuch commented Mar 27, 2024

Hi,
I haven't really used placeholder-pdfkit. @dhensby would be best to reply here. But from what I see in the source signature and widget are already ended. Try to work around that maybe and only end the form. Ideally, once you have it working, share your code and even better prepare a PR to introduce a placeholder-pdfkit example.

@Dmitrijs-Sakovics
Copy link
Author

@vbuch @dhensby
Hi,

I managed to get this working with pdfkit 0.14.0 by removing the form.end() statement (removing the whole foreach clause that .end()s all the refs after the pdfkitAddPlaceholder call)

While I am getting signed pdf-s out of it, I don't currently understand what's happening well enough to recommend this solution to others (hence no PR). It would be good if someone who knows the system could have a looks to see why this worked

@dhensby
Copy link
Collaborator

dhensby commented Apr 1, 2024

I'm actually using pdfmake and that uses @foliojs-fork/pdfkit instead of the actual pdfkit lib (probably because of all the problems that we've had previously with pdfkit. Their implementation of AcroForms really messed up integration and I don't recall if we ever got round to fixing it or not.

I guess that pdfkit no longer needs the .end() to be called and (if that's been taken from our examples) our examples may need updating!

@vbuch
Copy link
Owner

vbuch commented Apr 1, 2024

We just don't have a pdfkit example. We have the pdfkit010 ones and I'm guessing that's what @Dmitrijs-Sakovics here based his example on. The pdfkit010 is obviously a legacy one so... yes, an example using pdfkit > 10 is needed.

@Dmitrijs-Sakovics
Copy link
Author

Yes, my attempts were based on the pdfkit010 example since the pdfkit >0.10 helper readme states "This works in an identical way to the pdfkit010 package and the pdfkit010.js example is still relevant."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants