diff --git a/src/core/ChatProvider.js b/src/core/ChatProvider.js index d593d6c..3afc68c 100644 --- a/src/core/ChatProvider.js +++ b/src/core/ChatProvider.js @@ -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) { diff --git a/src/data/User.js b/src/data/User.js index ae49df7..feb6928 100644 --- a/src/data/User.js +++ b/src/data/User.js @@ -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; diff --git a/src/data/sql/RegUser.js b/src/data/sql/RegUser.js index 81a006b..918213e 100644 --- a/src/data/sql/RegUser.js +++ b/src/data/sql/RegUser.js @@ -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; diff --git a/src/socket/APISocketServer.js b/src/socket/APISocketServer.js index 08691ca..d603db9 100644 --- a/src/socket/APISocketServer.js +++ b/src/socket/APISocketServer.js @@ -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 */