make it needed to be verified to chat

autoban on message repeat
log chat ips on more places
This commit is contained in:
HF 2020-04-27 20:44:22 +02:00
parent b72fce1589
commit 29129b98f7
4 changed files with 73 additions and 4 deletions

View File

@ -16,6 +16,28 @@ class ChatProvider {
constructor() { constructor() {
this.history = []; 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) { addMessage(name, message) {
@ -31,16 +53,37 @@ class ChatProvider {
return 'You can\'t send a message this long :('; return 'You can\'t send a message this long :(';
} }
const name = (user.regUser) ? user.regUser.name : null; const name = (user.regUser) ? user.regUser.name : null;
if (!name) { if (!name) {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
return 'Couldn\'t send your message, pls log out and back in again.'; 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) === '/') { if (user.isAdmin() && message.charAt(0) === '/') {
// admin commands // admin commands
const cmd = message.split(' '); const cmd = message.split(' ');
if (cmd[0] === '/mute') { 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') { } if (cmd[0] === '/unmute') {
return ChatProvider.unmute(cmd.slice(1).join(' ')); return ChatProvider.unmute(cmd.slice(1).join(' '));
} }
@ -67,13 +110,22 @@ class ChatProvider {
webSockets.broadcastChatMessage(name, message, sendapi); 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) { static async checkIfMuted(user) {
const key = `mute:${user.id}`; const key = `mute:${user.id}`;
const ttl: number = await redis.ttlAsync(key); const ttl: number = await redis.ttlAsync(key);
return ttl; return ttl;
} }
static async mute(name, timeMin) { static async mute(name, timeMin = null) {
const id = await User.name2Id(name); const id = await User.name2Id(name);
if (!id) { if (!id) {
return `Couldn't find user ${name}`; return `Couldn't find user ${name}`;

View File

@ -7,10 +7,11 @@
import type { Request, Response } from 'express'; import type { Request, Response } from 'express';
import Sequelize from 'sequelize'; import Sequelize from 'sequelize';
import logger from '../../../core/logger';
import { RegUser } from '../../../data/models'; import { RegUser } from '../../../data/models';
import mailProvider from '../../../core/mail'; import mailProvider from '../../../core/mail';
import getMe from '../../../core/me'; import getMe from '../../../core/me';
import { getHostFromRequest } from '../../../utils/ip'; import { getIPFromRequest, getHostFromRequest } from '../../../utils/ip';
import { import {
validateEMail, validateEMail,
validateName, validateName,
@ -61,6 +62,9 @@ export default async (req: Request, res: Response) => {
return; return;
} }
const ip = await getIPFromRequest(req);
logger.info(`Created new user ${name} ${email} ${ip}`);
const user = req.noauthUser; const user = req.noauthUser;
user.id = newuser.id; user.id = newuser.id;
user.regUser = newuser; user.regUser = newuser;

View File

@ -229,6 +229,20 @@ class SocketServer extends WebSocketEvents {
if (errorMsg) { if (errorMsg) {
ws.send(JSON.stringify(['info', 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 { } else {
logger.info('Got empty message or message from unidentified ws'); logger.info('Got empty message or message from unidentified ws');
} }

View File

@ -65,7 +65,6 @@ class WebSockets {
message: string, message: string,
sendapi: boolean = true, sendapi: boolean = true,
) { ) {
logger.info(`Received chat message ${message} from ${name}`);
this.listeners.forEach( this.listeners.forEach(
(listener) => listener.broadcastChatMessage(name, message, sendapi), (listener) => listener.broadcastChatMessage(name, message, sendapi),
); );