Skip to content

Commit

Permalink
📦 [placeholder-pdf-lib]
Browse files Browse the repository at this point in the history
  • Loading branch information
vbuch committed Nov 14, 2023
1 parent 02cc367 commit 3612816
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 20 deletions.
10 changes: 7 additions & 3 deletions packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.d.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
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;
location: string;
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 42 additions & 16 deletions packages/placeholder-pdf-lib/dist/pdflibAddPlaceholder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/

Expand All @@ -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.
Expand All @@ -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({
Expand All @@ -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);
Expand All @@ -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;

0 comments on commit 3612816

Please sign in to comment.