From aa4a0fe43817a2eaf698f8b6e84356eb3e436ae3 Mon Sep 17 00:00:00 2001 From: yassinedorbozgithub Date: Wed, 29 Jan 2025 11:06:23 +0100 Subject: [PATCH] fix: make logout close sockets --- api/src/user/controllers/auth.controller.ts | 15 ++++++++++++++- api/src/websocket/websocket.gateway.ts | 15 +++++++++++++-- api/types/event-emitter.d.ts | 3 ++- package-lock.json | 4 ++-- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/api/src/user/controllers/auth.controller.ts b/api/src/user/controllers/auth.controller.ts index 559bc2ee..5a49cb53 100644 --- a/api/src/user/controllers/auth.controller.ts +++ b/api/src/user/controllers/auth.controller.ts @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Hexastack. All rights reserved. + * Copyright © 2025 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. @@ -11,6 +11,8 @@ import { Body, Controller, Get, + Headers, + Inject, InternalServerErrorException, Param, Post, @@ -21,7 +23,9 @@ import { UseGuards, UseInterceptors, } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; import { CsrfCheck, CsrfGen, CsrfGenAuth } from '@tekuconcept/nestjs-csrf'; +import cookie from 'cookie'; import { Request, Response } from 'express'; import { Session as ExpressSession } from 'express-session'; @@ -38,6 +42,9 @@ import { UserService } from '../services/user.service'; import { ValidateAccountService } from '../services/validate-account.service'; export class BaseAuthController { + @Inject(EventEmitter2) + private readonly eventEmitter: EventEmitter2; + constructor(protected readonly logger: LoggerService) {} /** @@ -66,7 +73,13 @@ export class BaseAuthController { logout( @Session() session: ExpressSession, @Res({ passthrough: true }) res: Response, + @Headers() headers: Record, ) { + const parsedCookie = cookie.parse(headers['cookie']); + const sessionCookie = encodeURIComponent( + String(parsedCookie[config.session.name] || ''), + ); + this.eventEmitter.emit('hook:websocket:session_data', sessionCookie); res.clearCookie(config.session.name); session.destroy((error) => { diff --git a/api/src/websocket/websocket.gateway.ts b/api/src/websocket/websocket.gateway.ts index 10c7c628..85ab1a72 100644 --- a/api/src/websocket/websocket.gateway.ts +++ b/api/src/websocket/websocket.gateway.ts @@ -1,12 +1,12 @@ /* - * Copyright © 2024 Hexastack. All rights reserved. + * Copyright © 2025 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). */ -import { EventEmitter2 } from '@nestjs/event-emitter'; +import { EventEmitter2, OnEvent } from '@nestjs/event-emitter'; import { ConnectedSocket, MessageBody, @@ -258,6 +258,17 @@ export class WebsocketGateway this.eventEmitter.emit(`hook:websocket:connection`, client); } + @OnEvent('hook:websocket:session_data') + disconnectSockets(sessionCookie: string) { + if (sessionCookie.length) { + for (const [socketId, socket] of this.io.sockets.sockets) { + if (socket.handshake.headers.cookie?.includes(sessionCookie)) { + this.io.sockets.sockets.get(socketId)?.disconnect(true); + } + } + } + } + async handleDisconnect(client: Socket): Promise { this.logger.log(`Client id:${client.id} disconnected`); // Configurable custom afterDisconnect logic here diff --git a/api/types/event-emitter.d.ts b/api/types/event-emitter.d.ts index a39d15cf..4c46f1ea 100644 --- a/api/types/event-emitter.d.ts +++ b/api/types/event-emitter.d.ts @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Hexastack. All rights reserved. + * Copyright © 2025 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. @@ -116,6 +116,7 @@ declare module '@nestjs/event-emitter' { object, { connection: Socket; + session_data: string; } >; } diff --git a/package-lock.json b/package-lock.json index 2372b00e..a201be15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "hexabot", - "version": "2.2.2", + "version": "2.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "hexabot", - "version": "2.2.2", + "version": "2.2.3", "license": "AGPL-3.0-only", "workspaces": [ "frontend",