mirror of
https://github.com/documenso/documenso.git
synced 2025-11-18 02:32:00 +10:00
feat: audit logs for copying links
This commit is contained in:
@ -39,6 +39,7 @@ export const ZDocumentAuditLogTypeSchema = z.enum([
|
||||
'DOCUMENT_TITLE_UPDATED', // When the document title is updated.
|
||||
'DOCUMENT_EXTERNAL_ID_UPDATED', // When the document external ID is updated.
|
||||
'DOCUMENT_MOVED_TO_TEAM', // When the document is moved to a team.
|
||||
'DOCUMENT_SIGNING_LINK_COPIED', // When a signing link is copied.
|
||||
]);
|
||||
|
||||
export const ZDocumentAuditLogEmailTypeSchema = z.enum([
|
||||
@ -225,6 +226,16 @@ export const ZDocumentAuditLogEventDocumentDeletedSchema = z.object({
|
||||
}),
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Document signing link copied.
|
||||
*/
|
||||
export const ZDocumentAuditLogEventDocumentSigningLinkCopiedSchema = z.object({
|
||||
type: z.literal(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_SIGNING_LINK_COPIED),
|
||||
data: ZBaseRecipientDataSchema.extend({
|
||||
isBulkCopy: z.boolean(),
|
||||
}),
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Document field inserted.
|
||||
*/
|
||||
@ -490,6 +501,7 @@ export const ZDocumentAuditLogSchema = ZDocumentAuditLogBaseSchema.and(
|
||||
ZDocumentAuditLogEventDocumentCompletedSchema,
|
||||
ZDocumentAuditLogEventDocumentCreatedSchema,
|
||||
ZDocumentAuditLogEventDocumentDeletedSchema,
|
||||
ZDocumentAuditLogEventDocumentSigningLinkCopiedSchema,
|
||||
ZDocumentAuditLogEventDocumentMovedToTeamSchema,
|
||||
ZDocumentAuditLogEventDocumentFieldInsertedSchema,
|
||||
ZDocumentAuditLogEventDocumentFieldUninsertedSchema,
|
||||
|
||||
@ -385,6 +385,10 @@ export const formatDocumentAuditLogAction = (
|
||||
anonymous: msg`Document completed`,
|
||||
identified: msg`Document completed`,
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_SIGNING_LINK_COPIED }, () => ({
|
||||
anonymous: msg`Document signing link copied`,
|
||||
identified: msg`${prefix} copied the document signing link`,
|
||||
}))
|
||||
.exhaustive();
|
||||
|
||||
return {
|
||||
|
||||
@ -25,6 +25,8 @@ import { sendDocument } from '@documenso/lib/server-only/document/send-document'
|
||||
import { updateDocument } from '@documenso/lib/server-only/document/update-document';
|
||||
import { symmetricEncrypt } from '@documenso/lib/universal/crypto';
|
||||
import { getPresignPostUrl } from '@documenso/lib/universal/upload/server-actions';
|
||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { DocumentDataType, DocumentStatus } from '@documenso/prisma/client';
|
||||
|
||||
import { authenticatedProcedure, procedure, router } from '../trpc';
|
||||
@ -626,4 +628,37 @@ export const documentRouter = router({
|
||||
url: `${NEXT_PUBLIC_WEBAPP_URL()}/__htmltopdf/certificate?d=${encrypted}`,
|
||||
};
|
||||
}),
|
||||
|
||||
createAuditLog: authenticatedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
documentId: z.number(),
|
||||
type: z.literal('DOCUMENT_SIGNING_LINK_COPIED'),
|
||||
data: z.object({
|
||||
recipientEmail: z.string(),
|
||||
recipientName: z.string(),
|
||||
recipientId: z.number(),
|
||||
recipientRole: z.string(),
|
||||
isBulkCopy: z.boolean(),
|
||||
}),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { documentId, type, data } = input;
|
||||
|
||||
console.log('input', input);
|
||||
console.log('copiedddd');
|
||||
|
||||
const auditLog = await prisma.documentAuditLog.create({
|
||||
data: createDocumentAuditLogData({
|
||||
type,
|
||||
data,
|
||||
documentId,
|
||||
user: ctx.user,
|
||||
metadata: ctx.metadata,
|
||||
}),
|
||||
});
|
||||
|
||||
return auditLog;
|
||||
}),
|
||||
});
|
||||
|
||||
@ -16,6 +16,7 @@ import {
|
||||
DocumentStatus,
|
||||
RecipientRole,
|
||||
} from '@documenso/prisma/client';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { DocumentSendEmailMessageHelper } from '@documenso/ui/components/document/document-send-email-message-helper';
|
||||
import { Tabs, TabsList, TabsTrigger } from '@documenso/ui/primitives/tabs';
|
||||
|
||||
@ -58,6 +59,8 @@ export const AddSubjectFormPartial = ({
|
||||
}: AddSubjectFormProps) => {
|
||||
const { _ } = useLingui();
|
||||
|
||||
const { mutateAsync: createAuditLog } = trpc.document.createAuditLog.useMutation();
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
@ -98,6 +101,25 @@ export const AddSubjectFormPartial = ({
|
||||
const onFormSubmit = handleSubmit(onSubmit);
|
||||
const { currentStep, totalSteps, previousStep } = useStep();
|
||||
|
||||
const onCopyLink = (recipient: Recipient) => {
|
||||
toast({
|
||||
title: _(msg`Copied to clipboard`),
|
||||
description: _(msg`The signing link has been copied to your clipboard.`),
|
||||
});
|
||||
|
||||
void createAuditLog({
|
||||
documentId: document.id,
|
||||
type: 'DOCUMENT_SIGNING_LINK_COPIED',
|
||||
data: {
|
||||
recipientEmail: recipient.email,
|
||||
recipientName: recipient.name,
|
||||
recipientId: recipient.id,
|
||||
recipientRole: recipient.role,
|
||||
isBulkCopy: false,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DocumentFlowFormContainerHeader
|
||||
@ -236,14 +258,7 @@ export const AddSubjectFormPartial = ({
|
||||
{recipient.role !== RecipientRole.CC && (
|
||||
<CopyTextButton
|
||||
value={formatSigningLink(recipient.token)}
|
||||
onCopySuccess={() => {
|
||||
toast({
|
||||
title: _(msg`Copied to clipboard`),
|
||||
description: _(
|
||||
msg`The signing link has been copied to your clipboard.`,
|
||||
),
|
||||
});
|
||||
}}
|
||||
onCopySuccess={() => void onCopyLink(recipient)}
|
||||
badgeContentUncopied={
|
||||
<p className="ml-1 text-xs">
|
||||
<Trans>Copy</Trans>
|
||||
|
||||
Reference in New Issue
Block a user