From 1480e8d7b2dcb4ddb7fb8a866dfa3425900f0550 Mon Sep 17 00:00:00 2001 From: Bastian Wagner Date: Mon, 9 Mar 2026 12:59:59 +0100 Subject: [PATCH] =?UTF-8?q?Unregister=20&=20Unsubscribe=20vom=20SSE=20f?= =?UTF-8?q?=C3=BCr=20Keys=20eingebaut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../realtime/sse/sse.controller.spec.ts | 5 ++-- .../modules/realtime/sse/sse.controller.ts | 8 +++++-- .../modules/realtime/sse/sse.service.spec.ts | 24 +++++++++++++++++++ api/src/modules/realtime/sse/sse.service.ts | 8 +++++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/api/src/modules/realtime/sse/sse.controller.spec.ts b/api/src/modules/realtime/sse/sse.controller.spec.ts index 169c3ed..467918f 100644 --- a/api/src/modules/realtime/sse/sse.controller.spec.ts +++ b/api/src/modules/realtime/sse/sse.controller.spec.ts @@ -6,6 +6,7 @@ import { JwtService } from '@nestjs/jwt'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { AuthService } from 'src/modules/auth/auth.service'; import { SseService } from './sse.service'; +import { Subject } from 'rxjs'; describe('SseController', () => { let controller: SseController; @@ -18,7 +19,6 @@ describe('SseController', () => { ConfigService, { provide: JwtService, useClass: MockJwTService }, { provide: SseTicketService, useClass: MockSseTicketService }, - { provide: UserService, useClass: MockUserService }, { provide: AuthService, useClass: MockAuthService }, { provide: SseService, useClass: MockSSEService } @@ -56,11 +56,10 @@ class MockSseTicketService { class MockSSEService { register = jest.fn().mockImplementation( (id) => { - return new Promise(resolve => resolve(null)) + return new Subject() }) } -class MockUserService { } class MockJwTService {} class MockAuthService {} \ No newline at end of file diff --git a/api/src/modules/realtime/sse/sse.controller.ts b/api/src/modules/realtime/sse/sse.controller.ts index 2b58de8..a90f9bc 100644 --- a/api/src/modules/realtime/sse/sse.controller.ts +++ b/api/src/modules/realtime/sse/sse.controller.ts @@ -2,7 +2,7 @@ import { Controller, Get, Param, Query, Req, Sse, UnauthorizedException, UseGuar import { AuthenticatedRequest } from 'src/model/interface/authenticated-request.interface'; import { SseTicketService } from './sse-ticket.service'; import { AuthGuard } from 'src/core/guards/auth.guard'; -import { Observable } from 'rxjs'; +import { finalize, Observable } from 'rxjs'; import { SseService } from './sse.service'; @Controller('sse') @@ -23,6 +23,10 @@ export class SseController { if (!userId) throw new UnauthorizedException('Invalid/expired ticket'); - return this.sseService.register(userId); + return this.sseService.register(userId).pipe( + finalize(() => { + this.sseService.unregister(userId) + }) + ); } } diff --git a/api/src/modules/realtime/sse/sse.service.spec.ts b/api/src/modules/realtime/sse/sse.service.spec.ts index 1f6f7ea..ac31252 100644 --- a/api/src/modules/realtime/sse/sse.service.spec.ts +++ b/api/src/modules/realtime/sse/sse.service.spec.ts @@ -1,8 +1,10 @@ import { Test, TestingModule } from '@nestjs/testing'; import { SseService } from './sse.service'; +import { Key } from 'src/model/entitites'; describe('SseService', () => { let service: SseService; + const userId = 'testuserid-54'; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -15,4 +17,26 @@ describe('SseService', () => { it('should be defined', () => { expect(service).toBeDefined(); }); + + it('should register new SSE clients', () => { + + const res = service.register(userId); + expect(service["clients"].has(userId)).toBeTruthy(); + }); + + it('should send keys to User', () => { + const sub = service.register(userId); + const key = new Key(); + const keyId = 'testkey-123'; + key.id = keyId; + sub.subscribe({ + next: val => { + expect(val.data).toBeTruthy(); + + expect(val.data[0]?.id).toBe(keyId) + } + }) + service.sendKeysToUsers(userId, [key]); + + }) }); diff --git a/api/src/modules/realtime/sse/sse.service.ts b/api/src/modules/realtime/sse/sse.service.ts index 8b38bf9..2a4c856 100644 --- a/api/src/modules/realtime/sse/sse.service.ts +++ b/api/src/modules/realtime/sse/sse.service.ts @@ -19,4 +19,12 @@ export class SseService { this.clients.set(userId, subj); return subj; } + + unregister(userId: string) { + if (!this.clients.has(userId)) { return; } + + const sub = this.clients.get(userId); + sub.unsubscribe(); + this.clients.delete(userId); + } }