From 36a789e3d63a20e0d2fb1ebed806de56f54a1fb1 Mon Sep 17 00:00:00 2001 From: Claudemir Todo Bom Date: Fri, 26 Jul 2024 12:20:37 -0300 Subject: [PATCH] Configurable file download limit - fix #130 --- .../WbotServices/wbotMessageListener.ts | 29 ++++++++++--- frontend/src/components/Settings/Options.js | 43 ++++++++++++++++++- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 639bdb5..b3b6050 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -53,7 +53,7 @@ import { cacheLayer } from "../../libs/cache"; import { debounce } from "../../helpers/Debounce"; import { getMessageOptions } from "./SendWhatsAppMedia"; import { makeRandomId } from "../../helpers/MakeRandomId"; -import { GetCompanySetting } from "../../helpers/CheckSettings"; +import CheckSettings, { GetCompanySetting } from "../../helpers/CheckSettings"; import Whatsapp from "../../models/Whatsapp"; type Session = WASocket & { @@ -287,7 +287,7 @@ const getMessageMedia = (message: proto.IMessage) => { ); } -const downloadMedia = async (msg: proto.IWebMessageInfo) => { +const downloadMedia = async (msg: proto.IWebMessageInfo, wbot: Session, ticket: Ticket) => { const unpackedMessage = getUnpackedMessage(msg); const message = getMessageMedia(unpackedMessage); @@ -295,6 +295,24 @@ const downloadMedia = async (msg: proto.IWebMessageInfo) => { return null; } + const fileLimit = parseInt(await CheckSettings("downloadLimit", "15"), 10); + if (wbot && message?.fileLength && +message.fileLength > fileLimit*1024*1024) { + const fileLimitMessage = { + text: `\u200e*Mensagem Automática*:\nNosso sistema aceita apenas arquivos com no máximo ${fileLimit} MiB` + }; + + const sendMsg = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + fileLimitMessage + ); + + sendMsg.message.extendedTextMessage.text = "\u200e*Mensagem do sistema*:\nArquivo recebido além do limite de tamanho do sistema, se for necessário ele pode ser obtido no aplicativo do whatsapp."; + + // eslint-disable-next-line no-use-before-define + await verifyMessage(sendMsg, ticket, ticket.contact); + throw new Error("ERR_FILESIZE_OVER_LIMIT"); + } + // eslint-disable-next-line no-nested-ternary const messageType = unpackedMessage?.documentMessage ? "document" @@ -429,11 +447,12 @@ const verifyQuotedMessage = async ( const verifyMediaMessage = async ( msg: proto.IWebMessageInfo, ticket: Ticket, - contact: Contact + contact: Contact, + wbot: Session = null ): Promise => { const io = getIO(); const quotedMsg = await verifyQuotedMessage(msg); - const media = await downloadMedia(msg); + const media = await downloadMedia(msg, wbot, ticket); if (!media) { throw new Error("ERR_WAPP_DOWNLOAD_MEDIA"); @@ -1443,7 +1462,7 @@ const handleMessage = async ( if (messageMedia) { - await verifyMediaMessage(msg, ticket, contact); + await verifyMediaMessage(msg, ticket, contact, wbot); } else if (msg.message?.editedMessage?.message?.protocolMessage?.editedMessage) { // message edited by Whatsapp App await verifyEditedMessage(msg.message.editedMessage.message.protocolMessage.editedMessage, ticket, msg.message.editedMessage.message.protocolMessage.key.id); diff --git a/frontend/src/components/Settings/Options.js b/frontend/src/components/Settings/Options.js index 00f50f3..62f8a73 100644 --- a/frontend/src/components/Settings/Options.js +++ b/frontend/src/components/Settings/Options.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useRef } from "react"; import Grid from "@material-ui/core/Grid"; import MenuItem from "@material-ui/core/MenuItem"; @@ -102,6 +102,7 @@ export default function Options(props) { const [chatbotAutoExit, setChatbotAutoExit] = useState("disabled"); const [CheckMsgIsGroup, setCheckMsgIsGroupType] = useState("enabled"); const [apiToken, setApiToken] = useState(""); + const [downloadLimit, setDownloadLimit] = useState("15"); const [loadingUserRating, setLoadingUserRating] = useState(false); const [loadingScheduleType, setLoadingScheduleType] = useState(false); @@ -112,9 +113,12 @@ export default function Options(props) { const [loadingChatbotAutoExit, setLoadingChatbotAutoExit] = useState(false); const [loadingCheckMsgIsGroup, setCheckMsgIsGroup] = useState(false); const [loadingApiToken, setLoadingApiToken] = useState(false); + const [loadingDownloadLimit, setLoadingDownloadLimit] = useState(false); const { getCurrentUserInfo } = useAuth(); const [currentUser, setCurrentUser] = useState({}); + const downloadLimitInput = useRef(null); + const { update } = useSettings(); useEffect(() => { @@ -158,6 +162,9 @@ export default function Options(props) { const apiToken = settings.find((s) => s.key === "apiToken"); setApiToken(apiToken?.value || ""); + + const downloadLimit = settings.find((s) => s.key === "downloadLimit"); + setDownloadLimit(downloadLimit?.value || ""); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [settings]); @@ -251,6 +258,17 @@ export default function Options(props) { setLoadingAllowSignup(false); } + async function handleDownloadLimit(value) { + setDownloadLimit(value); + setLoadingDownloadLimit(true); + await update({ + key: "downloadLimit", + value, + }); + toast.success("Operação atualizada com sucesso."); + setLoadingDownloadLimit(false); + } + async function generateApiToken() { const newToken = generateSecureToken(32); setApiToken(newToken); @@ -495,6 +513,7 @@ export default function Options(props) { ( + <> @@ -515,6 +534,28 @@ export default function Options(props) { + + + + + { + setDownloadLimit(e.target.value); + }} + onBlur={async (_) => { + await handleDownloadLimit(downloadLimit); + }} + /> + + + + )} />