From d15a8b18d92d2a48c2a7a3b86e9ce7fdb0ac5a51 Mon Sep 17 00:00:00 2001 From: Avinash Date: Thu, 11 May 2023 21:16:48 +0530 Subject: [PATCH] fix(backend): updated realtime connection's acceptEdit, close connection based on permission Signed-off-by: Avinash --- .../src/permissions/permissions.service.ts | 16 ++++----- .../realtime-note/realtime-note.service.ts | 36 ++++++++++++++++--- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/backend/src/permissions/permissions.service.ts b/backend/src/permissions/permissions.service.ts index 6bf3d62ef..14c7d303a 100644 --- a/backend/src/permissions/permissions.service.ts +++ b/backend/src/permissions/permissions.service.ts @@ -191,8 +191,8 @@ export class PermissionsService { return false; } - private notifyOthers(noteId: Note['id']): void { - this.eventEmitter.emit(NoteEvent.PERMISSION_CHANGE, noteId); + private notifyOthers(note: Note): void { + this.eventEmitter.emit(NoteEvent.PERMISSION_CHANGE, note); } /** @@ -256,7 +256,7 @@ export class PermissionsService { createdPermission.note = Promise.resolve(note); (await note.groupPermissions).push(createdPermission); } - this.notifyOthers(note.id); + this.notifyOthers(note); return await this.noteRepository.save(note); } @@ -291,7 +291,7 @@ export class PermissionsService { ); (await note.userPermissions).push(noteUserPermission); } - this.notifyOthers(note.id); + this.notifyOthers(note); return await this.noteRepository.save(note); } @@ -323,7 +323,7 @@ export class PermissionsService { } } note.userPermissions = Promise.resolve(newPermissions); - this.notifyOthers(note.id); + this.notifyOthers(note); return await this.noteRepository.save(note); } @@ -363,7 +363,7 @@ export class PermissionsService { ); (await note.groupPermissions).push(noteGroupPermission); } - this.notifyOthers(note.id); + this.notifyOthers(note); return await this.noteRepository.save(note); } @@ -398,7 +398,7 @@ export class PermissionsService { } } note.groupPermissions = Promise.resolve(newPermissions); - this.notifyOthers(note.id); + this.notifyOthers(note); return await this.noteRepository.save(note); } @@ -411,7 +411,7 @@ export class PermissionsService { */ async changeOwner(note: Note, owner: User): Promise { note.owner = Promise.resolve(owner); - this.notifyOthers(note.id); + this.notifyOthers(note); return await this.noteRepository.save(note); } } diff --git a/backend/src/realtime/realtime-note/realtime-note.service.ts b/backend/src/realtime/realtime-note/realtime-note.service.ts index 6ed01892e..ad13139fe 100644 --- a/backend/src/realtime/realtime-note/realtime-note.service.ts +++ b/backend/src/realtime/realtime-note/realtime-note.service.ts @@ -12,7 +12,9 @@ import appConfiguration, { AppConfig } from '../../config/app.config'; import { NoteEvent } from '../../events'; import { ConsoleLoggerService } from '../../logger/console-logger.service'; import { Note } from '../../notes/note.entity'; +import { PermissionsService } from '../../permissions/permissions.service'; import { RevisionsService } from '../../revisions/revisions.service'; +import { RealtimeConnection } from './realtime-connection'; import { RealtimeNote } from './realtime-note'; import { RealtimeNoteStore } from './realtime-note-store'; @@ -25,6 +27,7 @@ export class RealtimeNoteService implements BeforeApplicationShutdown { private schedulerRegistry: SchedulerRegistry, @Inject(appConfiguration.KEY) private appConfig: AppConfig, + private permissionService: PermissionsService, ) {} beforeApplicationShutdown(): void { @@ -109,13 +112,38 @@ export class RealtimeNoteService implements BeforeApplicationShutdown { } @OnEvent(NoteEvent.PERMISSION_CHANGE) - public handleNotePermissionChanged(noteId: Note['id']): void { - const realtimeNote = this.realtimeNoteStore.find(noteId); - if (realtimeNote) { - realtimeNote.announcePermissionChange(); + public async handleNotePermissionChanged(note: Note): Promise { + const realtimeNote = this.realtimeNoteStore.find(note.id); + if (!realtimeNote) return; + + realtimeNote.announcePermissionChange(); + const allConnections = realtimeNote.getConnections(); + await this.updateOrCloseConnection(allConnections, note); + } + + private async updateOrCloseConnection( + connections: RealtimeConnection[], + note: Note, + ): Promise { + for (const connection of connections) { + if (await this.connectionCanRead(connection, note)) { + connection.acceptEdits = await this.permissionService.mayWrite( + connection.getUser(), + note, + ); + } else { + connection.getTransporter().disconnect(); + } } } + private async connectionCanRead( + connection: RealtimeConnection, + note: Note, + ): Promise { + return await this.permissionService.mayRead(connection.getUser(), note); + } + @OnEvent(NoteEvent.DELETION) public handleNoteDeleted(noteId: Note['id']): void { const realtimeNote = this.realtimeNoteStore.find(noteId);