From 29129b98f70d309a875bd6fb958145b78b002289 Mon Sep 17 00:00:00 2001 From: HF Date: Mon, 27 Apr 2020 20:44:22 +0200 Subject: [PATCH] make it needed to be verified to chat autoban on message repeat log chat ips on more places --- src/core/ChatProvider.js | 56 +++++++++++++++++++++++++++++++-- src/routes/api/auth/register.js | 6 +++- src/socket/SocketServer.js | 14 +++++++++ src/socket/websockets.js | 1 - 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/core/ChatProvider.js b/src/core/ChatProvider.js index 7c79045..e7fae9e 100644 --- a/src/core/ChatProvider.js +++ b/src/core/ChatProvider.js @@ -16,6 +16,28 @@ class ChatProvider { constructor() { this.history = []; + this.filters = [ + { + regexp: /ADMIN/g, + matches: 2, + }, + { + regexp: /FUCK/g, + matches: 2, + }, + { + regexp: /admin/g, + matches: 3, + }, + { + regexp: /fuck/g, + matches: 3, + }, + { + regexp: /FACK/g, + matches: 3, + }, + ]; } addMessage(name, message) { @@ -31,16 +53,37 @@ class ChatProvider { return 'You can\'t send a message this long :('; } const name = (user.regUser) ? user.regUser.name : null; + if (!name) { // eslint-disable-next-line max-len return 'Couldn\'t send your message, pls log out and back in again.'; } + if (!user.regUser.verified) { + return 'Your mail has to be verified in order to chat'; + } + + if (message === message.toUpperCase()) { + return null; + } + + for (let i = 0; i < this.filters.length; i += 1) { + const filter = this.filters[i]; + const count = (message.match(filter.regexp) || []).length; + if (count >= filter.matches) { + ChatProvider.mute(name, 30); + return 'Ow no! Spam protection decided to mute you'; + } + } if (user.isAdmin() && message.charAt(0) === '/') { // admin commands const cmd = message.split(' '); if (cmd[0] === '/mute') { - return ChatProvider.mute(cmd.slice(1, -1).join(' '), cmd.slice(-1)); + const timeMin = Number(cmd.slice(-1)); + if (Number.isNaN(timeMin)) { + return ChatProvider.mute(cmd.slice(1).join(' ')); + } + return ChatProvider.mute(cmd.slice(1, -1).join(' '), timeMin); } if (cmd[0] === '/unmute') { return ChatProvider.unmute(cmd.slice(1).join(' ')); } @@ -67,13 +110,22 @@ class ChatProvider { webSockets.broadcastChatMessage(name, message, sendapi); } + /* + * that is really just because i do not like to import the class AND the + * singleton + */ + // eslint-disable-next-line class-methods-use-this + automute(name) { + ChatProvider.mute(name, 600); + } + static async checkIfMuted(user) { const key = `mute:${user.id}`; const ttl: number = await redis.ttlAsync(key); return ttl; } - static async mute(name, timeMin) { + static async mute(name, timeMin = null) { const id = await User.name2Id(name); if (!id) { return `Couldn't find user ${name}`; diff --git a/src/routes/api/auth/register.js b/src/routes/api/auth/register.js index 3c5b566..dc4b8b0 100644 --- a/src/routes/api/auth/register.js +++ b/src/routes/api/auth/register.js @@ -7,10 +7,11 @@ import type { Request, Response } from 'express'; import Sequelize from 'sequelize'; +import logger from '../../../core/logger'; import { RegUser } from '../../../data/models'; import mailProvider from '../../../core/mail'; import getMe from '../../../core/me'; -import { getHostFromRequest } from '../../../utils/ip'; +import { getIPFromRequest, getHostFromRequest } from '../../../utils/ip'; import { validateEMail, validateName, @@ -61,6 +62,9 @@ export default async (req: Request, res: Response) => { return; } + const ip = await getIPFromRequest(req); + logger.info(`Created new user ${name} ${email} ${ip}`); + const user = req.noauthUser; user.id = newuser.id; user.regUser = newuser; diff --git a/src/socket/SocketServer.js b/src/socket/SocketServer.js index 228fe2c..1c2ac70 100644 --- a/src/socket/SocketServer.js +++ b/src/socket/SocketServer.js @@ -229,6 +229,20 @@ class SocketServer extends WebSocketEvents { if (errorMsg) { ws.send(JSON.stringify(['info', errorMsg])); } + if (ws.last_message && ws.last_message === message) { + ws.message_repeat += 1; + if (ws.message_repeat >= 3) { + logger.info(`User ${ws.name} got automuted`); + chatProvider.automute(ws.name); + ws.message_repeat = 0; + } + } else { + ws.message_repeat = 0; + ws.last_message = message; + } + logger.info( + `Received chat message ${message} from ${ws.name} / ${ws.user.ip}`, + ); } else { logger.info('Got empty message or message from unidentified ws'); } diff --git a/src/socket/websockets.js b/src/socket/websockets.js index 3ed27d8..be0f2c0 100644 --- a/src/socket/websockets.js +++ b/src/socket/websockets.js @@ -65,7 +65,6 @@ class WebSockets { message: string, sendapi: boolean = true, ) { - logger.info(`Received chat message ${message} from ${name}`); this.listeners.forEach( (listener) => listener.broadcastChatMessage(name, message, sendapi), );