Files
documenso/packages/signing/index.ts
T
Lucas Smith 9035240b4d refactor: replace pdf-sign with libpdf/core for PDF operations (#2403)
Migrate from @documenso/pdf-sign and @cantoo/pdf-lib to @libpdf/core
for all PDF manipulation and signing operations. This includes:

- New signing transports for Google Cloud KMS and local certificates
- Consolidated PDF operations using libpdf API
- Added TSA (timestamp authority) helper for digital signatures
- Removed deprecated flatten and insert utilities
- Updated tests to use new PDF library
2026-01-21 15:16:23 +11:00

60 lines
1.6 KiB
TypeScript

import type { Signer } from '@libpdf/core';
import type { PDF } from '@libpdf/core';
import { match } from 'ts-pattern';
import {
NEXT_PRIVATE_USE_LEGACY_SIGNING_SUBFILTER,
NEXT_PUBLIC_SIGNING_CONTACT_INFO,
NEXT_PUBLIC_WEBAPP_URL,
} from '@documenso/lib/constants/app';
import { env } from '@documenso/lib/utils/env';
import { getTimestampAuthority } from './helpers/tsa';
import { createGoogleCloudSigner } from './transports/google-cloud';
import { createLocalSigner } from './transports/local';
export type SignOptions = {
pdf: PDF;
};
let signer: Signer | null = null;
const getSigner = async () => {
if (signer) {
return signer;
}
const transport = env('NEXT_PRIVATE_SIGNING_TRANSPORT') || 'local';
// eslint-disable-next-line require-atomic-updates
signer = await match(transport)
.with('local', async () => await createLocalSigner())
.with('gcloud-hsm', async () => await createGoogleCloudSigner())
.otherwise(() => {
throw new Error(`Unsupported signing transport: ${transport}`);
});
return signer;
};
export const signPdf = async ({ pdf }: SignOptions) => {
const signer = await getSigner();
const tsa = getTimestampAuthority();
const { bytes } = await pdf.sign({
signer,
reason: 'Signed by Documenso',
location: NEXT_PUBLIC_WEBAPP_URL(),
contactInfo: NEXT_PUBLIC_SIGNING_CONTACT_INFO(),
subFilter: NEXT_PRIVATE_USE_LEGACY_SIGNING_SUBFILTER()
? 'adbe.pkcs7.detached'
: 'ETSI.CAdES.detached',
timestampAuthority: tsa ?? undefined,
longTermValidation: !!tsa,
archivalTimestamp: !!tsa,
});
return bytes;
};