0

Recently a task is given to me for signing a pdf using pfx file using node.js . And I digitally signed the pdf and also the place the placeholder for sign. But visually the sign is not appearing as we see in official document or govt. Docs [like that]. In my pdf when I hover mouse cursor on that placeholder it shows signature validity but visually it is not appearing. This is the problem I am facing LIKE THAT. Here I am getting blank box but when I click on that ,a dialog box is opened it shows signature validity, but here nothing has visually appeared and there is not ✔ tick or cross ✖ or warning sign like I attached image below

I am expecting output like this on my pdf.

here is my code.

const express = require('express');
const { PDFDocument, rgb, StandardFonts, PDFName, PDFNumber } = require('pdf-lib');
const signpdf = require('@signpdf/signpdf').default;
const { P12Signer } = require('@signpdf/signer-p12');
const { pdflibAddPlaceholder } = require('@signpdf/placeholder-pdf-lib');
const pdfjsLib = require('pdfjs-dist/legacy/build/pdf.mjs');

const app = express();
app.use(express.json({ limit: '50mb' }));

async function findMarkerCoords(pdfBuffer, marker) {
  const loadingTask = pdfjsLib.getDocument({ data: new Uint8Array(pdfBuffer) });
  const pdf = await loadingTask.promise;
  const numPages = pdf.numPages;

  for (let pageIndex = 0; pageIndex < numPages; pageIndex++) {
    const page = await pdf.getPage(pageIndex + 1);
    const textContent = await page.getTextContent();

    for (const item of textContent.items) {
      if (item.str && item.str.includes(marker)) {
        return {
          pageIndex,
          x: item.transform[4],
          y: item.transform[5]
        };
      }
    }
  }

  throw new Error(`Marker "${marker}" not found in any page.`);
}

app.post('/sign', async (req, res) => {
  try {
    const { pdf, pfx, password } = req.body;
    if (!pdf || !pfx || !password) {
      return res.status(400).json({ status: 'error', message: 'Missing pdf, pfx, or password.' });
    }

    const pdfBuffer = Buffer.from(pdf, 'base64');
    const pfxBuffer = Buffer.from(pfx, 'base64');
    const marker = 'DigiSign';

    // Get coordinates of the marker text
    const { pageIndex, x, y } = await findMarkerCoords(pdfBuffer, marker);

    // Load PDF with pdf-lib
    const pdfDoc = await PDFDocument.load(pdfBuffer);
    const pdfPage = pdfDoc.getPages()[pageIndex];
    const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
    const fontSize = 10;

    // Draw the signature appearance box
    const sigX = x;
    const sigY = y;
    const sigWidth = 180;
    const sigHeight = 60;

 

      const pages = pdfDoc.getPages();
    for (const page of pages) {
      const annots = page.node.Annots();
      if (annots) {
        const annotsArray = annots.asArray();
        for (const annotRef of annotsArray) {
          const annot = pdfDoc.context.lookup(annotRef);
          annot.set(PDFName.of('F'), PDFNumber.of(4));
          annot.set(PDFName.of('Type'),PDFName.of('Annot'));
          annot.set(PDFName.of('Subtype'),PDFName.of('Widget'));
          annot.set(PDFName.of('FT'),PDFName.of('Sig'));
           const rect = pdfDoc.context.obj([sigX,sigY,sigX + sigWidth , sigY + sigHeight]);
           annot.set(PDFName.of('Rect'),rect);
        }
      }
    }

    // Add visible signature placeholder
     pdflibAddPlaceholder({
        pdfDoc : pdfDoc,
        pdfPage : pdfPage,
        reason: 'Signed for approval',
        contactInfo: '[email protected]',
        name: 'Aditya Garg',
        location: 'India',
        signingTime: new Date(),
        signatureLength: 12000,
        widgetRect: [sigX, sigY, sigX + sigWidth, sigY + sigHeight],
        });

    // Make signature annotation visible
  

    const pdfWithPlaceholder = await pdfDoc.save({ useObjectStreams: false });
   

    const signer = new P12Signer(pfxBuffer, { passphrase: password });
     const signedPdf = await signpdf.sign(Buffer.from(pdfWithPlaceholder), signer);
     

    return res.json({ status: 'success', signedPdf: signedPdf.toString('base64') });
  } catch (err) {
    console.error('Signing failed:', err);
    return res.status(500).json({ status: 'error', message: err.message });
  }
});

app.listen(3000, () => {
  console.log('✅ Digital Signature Server running at http://localhost:3000');
});
4
  • "there is not ✔ tick or cross ✖ or warning sign" - Those in-document validity information have been deprecated many many years ago, see this answer. Commented Jul 26 at 19:55
  • But how to show it visually . Like I attached the image above Commented Jul 28 at 10:11
  • But how to show it visually . Like I attached the image above. I made pfx file using OpenSSL for DEMO Commented Jul 28 at 10:25
  • "But how to show it visually": github.com/vbuch/node-signpdf/issues/… "The library does the crypto part of e-signature. The visuals you need to handle through something else - something lik pdf-lib" Commented Jul 28 at 19:53

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.