From c987845e31360afb9a2b80bfe59f0013f59c2921 Mon Sep 17 00:00:00 2001 From: Fabio Date: Thu, 29 Jun 2023 00:01:05 -0400 Subject: [PATCH 01/16] fix(websocket): adequando todos os nomes de eventos --- src/controller/messageController.ts | 10 +++-- src/controller/sessionController.ts | 12 ++++-- src/index.ts | 12 +++++- src/util/createSessionUtil.ts | 64 +++++++++++++++++++++++------ src/util/functions.ts | 6 ++- 5 files changed, 83 insertions(+), 21 deletions(-) diff --git a/src/controller/messageController.ts b/src/controller/messageController.ts index e6c8064465..69351d25a4 100644 --- a/src/controller/messageController.ts +++ b/src/controller/messageController.ts @@ -16,7 +16,7 @@ import { Request, Response } from 'express'; -import { unlinkAsync } from '../util/functions'; +import { callSocket, unlinkAsync } from '../util/functions'; function returnError(req: Request, res: Response, error: any) { req.logger.error(error); @@ -78,7 +78,10 @@ export async function sendMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - req.io.emit('mensagem-enviada', results); + // req.io.emit('send-message', results); + callSocket(req, 'send-message', { + results, + }); returnSucess(res, results); } catch (error) { returnError(req, res, error); @@ -627,7 +630,8 @@ export async function replyMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - req.io.emit('mensagem-enviada', { message: message, to: phone }); + // req.io.emit('send-message', { message: message, to: phone }); + callSocket(req, 'send-message', { message: message, to: phone }); returnSucess(res, results); } catch (error) { returnError(req, res, error); diff --git a/src/controller/sessionController.ts b/src/controller/sessionController.ts index 8814fe38e9..74e0c45a8b 100644 --- a/src/controller/sessionController.ts +++ b/src/controller/sessionController.ts @@ -23,7 +23,7 @@ import { Logger } from 'winston'; import { version } from '../../package.json'; import config from '../config'; import CreateSessionUtil from '../util/createSessionUtil'; -import { callWebHook, contactToArray } from '../util/functions'; +import { callSocket, callWebHook, contactToArray } from '../util/functions'; import getAllTokens from '../util/getAllTokens'; import { clientsArray, deleteSessionOnArray } from '../util/sessionUtil'; @@ -243,7 +243,10 @@ export async function closeSession(req: Request, res: Response) { (clientsArray as any)[session] = { status: null }; await req.client.close(); - req.io.emit('whatsapp-status', false); + // req.io.emit('whatsapp-status', false); + callSocket(req, 'whatsapp-status', { + status: false, + }); callWebHook(req.client, req, 'closesession', { message: `Session: ${session} disconnected`, connected: false, @@ -300,7 +303,10 @@ export async function logOutSession(req: Request, res: Response) { }); } - req.io.emit('whatsapp-status', false); + // req.io.emit('whatsapp-status', false); + callSocket(req, 'whatsapp-status', { + status: false, + }); callWebHook(req.client, req, 'logoutsession', { message: `Session: ${session} logged out`, connected: false, diff --git a/src/index.ts b/src/index.ts index a9a4fd46d0..7e793bc8c8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -95,10 +95,18 @@ export function initServer(serverOptions: any) { }); io.on('connection', (sock) => { - logger.info(`ID: ${sock.id} entrou`); + sock.on('joinChannel', (channelId: string) => { + sock.join(channelId); + logger.info(`ID: ${sock.id} entrou do canal ${channelId}`); + }); + + sock.on('leaveChannel', (channelId: string) => { + sock.leave(channelId); + logger.info(`ID: ${sock.id} saiu do canal ${channelId}`); + }); sock.on('disconnect', () => { - logger.info(`ID: ${sock.id} saiu`); + logger.info(`ID: ${sock.id} se desconectou`); }); }); diff --git a/src/util/createSessionUtil.ts b/src/util/createSessionUtil.ts index 4c07aa60da..fe93c58a30 100644 --- a/src/util/createSessionUtil.ts +++ b/src/util/createSessionUtil.ts @@ -19,7 +19,7 @@ import { Request } from 'express'; import { download } from '../controller/sessionController'; import { WhatsAppServer } from '../types/WhatsAppServer'; import chatWootClient from './chatWootClient'; -import { callWebHook, startHelper } from './functions'; +import { callSocket, callWebHook, startHelper } from './functions'; import { clientsArray, eventEmitter } from './sessionUtil'; import Factory from './tokenStore/factory'; @@ -97,6 +97,10 @@ export default class CreateSessionUtil { client.close(); clientsArray[session] = undefined; } + callSocket(req, 'status-find', { + status: statusFind, + session: client.session, + }); callWebHook(client, req, 'status-find', { status: statusFind, session: client.session, @@ -155,7 +159,12 @@ export default class CreateSessionUtil { qrCode = qrCode.replace('data:image/png;base64,', ''); const imageBuffer = Buffer.from(qrCode, 'base64'); - req.io.emit('qrCode', { + // req.io.emit('qrCode', { + // data: 'data:image/png;base64,' + imageBuffer.toString('base64'), + // session: client.session, + // }); + + callSocket(req, 'qr-code', { data: 'data:image/png;base64,' + imageBuffer.toString('base64'), session: client.session, }); @@ -181,11 +190,18 @@ export default class CreateSessionUtil { req.logger.info(`Started Session: ${client.session}`); //callWebHook(client, req, 'session-logged', { status: 'CONNECTED'}); - req.io.emit('session-logged', { status: true, session: client.session }); + // req.io.emit('session-logged', { status: true, session: client.session }); + callSocket(req, 'session-logged', { + status: true, + session: client.session, + }); startHelper(client, req); } catch (error) { req.logger.error(error); - req.io.emit('session-error', client.session); + // req.io.emit('session-error', client.session); + callSocket(req, 'session-error', { + session: client.session, + }); } await this.checkStateSession(client, req); @@ -228,25 +244,37 @@ export default class CreateSessionUtil { download(message, client, req.logger); } - req.io.emit('received-message', { response: message }); + // req.io.emit('received-message', { response: message }); + callSocket(req, 'received-message', { + message, + }); }); await client.onIncomingCall(async (call) => { - req.io.emit('incomingcall', call); + // req.io.emit('incomingcall', call); + callSocket(req, 'incoming-call', { + call, + }); callWebHook(client, req, 'incomingcall', call); }); } async listenAcks(client: WhatsAppServer, req: Request) { await client.onAck(async (ack) => { - req.io.emit('onack', ack); + // req.io.emit('onack', ack); + callSocket(req, 'on-ack', { + ack, + }); callWebHook(client, req, 'onack', ack); }); } async onPresenceChanged(client: WhatsAppServer, req: Request) { await client.onPresenceChanged(async (presenceChangedEvent) => { - req.io.emit('onpresencechanged', presenceChangedEvent); + // req.io.emit('onpresencechanged', presenceChangedEvent); + callSocket(req, 'on-presence-changed', { + presenceChangedEvent, + }); callWebHook(client, req, 'onpresencechanged', presenceChangedEvent); }); } @@ -254,7 +282,10 @@ export default class CreateSessionUtil { async onReactionMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onReactionMessage(async (reaction: any) => { - req.io.emit('onreactionmessage', reaction); + // req.io.emit('onreactionmessage', reaction); + callSocket(req, 'on-reaction-message', { + reaction, + }); callWebHook(client, req, 'onreactionmessage', reaction); }); } @@ -262,21 +293,30 @@ export default class CreateSessionUtil { async onRevokedMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onRevokedMessage(async (response: any) => { - req.io.emit('onrevokedmessage', response); + // req.io.emit('onrevokedmessage', response); + callSocket(req, 'on-revoked-message', { + response, + }); callWebHook(client, req, 'onrevokedmessage', response); }); } async onPollResponse(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onPollResponse(async (response: any) => { - req.io.emit('onpollresponse', response); + // req.io.emit('onpollresponse', response); + callSocket(req, 'on-poll-response', { + response, + }); callWebHook(client, req, 'onpollresponse', response); }); } async onLabelUpdated(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onUpdateLabel(async (response: any) => { - req.io.emit('onupdatelabel', response); + // req.io.emit('onupdatelabel', response); + callSocket(req, 'on-update-label', { + response, + }); callWebHook(client, req, 'onupdatelabel', response); }); } diff --git a/src/util/functions.ts b/src/util/functions.ts index 533027888e..4eef263aaf 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const { aws } = require("@aws-sdk/client-s3"); +const { aws } = require('@aws-sdk/client-s3'); import api from 'axios'; import Crypto from 'crypto'; import fs from 'fs'; @@ -92,6 +92,10 @@ export function groupNameToArray(group: any) { return localArr; } +export function callSocket(req: any, event: any, data: any) { + return req.io.to(req.session).emit(event, data); +} + export async function callWebHook( client: any, req: any, From 726d7f734e1c5881f0aaad2a5f8e649d0f12bbbb Mon Sep 17 00:00:00 2001 From: Fabio Date: Thu, 29 Jun 2023 00:22:33 -0400 Subject: [PATCH 02/16] =?UTF-8?q?fix(websocket):=20limpando=20c=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/messageController.ts | 4 ++-- src/controller/sessionController.ts | 3 +-- src/util/createSessionUtil.ts | 17 ++--------------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/controller/messageController.ts b/src/controller/messageController.ts index 69351d25a4..90999e56a6 100644 --- a/src/controller/messageController.ts +++ b/src/controller/messageController.ts @@ -78,7 +78,7 @@ export async function sendMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - // req.io.emit('send-message', results); + callSocket(req, 'send-message', { results, }); @@ -630,7 +630,7 @@ export async function replyMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - // req.io.emit('send-message', { message: message, to: phone }); + callSocket(req, 'send-message', { message: message, to: phone }); returnSucess(res, results); } catch (error) { diff --git a/src/controller/sessionController.ts b/src/controller/sessionController.ts index 74e0c45a8b..8b47fd8f87 100644 --- a/src/controller/sessionController.ts +++ b/src/controller/sessionController.ts @@ -243,7 +243,7 @@ export async function closeSession(req: Request, res: Response) { (clientsArray as any)[session] = { status: null }; await req.client.close(); - // req.io.emit('whatsapp-status', false); + callSocket(req, 'whatsapp-status', { status: false, }); @@ -303,7 +303,6 @@ export async function logOutSession(req: Request, res: Response) { }); } - // req.io.emit('whatsapp-status', false); callSocket(req, 'whatsapp-status', { status: false, }); diff --git a/src/util/createSessionUtil.ts b/src/util/createSessionUtil.ts index fe93c58a30..40de0e6a7e 100644 --- a/src/util/createSessionUtil.ts +++ b/src/util/createSessionUtil.ts @@ -159,11 +159,6 @@ export default class CreateSessionUtil { qrCode = qrCode.replace('data:image/png;base64,', ''); const imageBuffer = Buffer.from(qrCode, 'base64'); - // req.io.emit('qrCode', { - // data: 'data:image/png;base64,' + imageBuffer.toString('base64'), - // session: client.session, - // }); - callSocket(req, 'qr-code', { data: 'data:image/png;base64,' + imageBuffer.toString('base64'), session: client.session, @@ -190,7 +185,7 @@ export default class CreateSessionUtil { req.logger.info(`Started Session: ${client.session}`); //callWebHook(client, req, 'session-logged', { status: 'CONNECTED'}); - // req.io.emit('session-logged', { status: true, session: client.session }); + callSocket(req, 'session-logged', { status: true, session: client.session, @@ -198,7 +193,7 @@ export default class CreateSessionUtil { startHelper(client, req); } catch (error) { req.logger.error(error); - // req.io.emit('session-error', client.session); + callSocket(req, 'session-error', { session: client.session, }); @@ -244,14 +239,12 @@ export default class CreateSessionUtil { download(message, client, req.logger); } - // req.io.emit('received-message', { response: message }); callSocket(req, 'received-message', { message, }); }); await client.onIncomingCall(async (call) => { - // req.io.emit('incomingcall', call); callSocket(req, 'incoming-call', { call, }); @@ -261,7 +254,6 @@ export default class CreateSessionUtil { async listenAcks(client: WhatsAppServer, req: Request) { await client.onAck(async (ack) => { - // req.io.emit('onack', ack); callSocket(req, 'on-ack', { ack, }); @@ -271,7 +263,6 @@ export default class CreateSessionUtil { async onPresenceChanged(client: WhatsAppServer, req: Request) { await client.onPresenceChanged(async (presenceChangedEvent) => { - // req.io.emit('onpresencechanged', presenceChangedEvent); callSocket(req, 'on-presence-changed', { presenceChangedEvent, }); @@ -282,7 +273,6 @@ export default class CreateSessionUtil { async onReactionMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onReactionMessage(async (reaction: any) => { - // req.io.emit('onreactionmessage', reaction); callSocket(req, 'on-reaction-message', { reaction, }); @@ -293,7 +283,6 @@ export default class CreateSessionUtil { async onRevokedMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onRevokedMessage(async (response: any) => { - // req.io.emit('onrevokedmessage', response); callSocket(req, 'on-revoked-message', { response, }); @@ -303,7 +292,6 @@ export default class CreateSessionUtil { async onPollResponse(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onPollResponse(async (response: any) => { - // req.io.emit('onpollresponse', response); callSocket(req, 'on-poll-response', { response, }); @@ -313,7 +301,6 @@ export default class CreateSessionUtil { async onLabelUpdated(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onUpdateLabel(async (response: any) => { - // req.io.emit('onupdatelabel', response); callSocket(req, 'on-update-label', { response, }); From 6436440da3e05648edb105ff8596d1265fc253a2 Mon Sep 17 00:00:00 2001 From: Fabio Date: Thu, 29 Jun 2023 00:31:33 -0400 Subject: [PATCH 03/16] refactor(websocket): alterando send para o passado --- src/controller/messageController.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controller/messageController.ts b/src/controller/messageController.ts index 90999e56a6..b5e1e54feb 100644 --- a/src/controller/messageController.ts +++ b/src/controller/messageController.ts @@ -79,7 +79,7 @@ export async function sendMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - callSocket(req, 'send-message', { + callSocket(req, 'sent-message', { results, }); returnSucess(res, results); @@ -631,7 +631,7 @@ export async function replyMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - callSocket(req, 'send-message', { message: message, to: phone }); + callSocket(req, 'sent-message', { message: message, to: phone }); returnSucess(res, results); } catch (error) { returnError(req, res, error); From f4b3b2da922cf2014c94b81090b25c5532346334 Mon Sep 17 00:00:00 2001 From: Fabio Date: Thu, 29 Jun 2023 01:00:02 -0400 Subject: [PATCH 04/16] =?UTF-8?q?refactor(websocket):=20s=C3=B3=20enviando?= =?UTF-8?q?=20websocket=20se=20tem=20ouvinte=20no=20canal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/functions.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/functions.ts b/src/util/functions.ts index 4eef263aaf..cdbea2b844 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -93,6 +93,11 @@ export function groupNameToArray(group: any) { } export function callSocket(req: any, event: any, data: any) { + const listeners = + req.io?.sockets?.adapter?.rooms?.get(req.session)?.size || 0; + + if (listeners == 0) return; + return req.io.to(req.session).emit(event, data); } From 5bacca6baacb46dd5e3621cf91bb70dffb582397 Mon Sep 17 00:00:00 2001 From: Fabio Date: Fri, 30 Jun 2023 10:49:14 -0400 Subject: [PATCH 05/16] fix(websocket): Validando a session --- src/controller/messageController.ts | 4 +--- src/util/createSessionUtil.ts | 32 ++++++++--------------------- src/util/functions.ts | 7 ++++--- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/src/controller/messageController.ts b/src/controller/messageController.ts index b5e1e54feb..460a33e30c 100644 --- a/src/controller/messageController.ts +++ b/src/controller/messageController.ts @@ -79,9 +79,7 @@ export async function sendMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - callSocket(req, 'sent-message', { - results, - }); + callSocket(req, 'sent-message', results); returnSucess(res, results); } catch (error) { returnError(req, res, error); diff --git a/src/util/createSessionUtil.ts b/src/util/createSessionUtil.ts index 40de0e6a7e..0c96b26a8e 100644 --- a/src/util/createSessionUtil.ts +++ b/src/util/createSessionUtil.ts @@ -239,33 +239,25 @@ export default class CreateSessionUtil { download(message, client, req.logger); } - callSocket(req, 'received-message', { - message, - }); + callSocket(req, 'received-message', message); }); await client.onIncomingCall(async (call) => { - callSocket(req, 'incoming-call', { - call, - }); + callSocket(req, 'incoming-call', call); callWebHook(client, req, 'incomingcall', call); }); } async listenAcks(client: WhatsAppServer, req: Request) { await client.onAck(async (ack) => { - callSocket(req, 'on-ack', { - ack, - }); + callSocket(req, 'on-ack', ack); callWebHook(client, req, 'onack', ack); }); } async onPresenceChanged(client: WhatsAppServer, req: Request) { await client.onPresenceChanged(async (presenceChangedEvent) => { - callSocket(req, 'on-presence-changed', { - presenceChangedEvent, - }); + callSocket(req, 'on-presence-changed', presenceChangedEvent); callWebHook(client, req, 'onpresencechanged', presenceChangedEvent); }); } @@ -273,9 +265,7 @@ export default class CreateSessionUtil { async onReactionMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onReactionMessage(async (reaction: any) => { - callSocket(req, 'on-reaction-message', { - reaction, - }); + callSocket(req, 'on-reaction-message', reaction); callWebHook(client, req, 'onreactionmessage', reaction); }); } @@ -283,27 +273,21 @@ export default class CreateSessionUtil { async onRevokedMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onRevokedMessage(async (response: any) => { - callSocket(req, 'on-revoked-message', { - response, - }); + callSocket(req, 'on-revoked-message', response); callWebHook(client, req, 'onrevokedmessage', response); }); } async onPollResponse(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onPollResponse(async (response: any) => { - callSocket(req, 'on-poll-response', { - response, - }); + callSocket(req, 'on-poll-response', response); callWebHook(client, req, 'onpollresponse', response); }); } async onLabelUpdated(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onUpdateLabel(async (response: any) => { - callSocket(req, 'on-update-label', { - response, - }); + callSocket(req, 'on-update-label', response); callWebHook(client, req, 'onupdatelabel', response); }); } diff --git a/src/util/functions.ts b/src/util/functions.ts index cdbea2b844..e588dc0dfd 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -93,12 +93,13 @@ export function groupNameToArray(group: any) { } export function callSocket(req: any, event: any, data: any) { - const listeners = - req.io?.sockets?.adapter?.rooms?.get(req.session)?.size || 0; + const session = req?.session || data?.session; + + const listeners = req.io?.sockets?.adapter?.rooms?.get(session)?.size || 0; if (listeners == 0) return; - return req.io.to(req.session).emit(event, data); + return req.io.to(session).emit(event, data); } export async function callWebHook( From aafc14e69281f0dace3064332e9a7fb3967f02fd Mon Sep 17 00:00:00 2001 From: Fabio Date: Mon, 10 Jul 2023 13:19:43 -0400 Subject: [PATCH 06/16] fix(bucketAlreadyExists): verificando se existe o defaultBucketName --- src/util/functions.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/util/functions.ts b/src/util/functions.ts index c44ff2fc7b..89fe88d567 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -161,7 +161,10 @@ async function autoDownload(client: any, req: any, message: any) { config.aws_s3.defaultBucketName ? client.session + '/' : '' }${hashName}.${mime.extension(message.mimetype)}`; - if (!(await bucketAlreadyExists(bucketName))) { + if ( + !config.aws_s3.defaultBucketName && + !(await bucketAlreadyExists(bucketName)) + ) { await s3Client.send( new CreateBucketCommand({ Bucket: bucketName, From bc3ac0714b544218949d398d22020b099ec2f677 Mon Sep 17 00:00:00 2001 From: Fabio Date: Mon, 10 Jul 2023 13:26:56 -0400 Subject: [PATCH 07/16] fix(readme): atualizando o readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 711a35f156..8c83b2237e 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,8 @@ This server use config.ts file to define some options, default values are: region: 'sa-east-1', access_key_id: '', secret_key: '', + // If you already have a bucket created that will be used. Will bestored: you-default-bucket/{session}/{filename} + defaultBucketName: '' }, } ``` From 752a93b4bc9c363b7aa95fb23c6cd9a94f2d1df9 Mon Sep 17 00:00:00 2001 From: Fabio Date: Tue, 22 Aug 2023 15:00:16 -0400 Subject: [PATCH 08/16] fix(config): nome do arquivo com id da mensagem --- src/util/functions.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/util/functions.ts b/src/util/functions.ts index 573b109e6e..97b0b77ac1 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -141,7 +141,7 @@ async function autoDownload(client: any, req: any, message: any) { if (message && (message['mimetype'] || message.isMedia || message.isMMS)) { const buffer = await client.decryptFile(message); if (req.serverOptions.webhook.uploadS3) { - const hashName = crypto.randomBytes(24).toString('hex'); + const hashName = message.id.replace("true_", "").replace("false_", "") if ( !config.aws_s3.region || @@ -153,15 +153,7 @@ async function autoDownload(client: any, req: any, message: any) { let bucketName = config.aws_s3.defaultBucketName ? config.aws_s3.defaultBucketName : client.session; - bucketName = bucketName - .normalize('NFD') - .replace(/[\u0300-\u036f]|[— _.,?!]/g, '') - .toLowerCase(); - bucketName = - bucketName.length < 3 - ? bucketName + - `${Math.floor(Math.random() * (999 - 100 + 1)) + 100}` - : bucketName; + bucketName = bucketName.toLowerCase(); const fileName = `${ config.aws_s3.defaultBucketName ? client.session + '/' : '' }${hashName}.${mime.extension(message.mimetype)}`; From 0b40beaf3ae7093d0ec3fc564832f4d54499f390 Mon Sep 17 00:00:00 2001 From: Fabio Date: Thu, 24 Aug 2023 15:30:35 -0400 Subject: [PATCH 09/16] comment acl --- src/util/functions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/functions.ts b/src/util/functions.ts index 6d335edb07..aa7b283983 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -196,7 +196,7 @@ async function autoDownload(client: any, req: any, message: any) { Key: fileName, Body: buffer, ContentType: message.mimetype, - ACL: 'public-read', + // ACL: 'public-read', }) ); From 6bfc1bcdf086f5b6aae46057aa6a3bf74fc250fc Mon Sep 17 00:00:00 2001 From: Fabio Date: Thu, 24 Aug 2023 16:00:19 -0400 Subject: [PATCH 10/16] comment acl --- src/util/functions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/functions.ts b/src/util/functions.ts index aa7b283983..6d335edb07 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -196,7 +196,7 @@ async function autoDownload(client: any, req: any, message: any) { Key: fileName, Body: buffer, ContentType: message.mimetype, - // ACL: 'public-read', + ACL: 'public-read', }) ); From 5aeedeb3e4f475f7378117ea496114c51b53d6f3 Mon Sep 17 00:00:00 2001 From: Cleiton Carvalho Date: Sun, 27 Aug 2023 17:09:58 -0300 Subject: [PATCH 11/16] fix: Added scurity session for sockets --- src/index.ts | 20 +++++++---------- src/middleware/auth.ts | 50 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/index.ts b/src/index.ts index cfffa85800..b31d947896 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,6 +26,7 @@ import { Server as Socket } from 'socket.io'; import { version } from '../package.json'; import config from './config'; import { convert } from './mapper/index'; +import { verifyTokenSocket } from './middleware/auth'; import routes from './routes'; import { createFolders, @@ -66,7 +67,7 @@ export function initServer(serverOptions: any) { app.use((req: any, res: any, next: NextFunction) => { req.serverOptions = serverOptions; req.logger = logger; - req.io = io as any; + req.io = io; const oldSend = res.send; @@ -99,20 +100,15 @@ export function initServer(serverOptions: any) { origin: '*', }, }); + io.use(verifyTokenSocket); io.on('connection', (sock) => { - sock.on('joinChannel', (channelId: string) => { - sock.join(channelId); - logger.info(`ID: ${sock.id} entrou do canal ${channelId}`); - }); - - sock.on('leaveChannel', (channelId: string) => { - sock.leave(channelId); - logger.info(`ID: ${sock.id} saiu do canal ${channelId}`); - }); - sock.on('disconnect', () => { - logger.info(`ID: ${sock.id} se desconectou`); + logger.info( + `ID: ${sock.id} has disconnected. Session: ${ + sock.handshake.auth?.session || 'Unknown' + }` + ); }); }); diff --git a/src/middleware/auth.ts b/src/middleware/auth.ts index 2a41e5b2f7..0e54b6459f 100644 --- a/src/middleware/auth.ts +++ b/src/middleware/auth.ts @@ -15,7 +15,10 @@ */ import bcrypt from 'bcrypt'; import { NextFunction, Request, Response } from 'express'; +import { Socket } from 'socket.io'; +import { logger } from '..'; +import config from '../config'; import { clientsArray } from '../util/sessionUtil'; function formatSession(session: string) { @@ -89,4 +92,51 @@ const verifyToken = (req: Request, res: Response, next: NextFunction) => { } }; +export const verifyTokenSocket = (socket: Socket, next: any) => { + const secureToken = config.secretKey; + const { token, session } = socket.handshake.auth; + if (!session || !token) + return next(new Error('Session or token not informed')); + + try { + let tokenDecrypt = ''; + let sessionDecrypt = ''; + + try { + sessionDecrypt = session.split(':')[0]; + tokenDecrypt = token.split(':')[1].replace(/_/g, '/').replace(/-/g, '+'); + } catch (error) { + try { + if (token && token !== '' && token.split(' ').length > 0) { + const token_value = token.split(' ')[1]; + if (token_value) + tokenDecrypt = token_value.replace(/_/g, '/').replace(/-/g, '+'); + else tokenDecrypt = token; + } else { + tokenDecrypt = token; + } + } catch (e) { + logger.error(e); + return next(new Error('Check that a Session and Token are correct')); + } + } + bcrypt.compare( + sessionDecrypt + secureToken, + tokenDecrypt, + function (err, result) { + if (result) { + socket.join(session); + logger.info(`ID: ${socket.id} joined the channel ${session}`); + return next(); + } else { + return next(new Error('Check that a Session and Token are correct')); + } + } + ); + } catch (error) { + logger.error(error); + return next(new Error('Check that a Session and Token are correct')); + } +}; + export default verifyToken; From aa08c46e468697873791a97d46d25a1817fe509f Mon Sep 17 00:00:00 2001 From: Cleiton Carvalho Date: Sun, 27 Aug 2023 17:10:30 -0300 Subject: [PATCH 12/16] fix: improovment sockets events --- src/controller/messageController.ts | 14 +++++++++++--- src/controller/sessionController.ts | 8 ++------ src/util/createSessionUtil.ts | 16 ++++++++++------ src/util/functions.ts | 9 ++++++--- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/controller/messageController.ts b/src/controller/messageController.ts index 460a33e30c..36908b98b1 100644 --- a/src/controller/messageController.ts +++ b/src/controller/messageController.ts @@ -79,7 +79,10 @@ export async function sendMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - callSocket(req, 'sent-message', results); + /** + * Deprecated event 'mensagem-enviada' + */ + callSocket(req, ['mensagem-enviada', 'sent-message'], results); returnSucess(res, results); } catch (error) { returnError(req, res, error); @@ -628,8 +631,13 @@ export async function replyMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - - callSocket(req, 'sent-message', { message: message, to: phone }); + /** + * Deprecated event 'mensagem-enviada' + */ + callSocket(req, ['mensagem-enviada', 'sent-message'], { + message: message, + to: phone, + }); returnSucess(res, results); } catch (error) { returnError(req, res, error); diff --git a/src/controller/sessionController.ts b/src/controller/sessionController.ts index 8b47fd8f87..db1ec14992 100644 --- a/src/controller/sessionController.ts +++ b/src/controller/sessionController.ts @@ -244,9 +244,7 @@ export async function closeSession(req: Request, res: Response) { await req.client.close(); - callSocket(req, 'whatsapp-status', { - status: false, - }); + callSocket(req, 'whatsapp-status', false); callWebHook(req.client, req, 'closesession', { message: `Session: ${session} disconnected`, connected: false, @@ -303,9 +301,7 @@ export async function logOutSession(req: Request, res: Response) { }); } - callSocket(req, 'whatsapp-status', { - status: false, - }); + callSocket(req, 'whatsapp-status', false); callWebHook(req.client, req, 'logoutsession', { message: `Session: ${session} logged out`, connected: false, diff --git a/src/util/createSessionUtil.ts b/src/util/createSessionUtil.ts index b2b4dcc0a5..ce2a1ba165 100644 --- a/src/util/createSessionUtil.ts +++ b/src/util/createSessionUtil.ts @@ -163,7 +163,7 @@ export default class CreateSessionUtil { qrCode = qrCode.replace('data:image/png;base64,', ''); const imageBuffer = Buffer.from(qrCode, 'base64'); - callSocket(req, 'qr-code', { + callSocket(req, ['qrCode', 'qr-code'], { data: 'data:image/png;base64,' + imageBuffer.toString('base64'), session: client.session, }); @@ -256,14 +256,18 @@ export default class CreateSessionUtil { async listenAcks(client: WhatsAppServer, req: Request) { await client.onAck(async (ack) => { - callSocket(req, 'on-ack', ack); + callSocket(req, ['onack', 'on-ack'], ack); callWebHook(client, req, 'onack', ack); }); } async onPresenceChanged(client: WhatsAppServer, req: Request) { await client.onPresenceChanged(async (presenceChangedEvent) => { - callSocket(req, 'on-presence-changed', presenceChangedEvent); + callSocket( + req, + ['onpresencechanged', 'on-presence-changed'], + presenceChangedEvent + ); callWebHook(client, req, 'onpresencechanged', presenceChangedEvent); }); } @@ -271,7 +275,7 @@ export default class CreateSessionUtil { async onReactionMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onReactionMessage(async (reaction: any) => { - callSocket(req, 'on-reaction-message', reaction); + callSocket(req, ['onreactionmessage', 'on-reaction-message'], reaction); callWebHook(client, req, 'onreactionmessage', reaction); }); } @@ -279,7 +283,7 @@ export default class CreateSessionUtil { async onRevokedMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onRevokedMessage(async (response: any) => { - callSocket(req, 'on-revoked-message', response); + callSocket(req, ['onrevokedmessage', 'on-revoked-message'], response); callWebHook(client, req, 'onrevokedmessage', response); }); } @@ -293,7 +297,7 @@ export default class CreateSessionUtil { async onLabelUpdated(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onUpdateLabel(async (response: any) => { - callSocket(req, 'on-update-label', response); + callSocket(req, ['onupdatelabel', 'on-update-label'], response); callWebHook(client, req, 'onupdatelabel', response); }); } diff --git a/src/util/functions.ts b/src/util/functions.ts index 15c87c8f93..64ebe56d01 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -99,14 +99,17 @@ export function groupNameToArray(group: any) { return localArr; } -export function callSocket(req: any, event: any, data: any) { +export function callSocket(req: any, event: string | string[], data: any) { + event = Array.isArray(event) ? event : [event]; const session = req?.session || data?.session; const listeners = req.io?.sockets?.adapter?.rooms?.get(session)?.size || 0; if (listeners == 0) return; - - return req.io.to(session).emit(event, data); + for (const evt of event) { + req.io.to(session).emit(evt, data); + } + return; } export async function callWebHook( From fea536fa78d7015b496fb8aa17e89ff54de98db7 Mon Sep 17 00:00:00 2001 From: Fabio <57275833+fabioselau077@users.noreply.github.com> Date: Mon, 25 Sep 2023 12:42:24 -0400 Subject: [PATCH 13/16] Revert "Hotfix/melhorias websocket" --- src/controller/messageController.ts | 8 +++---- src/controller/sessionController.ts | 11 +++------ src/index.ts | 12 ++-------- src/util/createSessionUtil.ts | 35 ++++++++++------------------- src/util/functions.ts | 10 --------- 5 files changed, 20 insertions(+), 56 deletions(-) diff --git a/src/controller/messageController.ts b/src/controller/messageController.ts index bb473b34a8..6dc55ad082 100644 --- a/src/controller/messageController.ts +++ b/src/controller/messageController.ts @@ -16,7 +16,7 @@ import { Request, Response } from 'express'; -import { callSocket, unlinkAsync } from '../util/functions'; +import { unlinkAsync } from '../util/functions'; function returnError(req: Request, res: Response, error: any) { req.logger.error(error); @@ -87,8 +87,7 @@ export async function sendMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - - callSocket(req, 'sent-message', results); + req.io.emit('mensagem-enviada', results); returnSucess(res, results); } catch (error) { returnError(req, res, error); @@ -637,8 +636,7 @@ export async function replyMessage(req: Request, res: Response) { if (results.length === 0) return res.status(400).json('Error sending message'); - - callSocket(req, 'sent-message', { message: message, to: phone }); + req.io.emit('mensagem-enviada', { message: message, to: phone }); returnSucess(res, results); } catch (error) { returnError(req, res, error); diff --git a/src/controller/sessionController.ts b/src/controller/sessionController.ts index 8b47fd8f87..8814fe38e9 100644 --- a/src/controller/sessionController.ts +++ b/src/controller/sessionController.ts @@ -23,7 +23,7 @@ import { Logger } from 'winston'; import { version } from '../../package.json'; import config from '../config'; import CreateSessionUtil from '../util/createSessionUtil'; -import { callSocket, callWebHook, contactToArray } from '../util/functions'; +import { callWebHook, contactToArray } from '../util/functions'; import getAllTokens from '../util/getAllTokens'; import { clientsArray, deleteSessionOnArray } from '../util/sessionUtil'; @@ -243,10 +243,7 @@ export async function closeSession(req: Request, res: Response) { (clientsArray as any)[session] = { status: null }; await req.client.close(); - - callSocket(req, 'whatsapp-status', { - status: false, - }); + req.io.emit('whatsapp-status', false); callWebHook(req.client, req, 'closesession', { message: `Session: ${session} disconnected`, connected: false, @@ -303,9 +300,7 @@ export async function logOutSession(req: Request, res: Response) { }); } - callSocket(req, 'whatsapp-status', { - status: false, - }); + req.io.emit('whatsapp-status', false); callWebHook(req.client, req, 'logoutsession', { message: `Session: ${session} logged out`, connected: false, diff --git a/src/index.ts b/src/index.ts index 34c249edb8..bd9be0670c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -101,18 +101,10 @@ export function initServer(serverOptions: any) { }); io.on('connection', (sock) => { - sock.on('joinChannel', (channelId: string) => { - sock.join(channelId); - logger.info(`ID: ${sock.id} entrou do canal ${channelId}`); - }); - - sock.on('leaveChannel', (channelId: string) => { - sock.leave(channelId); - logger.info(`ID: ${sock.id} saiu do canal ${channelId}`); - }); + logger.info(`ID: ${sock.id} entrou`); sock.on('disconnect', () => { - logger.info(`ID: ${sock.id} se desconectou`); + logger.info(`ID: ${sock.id} saiu`); }); }); diff --git a/src/util/createSessionUtil.ts b/src/util/createSessionUtil.ts index f4d398a750..7c0232cf99 100644 --- a/src/util/createSessionUtil.ts +++ b/src/util/createSessionUtil.ts @@ -19,7 +19,7 @@ import { Request } from 'express'; import { download } from '../controller/sessionController'; import { WhatsAppServer } from '../types/WhatsAppServer'; import chatWootClient from './chatWootClient'; -import { callSocket, callWebHook, startHelper } from './functions'; +import { callWebHook, startHelper } from './functions'; import { clientsArray, eventEmitter } from './sessionUtil'; import Factory from './tokenStore/factory'; @@ -101,10 +101,6 @@ export default class CreateSessionUtil { client.close(); clientsArray[session] = undefined; } - callSocket(req, 'status-find', { - status: statusFind, - session: client.session, - }); callWebHook(client, req, 'status-find', { status: statusFind, session: client.session, @@ -163,7 +159,7 @@ export default class CreateSessionUtil { qrCode = qrCode.replace('data:image/png;base64,', ''); const imageBuffer = Buffer.from(qrCode, 'base64'); - callSocket(req, 'qr-code', { + req.io.emit('qrCode', { data: 'data:image/png;base64,' + imageBuffer.toString('base64'), session: client.session, }); @@ -196,18 +192,11 @@ export default class CreateSessionUtil { req.logger.info(`Started Session: ${client.session}`); //callWebHook(client, req, 'session-logged', { status: 'CONNECTED'}); - - callSocket(req, 'session-logged', { - status: true, - session: client.session, - }); + req.io.emit('session-logged', { status: true, session: client.session }); startHelper(client, req); } catch (error) { req.logger.error(error); - - callSocket(req, 'session-error', { - session: client.session, - }); + req.io.emit('session-error', client.session); } await this.checkStateSession(client, req); @@ -250,27 +239,27 @@ export default class CreateSessionUtil { download(message, client, req.logger); } - callSocket(req, 'received-message', message); + req.io.emit('received-message', { response: message }); if (req.serverOptions.webhook.onSelfMessage && message.fromMe) callWebHook(client, req, 'onselfmessage', message); }); await client.onIncomingCall(async (call) => { - callSocket(req, 'incoming-call', call); + req.io.emit('incomingcall', call); callWebHook(client, req, 'incomingcall', call); }); } async listenAcks(client: WhatsAppServer, req: Request) { await client.onAck(async (ack) => { - callSocket(req, 'on-ack', ack); + req.io.emit('onack', ack); callWebHook(client, req, 'onack', ack); }); } async onPresenceChanged(client: WhatsAppServer, req: Request) { await client.onPresenceChanged(async (presenceChangedEvent) => { - callSocket(req, 'on-presence-changed', presenceChangedEvent); + req.io.emit('onpresencechanged', presenceChangedEvent); callWebHook(client, req, 'onpresencechanged', presenceChangedEvent); }); } @@ -278,7 +267,7 @@ export default class CreateSessionUtil { async onReactionMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onReactionMessage(async (reaction: any) => { - callSocket(req, 'on-reaction-message', reaction); + req.io.emit('onreactionmessage', reaction); callWebHook(client, req, 'onreactionmessage', reaction); }); } @@ -286,21 +275,21 @@ export default class CreateSessionUtil { async onRevokedMessage(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onRevokedMessage(async (response: any) => { - callSocket(req, 'on-revoked-message', response); + req.io.emit('onrevokedmessage', response); callWebHook(client, req, 'onrevokedmessage', response); }); } async onPollResponse(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onPollResponse(async (response: any) => { - callSocket(req, 'on-poll-response', response); + req.io.emit('onpollresponse', response); callWebHook(client, req, 'onpollresponse', response); }); } async onLabelUpdated(client: WhatsAppServer, req: Request) { await client.isConnected(); await client.onUpdateLabel(async (response: any) => { - callSocket(req, 'on-update-label', response); + req.io.emit('onupdatelabel', response); callWebHook(client, req, 'onupdatelabel', response); }); } diff --git a/src/util/functions.ts b/src/util/functions.ts index 51d04e5d09..cf7dca9f65 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -99,16 +99,6 @@ export function groupNameToArray(group: any) { return localArr; } -export function callSocket(req: any, event: any, data: any) { - const session = req?.session || data?.session; - - const listeners = req.io?.sockets?.adapter?.rooms?.get(session)?.size || 0; - - if (listeners == 0) return; - - return req.io.to(session).emit(event, data); -} - export async function callWebHook( client: any, req: Request, From 7ad4b70eb09cf4032bbe7723d65a6ca0b6484148 Mon Sep 17 00:00:00 2001 From: Fabio Date: Mon, 25 Sep 2023 13:05:09 -0400 Subject: [PATCH 14/16] =?UTF-8?q?fix(functions):=20revertendo=20c=C3=B3dig?= =?UTF-8?q?o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/functions.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/util/functions.ts b/src/util/functions.ts index 8d2e2d5815..5afd078fcf 100644 --- a/src/util/functions.ts +++ b/src/util/functions.ts @@ -154,7 +154,7 @@ async function autoDownload(client: any, req: any, message: any) { if (message && (message['mimetype'] || message.isMedia || message.isMMS)) { const buffer = await client.decryptFile(message); if (req.serverOptions.webhook.uploadS3) { - const hashName = message.id.replace("true_", "").replace("false_", "") + const hashName = crypto.randomBytes(24).toString('hex'); if ( !config?.aws_s3?.region || @@ -170,7 +170,15 @@ async function autoDownload(client: any, req: any, message: any) { let bucketName = config?.aws_s3?.defaultBucketName ? config?.aws_s3?.defaultBucketName : client.session; - bucketName = bucketName.toLowerCase(); + bucketName = bucketName + .normalize('NFD') + .replace(/[\u0300-\u036f]|[— _.,?!]/g, '') + .toLowerCase(); + bucketName = + bucketName.length < 3 + ? bucketName + + `${Math.floor(Math.random() * (999 - 100 + 1)) + 100}` + : bucketName; const fileName = `${ config.aws_s3.defaultBucketName ? client.session + '/' : '' }${hashName}.${mime.extension(message.mimetype)}`; From 53bdc0733ca0b8c6ad0203ad200559959b8cffb8 Mon Sep 17 00:00:00 2001 From: Fabio Date: Mon, 25 Sep 2023 14:57:00 -0400 Subject: [PATCH 15/16] fix(auth): pegando a posicao correta do token --- src/middleware/auth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/auth.ts b/src/middleware/auth.ts index 0e54b6459f..567c21b11d 100644 --- a/src/middleware/auth.ts +++ b/src/middleware/auth.ts @@ -108,7 +108,7 @@ export const verifyTokenSocket = (socket: Socket, next: any) => { } catch (error) { try { if (token && token !== '' && token.split(' ').length > 0) { - const token_value = token.split(' ')[1]; + const token_value = token.split(' ')[0]; if (token_value) tokenDecrypt = token_value.replace(/_/g, '/').replace(/-/g, '+'); else tokenDecrypt = token; From 1ea9b182f1ef2676953b18c665e627e8f4be9e8d Mon Sep 17 00:00:00 2001 From: Fabio Date: Mon, 25 Sep 2023 16:16:51 -0400 Subject: [PATCH 16/16] fix(utils): add status find --- src/util/createSessionUtil.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/createSessionUtil.ts b/src/util/createSessionUtil.ts index 00eb4dd888..662d217794 100644 --- a/src/util/createSessionUtil.ts +++ b/src/util/createSessionUtil.ts @@ -101,6 +101,10 @@ export default class CreateSessionUtil { client.close(); clientsArray[session] = undefined; } + callSocket(req, 'status-find', { + status: statusFind, + session: client.session, + }); callWebHook(client, req, 'status-find', { status: statusFind, session: client.session,