From 345eec93fcc56a8110d98d4f27a266c873aa0fbb Mon Sep 17 00:00:00 2001 From: Declan Chidlow Date: Thu, 8 Aug 2024 19:22:47 +0800 Subject: [PATCH] Update bot tsconfig and apply knock on changes. Remove antispam enrollment notification for discover server owners. --- bot/src/bot/commands/admin/botadm.ts | 4 +- bot/src/bot/commands/admin/shell_eval.ts | 2 +- bot/src/bot/commands/configuration/login.ts | 6 +- bot/src/bot/commands/configuration/prefix.ts | 2 +- .../bot/commands/configuration/settings.ts | 4 +- bot/src/bot/commands/misc/healthcheck.ts | 2 +- bot/src/bot/commands/misc/help.ts | 2 +- bot/src/bot/commands/misc/test.ts | 2 +- bot/src/bot/commands/moderation/avatar.ts | 4 -- bot/src/bot/commands/moderation/kick.ts | 1 - bot/src/bot/commands/moderation/votekick.ts | 3 +- bot/src/bot/logger.ts | 2 +- bot/src/bot/modules/antispam.ts | 66 ++++--------------- .../custom_rules/message_content_trigger.ts | 2 +- bot/src/bot/modules/metrics.ts | 6 +- bot/src/bot/modules/mod_logs.ts | 2 - bot/src/bot/modules/raid_detection.ts | 2 +- bot/src/bot/modules/tempbans.ts | 1 - bot/src/bot/util.ts | 1 - bot/tsconfig.json | 35 +++++----- 20 files changed, 50 insertions(+), 99 deletions(-) diff --git a/bot/src/bot/commands/admin/botadm.ts b/bot/src/bot/commands/admin/botadm.ts index 7306622..795bb4d 100644 --- a/bot/src/bot/commands/admin/botadm.ts +++ b/bot/src/bot/commands/admin/botadm.ts @@ -7,7 +7,7 @@ import fs from 'fs'; import path from 'path'; import { User } from "revolt.js"; import CommandCategory from "../../../struct/commands/CommandCategory"; -import { getMutualServers, parseUserOrId } from "../../util"; +import { parseUserOrId } from "../../util"; const BLACKLIST_BAN_REASON = `This user is globally blacklisted and has been banned automatically. If you wish to opt out of the global blacklist, run '/botctl ignore_blacklist yes'.`; const BLACKLIST_MESSAGE = (username: string) => `\`@${username}\` has been banned automatically. Check the ban reason for more info.`; @@ -58,7 +58,7 @@ export default { + `Users: \`${client.users.size()}\`\n` + `### Misc\n` + `Command count: \`${commands.length}\`\n` - + `Environment: \`${process.env.NODE_ENV || 'testing'}\`\n` + + `Environment: \`${process.env['NODE_ENV'] || 'testing'}\`\n` + `Commit hash: \`${await getCommitHash() || 'Unknown'}\`\n` + `### Packages\n` + `revolt.js: \`${pjson.dependencies['revolt.js']}\`\n` diff --git a/bot/src/bot/commands/admin/shell_eval.ts b/bot/src/bot/commands/admin/shell_eval.ts index 5427449..494bb47 100644 --- a/bot/src/bot/commands/admin/shell_eval.ts +++ b/bot/src/bot/commands/admin/shell_eval.ts @@ -23,7 +23,7 @@ export default { } m?.edit({ content: str }) - .catch(e => console.warn('Failed to edit message')); + .catch(e => console.warn('Failed to edit message', e)); } } diff --git a/bot/src/bot/commands/configuration/login.ts b/bot/src/bot/commands/configuration/login.ts index 28b6a6d..3b9f977 100644 --- a/bot/src/bot/commands/configuration/login.ts +++ b/bot/src/bot/commands/configuration/login.ts @@ -1,5 +1,5 @@ import { FindOneResult } from "monk"; -import { client, dbs } from "../../.."; +import { dbs } from "../../.."; import CommandCategory from "../../../struct/commands/CommandCategory"; import SimpleCommand from "../../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../../struct/MessageCommandContext"; @@ -17,7 +17,7 @@ export default { const code = args.shift(); if (!code) { return message.reply(`If you're trying to log in, you can access the dashboard ` - + `[here](${process.env.WEB_UI_URL || 'https://automod.janderedev.xyz'}).\n\n` + + `[here](${process.env['WEB_UI_URL'] || 'https://automod.janderedev.xyz'}).\n\n` + `If you already have a code, you can use \`${DEFAULT_PREFIX}login [Code]\`.`); } @@ -41,7 +41,7 @@ export default { `# If someone told you to run this, stop!\n` + `This could give an attacker access to all servers you're using AutoMod in.\n` + `If someone else told you to run this command, **block them and ignore this.**\n\n` + - `Otherwise, if this was you trying to log in from <${process.env.WEB_UI_URL || 'https://automod.janderedev.xyz'}>, \n` + + `Otherwise, if this was you trying to log in from <${process.env['WEB_UI_URL'] || 'https://automod.janderedev.xyz'}>, \n` + `you can run this command again to continue.\n` + `##### You're seeing this because this is the first time you're trying to log in. Stay safe!` ), diff --git a/bot/src/bot/commands/configuration/prefix.ts b/bot/src/bot/commands/configuration/prefix.ts index 58fe313..c380337 100644 --- a/bot/src/bot/commands/configuration/prefix.ts +++ b/bot/src/bot/commands/configuration/prefix.ts @@ -1,5 +1,5 @@ import SimpleCommand from "../../../struct/commands/SimpleCommand"; -import { client, dbs } from "../../.."; +import { dbs } from "../../.."; import { DEFAULT_PREFIX } from "../../modules/command_handler"; import { isBotManager, NO_MANAGER_MSG } from "../../util"; import MessageCommandContext from "../../../struct/MessageCommandContext"; diff --git a/bot/src/bot/commands/configuration/settings.ts b/bot/src/bot/commands/configuration/settings.ts index b3da7b0..f9235b1 100644 --- a/bot/src/bot/commands/configuration/settings.ts +++ b/bot/src/bot/commands/configuration/settings.ts @@ -7,8 +7,8 @@ export default { aliases: [ 'setting' ], description: 'Manage AutoMod\'s configuration', category: CommandCategory.Config, - run: async (message: MessageCommandContext, args: string[]) => { + run: async (message: MessageCommandContext) => { await message.reply(`Bot configuration can be managed from ` - + `[here](<${process.env.WEB_UI_URL || 'https://automod.janderedev.xyz'}/dashboard>).`); + + `[here](<${process.env['WEB_UI_URL'] || 'https://automod.janderedev.xyz'}/dashboard>).`); } } as SimpleCommand; diff --git a/bot/src/bot/commands/misc/healthcheck.ts b/bot/src/bot/commands/misc/healthcheck.ts index 33b16b7..2d5f499 100644 --- a/bot/src/bot/commands/misc/healthcheck.ts +++ b/bot/src/bot/commands/misc/healthcheck.ts @@ -8,6 +8,6 @@ export default { description: 'Health check', category: CommandCategory.Miscellaneous, run: async (message: MessageCommandContext, args: string[]) => { - const msg = await message.reply('Health check success: ' + args.join(' ')); + await message.reply('Health check success: ' + args.join(' ')); } } as SimpleCommand; diff --git a/bot/src/bot/commands/misc/help.ts b/bot/src/bot/commands/misc/help.ts index bd5dd2f..713ee46 100644 --- a/bot/src/bot/commands/misc/help.ts +++ b/bot/src/bot/commands/misc/help.ts @@ -53,7 +53,7 @@ export default { `## AutoMod Help\n` + `Type **${prefix}help [category]** to view see all commands or **${prefix}help [command]** to learn more about a command.\n\n` + `### [Open Server Settings]` + - `(<${process.env.WEB_UI_URL || "https://automod.vale.rocks"}/dashboard/${message.channel?.serverId}>)\n\n`; + `(<${process.env['WEB_UI_URL'] || "https://automod.vale.rocks"}/dashboard/${message.channel?.serverId}>)\n\n`; let total = 0; diff --git a/bot/src/bot/commands/misc/test.ts b/bot/src/bot/commands/misc/test.ts index 1d14efc..244f92e 100644 --- a/bot/src/bot/commands/misc/test.ts +++ b/bot/src/bot/commands/misc/test.ts @@ -7,7 +7,7 @@ export default { aliases: ["testalias"], description: "Test command", category: CommandCategory.Miscellaneous, - run: (message: MessageCommandContext, args: string[]) => { + run: async (message: MessageCommandContext) => { message.reply({ content: "Beep boop.", embeds: [ diff --git a/bot/src/bot/commands/moderation/avatar.ts b/bot/src/bot/commands/moderation/avatar.ts index fe6a2f5..96a5995 100644 --- a/bot/src/bot/commands/moderation/avatar.ts +++ b/bot/src/bot/commands/moderation/avatar.ts @@ -1,11 +1,7 @@ -import { ServerMember } from "revolt.js"; -import axios from "axios"; import CommandCategory from "../../../struct/commands/CommandCategory"; import SimpleCommand from "../../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../../struct/MessageCommandContext"; import { isModerator, NO_MANAGER_MSG, parseUser } from "../../util"; -import AutomodClient from "../../../struct/AutomodClient"; -import { client } from "../../.."; export default { name: 'avatar', diff --git a/bot/src/bot/commands/moderation/kick.ts b/bot/src/bot/commands/moderation/kick.ts index 4b25fd7..dd1e439 100644 --- a/bot/src/bot/commands/moderation/kick.ts +++ b/bot/src/bot/commands/moderation/kick.ts @@ -17,7 +17,6 @@ import { getMembers, isModerator, NO_MANAGER_MSG, - parseUser, parseUserOrId, sanitizeMessageContent, storeInfraction, diff --git a/bot/src/bot/commands/moderation/votekick.ts b/bot/src/bot/commands/moderation/votekick.ts index ea04b78..06304bb 100644 --- a/bot/src/bot/commands/moderation/votekick.ts +++ b/bot/src/bot/commands/moderation/votekick.ts @@ -1,6 +1,5 @@ -import { FindResult } from "monk"; import { ulid } from "ulid"; -import { client, dbs } from "../../../"; +import { dbs } from "../../../"; import CommandCategory from "../../../struct/commands/CommandCategory"; import SimpleCommand from "../../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../../struct/MessageCommandContext"; diff --git a/bot/src/bot/logger.ts b/bot/src/bot/logger.ts index 62384c4..51b17a1 100644 --- a/bot/src/bot/logger.ts +++ b/bot/src/bot/logger.ts @@ -1,6 +1,6 @@ import Log75, { LogLevel } from 'log75'; // Thanks to being forced to switch to ESM this broke somehow? -let logger: Log75 = new (Log75 as any).default(process.env.NODE_ENV == 'production' ? LogLevel.Standard : LogLevel.Debug); +let logger: Log75 = new (Log75 as any).default(process.env['NODE_ENV'] == 'production' ? LogLevel.Standard : LogLevel.Debug); export default logger; diff --git a/bot/src/bot/modules/antispam.ts b/bot/src/bot/modules/antispam.ts index 48d4828..6d8629c 100644 --- a/bot/src/bot/modules/antispam.ts +++ b/bot/src/bot/modules/antispam.ts @@ -1,12 +1,12 @@ import { Message } from "revolt.js"; import { ulid } from "ulid"; -import { client, dbs } from "../.."; +import { dbs } from "../.."; import AntispamRule from "automod/dist/types/antispam/AntispamRule"; import Infraction from "automod/dist/types/antispam/Infraction"; import InfractionType from "automod/dist/types/antispam/InfractionType"; import ModerationAction from "automod/dist/types/antispam/ModerationAction"; import logger from "../logger"; -import { awaitClient, generateInfractionDMEmbed, isModerator, sendLogMessage, storeInfraction } from "../util"; +import { generateInfractionDMEmbed, isModerator, sendLogMessage, storeInfraction } from "../util"; import { getDmChannel, sanitizeMessageContent } from "../util"; import ServerConfig from "automod/dist/types/ServerConfig"; import { WORDLIST_DEFAULT_MESSAGE } from "../commands/configuration/botctl"; @@ -124,8 +124,7 @@ async function wordFilterCheck(message: Message, config: ServerConfig) { console.log('Message matched word filter!'); - // Lack of `break` is intended here - switch(config.wordlistAction?.action) { + switch (config.wordlistAction?.action) { case 'WARN': { try { const infraction: Infraction = { @@ -145,12 +144,14 @@ async function wordFilterCheck(message: Message, config: ServerConfig) { const dmChannel = await getDmChannel(message.author!); if (dmChannel.havePermission('SendMessage') && dmChannel.havePermission('SendEmbeds')) { - await dmChannel.sendMessage({ embeds: [ embed ] }); + await dmChannel.sendMessage({ embeds: [embed] }); } else logger.warn('Missing permission to DM user.'); } - } catch(e) { + break; + } catch (e) { console.error(e); + break; } } case 'DELETE': { @@ -164,7 +165,9 @@ async function wordFilterCheck(message: Message, config: ServerConfig) { await message.channel.sendMessage((config.wordlistAction.message || WORDLIST_DEFAULT_MESSAGE) .replaceAll('{{user_id}}', message.authorId!)); } + break; } + break; } case 'LOG': default: { @@ -177,10 +180,10 @@ async function wordFilterCheck(message: Message, config: ServerConfig) { `>${sanitizeMessageContent(message.content.substring(0, 1000)).trim().replace(/\n/g, '\n>')}`, color: '#ff557f', }); + break; } - } - } catch(e) { + } catch (e) { console.error(e); } } @@ -251,51 +254,4 @@ function checkMessageForFilteredWords(message: string, config: ServerConfig): bo return false; } -// Scan all servers for the `discoverable` flag and notify their owners that antispam is forcefully enabled -const notifyPublicServers = async () => { - logger.info('Sending antispam notification to public servers'); - - const servers = Array.from(client.servers.values()) - .filter(server => server.discoverable); - - const res = await dbs.SERVERS.find({ - id: { $in: servers.map(s => s.id) }, - discoverAutospamNotify: { $in: [ undefined, false ] }, - }); - - for (const serverConfig of res) { - try { - logger.info(`Sending notification to owner of server ${serverConfig.id}`); - - if (serverConfig.discoverAutospamNotify) { - logger.warn('This server already received the message'); - continue; - } - - await dbs.SERVERS.update( - { id: serverConfig.id }, - { $set: { discoverAutospamNotify: true, antispamEnabled: true, allowBlacklistedUsers: false } }, - ); - - const server = client.servers.get(serverConfig.id); - const channel = await getDmChannel(server!.ownerId); - await channel.sendMessage(`Hi there, - -It looks like your server, **${sanitizeMessageContent(server!.name).trim()}**, has been added to server discovery. Congratulations! - -In order to keep Revolt free of spam, AutoMod enables spam protection by default on public servers. -You are receiving this message to inform you that said features have been enabled automatically in your server. - -Please ensure that AutoMod has appropriate permissions to kick and ban users. -You may also want to set up a logging channel by running \`/botctl logs modaction #yourchannel\` to receive details about antispam events if you haven't done so already. - -Thanks for being part of Revolt!`); - } catch(e) { - console.error(e); - } - } -} - -// awaitClient().then(() => notifyPublicServers()); - export { antispam, wordFilterCheck, checkMessageForFilteredWords } diff --git a/bot/src/bot/modules/custom_rules/message_content_trigger.ts b/bot/src/bot/modules/custom_rules/message_content_trigger.ts index 8352355..5744068 100644 --- a/bot/src/bot/modules/custom_rules/message_content_trigger.ts +++ b/bot/src/bot/modules/custom_rules/message_content_trigger.ts @@ -39,7 +39,7 @@ async function messageContentTrigger(message: Message, trigger: CustomRuleTrigge let script = new VM.Script('matchedStrings = content.match(regex);', { timeout: 2 }); script.runInContext(ctx); - if (ctx.matchedStrings?.length) matched = true; + if (ctx['matchedStrings']?.length) matched = true; } catch(e) { console.error('Exception thrown while parsing RegEx: ' + e); } diff --git a/bot/src/bot/modules/metrics.ts b/bot/src/bot/modules/metrics.ts index aa4d7b1..b6b81d2 100644 --- a/bot/src/bot/modules/metrics.ts +++ b/bot/src/bot/modules/metrics.ts @@ -3,7 +3,7 @@ import http from 'http'; import logger from '../logger'; import { client } from '../..'; -const PORT = Number(process.env.BOT_METRICS_PORT); +const PORT = Number(process.env['BOT_METRICS_PORT']); prom.collectDefaultMetrics({ prefix: 'automod_' }); @@ -45,11 +45,11 @@ if (!isNaN(PORT)) { measureLatency(); setInterval(measureLatency, 10000); - if (process.env.BOT_METRICS_MSG_PING_CHANNEL) { + if (process.env['BOT_METRICS_MSG_PING_CHANNEL']) { logger.info('BOT_METRICS_MSG_PING_CHANNEL is set, enabling message latency measuring'); const getMsgPing = async () => { - const channel = client.channels.get(process.env.BOT_METRICS_MSG_PING_CHANNEL!); + const channel = client.channels.get(process.env['BOT_METRICS_MSG_PING_CHANNEL']!); try { const now = Date.now(); const msg = await channel?.sendMessage('Ping?'); diff --git a/bot/src/bot/modules/mod_logs.ts b/bot/src/bot/modules/mod_logs.ts index 8529500..1270fa3 100644 --- a/bot/src/bot/modules/mod_logs.ts +++ b/bot/src/bot/modules/mod_logs.ts @@ -56,7 +56,6 @@ client.on('messageUpdate', async (message, oldMessage) => { client.on('messageDelete', async (message) => { try { let channel = client.channels.get(message.channelId); - let author = message.authorId ? client.users.get(message.authorId) : null; if (!channel) return; let msgRaw = String(message.content ?? '(Unknown)'); @@ -114,7 +113,6 @@ client.on('messageDeleteBulk', async (messages) => { ]); } - const sheet = Xlsx.utils.aoa_to_sheet(data); const csv = Xlsx.utils.sheet_to_csv(data); let embed: LogMessage = { diff --git a/bot/src/bot/modules/raid_detection.ts b/bot/src/bot/modules/raid_detection.ts index 195b288..7e5c98c 100644 --- a/bot/src/bot/modules/raid_detection.ts +++ b/bot/src/bot/modules/raid_detection.ts @@ -5,5 +5,5 @@ import logger from '../logger'; if (process.env['AUTOMOD_LOAD_SPAM_DETECTION']) { logger.info('Importing spam detection'); import(path.join(process.cwd(), '..', 'private', 'automod-spam-detection', 'dist', 'index.js')) - .then(mod => mod.raidDetection(client as any, logger, client.db, process.env.REDIS_URL)); + .then(mod => mod.raidDetection(client as any, logger, client.db, process.env['REDIS_URL'])); } diff --git a/bot/src/bot/modules/tempbans.ts b/bot/src/bot/modules/tempbans.ts index dfd385b..611f646 100644 --- a/bot/src/bot/modules/tempbans.ts +++ b/bot/src/bot/modules/tempbans.ts @@ -1,4 +1,3 @@ -import { FindResult } from "monk"; import { client, dbs } from "../.."; import TempBan from "automod/dist/types/TempBan"; import logger from "../logger"; diff --git a/bot/src/bot/util.ts b/bot/src/bot/util.ts index 539ae3f..d12d58e 100644 --- a/bot/src/bot/util.ts +++ b/bot/src/bot/util.ts @@ -8,7 +8,6 @@ import { Server } from "revolt.js"; import LogConfig from "automod/dist/types/LogConfig"; import LogMessage from "automod/dist/types/LogMessage"; import logger from "./logger"; -import { ulid } from "ulid"; import { Channel } from "revolt.js"; import { Message } from "revolt.js"; import { isSudo } from "./commands/admin/botadm"; diff --git a/bot/tsconfig.json b/bot/tsconfig.json index 0c96cff..26c8483 100644 --- a/bot/tsconfig.json +++ b/bot/tsconfig.json @@ -1,25 +1,30 @@ { "compilerOptions": { // Enable latest features + "lib": ["ESNext", "DOM", "DOM.Iterable"], "target": "ESNext", "module": "ESNext", - "moduleResolution": "node", - + "moduleDetection": "force", + "allowJs": true, // Bundler mode - "declaration": true, - "sourceMap": true, - "rootDir": "./src", - "outDir": "./dist", - - // Interop - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - + "moduleResolution": "node", // Best practices "strict": true, - "strictPropertyInitialization": false, "skipLibCheck": true, - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "strictPropertyInitialization": false, + "noFallthroughCasesInSwitch": true, + // Some stricter flags (enabled) + "noUnusedLocals": true, + "noUnusedParameters": true, + "noPropertyAccessFromIndexSignature": true, + "declaration": true, + "declarationMap": true, + // Additional improvements + "esModuleInterop": true, + "resolveJsonModule": true, + "forceConsistentCasingInFileNames": true, + "useDefineForClassFields": true, + "rootDir": "./src", + "outDir": "./dist" + } }