diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface.ts b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface.ts index bd0f9a107..d7779124a 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface.ts @@ -25,4 +25,5 @@ export interface StorageDriver { folderPath: string; filename: string; }): Promise; + checkFolderExists(folderPath: string): Promise; } diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/local.driver.ts b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/local.driver.ts index e7fb17135..d524c0d3d 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/local.driver.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/local.driver.ts @@ -175,4 +175,10 @@ export class LocalDriver implements StorageDriver { return existsSync(filePath); } + + async checkFolderExists(folderPath: string): Promise { + const folderFullPath = join(this.options.storagePath, folderPath); + + return existsSync(folderFullPath); + } } diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/s3.driver.ts b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/s3.driver.ts index 219fa73ff..fb9d56b9e 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/s3.driver.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/s3.driver.ts @@ -417,4 +417,24 @@ export class S3Driver implements StorageDriver { return true; } + + async checkFolderExists(folderPath: string): Promise { + try { + const listCommand = new ListObjectsV2Command({ + Bucket: this.bucketName, + Prefix: folderPath, + MaxKeys: 1, + }); + + const result = await this.s3Client.send(listCommand); + + return (result.Contents && result.Contents.length > 0) || false; + } catch (error) { + if (error instanceof NotFound) { + return false; + } + + throw error; + } + } } diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts b/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts index ace0d2c7a..716687414 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts @@ -70,4 +70,10 @@ export class FileStorageService implements StorageDriver { return driver.checkFileExists(params); } + + checkFolderExists(folderPath: string): Promise { + const driver = this.fileStorageDriverFactory.getCurrentDriver(); + + return driver.checkFolderExists(folderPath); + } } diff --git a/packages/twenty-server/src/engine/core-modules/file/services/file.service.ts b/packages/twenty-server/src/engine/core-modules/file/services/file.service.ts index 6e570b469..ed06b50f8 100644 --- a/packages/twenty-server/src/engine/core-modules/file/services/file.service.ts +++ b/packages/twenty-server/src/engine/core-modules/file/services/file.service.ts @@ -93,6 +93,13 @@ export class FileService { async deleteWorkspaceFolder(workspaceId: string) { const workspaceFolderPath = `workspace-${workspaceId}`; + const isWorkspaceFolderFound = + await this.fileStorageService.checkFolderExists(workspaceFolderPath); + + if (!isWorkspaceFolderFound) { + return; + } + return await this.fileStorageService.delete({ folderPath: workspaceFolderPath, });