import { verify } from 'jsonwebtoken' import { TSocket } from '#application/types' import config from '#application/config' import { gameLogger } from '#application/logger' class SocketAuthenticator { private socket: TSocket private readonly next: any constructor(socket: TSocket, next: any) { this.socket = socket this.next = next } public async authenticate(): Promise { if (!this.socket.request.headers.cookie) { gameLogger.warn('No cookie provided') return this.next(new Error('Authentication error')) } const token = this.parseCookies()['token'] if (!token) { gameLogger.warn('No token provided') return this.next(new Error('Authentication error')) } this.verifyToken(token) } private parseCookies(): Record { return this.socket.request.headers.cookie.split('; ').reduce((prev: any, current: any) => { const [name, value] = current.split('=') prev[name] = value return prev }, {}) } private verifyToken(token: string): void { verify(token, config.JWT_SECRET, (err: any, decoded: any) => { if (err) { gameLogger.error('Invalid token') return this.next(new Error('Authentication error')) } this.socket.userId = decoded.id this.next() }) } } export async function Authentication(socket: TSocket, next: any) { const authenticator = new SocketAuthenticator(socket, next) await authenticator.authenticate() }