Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • code/js-toolbox/lib-pdf
1 result
Select Git revision
Show changes
Commits on Source (2)
......@@ -2,3 +2,4 @@ node_modules
.idea
yarn-error.log
__tests__/outputs/**
.DS_Store
......@@ -2,6 +2,8 @@
Vereign pdf prarser
Parses PDF's to extract information about pages, signatures and meta
Under the hood:
- Typescript
- Babel
......@@ -9,4 +11,3 @@ Under the hood:
- ESlint
- Prettier
Project building itself on installation using the `prepare` npm lifecycle script.
import fs from "fs";
import path from "path";
import * as fs from "fs";
import * as path from "path";
import { describe, it, expect } from "@jest/globals";
import PDFparser from "../src/pdfParser";
import { AppError } from "../src/lib/errors";
import { AppError, GeneralError } from "../src/lib/errors";
describe("PDF parser", () => {
it("should return pdf document metadata including signatures", async () => {
......@@ -22,8 +22,8 @@ describe("PDF parser", () => {
);
const parser = new PDFparser(file);
const actual = await parser.getPDFMeta();
expect(actual.pages).toEqual(1);
expect(actual.title).toEqual("PDF Digital Signatures");
expect(actual.author).toEqual("Tecxoft");
......@@ -32,7 +32,7 @@ describe("PDF parser", () => {
it("should throw error without file", async () => {
try {
const parser = new PDFparser(undefined);
const actual = await parser.getPDFMeta();
await parser.getPDFMeta();
} catch (error) {
expect(error).toBeInstanceOf(AppError);
}
......@@ -43,57 +43,23 @@ describe("PDF parser", () => {
try {
const parser = new PDFparser(file);
const actual = await parser.getPDFMeta();
await parser.getPDFMeta();
} catch (error) {
expect(error).toBeInstanceOf(AppError);
expect(error.message).toEqual("Only pdf file type is supported");
}
});
});
type SealCoords = {
[key: string]: { x: string; y: string };
};
describe("PDF insert", () => {
it("should insert qrcode into the pdf without breaking the signature", async () => {
// Signed-linux-libreOfficeWriterTest-v1.6-signed-pades-baseline-b
// Signed-linux-OpenOfficeWriter-v1.4-signed-pades-baseline-b
// Signed-mac-Adobe-1.3-signed-pades-baseline-b
// Signed-XXX-nopodofo-test-v.1.7-signed-pades-baseline-b
const filename = "abacus-two-signatures";
it("should throw error when parsing file with unsupported subfilter type", async () => {
const file = fs.readFileSync(
path.resolve(__dirname, `./source/${filename}.pdf`)
);
const qrcode = fs.readFileSync(path.resolve(__dirname, "./qrcode.png"));
const parser = new PDFparser(file);
await parser.initialize(
"demo:1652778685773:7b893c000300000000b9c455b21b7b47780dc82f9ef63ddc54ce5c282b"
path.resolve(__dirname, "./source/sample07.pdf")
);
const sealCoords: SealCoords = {
"1": { x: "261.6", y: "384.84" },
"2": { x: "261.6", y: "384.84" },
};
const resultPDF = await parser.insertQrCode(
qrcode.buffer,
"vereign.com",
sealCoords,
0.25,
"demo:1652778685773:7b893c000300000000b9c455b21b7b47780dc82f9ef63ddc54ce5c282b",
path.resolve(__dirname, "./cert.cer"),
"http://rfc3161timestamp.globalsign.com/advanced"
);
fs.writeFileSync(
`${__dirname}/outputs/tron/${filename}-im11age.pdf`,
Buffer.from(resultPDF)
);
expect(true).toBeTruthy();
}, 30000);
try {
const parser = new PDFparser(file);
await parser.getPDFMeta();
} catch (error) {
expect(error).toBeInstanceOf(GeneralError);
}
});
});
File added
/// <reference types="node" />
import { IGetMetaResponse } from "./types";
declare global {
interface Window {
PDFNet: any;
CoreControls: any;
}
}
declare class PDFparser {
readonly document: any;
constructor(document?: Buffer);
initialize: (licenseKey: string) => Promise<void>;
getPDFMeta: () => Promise<IGetMetaResponse>;
}
export default PDFparser;
......@@ -17,9 +17,6 @@ const errors_1 = require("./lib/errors");
const generalUtils_1 = require("./lib/generalUtils");
class PDFparser {
constructor(document) {
this.initialize = (licenseKey) => __awaiter(this, void 0, void 0, function* () {
// await PDFNet.initialize(licenseKey);
});
this.getPDFMeta = () => __awaiter(this, void 0, void 0, function* () {
if (!(this.document instanceof Buffer)) {
throw new errors_1.AppError("Document is not Buffer");
......
......@@ -5,6 +5,7 @@ const DEFAULT_BYTE_RANGE_PLACEHOLDER = "**********";
export const checkForSubFilter = (pdfBuffer: Buffer) => {
const matches = pdfBuffer.toString().match(/\/SubFilter\s*\/([\w.]*)/);
const subFilter = Array.isArray(matches) && matches[1];
if (!subFilter) {
throw new AppError("Can not find subfilter");
}
......@@ -16,7 +17,9 @@ export const checkForSubFilter = (pdfBuffer: Buffer) => {
];
if (!supportedTypes.includes(subFilter.trim().toLowerCase())) {
throw new AppError("Subfilter not supported");
throw new AppError(
`Subfilter not supported - ${subFilter.trim().toLowerCase()}`
);
}
};
......
......@@ -7,8 +7,7 @@ export const verifyPDF = (pdf: Buffer) => {
try {
checkForSubFilter(pdfBuffer);
} catch (error) {
console.log("no supported signatures found");
return null;
throw new Error(error.message);
}
try {
......
......@@ -5,20 +5,11 @@ import { verifyPDF } from "./lib";
import { formatPdfTime } from "./lib/timeUtils";
import { AppError, GeneralError } from "./lib/errors";
import { isPDF } from "./lib/generalUtils";
// import { TimestampAndEnableLTV } from "./utils";
// import { PDFNet } from "@pdftron/pdfnet-node";
type SealCoords = {
[key: string]: { x: string; y: string };
};
declare global {
interface Window {
PDFNet: any;
CoreControls: any;
}
}
class PDFparser {
readonly document;
......@@ -26,10 +17,6 @@ class PDFparser {
this.document = document;
}
initialize = async (licenseKey: string): Promise<void> => {
// await PDFNet.initialize(licenseKey);
};
getPDFMeta = async (): Promise<IGetMetaResponse> => {
if (!(this.document instanceof Buffer)) {
throw new AppError("Document is not Buffer");
......@@ -61,32 +48,6 @@ class PDFparser {
throw new GeneralError(error);
}
};
// insertQrCode = async (
// imgBytes: ArrayBuffer,
// url: string,
// coords: SealCoords,
// scaleFactor: number,
// licenseKey: string,
// certPath: string,
// certTSAUrl: string
// ): Promise<ArrayBuffer> => {
// let buf;
// try {
// buf = await TimestampAndEnableLTV(
// this.document,
// certPath,
// certTSAUrl,
// imgBytes,
// coords
// );
// } catch (error) {
// console.log(error);
// throw new GeneralError("Could Not sign pdf");
// }
// return buf;
// };
}
export default PDFparser;
// import { PDFNet } from "@pdftron/pdfnet-node";
// export const TimestampAndEnableLTV = async (
// docBuffer: ArrayBuffer,
// certPath: string,
// certTSAUrl: string,
// imgBytes: ArrayBuffer,
// coords: any
// ): Promise<ArrayBuffer> => {
// const doc = await PDFNet.PDFDoc.createFromBuffer(docBuffer);
// doc.initSecurityHandler();
// const tst_config = await PDFNet.TimestampingConfiguration.createFromURL(
// certTSAUrl
// );
// const opts = await PDFNet.VerificationOptions.create(
// PDFNet.VerificationOptions.SecurityLevel.e_compatibility_and_archiving
// );
// await opts.addTrustedCertificateUString(certPath);
// const img = await PDFNet.Image.createFromMemory2(doc, imgBytes);
// //make this dynamic with canvas lib
// const imgWidth = 300;
// const imgHeight = 300;
// const pagesForSining = Object.keys(coords).map((k) => {
// return parseInt(k);
// });
// const pages = await doc.getPageCount();
// let result;
// for (let p = 1; p <= pages; p++) {
// if (!pagesForSining.includes(p)) {
// continue;
// }
// const page = await doc.getPage(p);
// const doctimestamp_signature_field =
// await doc.createDigitalSignatureField();
// const widgetAnnot =
// await PDFNet.SignatureWidget.createWithDigitalSignatureField(
// doc,
// new PDFNet.Rect(
// parseFloat(coords[p].x),
// parseFloat(coords[p].x + imgWidth),
// parseFloat(coords[p].y),
// parseFloat(coords[p].y + imgHeight)
// ),
// doctimestamp_signature_field
// );
// await page.annotPushBack(widgetAnnot);
// await widgetAnnot.createSignatureAppearance(img);
// await doctimestamp_signature_field.timestampOnNextSave(tst_config, opts);
// result = await doc.saveMemoryBuffer(
// PDFNet.SDFDoc.SaveOptions.e_incremental
// );
// }
// return result.buffer;
// };
......@@ -7,5 +7,6 @@
"allowJs": true,
"esModuleInterop": true
},
"include": ["src/**/*"]
"include": ["src/**/*"],
"exclude": ["node_modules"]
}