diff --git a/apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx b/apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx index a7bb62eb2..849dd8a3a 100644 --- a/apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx +++ b/apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx @@ -122,7 +122,7 @@ export const EnvelopeItemEditDialog = ({ toast({ title: t`Failed to read file`, - description: t`The file is not a valid PDF.`, + description: t`The file is not a valid PDF or is password protected.`, variant: 'destructive', }); } diff --git a/apps/remix/app/utils/toast-error-messages.ts b/apps/remix/app/utils/toast-error-messages.ts index 49e4ceb62..e10033d3f 100644 --- a/apps/remix/app/utils/toast-error-messages.ts +++ b/apps/remix/app/utils/toast-error-messages.ts @@ -92,7 +92,7 @@ export const getUploadErrorMessage = (code: string): ToastMessageDescriptor => { .with(AppErrorCode.TOO_MANY_REQUESTS, () => FAIR_USE_LIMIT_EXCEEDED_ERROR_MESSAGE) .with('INVALID_DOCUMENT_FILE', () => ({ title: msg`Error`, - description: msg`You cannot upload encrypted PDFs.`, + description: msg`The file is not a valid PDF or is password protected.`, })) .with(AppErrorCode.LIMIT_EXCEEDED, () => ({ title: msg`Error`, diff --git a/package-lock.json b/package-lock.json index 1cbb19926..57b2baff4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "dependencies": { "@ai-sdk/google-vertex": "5.0.48", "@documenso/prisma": "*", - "@libpdf/core": "^0.4.2", + "@libpdf/core": "^0.5.1", "@lingui/conf": "^5.6.0", "@lingui/core": "^5.6.0", "@marsidev/react-turnstile": "^1.5.0", @@ -4480,9 +4480,9 @@ "license": "MIT" }, "node_modules/@libpdf/core": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@libpdf/core/-/core-0.4.2.tgz", - "integrity": "sha512-lbkIqLDZCCxjLpiC+8/Xvaru/ME7iVVoihl9tLqbp/CDUWZNF0q3u7s2tBJB9wRW/SzUWID6YPFvBWws770hrQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@libpdf/core/-/core-0.5.1.tgz", + "integrity": "sha512-q+y4AEk9ngqyC1pdX/hNScnfh0ROr4vSiqX4C9CmuBzhtuVukbfTesXCaGvHZ3pksi8AJYDPGQ/0HzSeHZfi3A==", "license": "MIT", "dependencies": { "@noble/ciphers": "^2.2.0", diff --git a/package.json b/package.json index dbe2f233c..72d301246 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "dependencies": { "@ai-sdk/google-vertex": "5.0.48", "@documenso/prisma": "*", - "@libpdf/core": "^0.4.2", + "@libpdf/core": "^0.5.1", "@lingui/conf": "^5.6.0", "@lingui/core": "^5.6.0", "@prisma/extension-read-replicas": "^0.4.1", diff --git a/packages/lib/server-only/pdf/normalize-pdf.ts b/packages/lib/server-only/pdf/normalize-pdf.ts index 01e5ac108..d2f5b8833 100644 --- a/packages/lib/server-only/pdf/normalize-pdf.ts +++ b/packages/lib/server-only/pdf/normalize-pdf.ts @@ -9,14 +9,18 @@ export const normalizePdf = async (pdf: Buffer, options: { flattenForm?: boolean console.error(`PDF normalization error: ${e.message}`); throw new AppError('INVALID_DOCUMENT_FILE', { - message: 'The document is not a valid PDF', + message: 'The document is not a valid PDF or is password protected', }); }); if (pdfDoc.isEncrypted) { - throw new AppError('INVALID_DOCUMENT_FILE', { - message: 'The document is encrypted', - }); + if (!pdfDoc.isAuthenticated) { + throw new AppError('INVALID_DOCUMENT_FILE', { + message: 'The document is password protected', + }); + } + + pdfDoc.removeProtection({ ignorePermissions: true }); } pdfDoc.flattenLayers();