mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 00:32:43 +10:00
97 lines
2.2 KiB
TypeScript
97 lines
2.2 KiB
TypeScript
import {
|
|
PDFArray,
|
|
PDFDict,
|
|
PDFDocument,
|
|
PDFHexString,
|
|
PDFName,
|
|
PDFNumber,
|
|
PDFString,
|
|
rectangle,
|
|
} from 'pdf-lib';
|
|
|
|
import { BYTE_RANGE_PLACEHOLDER } from '../constants/byte-range';
|
|
|
|
export type AddSigningPlaceholderOptions = {
|
|
pdf: Buffer;
|
|
};
|
|
|
|
export const addSigningPlaceholder = async ({ pdf }: AddSigningPlaceholderOptions) => {
|
|
const doc = await PDFDocument.load(pdf);
|
|
const [firstPage] = doc.getPages();
|
|
|
|
const byteRange = PDFArray.withContext(doc.context);
|
|
|
|
byteRange.push(PDFNumber.of(0));
|
|
byteRange.push(PDFName.of(BYTE_RANGE_PLACEHOLDER));
|
|
byteRange.push(PDFName.of(BYTE_RANGE_PLACEHOLDER));
|
|
byteRange.push(PDFName.of(BYTE_RANGE_PLACEHOLDER));
|
|
|
|
const signature = doc.context.register(
|
|
doc.context.obj({
|
|
Type: 'Sig',
|
|
Filter: 'Adobe.PPKLite',
|
|
SubFilter: 'adbe.pkcs7.detached',
|
|
ByteRange: byteRange,
|
|
Contents: PDFHexString.fromText(' '.repeat(8192)),
|
|
Reason: PDFString.of('Signed by Documenso'),
|
|
M: PDFString.fromDate(new Date()),
|
|
}),
|
|
);
|
|
|
|
const widget = doc.context.register(
|
|
doc.context.obj({
|
|
Type: 'Annot',
|
|
Subtype: 'Widget',
|
|
FT: 'Sig',
|
|
Rect: [0, 0, 0, 0],
|
|
V: signature,
|
|
T: PDFString.of('Signature1'),
|
|
F: 4,
|
|
P: firstPage.ref,
|
|
AP: doc.context.obj({
|
|
N: doc.context.register(doc.context.formXObject([rectangle(0, 0, 0, 0)])),
|
|
}),
|
|
}),
|
|
);
|
|
|
|
let widgets: PDFArray;
|
|
|
|
try {
|
|
widgets = firstPage.node.lookup(PDFName.of('Annots'), PDFArray);
|
|
} catch {
|
|
widgets = PDFArray.withContext(doc.context);
|
|
|
|
firstPage.node.set(PDFName.of('Annots'), widgets);
|
|
}
|
|
|
|
widgets.push(widget);
|
|
|
|
let arcoForm: PDFDict;
|
|
|
|
try {
|
|
arcoForm = doc.catalog.lookup(PDFName.of('AcroForm'), PDFDict);
|
|
} catch {
|
|
arcoForm = doc.context.obj({
|
|
Fields: PDFArray.withContext(doc.context),
|
|
});
|
|
|
|
doc.catalog.set(PDFName.of('AcroForm'), arcoForm);
|
|
}
|
|
|
|
let fields: PDFArray;
|
|
|
|
try {
|
|
fields = arcoForm.lookup(PDFName.of('Fields'), PDFArray);
|
|
} catch {
|
|
fields = PDFArray.withContext(doc.context);
|
|
|
|
arcoForm.set(PDFName.of('Fields'), fields);
|
|
}
|
|
|
|
fields.push(widget);
|
|
|
|
arcoForm.set(PDFName.of('SigFlags'), PDFNumber.of(3));
|
|
|
|
return Buffer.from(await doc.save({ useObjectStreams: false }));
|
|
};
|