From 832cdacebf5f2b61aebbb014a215f6746a17146b Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 30 Jul 2024 23:48:15 +0300 Subject: [PATCH 1/2] Download attachments with original filenames --- .../Attachments/AttachmentsController.ts | 2 ++ .../Attachments/AttachmentsApplication.ts | 5 +++-- .../Attachments/GetAttachmentPresignedUrl.ts | 22 +++++++++++++++---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/server/src/api/controllers/Attachments/AttachmentsController.ts b/packages/server/src/api/controllers/Attachments/AttachmentsController.ts index 657aa0240..ad75ef550 100644 --- a/packages/server/src/api/controllers/Attachments/AttachmentsController.ts +++ b/packages/server/src/api/controllers/Attachments/AttachmentsController.ts @@ -250,10 +250,12 @@ export class AttachmentsController extends BaseController { res: Response, next: NextFunction ): Promise { + const { tenantId } = req; const { id: documentKey } = req.params; try { const presignedUrl = await this.attachmentsApplication.getPresignedUrl( + tenantId, documentKey ); return res.status(200).send({ presignedUrl }); diff --git a/packages/server/src/services/Attachments/AttachmentsApplication.ts b/packages/server/src/services/Attachments/AttachmentsApplication.ts index 2cf7c08f1..6e75c9783 100644 --- a/packages/server/src/services/Attachments/AttachmentsApplication.ts +++ b/packages/server/src/services/Attachments/AttachmentsApplication.ts @@ -96,10 +96,11 @@ export class AttachmentsApplication { /** * Retrieves the presigned url of the given attachment key. + * @param {number} tenantId * @param {string} key * @returns {Promise} */ - public getPresignedUrl(key: string): Promise { - return this.getPresignedUrlService.getPresignedUrl(key); + public getPresignedUrl(tenantId: number, key: string): Promise { + return this.getPresignedUrlService.getPresignedUrl(tenantId, key); } } diff --git a/packages/server/src/services/Attachments/GetAttachmentPresignedUrl.ts b/packages/server/src/services/Attachments/GetAttachmentPresignedUrl.ts index 62ca3f91c..b76b5aa4e 100644 --- a/packages/server/src/services/Attachments/GetAttachmentPresignedUrl.ts +++ b/packages/server/src/services/Attachments/GetAttachmentPresignedUrl.ts @@ -1,20 +1,34 @@ -import { Service } from 'typedi'; +import { Inject, Service } from 'typedi'; import { GetObjectCommand } from '@aws-sdk/client-s3'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; import { s3 } from '@/lib/S3/S3'; import config from '@/config'; +import HasTenancyService from '../Tenancy/TenancyService'; @Service() export class getAttachmentPresignedUrl { + @Inject() + private tenancy: HasTenancyService; + /** - * Retrieves the presigned url of the given attachment key. + * Retrieves the presigned url of the given attachment key with the original filename. + * @param {number} tenantId * @param {string} key - * @returns {Promise} + * @returns {string} */ - async getPresignedUrl(key: string) { + async getPresignedUrl(tenantId: number, key: string) { + const { Document } = this.tenancy.models(tenantId); + const foundDocument = await Document.query().findOne({ key }); + + let ResponseContentDisposition = 'attachment'; + if (foundDocument && foundDocument.originName) { + ResponseContentDisposition += `; filename="${foundDocument.originName}"`; + } + const command = new GetObjectCommand({ Bucket: config.s3.bucket, Key: key, + ResponseContentDisposition, }); const signedUrl = await getSignedUrl(s3, command, { expiresIn: 300 }); From a1ddc81dac16ca6209956546a2b8356fd3faa453 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 30 Jul 2024 23:54:46 +0300 Subject: [PATCH 2/2] Fixed double slash in attachments route --- packages/webapp/src/hooks/query/attachments.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/webapp/src/hooks/query/attachments.ts b/packages/webapp/src/hooks/query/attachments.ts index 4255e3d0a..4b92bbbcb 100644 --- a/packages/webapp/src/hooks/query/attachments.ts +++ b/packages/webapp/src/hooks/query/attachments.ts @@ -9,7 +9,7 @@ export function useUploadAttachments(props) { const apiRequest = useApiRequest(); return useMutation( - (values) => apiRequest.post('/attachments', values), + (values) => apiRequest.post('attachments', values), props, ); } @@ -21,7 +21,7 @@ export function useDeleteAttachment(props) { const apiRequest = useApiRequest(); return useMutation( - (key: string) => apiRequest.delete(`/attachments/${key}`), + (key: string) => apiRequest.delete(`attachments/${key}`), props, ); } @@ -35,7 +35,7 @@ export function useGetPresignedUrlAttachment(props) { return useMutation( (key: string) => apiRequest - .get(`/attachments/${key}/presigned-url`) + .get(`attachments/${key}/presigned-url`) .then((res) => res.data), props, );