Skip to content
Snippets Groups Projects
pdfParser.ts 9.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • Zdravko Iliev's avatar
    Zdravko Iliev committed
    // import { PDFName, PDFPage, PDFString, PDFDocument, PDFImage } from "pdf-lib";
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    import { nopodofo as npdf, NPDFImageFormat } from "nopodofo";
    
    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
    import { verifyPDF } from "./lib";
    import { formatPdfTime } from "./lib/timeUtils";
    
    import { AppError, GeneralError } from "./lib/errors";
    
    import { isPDF } from "./lib/generalUtils";
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    import {
      getSignatureField,
      pdf,
      sign,
      TimestampAndEnableLTV,
      write,
    } from "./utils";
    import axios from "axios";
    import {
      createWriterToModify,
      PDFPageModifier,
      PDFRStreamForBuffer,
      PDFWStreamForBuffer,
    } from "hummus";
    import Stream from "pdf-lib/cjs/core/streams/Stream";
    import {
      asPDFName,
      degrees,
      drawImage,
      drawRectangle,
      drawText,
      PDFContentStream,
      PDFDocument,
      PDFName,
      PDFOperator,
      PDFOperatorNames,
      PDFPage,
      PDFString,
      popGraphicsState,
      pushGraphicsState,
      rgb,
      rotateDegrees,
      translate,
    } from "pdf-lib";
    const { Readable } = require("stream");
    const streams = require("memory-streams");
    import signer from "node-signpdf";
    import fs from "fs";
    import { PDFNet } from "@pdftron/pdfnet-node";
    // const { PDFNet } = require("@pdftron/pdfnet-node");
    
    
    type SealCoords = {
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
      [key: string]: { x: string; y: string };
    
    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> => {
    
        if (!(this.document instanceof Buffer)) {
          throw new AppError("Document is not Buffer");
        }
    
    
        if (!isPDF(this.document)) {
          throw new AppError("Only pdf file type is supported");
        }
    
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        try {
          const signaturesMeta = await verifyPDF(this.document);
    
          const pdfMeta = await PdfData.extract(this.document, config);
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
          const result = {
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
            pages: pdfMeta.pages,
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
            title: pdfMeta.info.Title || "Unknown",
            author: pdfMeta.info.Author || "Unknown",
            creation_date: formatPdfTime(pdfMeta.info.CreationDate),
            mod_date: formatPdfTime(pdfMeta.info.ModDate),
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
          };
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    
    
          if (signaturesMeta) {
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
            result["signatures"] = signaturesMeta.signatures;
    
            result["expired"] = signaturesMeta.expired;
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
          }
    
          return result;
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        } catch (error) {
    
          throw new GeneralError(error);
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        }
      };
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
      insertQrCode = async (
        imgBytes: ArrayBuffer,
    
        url: string,
    
        coords: SealCoords,
    
        scaleFactor: number
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
      ): Promise<ArrayBuffer> => {
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // tron pdf library start
        // PDFNet.initialize(licenseKey);
        await PDFNet.initialize(
          "demo:1652778685773:7b893c000300000000b9c455b21b7b47780dc82f9ef63ddc54ce5c282b"
        );
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        const input_path = `${__dirname}`;
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // try {
        //   const doc = await PDFNet.PDFDoc.createFromBuffer(this.document);
        //   doc.initSecurityHandler();
        //   const approval_signature_field = await doc.createDigitalSignatureField(
        //     "PDFTronApprovalSig"
        //   );
        //   const widgetAnnotApproval =
        //     await PDFNet.SignatureWidget.createWithDigitalSignatureField(
        //       doc,
        //       new PDFNet.Rect(300, 287, 376, 306),
        //       approval_signature_field
        //     );
        //   const page1 = await doc.getPage(1);
        //   await page1.annotPushBack(widgetAnnotApproval);
        //   await doc.save(
        //     output_path + "abc.pdf",
        //     PDFNet.SDFDoc.SaveOptions.e_remove_unused
        //   );
        // } catch (err) {
        //   console.log(err);
        // }
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        const buf = await TimestampAndEnableLTV(
          this.document,
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
          `${__dirname}/GlobalSignRootForTST.cer`,
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
          imgBytes
        );
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        return buf;
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // try {
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        //   if (
        //     !(await TimestampAndEnableLTV(
        //       this.document,
        //       input_path + "GlobalSignRootForTST.cer",
        //       input_path + "qrcode.png",
        //       output_path + "abc_LTV.pdf"
        //     ))
        //   ) {
        //     console.log("fail");
        //   }
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // } catch (error) {
        //   console.log(error);
        // }
    
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // tron pdf library end
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // lib-pdf signature start
        // const pdfDoc = await PDFDocument.load(this.document);
        // const pdfLibSigImg = await pdfDoc.embedPng(imgBytes);
        // const pdfLibSigImgName = "PDF_LIB_SIG_IMG";
        // const form = pdfDoc.getForm();
        // const sig = form.getSignature("Signature1");
        // sig.acroField.getWidgets().forEach((widget) => {
        //   const { context } = widget.dict;
        //   const { width, height } = widget.getRectangle();
        //   const appearance = [
        //     ...drawRectangle({
        //       x: 100,
        //       y: 0,
        //       width,
        //       height,
        //       borderWidth: 1,
        //       color: rgb(1, 0, 0),
        //       borderColor: rgb(1, 0.5, 0.75),
        //       rotate: degrees(0),
        //       xSkew: degrees(0),
        //       ySkew: degrees(0),
        //     }),
        //     ...drawImage(pdfLibSigImgName, {
        //       x: 100,
        //       y: 5,
        //       width: width - 10,
        //       height: height - 10,
        //       rotate: degrees(0),
        //       xSkew: degrees(0),
        //       ySkew: degrees(0),
        //     }),
        //   ];
        //   const stream = context.formXObject(appearance, {
        //     Resources: { XObject: { [pdfLibSigImgName]: pdfLibSigImg.ref } },
        //     BBox: context.obj([0, 0, width, height]),
        //     Matrix: context.obj([1, 0, 0, 1, 0, 0]),
        //   });
        //   const streamRef = context.register(stream);
        //   widget.setNormalAppearance(streamRef);
        // });
        // const pdfBytes = await pdfDoc.save();
        // const signatureAppearanceStreamRef = this.imageAppearanceStream();
        // pdfDoc.context.obj({
        //   Type: "Annot",
        //   Subtype: "Widget",
        //   FT: "Sig",
        //   Rect: [image.width, image.height, 0, 0],
        //   V: signatureDictRef,
        //   T: PDFString.of("Signature1"),
        //   F: 4,
        //   P: pages[pages.length - 1].ref, //lastPage
        //   AP: pdfDoc.context.obj({ N: signatureAppearanceStreamRef }),
        // });
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // for (let index = 0; index < pages.length; index++) {
        //   const page = pages[index];
        //   const x =
        //     typeof coords[index + 1] !== "undefined"
        //       ? parseFloat(coords[index + 1].x)
        //       : null;
        //   const y =
        //     typeof coords[index + 1] !== "undefined"
        //       ? parseFloat(coords[index + 1].y)
        //       : null;
        //   if (x && y) {
        //     page.drawImage(img, {
        //       x,
        //       y,
        //       width: scaled.width,
        //       height: scaled.height,
        //     });
        //     const link = this.createPageLinkAnnotation(page, url, {
        //       imgXPos: x,
        //       imgYPos: y,
        //       imgWidth: scaled.width,
        //       imagHeight: scaled.height,
        //     });
        //     page.node.set(PDFName.of("Annots"), pdfDoc.context.obj([link]));
        //   }
        // }
        // const pdfBytes = await pdfDoc.save();
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        //lib-pdf end
        //HUMMUS lib start
        // const result = new PDFWStreamForBuffer();
        // const pdfWriter = createWriterToModify(
        //   new PDFRStreamForBuffer(Buffer.from(this.document)),
        //   result
        // );
        // const imageOptions = {
        //   transformation: [0.5, 0, 0, 0.5, 0, 0],
        //   index: 1000,
        // };
        // const pageModifier = new PDFPageModifier(pdfWriter, 0);
        // pageModifier
        //   .startContext()
        //   .getContext()
        //   .drawImage(0, 100, __dirname + "/qrcode.png", imageOptions);
        // pageModifier.endContext().writePage();
        // pdfWriter.end();
        //HUMMUS lib end
        //qrcode as a signature nopodofo pdf lib start
        // const pdfDoc = await pdf(this.document);
        // const field = getSignatureField(pdfDoc);
        // const signer = new npdf.Signer(pdfDoc);
        // signer.signatureField = field;
        // const result = await sign(signer);
        //qrcode as a signature nopodofo pdf lib end
        // return result;
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // return pdfBytes;
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
        // return result;
    
        //node signer
    
        //node signer
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
      };
    
    
      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
    
      // imageAppearanceStream(image, rotation, width, height) {
      //   const dict = image.doc.context.obj({
      //     Type: "XObject",
      //     Subtype: "Form",
      //     FormType: 1,
      //     BBox: [0, 0, width, height],
      //     Resources: { XObject: { Image: image.ref } },
      //   });
      //   const operators = [
      //     rotateDegrees(rotation),
      //     translate(0, rotation % 90 === 0 ? -width : 0),
      //     ...drawImage("Image", {
      //       x: 0,
      //       y: width, //y = 0 is width for me
      //       width: width,
      //       height: height,
      //       rotate: degrees(0),
      //       xSkew: degrees(0),
      //       ySkew: degrees(0),
      //     }),
      //   ];
      //   const stream = PDFContentStream.of(dict, operators, false);
      //   return image.doc.context.register(stream);
      // }
    
    Zdravko Iliev's avatar
    Zdravko Iliev committed
    }
    
    export default PDFparser;