mirror of
https://github.com/documenso/documenso.git
synced 2026-07-27 18:35:05 +10:00
feat: configure audit log embedding per document
This commit is contained in:
+43
-1
@@ -41,6 +41,7 @@ import { TemplateTypeSelect, TemplateTypeTooltip } from '@documenso/ui/component
|
|||||||
import { cn } from '@documenso/ui/lib/utils';
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
import { Button } from '@documenso/ui/primitives/button';
|
import { Button } from '@documenso/ui/primitives/button';
|
||||||
import { CardDescription, CardHeader, CardTitle } from '@documenso/ui/primitives/card';
|
import { CardDescription, CardHeader, CardTitle } from '@documenso/ui/primitives/card';
|
||||||
|
import { Checkbox } from '@documenso/ui/primitives/checkbox';
|
||||||
import { Combobox } from '@documenso/ui/primitives/combobox';
|
import { Combobox } from '@documenso/ui/primitives/combobox';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -50,7 +51,15 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from '@documenso/ui/primitives/dialog';
|
} from '@documenso/ui/primitives/dialog';
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form';
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@documenso/ui/primitives/form/form';
|
||||||
import { Input } from '@documenso/ui/primitives/input';
|
import { Input } from '@documenso/ui/primitives/input';
|
||||||
import { MultiSelectCombobox } from '@documenso/ui/primitives/multi-select-combobox';
|
import { MultiSelectCombobox } from '@documenso/ui/primitives/multi-select-combobox';
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
|
||||||
@@ -93,6 +102,7 @@ export const ZAddSettingsFormSchema = z.object({
|
|||||||
timezone: ZDocumentMetaTimezoneSchema.default(DEFAULT_DOCUMENT_TIME_ZONE),
|
timezone: ZDocumentMetaTimezoneSchema.default(DEFAULT_DOCUMENT_TIME_ZONE),
|
||||||
dateFormat: ZDocumentMetaDateFormatSchema.default(DEFAULT_DOCUMENT_DATE_FORMAT),
|
dateFormat: ZDocumentMetaDateFormatSchema.default(DEFAULT_DOCUMENT_DATE_FORMAT),
|
||||||
distributionMethod: z.nativeEnum(DocumentDistributionMethod).optional().default(DocumentDistributionMethod.EMAIL),
|
distributionMethod: z.nativeEnum(DocumentDistributionMethod).optional().default(DocumentDistributionMethod.EMAIL),
|
||||||
|
includeAuditLog: z.boolean().default(false),
|
||||||
redirectUrl: z
|
redirectUrl: z
|
||||||
.string()
|
.string()
|
||||||
.optional()
|
.optional()
|
||||||
@@ -181,6 +191,7 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
|
|||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
dateFormat: (envelope.documentMeta.dateFormat ?? DEFAULT_DOCUMENT_DATE_FORMAT) as TDocumentMetaDateFormat,
|
dateFormat: (envelope.documentMeta.dateFormat ?? DEFAULT_DOCUMENT_DATE_FORMAT) as TDocumentMetaDateFormat,
|
||||||
distributionMethod: envelope.documentMeta.distributionMethod || DocumentDistributionMethod.EMAIL,
|
distributionMethod: envelope.documentMeta.distributionMethod || DocumentDistributionMethod.EMAIL,
|
||||||
|
includeAuditLog: envelope.documentMeta.includeAuditLog,
|
||||||
redirectUrl: envelope.documentMeta.redirectUrl ?? '',
|
redirectUrl: envelope.documentMeta.redirectUrl ?? '',
|
||||||
language: envelope.documentMeta.language ?? 'en',
|
language: envelope.documentMeta.language ?? 'en',
|
||||||
emailId: envelope.documentMeta.emailId ?? null,
|
emailId: envelope.documentMeta.emailId ?? null,
|
||||||
@@ -236,6 +247,7 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
|
|||||||
emailReplyTo,
|
emailReplyTo,
|
||||||
envelopeExpirationPeriod,
|
envelopeExpirationPeriod,
|
||||||
reminderSettings,
|
reminderSettings,
|
||||||
|
includeAuditLog,
|
||||||
} = data.meta;
|
} = data.meta;
|
||||||
|
|
||||||
const parsedGlobalAccessAuth = z.array(ZDocumentAccessAuthTypesSchema).safeParse(data.globalAccessAuth);
|
const parsedGlobalAccessAuth = z.array(ZDocumentAccessAuthTypesSchema).safeParse(data.globalAccessAuth);
|
||||||
@@ -265,6 +277,7 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
|
|||||||
uploadSignatureEnabled: signatureTypes.includes(DocumentSignatureType.UPLOAD),
|
uploadSignatureEnabled: signatureTypes.includes(DocumentSignatureType.UPLOAD),
|
||||||
envelopeExpirationPeriod,
|
envelopeExpirationPeriod,
|
||||||
reminderSettings,
|
reminderSettings,
|
||||||
|
includeAuditLog,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -892,6 +905,35 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="meta.includeAuditLog"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<FormControl>
|
||||||
|
<Checkbox
|
||||||
|
id="include-audit-log"
|
||||||
|
checked={field.value}
|
||||||
|
disabled={field.disabled || envelopeHasBeenSent}
|
||||||
|
onCheckedChange={(checked) => field.onChange(Boolean(checked))}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormLabel className="ml-2 text-muted-foreground text-sm" htmlFor="include-audit-log">
|
||||||
|
<Trans>Include audit logs in downloaded PDF</Trans>
|
||||||
|
</FormLabel>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FormDescription>
|
||||||
|
<Trans>
|
||||||
|
Audit logs remain available to download separately from the document logs page.
|
||||||
|
</Trans>
|
||||||
|
</FormDescription>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
{!isEmbedded && (
|
{!isEmbedded && (
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@@ -0,0 +1,208 @@
|
|||||||
|
import { getDocumentByToken } from '@documenso/lib/server-only/document/get-document-by-token';
|
||||||
|
import { getEnvelopeItemPdfUrl } from '@documenso/lib/utils/envelope-download';
|
||||||
|
import { prisma } from '@documenso/prisma';
|
||||||
|
import { PDF } from '@libpdf/core';
|
||||||
|
import { expect, type Page, test } from '@playwright/test';
|
||||||
|
import { DocumentStatus } from '@prisma/client';
|
||||||
|
import { apiCreateTestContext, apiSeedDraftDocument, apiSeedPendingDocument } from '../fixtures/api-seeds';
|
||||||
|
import { apiSignin } from '../fixtures/authentication';
|
||||||
|
import { signSignaturePad } from '../fixtures/signature';
|
||||||
|
|
||||||
|
type TeamDocumentSettings = {
|
||||||
|
includeAuditLog?: boolean;
|
||||||
|
includeSigningCertificate?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateTeamDocumentSettings = async (teamId: number, data: TeamDocumentSettings) => {
|
||||||
|
const teamSettings = await prisma.teamGlobalSettings.findFirstOrThrow({
|
||||||
|
where: {
|
||||||
|
team: {
|
||||||
|
id: teamId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.teamGlobalSettings.update({
|
||||||
|
where: {
|
||||||
|
id: teamSettings.id,
|
||||||
|
},
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFirstEnvelopeItemSignedPageCount = async (envelopeId: string, token: string) => {
|
||||||
|
const envelopeItem = await prisma.envelopeItem.findFirstOrThrow({
|
||||||
|
where: {
|
||||||
|
envelopeId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const documentUrl = getEnvelopeItemPdfUrl({
|
||||||
|
type: 'download',
|
||||||
|
envelopeItem,
|
||||||
|
token,
|
||||||
|
version: 'signed',
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await fetch(documentUrl);
|
||||||
|
|
||||||
|
expect(response.ok).toBe(true);
|
||||||
|
|
||||||
|
const pdfData = await response.arrayBuffer();
|
||||||
|
const pdfDoc = await PDF.load(new Uint8Array(pdfData));
|
||||||
|
|
||||||
|
return pdfDoc.getPageCount();
|
||||||
|
};
|
||||||
|
|
||||||
|
const completeSigning = async ({
|
||||||
|
page,
|
||||||
|
signingUrl,
|
||||||
|
recipientToken,
|
||||||
|
fieldId,
|
||||||
|
}: {
|
||||||
|
page: Page;
|
||||||
|
signingUrl: string;
|
||||||
|
recipientToken: string;
|
||||||
|
fieldId: number;
|
||||||
|
}) => {
|
||||||
|
await page.goto(signingUrl);
|
||||||
|
|
||||||
|
await signSignaturePad(page);
|
||||||
|
|
||||||
|
await page.locator(`#field-${fieldId}`).getByRole('button').click();
|
||||||
|
await expect(page.locator(`#field-${fieldId}`)).toHaveAttribute('data-inserted', 'true');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Complete' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Sign' }).click({ force: true });
|
||||||
|
await page.waitForURL(/\/complete$/);
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
|
const { status } = await getDocumentByToken({
|
||||||
|
token: recipientToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(status).toBe(DocumentStatus.COMPLETED);
|
||||||
|
}).toPass();
|
||||||
|
};
|
||||||
|
|
||||||
|
test.describe('Document audit log embedding', () => {
|
||||||
|
test('new documents derive audit-log embedding from team settings', async ({ request }) => {
|
||||||
|
const context = await apiCreateTestContext('e2e-audit-log-default');
|
||||||
|
|
||||||
|
await updateTeamDocumentSettings(context.team.id, {
|
||||||
|
includeAuditLog: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { envelope } = await apiSeedDraftDocument(request, {
|
||||||
|
context,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(envelope.documentMeta.includeAuditLog).toBe(true);
|
||||||
|
|
||||||
|
await updateTeamDocumentSettings(context.team.id, {
|
||||||
|
includeAuditLog: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const documentMeta = await prisma.documentMeta.findFirstOrThrow({
|
||||||
|
where: {
|
||||||
|
id: envelope.documentMeta.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(documentMeta.includeAuditLog).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('meta.includeAuditLog true appends audit-log pages when team default is false', async ({ page, request }) => {
|
||||||
|
const context = await apiCreateTestContext('e2e-audit-log-override-true');
|
||||||
|
|
||||||
|
await updateTeamDocumentSettings(context.team.id, {
|
||||||
|
includeAuditLog: false,
|
||||||
|
includeSigningCertificate: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { distributeResult, envelope } = await apiSeedPendingDocument(request, {
|
||||||
|
context,
|
||||||
|
meta: {
|
||||||
|
includeAuditLog: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(envelope.documentMeta.includeAuditLog).toBe(true);
|
||||||
|
|
||||||
|
const signer = distributeResult.recipients[0];
|
||||||
|
const signatureField = envelope.fields.find((field) => field.recipientId === signer.id);
|
||||||
|
|
||||||
|
if (!signatureField) {
|
||||||
|
throw new Error('Signature field not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const baselinePageCount = await getFirstEnvelopeItemSignedPageCount(envelope.id, signer.token);
|
||||||
|
|
||||||
|
await completeSigning({
|
||||||
|
page,
|
||||||
|
signingUrl: signer.signingUrl,
|
||||||
|
recipientToken: signer.token,
|
||||||
|
fieldId: signatureField.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
|
const signedPageCount = await getFirstEnvelopeItemSignedPageCount(envelope.id, signer.token);
|
||||||
|
|
||||||
|
expect(signedPageCount).toBe(baselinePageCount + 1);
|
||||||
|
}).toPass();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('meta.includeAuditLog false skips embedded audit logs when team default is true', async ({ page, request }) => {
|
||||||
|
const context = await apiCreateTestContext('e2e-audit-log-override-false');
|
||||||
|
|
||||||
|
await updateTeamDocumentSettings(context.team.id, {
|
||||||
|
includeAuditLog: true,
|
||||||
|
includeSigningCertificate: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { distributeResult, envelope, team, user } = await apiSeedPendingDocument(request, {
|
||||||
|
context,
|
||||||
|
meta: {
|
||||||
|
includeAuditLog: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(envelope.documentMeta.includeAuditLog).toBe(false);
|
||||||
|
|
||||||
|
const signer = distributeResult.recipients[0];
|
||||||
|
const signatureField = envelope.fields.find((field) => field.recipientId === signer.id);
|
||||||
|
|
||||||
|
if (!signatureField) {
|
||||||
|
throw new Error('Signature field not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const baselinePageCount = await getFirstEnvelopeItemSignedPageCount(envelope.id, signer.token);
|
||||||
|
|
||||||
|
await completeSigning({
|
||||||
|
page,
|
||||||
|
signingUrl: signer.signingUrl,
|
||||||
|
recipientToken: signer.token,
|
||||||
|
fieldId: signatureField.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
|
const signedPageCount = await getFirstEnvelopeItemSignedPageCount(envelope.id, signer.token);
|
||||||
|
|
||||||
|
expect(signedPageCount).toBe(baselinePageCount);
|
||||||
|
}).toPass();
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: user.email,
|
||||||
|
redirectPath: `/t/${team.url}/documents/${envelope.id}/logs`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const downloadPromise = page.waitForEvent('download');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Download Audit Logs' }).click();
|
||||||
|
|
||||||
|
const download = await downloadPromise;
|
||||||
|
|
||||||
|
expect(download.suggestedFilename()).toContain('Audit Logs.pdf');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -177,7 +177,7 @@ export const run = async ({ payload, io }: { payload: TSealDocumentJobDefinition
|
|||||||
const usePlaywrightPdf = NEXT_PRIVATE_USE_PLAYWRIGHT_PDF();
|
const usePlaywrightPdf = NEXT_PRIVATE_USE_PLAYWRIGHT_PDF();
|
||||||
|
|
||||||
const needsCertificate = settings.includeSigningCertificate;
|
const needsCertificate = settings.includeSigningCertificate;
|
||||||
const needsAuditLog = settings.includeAuditLog;
|
const needsAuditLog = envelope.documentMeta.includeAuditLog;
|
||||||
|
|
||||||
const newDocumentData: Array<{ oldDocumentDataId: string; newDocumentDataId: string }> = [];
|
const newDocumentData: Array<{ oldDocumentDataId: string; newDocumentDataId: string }> = [];
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-log
|
|||||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData, diffDocumentMetaChanges } from '@documenso/lib/utils/document-audit-logs';
|
import { createDocumentAuditLogData, diffDocumentMetaChanges } from '@documenso/lib/utils/document-audit-logs';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { type DocumentDistributionMethod, type DocumentSigningOrder, EnvelopeType } from '@prisma/client';
|
import {
|
||||||
|
type DocumentDistributionMethod,
|
||||||
|
type DocumentSigningOrder,
|
||||||
|
EnvelopeType,
|
||||||
|
RecipientRole,
|
||||||
|
SendStatus,
|
||||||
|
} from '@prisma/client';
|
||||||
|
|
||||||
import type { SupportedLanguageCodes } from '../../constants/i18n';
|
import type { SupportedLanguageCodes } from '../../constants/i18n';
|
||||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||||
@@ -25,6 +31,7 @@ export type CreateDocumentMetaOptions = {
|
|||||||
signingOrder?: DocumentSigningOrder;
|
signingOrder?: DocumentSigningOrder;
|
||||||
allowDictateNextSigner?: boolean;
|
allowDictateNextSigner?: boolean;
|
||||||
distributionMethod?: DocumentDistributionMethod;
|
distributionMethod?: DocumentDistributionMethod;
|
||||||
|
includeAuditLog?: boolean;
|
||||||
typedSignatureEnabled?: boolean;
|
typedSignatureEnabled?: boolean;
|
||||||
uploadSignatureEnabled?: boolean;
|
uploadSignatureEnabled?: boolean;
|
||||||
drawSignatureEnabled?: boolean;
|
drawSignatureEnabled?: boolean;
|
||||||
@@ -47,6 +54,7 @@ export const updateDocumentMeta = async ({
|
|||||||
emailReplyTo,
|
emailReplyTo,
|
||||||
emailSettings,
|
emailSettings,
|
||||||
distributionMethod,
|
distributionMethod,
|
||||||
|
includeAuditLog,
|
||||||
typedSignatureEnabled,
|
typedSignatureEnabled,
|
||||||
uploadSignatureEnabled,
|
uploadSignatureEnabled,
|
||||||
drawSignatureEnabled,
|
drawSignatureEnabled,
|
||||||
@@ -91,6 +99,28 @@ export const updateDocumentMeta = async ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
envelope.type === EnvelopeType.DOCUMENT &&
|
||||||
|
includeAuditLog !== undefined &&
|
||||||
|
includeAuditLog !== envelope.documentMeta.includeAuditLog
|
||||||
|
) {
|
||||||
|
const sentRecipientCount = await prisma.recipient.count({
|
||||||
|
where: {
|
||||||
|
envelopeId: envelope.id,
|
||||||
|
role: {
|
||||||
|
not: RecipientRole.CC,
|
||||||
|
},
|
||||||
|
sendStatus: SendStatus.SENT,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (sentRecipientCount > 0) {
|
||||||
|
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||||
|
message: 'Audit log embedding can only be changed before the document is sent',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return await prisma.$transaction(async (tx) => {
|
return await prisma.$transaction(async (tx) => {
|
||||||
const upsertedDocumentMeta = await tx.documentMeta.update({
|
const upsertedDocumentMeta = await tx.documentMeta.update({
|
||||||
where: {
|
where: {
|
||||||
@@ -108,6 +138,7 @@ export const updateDocumentMeta = async ({
|
|||||||
emailReplyTo,
|
emailReplyTo,
|
||||||
emailSettings,
|
emailSettings,
|
||||||
distributionMethod,
|
distributionMethod,
|
||||||
|
includeAuditLog,
|
||||||
typedSignatureEnabled,
|
typedSignatureEnabled,
|
||||||
uploadSignatureEnabled,
|
uploadSignatureEnabled,
|
||||||
drawSignatureEnabled,
|
drawSignatureEnabled,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export const ZEnvelopeForSigningResponse = z.object({
|
|||||||
documentMeta: DocumentMetaSchema.pick({
|
documentMeta: DocumentMetaSchema.pick({
|
||||||
signingOrder: true,
|
signingOrder: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
timezone: true,
|
timezone: true,
|
||||||
dateFormat: true,
|
dateFormat: true,
|
||||||
redirectUrl: true,
|
redirectUrl: true,
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ import type { CreateDocumentAuditLogDataResponse } from '@documenso/lib/utils/do
|
|||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { DocumentMeta, DocumentVisibility, Prisma, TemplateType } from '@prisma/client';
|
import type { DocumentMeta, DocumentVisibility, Prisma, TemplateType } from '@prisma/client';
|
||||||
import { DocumentStatus, EnvelopeType, FolderType, WebhookTriggerEvents } from '@prisma/client';
|
import {
|
||||||
|
DocumentStatus,
|
||||||
|
EnvelopeType,
|
||||||
|
FolderType,
|
||||||
|
RecipientRole,
|
||||||
|
SendStatus,
|
||||||
|
WebhookTriggerEvents,
|
||||||
|
} from '@prisma/client';
|
||||||
import { isDeepEqual } from 'remeda';
|
import { isDeepEqual } from 'remeda';
|
||||||
|
|
||||||
import { TEAM_DOCUMENT_VISIBILITY_MAP } from '../../constants/teams';
|
import { TEAM_DOCUMENT_VISIBILITY_MAP } from '../../constants/teams';
|
||||||
@@ -137,6 +144,28 @@ export const updateEnvelope = async ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
envelope.type === EnvelopeType.DOCUMENT &&
|
||||||
|
meta.includeAuditLog !== undefined &&
|
||||||
|
meta.includeAuditLog !== envelope.documentMeta.includeAuditLog
|
||||||
|
) {
|
||||||
|
const sentRecipientCount = await prisma.recipient.count({
|
||||||
|
where: {
|
||||||
|
envelopeId: envelope.id,
|
||||||
|
role: {
|
||||||
|
not: RecipientRole.CC,
|
||||||
|
},
|
||||||
|
sendStatus: SendStatus.SENT,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (sentRecipientCount > 0) {
|
||||||
|
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||||
|
message: 'Audit log embedding can only be changed before the document is sent',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let folderUpdateQuery: Prisma.FolderUpdateOneWithoutEnvelopesNestedInput | undefined;
|
let folderUpdateQuery: Prisma.FolderUpdateOneWithoutEnvelopesNestedInput | undefined;
|
||||||
|
|
||||||
// Validate folder ID.
|
// Validate folder ID.
|
||||||
@@ -182,11 +211,6 @@ export const updateEnvelope = async ({
|
|||||||
const isGlobalActionSame =
|
const isGlobalActionSame =
|
||||||
documentGlobalActionAuth === undefined || isDeepEqual(documentGlobalActionAuth, newGlobalActionAuth);
|
documentGlobalActionAuth === undefined || isDeepEqual(documentGlobalActionAuth, newGlobalActionAuth);
|
||||||
const isDocumentVisibilitySame = data.visibility === undefined || data.visibility === envelope.visibility;
|
const isDocumentVisibilitySame = data.visibility === undefined || data.visibility === envelope.visibility;
|
||||||
const isFolderSame = data.folderId === undefined || data.folderId === envelope.folderId;
|
|
||||||
const isTemplateTypeSame = data.templateType === undefined || data.templateType === envelope.templateType;
|
|
||||||
const isPublicDescriptionSame =
|
|
||||||
data.publicDescription === undefined || data.publicDescription === envelope.publicDescription;
|
|
||||||
const isPublicTitleSame = data.publicTitle === undefined || data.publicTitle === envelope.publicTitle;
|
|
||||||
|
|
||||||
const auditLogs: CreateDocumentAuditLogDataResponse[] = [];
|
const auditLogs: CreateDocumentAuditLogDataResponse[] = [];
|
||||||
|
|
||||||
@@ -266,36 +290,6 @@ export const updateEnvelope = async ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Decide if we want to log moving the document around.
|
|
||||||
// if (!isFolderSame) {
|
|
||||||
// auditLogs.push(
|
|
||||||
// createDocumentAuditLogData({
|
|
||||||
// type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FOLDER_UPDATED,
|
|
||||||
// envelopeId: envelope.id,
|
|
||||||
// metadata: requestMetadata,
|
|
||||||
// data: {
|
|
||||||
// from: envelope.folderId,
|
|
||||||
// to: data.folderId || '',
|
|
||||||
// },
|
|
||||||
// }),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Todo: Determine if changes are made
|
|
||||||
// Commented out since we didn't detect the changes to sequence.
|
|
||||||
// const isMetaSame = isDeepEqual(envelope.documentMeta, meta);
|
|
||||||
// Early return if nothing is required.
|
|
||||||
// if (
|
|
||||||
// auditLogs.length === 0 &&
|
|
||||||
// data.useLegacyFieldInsertion === undefined &&
|
|
||||||
// isFolderSame &&
|
|
||||||
// isTemplateTypeSame &&
|
|
||||||
// isPublicDescriptionSame &&
|
|
||||||
// isPublicTitleSame
|
|
||||||
// ) {
|
|
||||||
// return envelope;
|
|
||||||
// }
|
|
||||||
|
|
||||||
const updatedEnvelope = await prisma.$transaction(async (tx) => {
|
const updatedEnvelope = await prisma.$transaction(async (tx) => {
|
||||||
const result = await tx.envelope.update({
|
const result = await tx.envelope.update({
|
||||||
where: {
|
where: {
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ export type CreateDocumentFromTemplateOptions = {
|
|||||||
language?: SupportedLanguageCodes;
|
language?: SupportedLanguageCodes;
|
||||||
distributionMethod?: DocumentDistributionMethod;
|
distributionMethod?: DocumentDistributionMethod;
|
||||||
allowDictateNextSigner?: boolean;
|
allowDictateNextSigner?: boolean;
|
||||||
|
includeAuditLog?: boolean;
|
||||||
emailSettings?: TDocumentEmailSettings;
|
emailSettings?: TDocumentEmailSettings;
|
||||||
typedSignatureEnabled?: boolean;
|
typedSignatureEnabled?: boolean;
|
||||||
uploadSignatureEnabled?: boolean;
|
uploadSignatureEnabled?: boolean;
|
||||||
@@ -513,6 +514,7 @@ export const createDocumentFromTemplate = async ({
|
|||||||
dateFormat: override?.dateFormat || template.documentMeta?.dateFormat,
|
dateFormat: override?.dateFormat || template.documentMeta?.dateFormat,
|
||||||
redirectUrl: override?.redirectUrl || template.documentMeta?.redirectUrl,
|
redirectUrl: override?.redirectUrl || template.documentMeta?.redirectUrl,
|
||||||
distributionMethod: override?.distributionMethod || template.documentMeta?.distributionMethod,
|
distributionMethod: override?.distributionMethod || template.documentMeta?.distributionMethod,
|
||||||
|
includeAuditLog: override?.includeAuditLog ?? template.documentMeta?.includeAuditLog,
|
||||||
emailSettings: override?.emailSettings || template.documentMeta?.emailSettings,
|
emailSettings: override?.emailSettings || template.documentMeta?.emailSettings,
|
||||||
signingOrder: override?.signingOrder || template.documentMeta?.signingOrder,
|
signingOrder: override?.signingOrder || template.documentMeta?.signingOrder,
|
||||||
language: override?.language || template.documentMeta?.language || settings.documentLanguage,
|
language: override?.language || template.documentMeta?.language || settings.documentLanguage,
|
||||||
@@ -666,7 +668,7 @@ export const createDocumentFromTemplate = async ({
|
|||||||
|
|
||||||
const date = new Date(selector.value);
|
const date = new Date(selector.value);
|
||||||
|
|
||||||
if (isNaN(date.getTime())) {
|
if (Number.isNaN(date.getTime())) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||||
message: `Invalid date value for field ${field.id}: ${selector.value}`,
|
message: `Invalid date value for field ${field.id}: ${selector.value}`,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ export const generateSampleWebhookPayload = (event: WebhookTriggerEvents, webhoo
|
|||||||
drawSignatureEnabled: true,
|
drawSignatureEnabled: true,
|
||||||
language: 'en',
|
language: 'en',
|
||||||
distributionMethod: DocumentDistributionMethod.EMAIL,
|
distributionMethod: DocumentDistributionMethod.EMAIL,
|
||||||
|
includeAuditLog: false,
|
||||||
emailSettings: null,
|
emailSettings: null,
|
||||||
},
|
},
|
||||||
recipients: [
|
recipients: [
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { ZDocumentEmailSettingsSchema } from './document-email';
|
|||||||
export const ZDocumentMetaSchema = DocumentMetaSchema.pick({
|
export const ZDocumentMetaSchema = DocumentMetaSchema.pick({
|
||||||
signingOrder: true,
|
signingOrder: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
id: true,
|
id: true,
|
||||||
subject: true,
|
subject: true,
|
||||||
message: true,
|
message: true,
|
||||||
@@ -93,6 +94,10 @@ export const ZDocumentMetaDistributionMethodSchema = z
|
|||||||
.nativeEnum(DocumentDistributionMethod)
|
.nativeEnum(DocumentDistributionMethod)
|
||||||
.describe('The distribution method to use when sending the document to the recipients.');
|
.describe('The distribution method to use when sending the document to the recipients.');
|
||||||
|
|
||||||
|
export const ZDocumentMetaIncludeAuditLogSchema = z
|
||||||
|
.boolean()
|
||||||
|
.describe('Whether to include the audit logs in the sealed document PDF.');
|
||||||
|
|
||||||
export const ZDocumentMetaTypedSignatureEnabledSchema = z
|
export const ZDocumentMetaTypedSignatureEnabledSchema = z
|
||||||
.boolean()
|
.boolean()
|
||||||
.describe('Whether to allow recipients to sign using a typed signature.');
|
.describe('Whether to allow recipients to sign using a typed signature.');
|
||||||
@@ -116,6 +121,7 @@ export const ZDocumentMetaCreateSchema = z.object({
|
|||||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||||
|
includeAuditLog: ZDocumentMetaIncludeAuditLogSchema.optional(),
|
||||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||||
allowDictateNextSigner: z.boolean().optional(),
|
allowDictateNextSigner: z.boolean().optional(),
|
||||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ export const ZDocumentSchema = LegacyDocumentSchema.pick({
|
|||||||
documentMeta: DocumentMetaSchema.pick({
|
documentMeta: DocumentMetaSchema.pick({
|
||||||
signingOrder: true,
|
signingOrder: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
id: true,
|
id: true,
|
||||||
subject: true,
|
subject: true,
|
||||||
message: true,
|
message: true,
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ export const ZEditorEnvelopeSchema = EnvelopeSchema.pick({
|
|||||||
documentMeta: DocumentMetaSchema.pick({
|
documentMeta: DocumentMetaSchema.pick({
|
||||||
signingOrder: true,
|
signingOrder: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
id: true,
|
id: true,
|
||||||
subject: true,
|
subject: true,
|
||||||
message: true,
|
message: true,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export const ZEnvelopeSchema = EnvelopeSchema.pick({
|
|||||||
documentMeta: DocumentMetaSchema.pick({
|
documentMeta: DocumentMetaSchema.pick({
|
||||||
signingOrder: true,
|
signingOrder: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
id: true,
|
id: true,
|
||||||
subject: true,
|
subject: true,
|
||||||
message: true,
|
message: true,
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export const ZTemplateSchema = TemplateSchema.pick({
|
|||||||
drawSignatureEnabled: true,
|
drawSignatureEnabled: true,
|
||||||
allowDictateNextSigner: true,
|
allowDictateNextSigner: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
redirectUrl: true,
|
redirectUrl: true,
|
||||||
language: true,
|
language: true,
|
||||||
emailSettings: true,
|
emailSettings: true,
|
||||||
@@ -149,6 +150,7 @@ export const ZTemplateManySchema = TemplateSchema.pick({
|
|||||||
templateMeta: DocumentMetaSchema.pick({
|
templateMeta: DocumentMetaSchema.pick({
|
||||||
signingOrder: true,
|
signingOrder: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
}).nullable(),
|
}).nullable(),
|
||||||
directLink: LegacyTemplateDirectLinkSchema.pick({
|
directLink: LegacyTemplateDirectLinkSchema.pick({
|
||||||
token: true,
|
token: true,
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export const ZWebhookDocumentMetaSchema = z.object({
|
|||||||
drawSignatureEnabled: z.boolean(),
|
drawSignatureEnabled: z.boolean(),
|
||||||
language: z.string(),
|
language: z.string(),
|
||||||
distributionMethod: z.nativeEnum(DocumentDistributionMethod),
|
distributionMethod: z.nativeEnum(DocumentDistributionMethod),
|
||||||
|
includeAuditLog: z.boolean(),
|
||||||
emailSettings: z.any().nullable(),
|
emailSettings: z.any().nullable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export const extractDerivedDocumentMeta = (
|
|||||||
signingOrder: meta.signingOrder || DocumentSigningOrder.PARALLEL,
|
signingOrder: meta.signingOrder || DocumentSigningOrder.PARALLEL,
|
||||||
allowDictateNextSigner: meta.allowDictateNextSigner ?? false,
|
allowDictateNextSigner: meta.allowDictateNextSigner ?? false,
|
||||||
distributionMethod: meta.distributionMethod || DocumentDistributionMethod.EMAIL, // Todo: Make this a setting.
|
distributionMethod: meta.distributionMethod || DocumentDistributionMethod.EMAIL, // Todo: Make this a setting.
|
||||||
|
includeAuditLog: meta.includeAuditLog ?? settings.includeAuditLog,
|
||||||
|
|
||||||
// Signature settings.
|
// Signature settings.
|
||||||
typedSignatureEnabled: meta.typedSignatureEnabled ?? settings.typedSignatureEnabled,
|
typedSignatureEnabled: meta.typedSignatureEnabled ?? settings.typedSignatureEnabled,
|
||||||
|
|||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "DocumentMeta" ADD COLUMN "includeAuditLog" BOOLEAN NOT NULL DEFAULT false;
|
||||||
@@ -524,6 +524,7 @@ model DocumentMeta {
|
|||||||
|
|
||||||
language String @default("en")
|
language String @default("en")
|
||||||
distributionMethod DocumentDistributionMethod @default(EMAIL)
|
distributionMethod DocumentDistributionMethod @default(EMAIL)
|
||||||
|
includeAuditLog Boolean @default(false)
|
||||||
|
|
||||||
emailSettings Json? /// [DocumentEmailSettings] @zod.custom.use(ZDocumentEmailSettingsSchema)
|
emailSettings Json? /// [DocumentEmailSettings] @zod.custom.use(ZDocumentEmailSettingsSchema)
|
||||||
emailReplyTo String?
|
emailReplyTo String?
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export const distributeDocumentRoute = authenticatedProcedure
|
|||||||
timezone: meta.timezone,
|
timezone: meta.timezone,
|
||||||
redirectUrl: meta.redirectUrl,
|
redirectUrl: meta.redirectUrl,
|
||||||
distributionMethod: meta.distributionMethod,
|
distributionMethod: meta.distributionMethod,
|
||||||
|
includeAuditLog: meta.includeAuditLog,
|
||||||
emailSettings: meta.emailSettings ?? undefined,
|
emailSettings: meta.emailSettings ?? undefined,
|
||||||
language: meta.language,
|
language: meta.language,
|
||||||
emailId: meta.emailId,
|
emailId: meta.emailId,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-emai
|
|||||||
import {
|
import {
|
||||||
ZDocumentMetaDateFormatSchema,
|
ZDocumentMetaDateFormatSchema,
|
||||||
ZDocumentMetaDistributionMethodSchema,
|
ZDocumentMetaDistributionMethodSchema,
|
||||||
|
ZDocumentMetaIncludeAuditLogSchema,
|
||||||
ZDocumentMetaLanguageSchema,
|
ZDocumentMetaLanguageSchema,
|
||||||
ZDocumentMetaMessageSchema,
|
ZDocumentMetaMessageSchema,
|
||||||
ZDocumentMetaRedirectUrlSchema,
|
ZDocumentMetaRedirectUrlSchema,
|
||||||
@@ -33,6 +34,7 @@ export const ZDistributeDocumentRequestSchema = z.object({
|
|||||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||||
|
includeAuditLog: ZDocumentMetaIncludeAuditLogSchema.optional(),
|
||||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||||
language: ZDocumentMetaLanguageSchema.optional(),
|
language: ZDocumentMetaLanguageSchema.optional(),
|
||||||
emailId: z.string().nullish(),
|
emailId: z.string().nullish(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
ZDocumentMetaDateFormatSchema,
|
ZDocumentMetaDateFormatSchema,
|
||||||
ZDocumentMetaDistributionMethodSchema,
|
ZDocumentMetaDistributionMethodSchema,
|
||||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||||
|
ZDocumentMetaIncludeAuditLogSchema,
|
||||||
ZDocumentMetaLanguageSchema,
|
ZDocumentMetaLanguageSchema,
|
||||||
ZDocumentMetaMessageSchema,
|
ZDocumentMetaMessageSchema,
|
||||||
ZDocumentMetaRedirectUrlSchema,
|
ZDocumentMetaRedirectUrlSchema,
|
||||||
@@ -59,6 +60,7 @@ export const ZCreateEmbeddingDocumentRequestSchema = z.object({
|
|||||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||||
|
includeAuditLog: ZDocumentMetaIncludeAuditLogSchema.optional(),
|
||||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||||
language: ZDocumentMetaLanguageSchema.optional(),
|
language: ZDocumentMetaLanguageSchema.optional(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
ZDocumentMetaDateFormatSchema,
|
ZDocumentMetaDateFormatSchema,
|
||||||
ZDocumentMetaDistributionMethodSchema,
|
ZDocumentMetaDistributionMethodSchema,
|
||||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||||
|
ZDocumentMetaIncludeAuditLogSchema,
|
||||||
ZDocumentMetaLanguageSchema,
|
ZDocumentMetaLanguageSchema,
|
||||||
ZDocumentMetaMessageSchema,
|
ZDocumentMetaMessageSchema,
|
||||||
ZDocumentMetaRedirectUrlSchema,
|
ZDocumentMetaRedirectUrlSchema,
|
||||||
@@ -56,6 +57,7 @@ export const ZCreateEmbeddingTemplateRequestSchema = z.object({
|
|||||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||||
|
includeAuditLog: ZDocumentMetaIncludeAuditLogSchema.optional(),
|
||||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||||
language: ZDocumentMetaLanguageSchema.optional(),
|
language: ZDocumentMetaLanguageSchema.optional(),
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export const ZGetMultiSignDocumentResponseSchema = ZDocumentLiteSchema.extend({
|
|||||||
documentMeta: DocumentMetaSchema.pick({
|
documentMeta: DocumentMetaSchema.pick({
|
||||||
signingOrder: true,
|
signingOrder: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
id: true,
|
id: true,
|
||||||
subject: true,
|
subject: true,
|
||||||
message: true,
|
message: true,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
ZDocumentMetaDateFormatSchema,
|
ZDocumentMetaDateFormatSchema,
|
||||||
ZDocumentMetaDistributionMethodSchema,
|
ZDocumentMetaDistributionMethodSchema,
|
||||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||||
|
ZDocumentMetaIncludeAuditLogSchema,
|
||||||
ZDocumentMetaLanguageSchema,
|
ZDocumentMetaLanguageSchema,
|
||||||
ZDocumentMetaMessageSchema,
|
ZDocumentMetaMessageSchema,
|
||||||
ZDocumentMetaRedirectUrlSchema,
|
ZDocumentMetaRedirectUrlSchema,
|
||||||
@@ -60,6 +61,7 @@ export const ZUpdateEmbeddingDocumentRequestSchema = z.object({
|
|||||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||||
|
includeAuditLog: ZDocumentMetaIncludeAuditLogSchema.optional(),
|
||||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||||
language: ZDocumentMetaLanguageSchema.optional(),
|
language: ZDocumentMetaLanguageSchema.optional(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
ZDocumentMetaDateFormatSchema,
|
ZDocumentMetaDateFormatSchema,
|
||||||
ZDocumentMetaDistributionMethodSchema,
|
ZDocumentMetaDistributionMethodSchema,
|
||||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||||
|
ZDocumentMetaIncludeAuditLogSchema,
|
||||||
ZDocumentMetaLanguageSchema,
|
ZDocumentMetaLanguageSchema,
|
||||||
ZDocumentMetaMessageSchema,
|
ZDocumentMetaMessageSchema,
|
||||||
ZDocumentMetaRedirectUrlSchema,
|
ZDocumentMetaRedirectUrlSchema,
|
||||||
@@ -60,6 +61,7 @@ export const ZUpdateEmbeddingTemplateRequestSchema = z.object({
|
|||||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||||
|
includeAuditLog: ZDocumentMetaIncludeAuditLogSchema.optional(),
|
||||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||||
language: ZDocumentMetaLanguageSchema.optional(),
|
language: ZDocumentMetaLanguageSchema.optional(),
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export const distributeEnvelopeRoute = authenticatedProcedure
|
|||||||
timezone: meta.timezone,
|
timezone: meta.timezone,
|
||||||
redirectUrl: meta.redirectUrl,
|
redirectUrl: meta.redirectUrl,
|
||||||
distributionMethod: meta.distributionMethod,
|
distributionMethod: meta.distributionMethod,
|
||||||
|
includeAuditLog: meta.includeAuditLog,
|
||||||
emailSettings: meta.emailSettings ?? undefined,
|
emailSettings: meta.emailSettings ?? undefined,
|
||||||
language: meta.language,
|
language: meta.language,
|
||||||
emailId: meta.emailId,
|
emailId: meta.emailId,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export const ZDistributeEnvelopeRequestSchema = z.object({
|
|||||||
timezone: true,
|
timezone: true,
|
||||||
dateFormat: true,
|
dateFormat: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
redirectUrl: true,
|
redirectUrl: true,
|
||||||
language: true,
|
language: true,
|
||||||
emailId: true,
|
emailId: true,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
ZDocumentMetaDateFormatSchema,
|
ZDocumentMetaDateFormatSchema,
|
||||||
ZDocumentMetaDistributionMethodSchema,
|
ZDocumentMetaDistributionMethodSchema,
|
||||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||||
|
ZDocumentMetaIncludeAuditLogSchema,
|
||||||
ZDocumentMetaLanguageSchema,
|
ZDocumentMetaLanguageSchema,
|
||||||
ZDocumentMetaMessageSchema,
|
ZDocumentMetaMessageSchema,
|
||||||
ZDocumentMetaRedirectUrlSchema,
|
ZDocumentMetaRedirectUrlSchema,
|
||||||
@@ -89,6 +90,7 @@ export const ZUseEnvelopePayloadSchema = z.object({
|
|||||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||||
|
includeAuditLog: ZDocumentMetaIncludeAuditLogSchema.optional(),
|
||||||
emailSettings: ZDocumentEmailSettingsSchema.optional(),
|
emailSettings: ZDocumentEmailSettingsSchema.optional(),
|
||||||
language: ZDocumentMetaLanguageSchema.optional(),
|
language: ZDocumentMetaLanguageSchema.optional(),
|
||||||
typedSignatureEnabled: ZDocumentMetaTypedSignatureEnabledSchema.optional(),
|
typedSignatureEnabled: ZDocumentMetaTypedSignatureEnabledSchema.optional(),
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ export const getTemplatesByIdsRoute = authenticatedProcedure
|
|||||||
select: {
|
select: {
|
||||||
signingOrder: true,
|
signingOrder: true,
|
||||||
distributionMethod: true,
|
distributionMethod: true,
|
||||||
|
includeAuditLog: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
directLink: {
|
directLink: {
|
||||||
@@ -106,6 +107,7 @@ export const getTemplatesByIdsRoute = authenticatedProcedure
|
|||||||
? {
|
? {
|
||||||
signingOrder: envelope.documentMeta.signingOrder,
|
signingOrder: envelope.documentMeta.signingOrder,
|
||||||
distributionMethod: envelope.documentMeta.distributionMethod,
|
distributionMethod: envelope.documentMeta.distributionMethod,
|
||||||
|
includeAuditLog: envelope.documentMeta.includeAuditLog,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
directLink: envelope.directLink
|
directLink: envelope.directLink
|
||||||
|
|||||||
Reference in New Issue
Block a user