Allow warning unknown users

This commit is contained in:
janderedev 2022-01-03 15:43:59 +01:00
parent 5731b1f254
commit 51291998b3
Signed by: Lea
GPG key ID: 5D5E18ACB990F57A
4 changed files with 26 additions and 18 deletions

View file

@ -1,9 +1,9 @@
import Command from "../../struct/Command"; import Command from "../../struct/Command";
import { isModerator, NO_MANAGER_MSG, parseUser, storeInfraction } from "../util"; import { isModerator, NO_MANAGER_MSG, parseUserOrId, storeInfraction } from "../util";
import Infraction from "../../struct/antispam/Infraction"; import Infraction from "../../struct/antispam/Infraction";
import { ulid } from "ulid"; import { ulid } from "ulid";
import InfractionType from "../../struct/antispam/InfractionType"; import InfractionType from "../../struct/antispam/InfractionType";
import { logModAction } from "../modules/mod_logs"; import { fetchUsername, logModAction } from "../modules/mod_logs";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
export default { export default {
@ -13,9 +13,9 @@ export default {
description: 'add an infraction to an user\'s record', description: 'add an infraction to an user\'s record',
run: async (message: MessageCommandContext, args: string[]) => { run: async (message: MessageCommandContext, args: string[]) => {
if (!await isModerator(message.member!, message.serverContext)) return message.reply(NO_MANAGER_MSG); if (!await isModerator(message.member!, message.serverContext)) return message.reply(NO_MANAGER_MSG);
let user = await parseUser(args.shift() ?? ''); let user = await parseUserOrId(args.shift() ?? '');
if (!user) return message.reply('I can\'t find that user.'); if (!user) return message.reply('I can\'t find that user.');
if (user.bot != null) return message.reply('You cannot warn bots.'); if ((user as any)?.bot != null) return message.reply('You cannot warn bots.');
let reason: string = args.join(' ') let reason: string = args.join(' ')
?.replace(new RegExp('`', 'g'), '\'') ?.replace(new RegExp('`', 'g'), '\'')
@ -39,10 +39,10 @@ export default {
message.reply(`### User warned` message.reply(`### User warned`
+ `${message.serverContext._id != message.channel?.server_id ? ` in **${message.serverContext.name}**` : ''}.\n` + `${message.serverContext._id != message.channel?.server_id ? ` in **${message.serverContext.name}**` : ''}.\n`
+ `This is ${userWarnCount == 1 ? '**the first warn**' : `warn number **${userWarnCount}**`}` + `This is ${userWarnCount == 1 ? '**the first warn**' : `warn number **${userWarnCount}**`}`
+ ` for ${user.username ?? 'this user'}.\n` + ` for ${await fetchUsername(user._id)}.\n`
+ `**Infraction ID:** \`${infraction._id}\`\n` + `**Infraction ID:** \`${infraction._id}\`\n`
+ `**Reason:** \`${infraction.reason}\``), + `**Reason:** \`${infraction.reason}\``),
logModAction('warn', message.serverContext, message.member!, user, reason, `This is warn number **${userWarnCount}** for this user.`), logModAction('warn', message.serverContext, message.member!, user._id, reason, `This is warn number **${userWarnCount}** for this user.`),
]); ]);
} }
} as Command; } as Command;

View file

@ -1,14 +1,11 @@
import Command from "../../struct/Command"; import Command from "../../struct/Command";
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
import { client } from "../.."; import { client } from "../..";
import Infraction from "../../struct/antispam/Infraction"; import Infraction from "../../struct/antispam/Infraction";
import InfractionType from "../../struct/antispam/InfractionType"; import InfractionType from "../../struct/antispam/InfractionType";
import { isModerator, NO_MANAGER_MSG, parseUser, uploadFile } from "../util"; import { isModerator, NO_MANAGER_MSG, parseUserOrId, uploadFile } from "../util";
import Day from 'dayjs'; import Day from 'dayjs';
import RelativeTime from 'dayjs/plugin/relativeTime'; import RelativeTime from 'dayjs/plugin/relativeTime';
import Xlsx from 'xlsx'; import Xlsx from 'xlsx';
import FormData from 'form-data';
import axios from "axios";
import { fetchUsername } from "../modules/mod_logs"; import { fetchUsername } from "../modules/mod_logs";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
@ -65,13 +62,13 @@ export default {
+ `Created ${Day(inf.date).fromNow()}`); + `Created ${Day(inf.date).fromNow()}`);
break; break;
default: default:
let user = await parseUser(args[0]); let user = await parseUserOrId(args[0]);
if (!user) return message.reply('Unknown user'); if (!user?._id) return message.reply('I can\'t find this user.');
let infs = userInfractions.get(user._id); let infs = userInfractions.get(user._id);
if (!infs) return message.reply(`There are no infractions stored for \`@${user.username}\`.`); if (!infs) return message.reply(`There are no infractions stored for \`${await fetchUsername(user._id)}\`.`);
else { else {
let msg = `## ${infs.length} infractions stored for @${user.username}\n\u200b\n`; let msg = `## ${infs.length} infractions stored for ${await fetchUsername(user._id)}\n\u200b\n`;
let attachSpreadsheet = false; let attachSpreadsheet = false;
for (const i in infs) { for (const i in infs) {
let inf = infs[i]; let inf = infs[i];
@ -94,7 +91,7 @@ export default {
if (attachSpreadsheet) { if (attachSpreadsheet) {
try { try {
let csv_data = [ let csv_data = [
[`Warns for @${user.username} (${user._id}) - ${Day().toString()}`], [`Warns for ${await fetchUsername(user._id)} (${user._id}) - ${Day().toString()}`],
[], [],
['Date', 'Reason', 'Created By', 'Type', 'Action Type', 'ID'], ['Date', 'Reason', 'Created By', 'Type', 'Action Type', 'ID'],
]; ];

View file

@ -1,6 +1,5 @@
import { Member } from "@janderedev/revolt.js/dist/maps/Members"; import { Member } from "@janderedev/revolt.js/dist/maps/Members";
import { Server } from "@janderedev/revolt.js/dist/maps/Servers"; import { Server } from "@janderedev/revolt.js/dist/maps/Servers";
import { User } from "@janderedev/revolt.js/dist/maps/Users";
import { client } from "../.."; import { client } from "../..";
import ServerConfig from "../../struct/ServerConfig"; import ServerConfig from "../../struct/ServerConfig";
import logger from "../logger"; import logger from "../logger";
@ -115,7 +114,7 @@ client.on('packet', async (packet) => {
} }
}); });
async function logModAction(type: 'warn'|'kick'|'ban', server: Server, mod: Member, target: User, reason: string|null, extraText?: string|null): Promise<void> { async function logModAction(type: 'warn'|'kick'|'ban', server: Server, mod: Member, target: string, reason: string|null, extraText?: string|null): Promise<void> {
try { try {
let config: ServerConfig = await client.db.get('servers').findOne({ id: server._id }) ?? {}; let config: ServerConfig = await client.db.get('servers').findOne({ id: server._id }) ?? {};
let logChannelID = config.logs?.modAction; let logChannelID = config.logs?.modAction;
@ -125,7 +124,7 @@ async function logModAction(type: 'warn'|'kick'|'ban', server: Server, mod: Memb
let aType = type == 'ban' ? 'banned' : type + 'ed'; let aType = type == 'ban' ? 'banned' : type + 'ed';
let msg = `User ${aType}\n` let msg = `User ${aType}\n`
+ `\`@${mod.user?.username}\` **${aType}** \`@` + `\`@${mod.user?.username}\` **${aType}** \`@`
+ `${target.username}\`${type == 'warn' ? '.' : ` from ${server.name}.`}\n` + `${await fetchUsername(target)}\`${type == 'warn' ? '.' : ` from ${server.name}.`}\n`
+ `**Reason**: \`${reason ? reason : 'No reason provided.'}\`\n` + `**Reason**: \`${reason ? reason : 'No reason provided.'}\`\n`
+ (extraText ?? ''); + (extraText ?? '');

View file

@ -67,6 +67,17 @@ async function parseUser(text: string): Promise<User|null> {
} catch(e) { return null; } } catch(e) { return null; }
} }
/**
* Does the exact same as `parseUser`, but returns only `_id` instead
* of null if the user was not found and the input is also an ID
*/
async function parseUserOrId(text: string): Promise<User|{_id: string}|null> {
let parsed = await parseUser(text);
if (parsed) return parsed;
if (ULID_REGEX.test(text)) return { _id: text.toUpperCase() };
return null;
}
async function isModerator(member: Member, server: Server) { async function isModerator(member: Member, server: Server) {
return hasPerm(member, 'KickMembers') return hasPerm(member, 'KickMembers')
|| await isBotManager(member, server) || await isBotManager(member, server)
@ -160,6 +171,7 @@ export {
isModerator, isModerator,
isBotManager, isBotManager,
parseUser, parseUser,
parseUserOrId,
storeInfraction, storeInfraction,
uploadFile, uploadFile,
sanitizeMessageContent, sanitizeMessageContent,