documenso/packages/lib/server-only/pdf/generate-audit-log-pdf.ts
David Nguyen 0d65693d55
fix: highlight rejected certificate text (#2478)
## Description

- Update the rejected certificate so that is it more clear on who
rejected the document.
- Updated the audit log generation so that the completed audit log is
included

### Before

<img width="681" height="597" alt="image"
src="https://github.com/user-attachments/assets/3dab41c1-c86f-4555-8d50-3d9245be65d5"
/>

### After

Note that the order of the recipient is different in this case

<img width="818" height="769" alt="image"
src="https://github.com/user-attachments/assets/71f0ac12-5859-47b4-8980-2420ef949d18"
/>

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2026-02-12 16:06:43 +11:00

74 lines
2 KiB
TypeScript

import { PDF } from '@libpdf/core';
import { i18n } from '@lingui/core';
import { type TDocumentAuditLog } from '@documenso/lib/types/document-audit-logs';
import { prisma } from '@documenso/prisma';
import { ZSupportedLanguageCodeSchema } from '../../constants/i18n';
import { parseDocumentAuditLogData } from '../../utils/document-audit-logs';
import { getTranslations } from '../../utils/i18n';
import { getOrganisationClaimByTeamId } from '../organisation/get-organisation-claims';
import type { GenerateCertificatePdfOptions } from './generate-certificate-pdf';
import { renderAuditLogs } from './render-audit-logs';
type GenerateAuditLogPdfOptions = GenerateCertificatePdfOptions & {
envelopeItems: string[];
additionalAuditLogs?: TDocumentAuditLog[];
};
export const generateAuditLogPdf = async (options: GenerateAuditLogPdfOptions) => {
const {
envelope,
envelopeOwner,
envelopeItems,
recipients,
language,
pageWidth,
pageHeight,
additionalAuditLogs = [],
} = options;
const documentLanguage = ZSupportedLanguageCodeSchema.parse(language);
const [organisationClaim, partialAuditLogs, messages] = await Promise.all([
getOrganisationClaimByTeamId({ teamId: envelope.teamId }),
getAuditLogs(envelope.id),
getTranslations(documentLanguage),
]);
i18n.loadAndActivate({
locale: documentLanguage,
messages,
});
const auditLogs: TDocumentAuditLog[] = [...additionalAuditLogs, ...partialAuditLogs];
const auditLogPages = await renderAuditLogs({
envelope,
envelopeOwner,
envelopeItems,
recipients,
auditLogs,
hidePoweredBy: organisationClaim.flags.hidePoweredBy ?? false,
pageWidth,
pageHeight,
i18n,
});
return await PDF.merge(auditLogPages, {
includeAnnotations: true,
});
};
const getAuditLogs = async (envelopeId: string) => {
const auditLogs = await prisma.documentAuditLog.findMany({
where: {
envelopeId,
},
orderBy: {
createdAt: 'desc',
},
});
return auditLogs.map((auditLog) => parseDocumentAuditLogData(auditLog));
};