Compare commits

..

2 Commits

Author SHA1 Message Date
Mythie 76e4807c67 v1.9.0-rc.2 2024-12-12 14:24:40 +11:00
Mythie efd6531d3e feat: add controls for sending completion emails to document owners
Adds a new `ownerDocumentCompleted` to the email settings that
controls whether a document will be sent to the owner upon completion.

This was previously the only email you couldn't disable and didn't
account for users integrating with just the API and Webhooks.

Also adds a flag to the public `sendDocument` endpoint which will
adjust this setting while sendint the document for users who aren't
using `emailSettings` on the `createDocument` endpoint.
2024-12-12 13:55:46 +11:00
5 changed files with 11 additions and 41 deletions
@@ -6,12 +6,8 @@ import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-po
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
import { prisma } from '@documenso/prisma';
import {
DocumentStatus,
RecipientRole,
SigningStatus,
WebhookTriggerEvents,
} from '@documenso/prisma/client';
import { DocumentStatus, RecipientRole, SigningStatus } from '@documenso/prisma/client';
import { WebhookTriggerEvents } from '@documenso/prisma/client';
import { signPdf } from '@documenso/signing';
import { ZWebhookDocumentSchema } from '../../types/webhook-payload';
@@ -9,8 +9,8 @@ import {
RecipientRole,
SendStatus,
SigningStatus,
WebhookTriggerEvents,
} from '@documenso/prisma/client';
import { WebhookTriggerEvents } from '@documenso/prisma/client';
import { jobs } from '../../jobs/client';
import { extractDerivedDocumentEmailSettings } from '../../types/document-email';
+1 -14
View File
@@ -1,11 +1,9 @@
import type { PDFField, PDFWidgetAnnotation } from 'pdf-lib';
import { PDFCheckBox, PDFRadioGroup, PDFRef } from 'pdf-lib';
import {
PDFCheckBox,
PDFDict,
type PDFDocument,
PDFName,
PDFRadioGroup,
PDFRef,
drawObject,
popGraphicsState,
pushGraphicsState,
@@ -13,18 +11,7 @@ import {
translate,
} from 'pdf-lib';
export const removeOptionalContentGroups = (document: PDFDocument) => {
const context = document.context;
const catalog = context.lookup(context.trailerInfo.Root);
if (catalog instanceof PDFDict) {
catalog.delete(PDFName.of('OCProperties'));
}
};
export const flattenForm = (document: PDFDocument) => {
removeOptionalContentGroups(document);
const form = document.getForm();
form.updateFieldAppearances();
+7 -13
View File
@@ -8,7 +8,6 @@ import { DocumentDataType } from '@documenso/prisma/client';
import { AppError } from '../../errors/app-error';
import { createDocumentData } from '../../server-only/document-data/create-document-data';
import { removeOptionalContentGroups } from '../../server-only/pdf/flatten-form';
type File = {
name: string;
@@ -25,25 +24,20 @@ export const putPdfFile = async (file: File) => {
() => false,
);
const pdf = await PDFDocument.load(await file.arrayBuffer()).catch((e) => {
console.error(`PDF upload parse error: ${e.message}`);
// This will prevent uploading encrypted PDFs or anything that can't be opened.
if (!isEncryptedDocumentsAllowed) {
await PDFDocument.load(await file.arrayBuffer()).catch((e) => {
console.error(`PDF upload parse error: ${e.message}`);
throw new AppError('INVALID_DOCUMENT_FILE');
});
if (!isEncryptedDocumentsAllowed && pdf.isEncrypted) {
throw new AppError('INVALID_DOCUMENT_FILE');
throw new AppError('INVALID_DOCUMENT_FILE');
});
}
if (!file.name.endsWith('.pdf')) {
file.name = `${file.name}.pdf`;
}
removeOptionalContentGroups(pdf);
const bytes = await pdf.save();
const { type, data } = await putFile(new File([bytes], file.name, { type: 'application/pdf' }));
const { type, data } = await putFile(file);
return await createDocumentData({ type, data });
};
@@ -351,17 +351,10 @@ export const SignaturePad = ({
const newValue = event.target.value;
setTypedSignature(newValue);
if ($el.current) {
const ctx = $el.current.getContext('2d');
ctx?.clearRect(0, 0, $el.current.width, $el.current.height);
}
if (newValue.trim() !== '') {
onChange?.(newValue);
onValidityChange?.(true);
} else {
onChange?.(null);
onValidityChange?.(false);
}
};