From 786566bae472d6a82f9a05fee506407757b29218 Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Tue, 12 Nov 2024 13:26:14 +0900 Subject: [PATCH] fix: certificate translations (#1460) ## Description Currently certificate translations on production sometimes does not show the required language. This could not be replicated when creating certificates on staging (Browserless.io) and local development (Chromium), which means this fix ultimately cannot be tested unless on live. This is an attempt to fix it by isolating the certificate generation into it's own context, and applying a cookie to define the required language. This fix is based on the assumption that there is some sort of error which pushes the certificate to be generated on the client side, which ultimately will render in English due to constraints on nextjs. ## Changes Made - Apply language into cookie instead purely dynamically on SSR - Minor unrelated fixes ## Testing Performed Tested to ensure certificates could still be generated --- .../[id]/logs/document-logs-page-view.tsx | 1 + .../[id]/logs/download-certificate-button.tsx | 4 +++- .../preferences/document-preferences.tsx | 6 +++--- .../lib/server-only/document/seal-document.ts | 6 +++++- .../htmltopdf/get-certificate-pdf.ts | 20 +++++++++++++++++-- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-page-view.tsx b/apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-page-view.tsx index c6c3c9ad3..4bd852248 100644 --- a/apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-page-view.tsx +++ b/apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-page-view.tsx @@ -139,6 +139,7 @@ export const DocumentLogsPageView = async ({ params, team }: DocumentLogsPageVie className="mr-2" documentId={document.id} documentStatus={document.status} + teamId={team?.id} /> diff --git a/apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx b/apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx index aed252670..7cc262d3d 100644 --- a/apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx +++ b/apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx @@ -14,12 +14,14 @@ export type DownloadCertificateButtonProps = { className?: string; documentId: number; documentStatus: DocumentStatus; + teamId?: number; }; export const DownloadCertificateButton = ({ className, documentId, documentStatus, + teamId, }: DownloadCertificateButtonProps) => { const { toast } = useToast(); const { _ } = useLingui(); @@ -29,7 +31,7 @@ export const DownloadCertificateButton = ({ const onDownloadCertificatesClick = async () => { try { - const { url } = await downloadCertificate({ documentId }); + const { url } = await downloadCertificate({ documentId, teamId }); const iframe = Object.assign(document.createElement('iframe'), { src: url, diff --git a/apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx b/apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx index 26409c01b..e021b66b2 100644 --- a/apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx +++ b/apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx @@ -206,9 +206,9 @@ export const TeamDocumentPreferencesForm = ({ {includeSenderDetails - ? _(msg`"${placeholderEmail}" on behalf of "${team.name}" has invited you to sign "example - document".`) - : _(msg`"${team.name}" has invited you to sign "example document".`)} + ? _(msg`'${placeholderEmail}' on behalf of '${team.name}' has invited you to sign 'example + document'.`) + : _(msg`'${team.name}' has invited you to sign 'example document'.`)} diff --git a/packages/lib/server-only/document/seal-document.ts b/packages/lib/server-only/document/seal-document.ts index 7c0c3bced..31e66d25f 100644 --- a/packages/lib/server-only/document/seal-document.ts +++ b/packages/lib/server-only/document/seal-document.ts @@ -10,6 +10,7 @@ import { DocumentStatus, RecipientRole, SigningStatus } from '@documenso/prisma/ import { WebhookTriggerEvents } from '@documenso/prisma/client'; import { signPdf } from '@documenso/signing'; +import { ZSupportedLanguageCodeSchema } from '../../constants/i18n'; import type { RequestMetadata } from '../../universal/extract-request-metadata'; import { getFile } from '../../universal/upload/get-file'; import { putPdfFile } from '../../universal/upload/put-file'; @@ -45,6 +46,7 @@ export const sealDocument = async ({ }, include: { documentData: true, + documentMeta: true, Recipient: true, }, }); @@ -90,7 +92,9 @@ export const sealDocument = async ({ // !: Need to write the fields onto the document as a hard copy const pdfData = await getFile(documentData); - const certificate = await getCertificatePdf({ documentId }) + const documentLanguage = ZSupportedLanguageCodeSchema.parse(document.documentMeta?.language); + + const certificate = await getCertificatePdf({ documentId, language: documentLanguage }) .then(async (doc) => PDFDocument.load(doc)) .catch(() => null); diff --git a/packages/lib/server-only/htmltopdf/get-certificate-pdf.ts b/packages/lib/server-only/htmltopdf/get-certificate-pdf.ts index 56c2e32cf..e5348ae1e 100644 --- a/packages/lib/server-only/htmltopdf/get-certificate-pdf.ts +++ b/packages/lib/server-only/htmltopdf/get-certificate-pdf.ts @@ -2,13 +2,15 @@ import { DateTime } from 'luxon'; import type { Browser } from 'playwright'; import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app'; +import type { SupportedLanguageCodes } from '../../constants/i18n'; import { encryptSecondaryData } from '../crypto/encrypt'; export type GetCertificatePdfOptions = { documentId: number; + language?: SupportedLanguageCodes; }; -export const getCertificatePdf = async ({ documentId }: GetCertificatePdfOptions) => { +export const getCertificatePdf = async ({ documentId, language }: GetCertificatePdfOptions) => { const { chromium } = await import('playwright'); const encryptedId = encryptSecondaryData({ @@ -32,7 +34,19 @@ export const getCertificatePdf = async ({ documentId }: GetCertificatePdfOptions ); } - const page = await browser.newPage(); + const browserContext = await browser.newContext(); + + const page = await browserContext.newPage(); + + if (language) { + await page.context().addCookies([ + { + name: 'language', + value: language, + url: NEXT_PUBLIC_WEBAPP_URL(), + }, + ]); + } await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/__htmltopdf/certificate?d=${encryptedId}`, { waitUntil: 'networkidle', @@ -43,6 +57,8 @@ export const getCertificatePdf = async ({ documentId }: GetCertificatePdfOptions format: 'A4', }); + await browserContext.close(); + void browser.close(); return result;