Merge pull request #553 from oleynikd/attachments

Download attachments (documents) with original filenames
This commit is contained in:
Ahmed Bouhuolia
2024-08-02 02:42:52 +02:00
committed by GitHub
4 changed files with 26 additions and 9 deletions

View File

@@ -250,10 +250,12 @@ export class AttachmentsController extends BaseController {
res: Response, res: Response,
next: NextFunction next: NextFunction
): Promise<Response | void> { ): Promise<Response | void> {
const { tenantId } = req;
const { id: documentKey } = req.params; const { id: documentKey } = req.params;
try { try {
const presignedUrl = await this.attachmentsApplication.getPresignedUrl( const presignedUrl = await this.attachmentsApplication.getPresignedUrl(
tenantId,
documentKey documentKey
); );
return res.status(200).send({ presignedUrl }); return res.status(200).send({ presignedUrl });

View File

@@ -96,10 +96,11 @@ export class AttachmentsApplication {
/** /**
* Retrieves the presigned url of the given attachment key. * Retrieves the presigned url of the given attachment key.
* @param {number} tenantId
* @param {string} key * @param {string} key
* @returns {Promise<string>} * @returns {Promise<string>}
*/ */
public getPresignedUrl(key: string): Promise<string> { public getPresignedUrl(tenantId: number, key: string): Promise<string> {
return this.getPresignedUrlService.getPresignedUrl(key); return this.getPresignedUrlService.getPresignedUrl(tenantId, key);
} }
} }

View File

@@ -1,20 +1,34 @@
import { Service } from 'typedi'; import { Inject, Service } from 'typedi';
import { GetObjectCommand } from '@aws-sdk/client-s3'; import { GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { s3 } from '@/lib/S3/S3'; import { s3 } from '@/lib/S3/S3';
import config from '@/config'; import config from '@/config';
import HasTenancyService from '../Tenancy/TenancyService';
@Service() @Service()
export class getAttachmentPresignedUrl { 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 * @param {string} key
* @returns {Promise<string?>} * @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({ const command = new GetObjectCommand({
Bucket: config.s3.bucket, Bucket: config.s3.bucket,
Key: key, Key: key,
ResponseContentDisposition,
}); });
const signedUrl = await getSignedUrl(s3, command, { expiresIn: 300 }); const signedUrl = await getSignedUrl(s3, command, { expiresIn: 300 });

View File

@@ -9,7 +9,7 @@ export function useUploadAttachments(props) {
const apiRequest = useApiRequest(); const apiRequest = useApiRequest();
return useMutation( return useMutation(
(values) => apiRequest.post('/attachments', values), (values) => apiRequest.post('attachments', values),
props, props,
); );
} }
@@ -21,7 +21,7 @@ export function useDeleteAttachment(props) {
const apiRequest = useApiRequest(); const apiRequest = useApiRequest();
return useMutation( return useMutation(
(key: string) => apiRequest.delete(`/attachments/${key}`), (key: string) => apiRequest.delete(`attachments/${key}`),
props, props,
); );
} }
@@ -35,7 +35,7 @@ export function useGetPresignedUrlAttachment(props) {
return useMutation( return useMutation(
(key: string) => (key: string) =>
apiRequest apiRequest
.get(`/attachments/${key}/presigned-url`) .get(`attachments/${key}/presigned-url`)
.then((res) => res.data), .then((res) => res.data),
props, props,
); );