Error when trying to sign a pdf document when using @signpdf module
I get the following error when trying to sign a document using @signpdf module. Can anyone please help me regarding this issue?
This is the code I use:
const {onRequest} = require("firebase-functions/v2/https");
const {onObjectFinalized} = require("firebase-functions/v2/storage");
const admin = require('firebase-admin')
const {initializeApp} = require("firebase-admin/app");
const {getStorage} = require("firebase-admin/storage");
const logger = require("firebase-functions/logger");
const path = require('path');
const {setGlobalOptions} = require("firebase-functions/v2");
const getRawBody = require('raw-body')
var pdflibAddPlaceholder = require('@signpdf/placeholder-pdf-lib').pdflibAddPlaceholder;
var signpdf = require('@signpdf/signpdf').default;
var P12Signer = require('@signpdf/signer-p12').P12Signer;
var { SUBFILTER_ETSI_CADES_DETACHED } = require('@signpdf/utils');
var PDFDocument = require('pdf-lib').PDFDocument;
var { StandardFonts } = require('@pdf-lib/standard-fonts');
setGlobalOptions({region: "europe-west1"});
initializeApp();
exports.processPDF = onObjectFinalized({}, async (event) => {
const bucket = admin.storage().bucket()
const fileBucket = event.data.bucket; // Storage bucket containing the file.
const filePath = event.data.name; // File path in the bucket.
const contentType = event.data.contentType; // File content type.
console.log(filePath);
const certificatePath = "/certificate/client-identity.p12";
const file = bucket.file(filePath);
const certificateFile = bucket.file(certificatePath);
const fileDir = path.dirname(filePath);
const fileBasename = path.basename(filePath);
console.log(fileDir);
if (fileDir != 'uploads') { return; } //Only continue if the file is uploaded into uploads folder
getRawBody(file.createReadStream())
.then((pdfBuffer) => {
console.log(pdfBuffer.length + ' bytes submitted');
getRawBody(certificateFile.createReadStream())
.then((certBuff) => {
console.log(certBuff.length + 'bytes cert');
PDFDocument.load(pdfBuffer).then(function (pdfDoc) {
console.log("loading pdf document");
console.log(pdfDoc);
var signer = new P12Signer(certBuff, {passphrase: "123456"}); //This is the password's certificate
pdflibAddPlaceholder({
pdfDoc: pdfDoc,
reason: 'The user is declaring consent through JavaScript.',
contactInfo: '[email protected]',
name: 'John Doe',
location: 'Free Text Str., Free World',
});
pdfDoc.save().then(function (pdfWithPlaceholderBytes) {
// And finally sign the document.
signpdf
.sign(pdfWithPlaceholderBytes, signer)
.then(function (signedPdf) {
console.log('Signed PDF');
})
})
});
})
.catch((err) => {
console.log(err.message);
});
})
.catch((err) => {
console.log(err.message);
});
});
The error is the following:
TypeError: Cannot read properties of undefined (reading 'push')
> at pdflibAddPlaceholder (/Users/Desktop/docSignLocal/node_modules/@signpdf/placeholder-pdf-lib/dist/pdflibAddPlaceholder.js:174:10)
> at /Users/Desktop/docSignLocal/functions/index.js:51:25
> at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
I tried different libraries for signing a pdf file but none work. The error is "Cannot read properties of undefined (reading 'push')" when using @signpdf module. I need the document to be signed using the placeholder and signer. Thanks!
This is hard to troubleshoot without an example PDF file, but one thing to know with pdf-lib is that it has some limitations such as not handling encrypted documents (https://github.com/Hopding/pdf-lib?tab=readme-ov-file#encryption-handling).
Looking at the error message, it seems the placeholder code is having difficulty adding a signature placeholder to a new or existing acroForm at: https://github.com/vbuch/node-signpdf/blob/4a6a2a46a6a786f35d58a3e00c6acd13827445ee/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.js#L174
Unfortunately the pdf-lib dependency hasn't been updated in over 2 years. I've been looking for a solution too, and while this node-signpdf does a nice job of its purpose of showing how to sign a typical PDF, it isn't a production-ready library for a full range of existing PDFs.