From 361281640cdeeddb1856fa8354f8b636e75979ef Mon Sep 17 00:00:00 2001 From: Valery Buchinsky Date: Mon, 13 Nov 2023 17:24:33 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=A6=20[placeholder-pdf-lib]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dist/pdflibAddPlaceholder.d.ts | 10 +++- .../dist/pdflibAddPlaceholder.d.ts.map | 2 +- .../dist/pdflibAddPlaceholder.js | 58 ++++++++++++++----- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts b/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts index 36e54366..3d3332b1 100644 --- a/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts +++ b/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts @@ -1,7 +1,7 @@ export function pdflibAddPlaceholder({ pdfDoc, reason, contactInfo, name, location, signatureLength, byteRangePlaceholder, subFilter, widgetRect, }: InputType): void; -export type PDFDocumentFactory = import('pdf-lib').PDFDocumentFactory; +export type PDFDocument = import('pdf-lib').PDFDocument; export type InputType = { - pdfDoc: any; + pdfDoc: PDFDocument; reason: string; contactInfo: string; name: string; @@ -9,8 +9,12 @@ export type InputType = { signatureLength?: number; byteRangePlaceholder?: string; /** - * One of SUBFILTER_* from + * One of SUBFILTER_* from \@signpdf/utils */ subFilter?: string; + /** + * [x1, y1, x2, y2] widget rectangle + */ + widgetRect?: number[]; }; //# sourceMappingURL=pdflibAddPlaceholder.d.ts.map \ No newline at end of file diff --git a/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts.map b/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts.map index eac4ddcb..1aac768f 100644 --- a/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts.map +++ b/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"pdflibAddPlaceholder.d.ts","sourceRoot":"","sources":["../src/pdflibAddPlaceholder.js"],"names":[],"mappings":"AA8BO,qJAHI,SAAS,GACP,IAAI,CAsEhB;iCA5FY,OAAO,SAAS,EAAE,kBAAkB;;;YAMpC,MAAM;iBACN,MAAM;UACN,MAAM;cACN,MAAM;sBACN,MAAM;2BACN,MAAM;;;;gBACN,MAAM"} \ No newline at end of file +{"version":3,"file":"pdflibAddPlaceholder.d.ts","sourceRoot":"","sources":["../src/pdflibAddPlaceholder.js"],"names":[],"mappings":"AAoCO,qJAHI,SAAS,GACP,IAAI,CA0FhB;0BAhHY,OAAO,SAAS,EAAE,WAAW;;YAK7B,WAAW;YACX,MAAM;iBACN,MAAM;UACN,MAAM;cACN,MAAM;sBACN,MAAM;2BACN,MAAM;;;;gBACN,MAAM;;;;iBACN,MAAM,EAAE"} \ No newline at end of file diff --git a/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.js b/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.js index 3cb48e33..f1bad163 100644 --- a/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.js +++ b/packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.js @@ -7,19 +7,19 @@ exports.pdflibAddPlaceholder = void 0; var _utils = require("@signpdf/utils"); var _pdfLib = require("pdf-lib"); /** - * @typedef {import('pdf-lib').PDFDocumentFactory} PDFDocumentFactory + * @typedef {import('pdf-lib').PDFDocument} PDFDocument */ /** * @typedef {object} InputType -* @property {PDFDocumentFactory} pdfDoc +* @property {PDFDocument} pdfDoc * @property {string} reason * @property {string} contactInfo * @property {string} name * @property {string} location * @property {number} [signatureLength] * @property {string} [byteRangePlaceholder] -* @property {string} [subFilter] One of SUBFILTER_* from @signpdf/utils +* @property {string} [subFilter] One of SUBFILTER_* from \@signpdf/utils * @property {number[]} [widgetRect] [x1, y1, x2, y2] widget rectangle */ @@ -42,7 +42,7 @@ const pdflibAddPlaceholder = ({ subFilter = _utils.SUBFILTER_ADOBE_PKCS7_DETACHED, widgetRect = [0, 0, 0, 0] }) => { - const pages = pdfDoc.getPages(); + const page = pdfDoc.getPage(0); // Create a placeholder where the the last 3 parameters of the // actual range will be replaced when signing is done. @@ -53,8 +53,7 @@ const pdflibAddPlaceholder = ({ byteRange.push(_pdfLib.PDFName.of(byteRangePlaceholder)); // Fill the contents of the placeholder with 00s. - const hexNull = (0, _pdfLib.toHexStringOfMinLength)(0, 4); - const placeholder = _pdfLib.PDFHexString.of(hexNull.repeat(signatureLength)); + const placeholder = _pdfLib.PDFHexString.of(String.fromCharCode(0).repeat(signatureLength)); // Create a signature dictionary to be referenced in the signature widget. const signatureDict = pdfDoc.context.obj({ @@ -69,6 +68,7 @@ const pdflibAddPlaceholder = ({ Name: _pdfLib.PDFString.of(name), Location: _pdfLib.PDFString.of(location) }, pdfDoc.index); + const signatureDictRef = pdfDoc.context.register(signatureDict); // Create the signature widget const rect = _pdfLib.PDFArray.withContext(pdfDoc.context); @@ -78,20 +78,46 @@ const pdflibAddPlaceholder = ({ Subtype: 'Widget', FT: 'Sig', Rect: rect, - V: signatureDict, + V: signatureDictRef, T: _pdfLib.PDFString.of('Signature1'), - F: 4, - P: pages[0].ref + F: _utils.ANNOTATION_FLAGS.PRINT, + P: page.ref }, pdfDoc.index); const widgetDictRef = pdfDoc.context.register(widgetDict); - // Annotate the widget - pages[0].node.set(_pdfLib.PDFName.of('Annots'), pdfDoc.context.obj([widgetDictRef])); + // Annotate the widget on the first page + let annotations = page.node.lookupMaybe(_pdfLib.PDFName.of('Annots'), _pdfLib.PDFArray); + if (typeof annotations === 'undefined') { + annotations = pdfDoc.context.obj([]); + } + annotations.push(widgetDictRef); + page.node.set(_pdfLib.PDFName.of('Annots'), annotations); - // Reference the widget in the AcroForm - pdfDoc.catalog.set(_pdfLib.PDFName.of('AcroForm'), pdfDoc.context.obj({ - SigFlags: 3, - Fields: [widgetDictRef] - })); + // Add an AcroForm or update the existing one + let acroForm = pdfDoc.catalog.lookupMaybe(_pdfLib.PDFName.of('AcroForm'), _pdfLib.PDFDict); + if (typeof acroForm === 'undefined') { + // Need to create a new AcroForm + acroForm = pdfDoc.context.obj({ + Fields: [] + }); + const acroFormRef = pdfDoc.context.register(acroForm); + pdfDoc.catalog.set(_pdfLib.PDFName.of('AcroForm'), acroFormRef); + } + + /** + * @type {PDFNumber} + */ + let sigFlags; + if (acroForm.has(_pdfLib.PDFName.of('SigFlags'))) { + // Already has some flags, will merge + sigFlags = acroForm.get(_pdfLib.PDFName.of('SigFlags')); + } else { + // Create blank flags + sigFlags = _pdfLib.PDFNumber.of(0); + } + const updatedFlags = _pdfLib.PDFNumber.of(sigFlags.asNumber() | _utils.SIG_FLAGS.SIGNATURES_EXIST | _utils.SIG_FLAGS.APPEND_ONLY); + acroForm.set(_pdfLib.PDFName.of('SigFlags'), updatedFlags); + const fields = acroForm.get(_pdfLib.PDFName.of('Fields')); + fields.push(widgetDictRef); }; exports.pdflibAddPlaceholder = pdflibAddPlaceholder; \ No newline at end of file