From a17d4a2a39b33bbfe34dd89a0fe4987f4547d5a4 Mon Sep 17 00:00:00 2001 From: Mythie Date: Sun, 3 Mar 2024 11:36:28 +1100 Subject: [PATCH] fix: handle signature annotations --- .../lib/server-only/document/seal-document.ts | 27 +++++++++++++++++-- .../signing/helpers/addSigningPlaceholder.ts | 16 ++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/packages/lib/server-only/document/seal-document.ts b/packages/lib/server-only/document/seal-document.ts index dd427dc95..95b7d9dc4 100644 --- a/packages/lib/server-only/document/seal-document.ts +++ b/packages/lib/server-only/document/seal-document.ts @@ -2,7 +2,7 @@ import { nanoid } from 'nanoid'; import path from 'node:path'; -import { PDFDocument } from 'pdf-lib'; +import { PDFDocument, PDFSignature, rectangle } from 'pdf-lib'; import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; @@ -91,8 +91,31 @@ export const sealDocument = async ({ const doc = await PDFDocument.load(pdfData); + const form = doc.getForm(); + + // Remove old signatures + for (const field of form.getFields()) { + if (field instanceof PDFSignature) { + field.acroField.getWidgets().forEach((widget) => { + widget.ensureAP(); + + try { + widget.getNormalAppearance(); + } catch (e) { + const { context } = widget.dict; + + const xobj = context.formXObject([rectangle(0, 0, 0, 0)]); + + const streamRef = context.register(xobj); + + widget.setNormalAppearance(streamRef); + } + }); + } + } + // Flatten the form to stop annotation layers from appearing above documenso fields - doc.getForm().flatten(); + form.flatten(); for (const field of fields) { await insertFieldInPDF(doc, field); diff --git a/packages/signing/helpers/addSigningPlaceholder.ts b/packages/signing/helpers/addSigningPlaceholder.ts index 6c7bb18e3..211a534ea 100644 --- a/packages/signing/helpers/addSigningPlaceholder.ts +++ b/packages/signing/helpers/addSigningPlaceholder.ts @@ -1,5 +1,13 @@ import signer from 'node-signpdf'; -import { PDFArray, PDFDocument, PDFHexString, PDFName, PDFNumber, PDFString } from 'pdf-lib'; +import { + PDFArray, + PDFDocument, + PDFHexString, + PDFName, + PDFNumber, + PDFString, + rectangle, +} from 'pdf-lib'; export type AddSigningPlaceholderOptions = { pdf: Buffer; @@ -39,6 +47,12 @@ export const addSigningPlaceholder = async ({ pdf }: AddSigningPlaceholderOption P: pages[0].ref, }); + const xobj = widget.context.formXObject([rectangle(0, 0, 0, 0)]); + + const streamRef = widget.context.register(xobj); + + widget.set(PDFName.of('AP'), widget.context.obj({ N: streamRef })); + const widgetRef = doc.context.register(widget); let widgets = pages[0].node.get(PDFName.of('Annots'));