Skip to content
Snippets Groups Projects
pdfParser.ts 2.7 KiB
Newer Older
Zdravko Iliev's avatar
Zdravko Iliev committed
import verifyPDF from "@ninja-labs/verify-pdf";
import { PDFName, PDFPage, PDFString } from "pdf-lib";
Zdravko Iliev's avatar
Zdravko Iliev committed
import { PdfData } from "pdfdataextract";
import { config } from "./config";
import { IgetMetaResponse } from "./types";
Zdravko Iliev's avatar
Zdravko Iliev committed
const { PDFDocument } = require("pdf-lib");
Zdravko Iliev's avatar
Zdravko Iliev committed
class PDFparser {
  readonly document;
  readonly config;

  constructor(document: Buffer) {
    this.document = document;
    this.config = config;
  }

  getPDFMeta = async (): Promise<IgetMetaResponse> => {
    try {
      const pdfMeta = await PdfData.extract(this.document, config);
      const signaturesMeta = await verifyPDF(this.document);

      return {
        verified: signaturesMeta.verified,
        authenticity: signaturesMeta.authenticity,
        integrity: signaturesMeta.integrity,
        expired: signaturesMeta.expired,
        meta: {
          certs: signaturesMeta.certs,
        },
        pages: pdfMeta.pages,
        fingerpring: pdfMeta.fingerprint,
        creation_data: pdfMeta.info.CreationDate,
        creator: pdfMeta.info.Creator,
        author: pdfMeta.info.Author,
        title: pdfMeta.info.Title,
        description: pdfMeta.info.Keywords,
        mod_date: pdfMeta.info.ModDate,
      };
    } catch (error) {
      console.error(error);
      throw new Error("Could not get pdf metadata");
    }
  };
Zdravko Iliev's avatar
Zdravko Iliev committed

Zdravko Iliev's avatar
Zdravko Iliev committed
  insertQrCode = async (
    imgBytes: ArrayBuffer,
    url: string
  ): Promise<ArrayBuffer> => {
Zdravko Iliev's avatar
Zdravko Iliev committed
    const pdfDoc = await PDFDocument.load(this.document);
    const img = await pdfDoc.embedPng(imgBytes);
Zdravko Iliev's avatar
Zdravko Iliev committed
    const scaled = img.scale(0.2);
Zdravko Iliev's avatar
Zdravko Iliev committed

Zdravko Iliev's avatar
Zdravko Iliev committed
    const pages = pdfDoc.getPages();

Zdravko Iliev's avatar
Zdravko Iliev committed
    for (let index = 0; index < pages.length; index++) {
      const page = pages[index];
Zdravko Iliev's avatar
Zdravko Iliev committed

Zdravko Iliev's avatar
Zdravko Iliev committed
      page.drawImage(img, {
        x: page.getWidth() / 2 - scaled.width / 2,
        y: page.getHeight() / 2 - scaled.height / 2,
        width: scaled.width,
        height: scaled.height,
      });
Zdravko Iliev's avatar
Zdravko Iliev committed

Zdravko Iliev's avatar
Zdravko Iliev committed
      const link = this.createPageLinkAnnotation(page, url, {
        imgXPos: page.getWidth() / 2 - scaled.width / 2,
        imgYPos: page.getHeight() / 2 - scaled.height / 2,
        imgWidth: scaled.width,
        imagHeight: scaled.height,
      });
Zdravko Iliev's avatar
Zdravko Iliev committed
      page.node.set(PDFName.of("Annots"), pdfDoc.context.obj([link]));
    }
Zdravko Iliev's avatar
Zdravko Iliev committed

Zdravko Iliev's avatar
Zdravko Iliev committed
    const pdfBytes = await pdfDoc.save();

    return pdfBytes;
  };

  private createPageLinkAnnotation = (
    page: PDFPage,
    uri: string,
    { imgXPos, imgYPos, imgWidth, imagHeight }
  ) =>
    page.doc.context.register(
      page.doc.context.obj({
        Type: "Annot",
        Subtype: "Link",
        Rect: [imgXPos, imgYPos, imgXPos + imgWidth, imgYPos + imagHeight],
        A: {
          Type: "Action",
          S: "URI",
          URI: PDFString.of(uri),
        },
      })
    );
Zdravko Iliev's avatar
Zdravko Iliev committed
}

export default PDFparser;