From 3165d77f602c7548ebe611cf1f4fef0058d82845 Mon Sep 17 00:00:00 2001 From: Jonas Gloning <34194370+jonasgloning@users.noreply.github.com> Date: Thu, 17 Nov 2022 20:54:02 +0100 Subject: [PATCH 1/2] refactor(types): `MyWebSocket` resulted in wrong type hints . --- src/models/client.ts | 12 ++++++------ src/services/webSocketServer/index.ts | 12 ++++++------ src/services/webSocketServer/webSocket.ts | 4 ---- test/messageHandler/handlers/transmission/index.ts | 6 +++--- 4 files changed, 15 insertions(+), 19 deletions(-) delete mode 100644 src/services/webSocketServer/webSocket.ts diff --git a/src/models/client.ts b/src/models/client.ts index f4b12c63c..051219cb0 100644 --- a/src/models/client.ts +++ b/src/models/client.ts @@ -1,13 +1,13 @@ -import { MyWebSocket } from "../services/webSocketServer/webSocket"; +import type WebSocket from "ws"; export interface IClient { getId(): string; getToken(): string; - getSocket(): MyWebSocket | null; + getSocket(): WebSocket | null; - setSocket(socket: MyWebSocket | null): void; + setSocket(socket: WebSocket | null): void; getLastPing(): number; @@ -19,7 +19,7 @@ export interface IClient { export class Client implements IClient { private readonly id: string; private readonly token: string; - private socket: MyWebSocket | null = null; + private socket: WebSocket | null = null; private lastPing: number = new Date().getTime(); constructor({ id, token }: { id: string; token: string; }) { @@ -35,11 +35,11 @@ export class Client implements IClient { return this.token; } - public getSocket(): MyWebSocket | null { + public getSocket(): WebSocket | null { return this.socket; } - public setSocket(socket: MyWebSocket | null): void { + public setSocket(socket: WebSocket | null): void { this.socket = socket; } diff --git a/src/services/webSocketServer/index.ts b/src/services/webSocketServer/index.ts index d9f2c5e7e..553d46b67 100644 --- a/src/services/webSocketServer/index.ts +++ b/src/services/webSocketServer/index.ts @@ -6,7 +6,7 @@ import { IConfig } from "../../config"; import { Errors, MessageType } from "../../enums"; import { Client, IClient } from "../../models/client"; import { IRealm } from "../../models/realm"; -import { MyWebSocket } from "./webSocket"; +import type WebSocket from "ws"; export interface IWebSocketServer extends EventEmitter { readonly path: string; @@ -42,11 +42,11 @@ export class WebSocketServer extends EventEmitter implements IWebSocketServer { this.socketServer = new WebSocketLib.Server({ path: this.path, server }); - this.socketServer.on("connection", (socket: MyWebSocket, req) => this._onSocketConnection(socket, req)); + this.socketServer.on("connection", (socket, req) => this._onSocketConnection(socket, req)); this.socketServer.on("error", (error: Error) => this._onSocketError(error)); } - private _onSocketConnection(socket: MyWebSocket, req: IncomingMessage): void { + private _onSocketConnection(socket: WebSocket, req: IncomingMessage): void { const { query = {} } = url.parse(req.url ?? '', true); const { id, token, key }: IAuthParams = query; @@ -85,7 +85,7 @@ export class WebSocketServer extends EventEmitter implements IWebSocketServer { private _registerClient({ socket, id, token }: { - socket: MyWebSocket; + socket: WebSocket; id: string; token: string; }): void { @@ -103,7 +103,7 @@ export class WebSocketServer extends EventEmitter implements IWebSocketServer { this._configureWS(socket, newClient); } - private _configureWS(socket: MyWebSocket, client: IClient): void { + private _configureWS(socket: WebSocket, client: IClient): void { client.setSocket(socket); // Cleanup after a socket closes. @@ -130,7 +130,7 @@ export class WebSocketServer extends EventEmitter implements IWebSocketServer { this.emit("connection", client); } - private _sendErrorAndClose(socket: MyWebSocket, msg: Errors): void { + private _sendErrorAndClose(socket: WebSocket, msg: Errors): void { socket.send( JSON.stringify({ type: MessageType.ERROR, diff --git a/src/services/webSocketServer/webSocket.ts b/src/services/webSocketServer/webSocket.ts deleted file mode 100644 index 1e045653f..000000000 --- a/src/services/webSocketServer/webSocket.ts +++ /dev/null @@ -1,4 +0,0 @@ -import EventEmitter from "events"; -import WebSocketLib from "ws"; - -export type MyWebSocket = WebSocketLib & EventEmitter; diff --git a/test/messageHandler/handlers/transmission/index.ts b/test/messageHandler/handlers/transmission/index.ts index 83b1ff6c6..59c6c06ca 100644 --- a/test/messageHandler/handlers/transmission/index.ts +++ b/test/messageHandler/handlers/transmission/index.ts @@ -3,9 +3,9 @@ import { Client } from '../../../../src/models/client'; import { TransmissionHandler } from '../../../../src/messageHandler/handlers'; import { Realm } from '../../../../src/models/realm'; import { MessageType } from '../../../../src/enums'; -import { MyWebSocket } from '../../../../src/services/webSocketServer/webSocket'; +import type WebSocket from "ws"; -const createFakeSocket = (): MyWebSocket => { +const createFakeSocket = (): WebSocket => { /* eslint-disable @typescript-eslint/no-empty-function */ const sock = { send: (): void => { }, @@ -14,7 +14,7 @@ const createFakeSocket = (): MyWebSocket => { }; /* eslint-enable @typescript-eslint/no-empty-function */ - return (sock as unknown as MyWebSocket); + return (sock as unknown as WebSocket); }; describe('Transmission handler', () => { From 29394dea5e1303cdf07337d39c2c93249fdd41db Mon Sep 17 00:00:00 2001 From: Jonas Gloning <34194370+jonasgloning@users.noreply.github.com> Date: Thu, 17 Nov 2022 20:58:06 +0100 Subject: [PATCH 2/2] fix: the server could crash if a client sends invalid frames --- src/services/webSocketServer/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/services/webSocketServer/index.ts b/src/services/webSocketServer/index.ts index 553d46b67..a2c335e78 100644 --- a/src/services/webSocketServer/index.ts +++ b/src/services/webSocketServer/index.ts @@ -47,6 +47,9 @@ export class WebSocketServer extends EventEmitter implements IWebSocketServer { } private _onSocketConnection(socket: WebSocket, req: IncomingMessage): void { + // An unhandled socket error might crash the server. Handle it first. + socket.on("error", error => this._onSocketError(error)) + const { query = {} } = url.parse(req.url ?? '', true); const { id, token, key }: IAuthParams = query;