From 0244f021ab224c6718bc607ec88a4a8c87b38272 Mon Sep 17 00:00:00 2001 From: Catalin Pit <25515812+catalinpit@users.noreply.github.com> Date: Fri, 9 Aug 2024 04:19:48 +0200 Subject: [PATCH] fix: download audit log certificate (#1268) Previously, it wasn't possible to download an audit log of a document uploaded by another user because the function used the ID of the user making the request to retrieve the document. However, the document uploaded by another user has that user's ID, not the ID of the user making the request. --- .../documents/[id]/logs/document-logs-page-view.tsx | 2 +- .../[id]/logs/download-audit-log-button.tsx | 9 +++++++-- packages/trpc/server/document-router/router.ts | 12 ++++++++++-- packages/trpc/server/document-router/schema.ts | 5 +++++ 4 files changed, 23 insertions(+), 5 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 cf68173dc..2069247fb 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,7 +139,7 @@ export const DocumentLogsPageView = async ({ params, team }: DocumentLogsPageVie documentStatus={document.status} /> - + diff --git a/apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx b/apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx index 0847d63fa..8b662f5ce 100644 --- a/apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx +++ b/apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx @@ -9,10 +9,15 @@ import { useToast } from '@documenso/ui/primitives/use-toast'; export type DownloadAuditLogButtonProps = { className?: string; + teamId?: number; documentId: number; }; -export const DownloadAuditLogButton = ({ className, documentId }: DownloadAuditLogButtonProps) => { +export const DownloadAuditLogButton = ({ + className, + teamId, + documentId, +}: DownloadAuditLogButtonProps) => { const { toast } = useToast(); const { mutateAsync: downloadAuditLogs, isLoading } = @@ -20,7 +25,7 @@ export const DownloadAuditLogButton = ({ className, documentId }: DownloadAuditL const onDownloadAuditLogsClick = async () => { try { - const { url } = await downloadAuditLogs({ documentId }); + const { url } = await downloadAuditLogs({ teamId, documentId }); const iframe = Object.assign(document.createElement('iframe'), { src: url, diff --git a/packages/trpc/server/document-router/router.ts b/packages/trpc/server/document-router/router.ts index 07726b451..85c87e3b6 100644 --- a/packages/trpc/server/document-router/router.ts +++ b/packages/trpc/server/document-router/router.ts @@ -29,6 +29,7 @@ import { ZCreateDocumentMutationSchema, ZDeleteDraftDocumentMutationSchema as ZDeleteDocumentMutationSchema, ZDownloadAuditLogsMutationSchema, + ZDownloadCertificateMutationSchema, ZFindDocumentAuditLogsQuerySchema, ZGetDocumentByIdQuerySchema, ZGetDocumentByTokenQuerySchema, @@ -411,7 +412,14 @@ export const documentRouter = router({ id: documentId, userId: ctx.user.id, teamId, - }); + }).catch(() => null); + + if (!document || document.teamId !== teamId) { + throw new TRPCError({ + code: 'FORBIDDEN', + message: 'You do not have access to this document.', + }); + } const encrypted = encryptSecondaryData({ data: document.id.toString(), @@ -433,7 +441,7 @@ export const documentRouter = router({ }), downloadCertificate: authenticatedProcedure - .input(ZDownloadAuditLogsMutationSchema) + .input(ZDownloadCertificateMutationSchema) .mutation(async ({ input, ctx }) => { try { const { documentId, teamId } = input; diff --git a/packages/trpc/server/document-router/schema.ts b/packages/trpc/server/document-router/schema.ts index 80efc7c15..31e049173 100644 --- a/packages/trpc/server/document-router/schema.ts +++ b/packages/trpc/server/document-router/schema.ts @@ -172,6 +172,11 @@ export const ZDownloadAuditLogsMutationSchema = z.object({ teamId: z.number().optional(), }); +export const ZDownloadCertificateMutationSchema = z.object({ + documentId: z.number(), + teamId: z.number().optional(), +}); + export const ZMoveDocumentsToTeamSchema = z.object({ documentId: z.number(), teamId: z.number(),