From dce5a64ec5738be9cdffe47fd7472539e0e6634a Mon Sep 17 00:00:00 2001 From: Weiko Date: Wed, 7 Aug 2024 11:45:17 +0200 Subject: [PATCH] Fix images in note rich text (#6550) ## Before Screenshot 2024-08-06 at 11 20 06 ## After Screenshot 2024-08-06 at 11 20 09 --- .../activity-query-result-getter.handler.ts | 57 +++++++++++++++++++ .../attachment-query-result-getter.handler.ts | 6 +- .../person-query-result-getter.handler.ts | 2 +- ...pace-member-query-result-getter.handler.ts | 2 +- .../query-result-getters.factory.ts | 3 + .../file/file-upload/file-upload.module.ts | 4 +- .../services/file-upload.service.spec.ts | 32 ----------- .../services/file-upload.service.ts | 12 +++- .../engine/core-modules/file/file.module.ts | 3 +- 9 files changed, 81 insertions(+), 40 deletions(-) create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/activity-query-result-getter.handler.ts delete mode 100644 packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.spec.ts diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/activity-query-result-getter.handler.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/activity-query-result-getter.handler.ts new file mode 100644 index 000000000..aa6da51f4 --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/activity-query-result-getter.handler.ts @@ -0,0 +1,57 @@ +import { QueryResultGetterHandlerInterface } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-getter-handler.interface'; + +import { FileService } from 'src/engine/core-modules/file/services/file.service'; +import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.workspace-entity'; +import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; + +type RichTextBlock = Record; + +type RichTextBody = RichTextBlock[]; + +export class ActivityQueryResultGetterHandler + implements QueryResultGetterHandlerInterface +{ + constructor(private readonly fileService: FileService) {} + + async handle( + activity: TaskWorkspaceEntity | NoteWorkspaceEntity, + workspaceId: string, + ): Promise { + if (!activity.id || !activity.body) { + return activity; + } + + const body: RichTextBody = JSON.parse(activity.body); + + const bodyWithSignedPayload = await Promise.all( + body.map(async (block: RichTextBlock) => { + if (block.type !== 'image' || !block.props.url) { + return block; + } + + const imageProps = block.props; + const imageUrl = new URL(imageProps.url); + + imageUrl.searchParams.delete('token'); + + const signedPayload = await this.fileService.encodeFileToken({ + note_block_id: block.id, + workspace_id: workspaceId, + }); + + return { + ...block, + props: { + ...imageProps, + url: `${imageUrl.toString()}?token=${signedPayload}`, + }, + }; + }), + ); + + return { + ...activity, + body: JSON.stringify(bodyWithSignedPayload), + }; + } +} diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/attachment-query-result-getter.handler.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/attachment-query-result-getter.handler.ts index 909c313cc..d6e642ba6 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/attachment-query-result-getter.handler.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/attachment-query-result-getter.handler.ts @@ -1,13 +1,17 @@ import { QueryResultGetterHandlerInterface } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-getter-handler.interface'; import { FileService } from 'src/engine/core-modules/file/services/file.service'; +import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; export class AttachmentQueryResultGetterHandler implements QueryResultGetterHandlerInterface { constructor(private readonly fileService: FileService) {} - async handle(attachment: any, workspaceId: string): Promise { + async handle( + attachment: AttachmentWorkspaceEntity, + workspaceId: string, + ): Promise { if (!attachment.id || !attachment?.fullPath) { return attachment; } diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/person-query-result-getter.handler.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/person-query-result-getter.handler.ts index 17410286a..4b6dfb114 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/person-query-result-getter.handler.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/person-query-result-getter.handler.ts @@ -11,7 +11,7 @@ export class PersonQueryResultGetterHandler async handle( person: PersonWorkspaceEntity, workspaceId: string, - ): Promise { + ): Promise { if (!person.id || !person?.avatarUrl) { return person; } diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/workspace-member-query-result-getter.handler.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/workspace-member-query-result-getter.handler.ts index 06dead059..34a94f833 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/workspace-member-query-result-getter.handler.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/workspace-member-query-result-getter.handler.ts @@ -11,7 +11,7 @@ export class WorkspaceMemberQueryResultGetterHandler async handle( workspaceMember: WorkspaceMemberWorkspaceEntity, workspaceId: string, - ): Promise { + ): Promise { if (!workspaceMember.id || !workspaceMember?.avatarUrl) { return workspaceMember; } diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/query-result-getters.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/query-result-getters.factory.ts index 047217f42..1f3b72b76 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/query-result-getters.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/query-result-getters.factory.ts @@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common'; import { QueryResultGetterHandlerInterface } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-getter-handler.interface'; import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; +import { ActivityQueryResultGetterHandler } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/activity-query-result-getter.handler'; import { AttachmentQueryResultGetterHandler } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/attachment-query-result-getter.handler'; import { PersonQueryResultGetterHandler } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/person-query-result-getter.handler'; import { WorkspaceMemberQueryResultGetterHandler } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/workspace-member-query-result-getter.handler'; @@ -24,6 +25,8 @@ export class QueryResultGettersFactory { 'workspaceMember', new WorkspaceMemberQueryResultGetterHandler(this.fileService), ], + ['note', new ActivityQueryResultGetterHandler(this.fileService)], + ['task', new ActivityQueryResultGetterHandler(this.fileService)], ]); } diff --git a/packages/twenty-server/src/engine/core-modules/file/file-upload/file-upload.module.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/file-upload.module.ts index 5af72bd7a..d33c45f7a 100644 --- a/packages/twenty-server/src/engine/core-modules/file/file-upload/file-upload.module.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file-upload/file-upload.module.ts @@ -1,10 +1,12 @@ import { Module } from '@nestjs/common'; -import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { FileUploadResolver } from 'src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver'; import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; +import { FileModule } from 'src/engine/core-modules/file/file.module'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Module({ + imports: [FileModule], providers: [FileUploadService, FileUploadResolver, EnvironmentService], exports: [FileUploadService, FileUploadResolver], }) diff --git a/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.spec.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.spec.ts deleted file mode 100644 index c972a27c4..000000000 --- a/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; - -import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service'; - -import { FileUploadService } from './file-upload.service'; - -describe('FileUploadService', () => { - let service: FileUploadService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - FileUploadService, - { - provide: FileStorageService, - useValue: {}, - }, - { - provide: EnvironmentService, - useValue: {}, - }, - ], - }).compile(); - - service = module.get(FileUploadService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.ts index a50f5a012..e408178e8 100644 --- a/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.ts @@ -8,12 +8,16 @@ import { v4 as uuidV4 } from 'uuid'; import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; import { settings } from 'src/engine/constants/settings'; +import { FileService } from 'src/engine/core-modules/file/services/file.service'; import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service'; import { getCropSize } from 'src/utils/image'; @Injectable() export class FileUploadService { - constructor(private readonly fileStorage: FileStorageService) {} + constructor( + private readonly fileStorage: FileStorageService, + private readonly fileService: FileService, + ) {} private async _uploadFile({ file, @@ -78,10 +82,14 @@ export class FileUploadService { folder, }); + const signedPayload = await this.fileService.encodeFileToken({ + workspace_id: workspaceId, + }); + return { id, mimeType, - path: `${fileFolder}/${name}`, + path: `${fileFolder}/${name}?token=${signedPayload}`, }; } diff --git a/packages/twenty-server/src/engine/core-modules/file/file.module.ts b/packages/twenty-server/src/engine/core-modules/file/file.module.ts index dc9de78fd..c7d4c838c 100644 --- a/packages/twenty-server/src/engine/core-modules/file/file.module.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file.module.ts @@ -1,6 +1,5 @@ import { Module } from '@nestjs/common'; -import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module'; import { FilePathGuard } from 'src/engine/core-modules/file/guards/file-path-guard'; import { JwtModule } from 'src/engine/core-modules/jwt/jwt.module'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @@ -9,7 +8,7 @@ import { FileController } from './controllers/file.controller'; import { FileService } from './services/file.service'; @Module({ - imports: [FileUploadModule, JwtModule], + imports: [JwtModule], providers: [FileService, EnvironmentService, FilePathGuard], exports: [FileService], controllers: [FileController],