diff --git a/packages/server/src/api/controllers/Attachments/AttachmentsController.ts b/packages/server/src/api/controllers/Attachments/AttachmentsController.ts index ba41db541..657aa0240 100644 --- a/packages/server/src/api/controllers/Attachments/AttachmentsController.ts +++ b/packages/server/src/api/controllers/Attachments/AttachmentsController.ts @@ -4,12 +4,16 @@ import { Router, Response, NextFunction, Request } from 'express'; import { body, param } from 'express-validator'; import BaseController from '@/api/controllers/BaseController'; import { AttachmentsApplication } from '@/services/Attachments/AttachmentsApplication'; +import { AttachmentUploadPipeline } from '@/services/Attachments/S3UploadPipeline'; @Service() export class AttachmentsController extends BaseController { @Inject() private attachmentsApplication: AttachmentsApplication; + @Inject() + private uploadPipelineService: AttachmentUploadPipeline; + /** * Router constructor. */ @@ -18,7 +22,8 @@ export class AttachmentsController extends BaseController { router.post( '/', - this.attachmentsApplication.uploadPipeline.single('file'), + this.uploadPipelineService.validateS3Configured, + this.uploadPipelineService.uploadPipeline().single('file'), this.validateUploadedFileExistance, this.uploadAttachment.bind(this) ); diff --git a/packages/server/src/config/index.ts b/packages/server/src/config/index.ts index a9e2212b1..8172ddace 100644 --- a/packages/server/src/config/index.ts +++ b/packages/server/src/config/index.ts @@ -235,6 +235,6 @@ module.exports = { accessKeyId: process.env.S3_ACCESS_KEY_ID, secretAccessKey: process.env.S3_SECRET_ACCESS_KEY, endpoint: process.env.S3_ENDPOINT, - bucket: process.env.S3_BUCKET, + bucket: process.env.S3_BUCKET || 'bigcapital-documents', }, }; diff --git a/packages/server/src/services/Attachments/AttachmentsApplication.ts b/packages/server/src/services/Attachments/AttachmentsApplication.ts index ce297d3ba..2cf7c08f1 100644 --- a/packages/server/src/services/Attachments/AttachmentsApplication.ts +++ b/packages/server/src/services/Attachments/AttachmentsApplication.ts @@ -2,11 +2,9 @@ import { Inject, Service } from 'typedi'; import { UploadDocument } from './UploadDocument'; import { DeleteAttachment } from './DeleteAttachment'; import { GetAttachment } from './GetAttachment'; -import { AttachmentUploadPipeline } from './S3UploadPipeline'; import { LinkAttachment } from './LinkAttachment'; import { UnlinkAttachment } from './UnlinkAttachment'; import { getAttachmentPresignedUrl } from './GetAttachmentPresignedUrl'; -import type { Multer } from 'multer'; @Service() export class AttachmentsApplication { @@ -19,9 +17,6 @@ export class AttachmentsApplication { @Inject() private getDocumentService: GetAttachment; - @Inject() - private uploadPipelineService: AttachmentUploadPipeline; - @Inject() private linkDocumentService: LinkAttachment; @@ -31,14 +26,6 @@ export class AttachmentsApplication { @Inject() private getPresignedUrlService: getAttachmentPresignedUrl; - /** - * Express middleware for uploading attachments to an S3 bucket. - * @returns {Multer} - */ - get uploadPipeline(): Multer { - return this.uploadPipelineService.uploadPipeline(); - } - /** * Saves the metadata of uploaded document to S3 on database. * @param {number} tenantId diff --git a/packages/server/src/services/Attachments/S3UploadPipeline.ts b/packages/server/src/services/Attachments/S3UploadPipeline.ts index c79d2855f..b2443e318 100644 --- a/packages/server/src/services/Attachments/S3UploadPipeline.ts +++ b/packages/server/src/services/Attachments/S3UploadPipeline.ts @@ -1,12 +1,38 @@ import multer from 'multer'; -import type { Multer } from 'multer' +import type { Multer } from 'multer'; import multerS3 from 'multer-s3'; import { s3 } from '@/lib/S3/S3'; import { Service } from 'typedi'; import config from '@/config'; +import { NextFunction, Request, Response } from 'express'; @Service() export class AttachmentUploadPipeline { + /** + * Middleware to ensure that S3 configuration is properly set before proceeding. + * This function checks if the necessary S3 configuration keys are present and throws an error if any are missing. + * + * @param req The HTTP request object. + * @param res The HTTP response object. + * @param next The callback to pass control to the next middleware function. + */ + public validateS3Configured(req: Request, res: Response, next: NextFunction) { + if ( + !config.s3.region || + !config.s3.accessKeyId || + !config.s3.secretAccessKey + ) { + const missingKeys = []; + if (!config.s3.region) missingKeys.push('region'); + if (!config.s3.accessKeyId) missingKeys.push('accessKeyId'); + if (!config.s3.secretAccessKey) missingKeys.push('secretAccessKey'); + const missing = missingKeys.join(', '); + + throw new Error(`S3 configuration error: Missing ${missing}`); + } + next(); + } + /** * Express middleware for uploading attachments to an S3 bucket. * It utilizes the multer middleware for handling multipart/form-data, specifically for file uploads.