Mute by Ids

Don't bypass mutes on APISocket chat messages
closes #2
This commit is contained in:
HF 2022-06-20 02:51:42 +02:00
parent 6dc283765c
commit b63fe24307
4 changed files with 69 additions and 41 deletions

View File

@ -4,11 +4,11 @@
import { Op } from 'sequelize';
import logger from './logger';
import redis from '../data/redis/client';
import User from '../data/User';
import RateLimiter from '../utils/RateLimiter';
import {
Channel, RegUser, UserChannel, Message,
} from '../data/sql';
import { findIdByNameOrId } from '../data/sql/RegUser';
import ChatMessageBuffer from './ChatMessageBuffer';
import socketEvents from '../socket/SocketEvents';
import { cheapDetector } from './isProxy';
@ -26,9 +26,12 @@ function getUserFromMd(mdUserLink) {
let mdUser = mdUserLink.trim();
if (mdUser[0] === '@') {
mdUser = mdUser.substring(1);
}
if (mdUser[0] === '[' && mdUser[mdUser.length - 1] === ')') {
return mdUser.substring(1, mdUser.lastIndexOf(']')).trim();
if (mdUser[0] === '[' && mdUser[mdUser.length - 1] === ')') {
// if mdUser ping, select Id
mdUser = mdUser.substring(
mdUser.lastIndexOf('(') + 1, mdUser.length - 1,
).trim();
}
}
return mdUser;
}
@ -416,7 +419,7 @@ export class ChatProvider {
return t`Your mail has to be verified in order to chat`;
}
const muted = await ChatProvider.checkIfMuted(user);
const muted = await ChatProvider.checkIfMuted(user.id);
if (muted === -1) {
return t`You are permanently muted, join our guilded to apppeal the mute`;
}
@ -510,24 +513,24 @@ export class ChatProvider {
);
}
static async checkIfMuted(user) {
const key = `mute:${user.id}`;
static async checkIfMuted(uid) {
const key = `mute:${uid}`;
const ttl = await redis.ttl(key);
return ttl;
}
async mute(plainName, opts) {
async mute(nameOrId, opts) {
const timeMin = opts.duration || null;
const initiator = opts.initiator || null;
const printChannel = opts.printChannel || null;
const name = (plainName.startsWith('@'))
? plainName.substring(1) : plainName;
const id = await User.name2Id(name);
if (!id) {
return `Couldn't find user ${name}`;
const searchResult = await findIdByNameOrId(nameOrId);
if (!searchResult) {
return `Couldn't find user ${nameOrId}`;
}
const { name, id } = searchResult;
const userPing = `@[${name}](${id})`;
const key = `mute:${id}`;
if (timeMin) {
const ttl = timeMin * 60;
@ -561,17 +564,17 @@ export class ChatProvider {
return null;
}
async unmute(plainName, opts) {
async unmute(nameOrId, opts) {
const initiator = opts.initiator || null;
const printChannel = opts.printChannel || null;
const name = (plainName.startsWith('@'))
? plainName.substring(1) : plainName;
const id = await User.name2Id(name);
if (!id) {
return `Couldn't find user ${name}`;
const searchResult = await findIdByNameOrId(nameOrId);
if (!searchResult) {
return `Couldn't find user ${nameOrId}`;
}
const { name, id } = searchResult;
const userPing = `@[${name}](${id})`;
const key = `mute:${id}`;
const delKeys = await redis.del(key);
if (delKeys !== 1) {

View File

@ -7,7 +7,7 @@
* @flow
* */
import Sequelize from 'sequelize';
import { QueryTypes, Utils } from 'sequelize';
import redis from './redis/client';
import logger from '../core/logger';
@ -93,23 +93,6 @@ class User {
}
}
static async name2Id(name: string) {
try {
const userq = await sequelize.query(
'SELECT id FROM Users WHERE name = $1',
{
bind: [name],
type: Sequelize.QueryTypes.SELECT,
raw: true,
plain: true,
},
);
return userq.id;
} catch {
return null;
}
}
setRegUser(reguser) {
this.regUser = reguser;
this.id = reguser.id;
@ -244,7 +227,7 @@ class User {
'SELECT totalPixels FROM Users WHERE id = $1',
{
bind: [id],
type: Sequelize.QueryTypes.SELECT,
type: QueryTypes.SELECT,
raw: true,
plain: true,
},
@ -267,7 +250,7 @@ class User {
if (!this.regUser) return false;
try {
await this.regUser.update({
lastLogIn: Sequelize.literal('CURRENT_TIMESTAMP'),
lastLogIn: new Utils.Literal('CURRENT_TIMESTAMP'),
});
} catch (err) {
return false;

View File

@ -5,7 +5,7 @@
*
*/
import { DataTypes } from 'sequelize';
import { DataTypes, QueryTypes } from 'sequelize';
import sequelize from './sequelize';
import { generateHash } from '../../utils/hash';
@ -146,4 +146,39 @@ const RegUser = sequelize.define('User', {
});
export async function name2Id(name) {
try {
const userq = await sequelize.query(
'SELECT id FROM Users WHERE name = $1',
{
bind: [name],
type: QueryTypes.SELECT,
raw: true,
plain: true,
},
);
return userq.id;
} catch {
return null;
}
}
export async function findIdByNameOrId(searchString) {
let id = await name2Id(searchString);
if (id) {
return { name: searchString, id };
}
id = parseInt(searchString, 10);
if (!Number.isNaN(id)) {
const user = await RegUser.findByPk(id, {
attributes: ['name'],
raw: true,
});
if (user) {
return { name: user.name, id };
}
}
return null;
}
export default RegUser;

View File

@ -11,7 +11,7 @@
import WebSocket from 'ws';
import socketEvents from './SocketEvents';
import chatProvider from '../core/ChatProvider';
import chatProvider, { ChatProvider } from '../core/ChatProvider';
import { RegUser } from '../data/sql';
import { getIPFromRequest } from '../utils/ip';
import { setPixelByCoords } from '../core/setPixel';
@ -239,6 +239,13 @@ class APISocketServer {
if (command === 'chat') {
const [name, id, msg, country, channelId] = packet;
const uid = id || chatProvider.apiSocketUserId;
/*
* don't send if muted
*/
const mutedTtl = await ChatProvider.checkIfMuted(uid);
if (mutedTtl !== -2) {
return;
}
/*
* do not send message back up ws that sent it
*/