Update bot tsconfig and apply knock on changes. Remove antispam enrollment notification for discover server owners.

This commit is contained in:
Declan Chidlow 2024-08-08 19:22:47 +08:00
parent 9eac9fffc8
commit 345eec93fc
20 changed files with 50 additions and 99 deletions

View file

@ -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`

View file

@ -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));
}
}

View file

@ -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!`
),

View file

@ -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";

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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: [

View file

@ -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',

View file

@ -17,7 +17,6 @@ import {
getMembers,
isModerator,
NO_MANAGER_MSG,
parseUser,
parseUserOrId,
sanitizeMessageContent,
storeInfraction,

View file

@ -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";

View file

@ -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;

View file

@ -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 }

View file

@ -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);
}

View file

@ -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?');

View file

@ -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 = {

View file

@ -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']));
}

View file

@ -1,4 +1,3 @@
import { FindResult } from "monk";
import { client, dbs } from "../..";
import TempBan from "automod/dist/types/TempBan";
import logger from "../logger";

View file

@ -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";

View file

@ -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"
}
}