refactoring

This commit is contained in:
janderedev 2022-04-09 13:03:12 +02:00
parent f5515a6716
commit a06c3547fb
Signed by: Lea
GPG key ID: 5D5E18ACB990F57A
22 changed files with 179 additions and 143 deletions

View file

@ -1,7 +1,7 @@
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import { hasPerm, parseUser } from "../util"; import { hasPerm, parseUser } from "../util";
import ServerConfig from "../../struct/ServerConfig"; import ServerConfig from "../../struct/ServerConfig";
import { client } from "../.."; import { client, dbs } from "../..";
import { User } from "@janderedev/revolt.js/dist/maps/Users"; import { User } from "@janderedev/revolt.js/dist/maps/Users";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
@ -18,8 +18,8 @@ export default {
if (!hasPerm(message.member!, 'ManageServer')) if (!hasPerm(message.member!, 'ManageServer'))
return message.reply('You need **ManageServer** permission to use this command.'); return message.reply('You need **ManageServer** permission to use this command.');
let config: ServerConfig = (await client.db.get('servers').findOne({ id: message.serverContext._id })) ?? {}; let config = await dbs.SERVERS.findOne({ id: message.serverContext._id });
let admins = config.botManagers ?? []; let admins = config?.botManagers ?? [];
let user: User|null; let user: User|null;
switch(args[0]?.toLowerCase()) { switch(args[0]?.toLowerCase()) {
@ -32,7 +32,7 @@ export default {
if (admins.indexOf(user._id) > -1) return message.reply('This user is already added as bot admin.'); if (admins.indexOf(user._id) > -1) return message.reply('This user is already added as bot admin.');
admins.push(user._id); admins.push(user._id);
await client.db.get('servers').update({ id: message.serverContext._id }, { $set: { botManagers: admins } }); await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { botManagers: admins } });
message.reply(`✅ Added [@${user.username}](/@${user._id}) to bot admins.`); message.reply(`✅ Added [@${user.username}](/@${user._id}) to bot admins.`);
break; break;
@ -47,7 +47,7 @@ export default {
if (admins.indexOf(user._id) == -1) return message.reply('This user is not added as bot admin.'); if (admins.indexOf(user._id) == -1) return message.reply('This user is not added as bot admin.');
admins = admins.filter(a => a != user?._id); admins = admins.filter(a => a != user?._id);
await client.db.get('servers').update({ id: message.serverContext._id }, { $set: { botManagers: admins } }); await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { botManagers: admins } });
message.reply(`✅ Removed [@${user.username}](/@${user._id}) from bot admins.`); message.reply(`✅ Removed [@${user.username}](/@${user._id}) from bot admins.`);
break; break;

View file

@ -1,5 +1,5 @@
import { FindOneResult } from "monk"; import { FindOneResult } from "monk";
import { client } from "../.."; import { client, dbs } from "../..";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
@ -21,7 +21,7 @@ export default {
switch(action) { switch(action) {
case 'scan_userlist': case 'scan_userlist':
try { try {
let serverConf: FindOneResult<ServerConfig> = await client.db.get('servers').findOne({ id: message.serverContext._id }); let serverConf: FindOneResult<ServerConfig> = await dbs.SERVERS.findOne({ id: message.serverContext._id });
if (!serverConf?.enableUserScan) return message.reply(`User scanning is not enabled for this server.`); if (!serverConf?.enableUserScan) return message.reply(`User scanning is not enabled for this server.`);
if (userscans.includes(message.serverContext._id)) return message.reply(`There is already a scan running for this server.`); if (userscans.includes(message.serverContext._id)) return message.reply(`There is already a scan running for this server.`);

View file

@ -1,5 +1,5 @@
import { FindOneResult } from "monk"; import { FindOneResult } from "monk";
import { client } from "../.."; import { client, dbs } from "../..";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
@ -21,7 +21,7 @@ export default {
+ `If you already have a code, you can use \`${DEFAULT_PREFIX}login [Code]\`.`); + `If you already have a code, you can use \`${DEFAULT_PREFIX}login [Code]\`.`);
} }
const login: FindOneResult<PendingLogin> = await client.db.get('pending_logins').findOne({ const login: FindOneResult<PendingLogin> = await dbs.PENDING_LOGINS.findOne({
code, code,
user: message.author_id, user: message.author_id,
confirmed: false, confirmed: false,
@ -45,7 +45,7 @@ export default {
`you can run this command again to continue.\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!` `##### You're seeing this because this is the first time you're trying to log in. Stay safe!`
), ),
client.db.get('pending_logins').update({ _id: login._id }, { $set: { requirePhishingConfirmation: false } }), dbs.PENDING_LOGINS.update({ _id: login._id }, { $set: { requirePhishingConfirmation: false } }),
]); ]);
return; return;
} }
@ -53,7 +53,7 @@ export default {
await Promise.all([ await Promise.all([
message.reply(`Successfully logged in.\n\n` + message.reply(`Successfully logged in.\n\n` +
`If this wasn't you, run \`${DEFAULT_PREFIX}logout ${code}\` immediately.`), `If this wasn't you, run \`${DEFAULT_PREFIX}logout ${code}\` immediately.`),
client.db.get('pending_logins').update({ _id: login._id }, { $set: { confirmed: true } }), dbs.PENDING_LOGINS.update({ _id: login._id }, { $set: { confirmed: true } }),
]); ]);
} catch(e) { } catch(e) {
console.error(e); console.error(e);

View file

@ -1,5 +1,5 @@
import { FindOneResult, FindResult } from "monk"; import { FindOneResult, FindResult } from "monk";
import { client } from "../.."; import { client, dbs } from "../..";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
@ -22,16 +22,15 @@ export default {
if (code.toLowerCase() == 'all') { if (code.toLowerCase() == 'all') {
const [resA, resB] = await Promise.all([ const [resA, resB] = await Promise.all([
client.db.get('pending_logins').update({ user: message.author_id, invalid: false }, { $set: { invalid: true } }), dbs.PENDING_LOGINS.update({ user: message.author_id, invalid: false }, { $set: { invalid: true } }),
client.db.get('sessions').update({ user: message.author_id, invalid: false }, { $set: { invalid: true } }), dbs.SESSIONS.update({ user: message.author_id, invalid: false }, { $set: { invalid: true } }),
]); ]);
if (resA.nModified == 0 && resB.nModified == 0) return message.reply('There are no sessions to invalidate.'); if (resA.nModified == 0 && resB.nModified == 0) return message.reply('There are no sessions to invalidate.');
message.reply(`Successfully invalidated ${resA.nModified} codes and ${resB.nModified} sessions.`); message.reply(`Successfully invalidated ${resA.nModified} codes and ${resB.nModified} sessions.`);
} else { } else {
const loginAttempt: FindOneResult<PendingLogin> = await client.db.get('pending_logins') const loginAttempt = await dbs.PENDING_LOGINS.findOne({
.findOne({
code: code.toUpperCase(), code: code.toUpperCase(),
user: message.author_id, user: message.author_id,
}); });
@ -40,12 +39,12 @@ export default {
return message.reply('That code doesn\'t seem to exist.'); return message.reply('That code doesn\'t seem to exist.');
} }
await client.db.get('pending_logins').update({ _id: loginAttempt._id }, { $set: { invalid: true } }); await dbs.PENDING_LOGINS.update({ _id: loginAttempt._id }, { $set: { invalid: true } });
if (loginAttempt.exchanged) { if (loginAttempt.exchanged) {
const session: FindOneResult<any> = await client.db.get('sessions').findOne({ nonce: loginAttempt.nonce }); const session = await dbs.SESSIONS.findOne({ nonce: loginAttempt.nonce });
if (session) { if (session) {
await client.db.get('sessions').update({ _id: session._id }, { $set: { invalid: true } }); await dbs.SESSIONS.update({ _id: session._id }, { $set: { invalid: true } });
return message.reply(`Successfully invalidated code and terminated associated session.`); return message.reply(`Successfully invalidated code and terminated associated session.`);
} }
} }

View file

@ -2,7 +2,7 @@ import SimpleCommand from "../../struct/commands/SimpleCommand";
import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
import { isBotManager, NO_MANAGER_MSG, parseUser } from "../util"; import { isBotManager, NO_MANAGER_MSG, parseUser } from "../util";
import ServerConfig from "../../struct/ServerConfig"; import ServerConfig from "../../struct/ServerConfig";
import { client } from "../.."; import { client, dbs } from "../..";
import { User } from "@janderedev/revolt.js/dist/maps/Users"; import { User } from "@janderedev/revolt.js/dist/maps/Users";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
@ -20,8 +20,8 @@ export default {
run: async (message: MessageCommandContext, args: string[]) => { run: async (message: MessageCommandContext, args: string[]) => {
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG); if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
let config: ServerConfig = (await client.db.get('servers').findOne({ id: message.serverContext._id })) ?? {}; let config = await dbs.SERVERS.findOne({ id: message.serverContext._id });
let mods = config.moderators ?? []; let mods = config?.moderators ?? [];
let user: User|null; let user: User|null;
switch(args[0]?.toLowerCase()) { switch(args[0]?.toLowerCase()) {
@ -34,7 +34,7 @@ export default {
if (mods.indexOf(user._id) > -1) return message.reply('This user is already added as moderator.'); if (mods.indexOf(user._id) > -1) return message.reply('This user is already added as moderator.');
mods.push(user._id); mods.push(user._id);
await client.db.get('servers').update({ id: message.serverContext._id }, { $set: { moderators: mods } }); await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { moderators: mods } });
message.reply(`✅ Added [@${user.username}](/@${user._id}) to moderators.`); message.reply(`✅ Added [@${user.username}](/@${user._id}) to moderators.`);
break; break;
@ -49,7 +49,7 @@ export default {
if (mods.indexOf(user._id) == -1) return message.reply('This user is not added as moderator.'); if (mods.indexOf(user._id) == -1) return message.reply('This user is not added as moderator.');
mods = mods.filter(a => a != user?._id); mods = mods.filter(a => a != user?._id);
await client.db.get('servers').update({ id: message.serverContext._id }, { $set: { moderators: mods } }); await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { moderators: mods } });
message.reply(`✅ Removed [@${user.username}](/@${user._id}) from moderators.`); message.reply(`✅ Removed [@${user.username}](/@${user._id}) from moderators.`);
break; break;

View file

@ -1,9 +1,8 @@
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { client, dbs } from "../..";
import { client } from "../..";
import ServerConfig from "../../struct/ServerConfig"; import ServerConfig from "../../struct/ServerConfig";
import { DEFAULT_PREFIX } from "../modules/command_handler"; import { DEFAULT_PREFIX } from "../modules/command_handler";
import { hasPerm, isBotManager, NO_MANAGER_MSG } from "../util"; import { isBotManager, NO_MANAGER_MSG } from "../util";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
@ -17,7 +16,7 @@ export default {
syntax: SYNTAX, syntax: SYNTAX,
category: CommandCategory.Config, category: CommandCategory.Config,
run: async (message: MessageCommandContext, args: string[]) => { run: async (message: MessageCommandContext, args: string[]) => {
let config: ServerConfig = (await client.db.get('servers').findOne({ id: message.channel?.server_id })) ?? {}; let config = await dbs.SERVERS.findOne({ id: message.channel!.server_id! });
switch(args[0]?.toLowerCase()) { switch(args[0]?.toLowerCase()) {
case 'set': case 'set':
@ -26,28 +25,28 @@ export default {
args.shift(); args.shift();
if (args.length == 0) return message.reply('You need to specify a prefix.'); if (args.length == 0) return message.reply('You need to specify a prefix.');
let newPrefix = args.join(' ').trim(); let newPrefix = args.join(' ').trim();
let oldPrefix = config.prefix ?? DEFAULT_PREFIX; let oldPrefix = config?.prefix ?? DEFAULT_PREFIX;
let val = validatePrefix(newPrefix); let val = validatePrefix(newPrefix);
if (typeof val != 'boolean') { if (typeof val != 'boolean') {
return message.reply(val); return message.reply(val);
} }
await client.db.get('servers').update({ 'id': message.channel?.server_id }, { $set: { 'prefix': newPrefix } }); await dbs.SERVERS.update({ id: message.channel!.server_id! }, { $set: { 'prefix': newPrefix } });
message.reply(`✅ Prefix has been changed from \`${oldPrefix}\` to \`${newPrefix}\`.\n${MENTION_TEXT}`); message.reply(`✅ Prefix has been changed from \`${oldPrefix}\` to \`${newPrefix}\`.\n${MENTION_TEXT}`);
break; break;
case 'get': case 'get':
case undefined: case undefined:
if (config.prefix) message.reply(`This server's prefix is \`${config.prefix}\`.\n${MENTION_TEXT}`); if (config?.prefix) message.reply(`This server's prefix is \`${config.prefix}\`.\n${MENTION_TEXT}`);
else message.reply(`This server uses the default prefix \`${DEFAULT_PREFIX}\`.\n${MENTION_TEXT}`); else message.reply(`This server uses the default prefix \`${DEFAULT_PREFIX}\`.\n${MENTION_TEXT}`);
break; break;
case 'clear': case 'clear':
case 'reset': case 'reset':
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG); if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
if (config.prefix != null) { if (config?.prefix != null) {
await client.db.get('servers').update({ 'id': message.channel?.server_id }, { $set: { 'prefix': null } }); await dbs.SERVERS.update({ id: message.channel!.server_id! }, { $set: { prefix: undefined } });
} }
message.reply(`✅ Prefix has been reset to the default: \`${DEFAULT_PREFIX}\`.`); message.reply(`✅ Prefix has been reset to the default: \`${DEFAULT_PREFIX}\`.`);
@ -55,7 +54,6 @@ export default {
default: default:
message.reply(`Unknown action. Correct syntax: \`${SYNTAX}\``); message.reply(`Unknown action. Correct syntax: \`${SYNTAX}\``);
} }
} }
} as SimpleCommand; } as SimpleCommand;

View file

@ -1,5 +1,5 @@
import { FindResult } from "monk"; import { FindResult } from "monk";
import { client } from "../.."; import { client, dbs } from "../..";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
@ -17,7 +17,7 @@ export default {
if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG); if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG);
let checkTempBans = async (id: string): Promise<number> => { let checkTempBans = async (id: string): Promise<number> => {
let tempbans: FindResult<TempBan> = await client.db.get('tempbans').find({ bannedUser: id, server: message.serverContext._id }); let tempbans = await dbs.TEMPBANS.find({ bannedUser: id, server: message.serverContext._id });
if (tempbans.length > 0) { if (tempbans.length > 0) {
for (const ban of tempbans) { for (const ban of tempbans) {
await removeTempBan(ban.id); await removeTempBan(ban.id);

View file

@ -1,6 +1,6 @@
import { FindResult } from "monk"; import { FindResult } from "monk";
import { ulid } from "ulid"; import { ulid } from "ulid";
import { client } from "../.."; import { client, dbs } from "../..";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
@ -25,7 +25,7 @@ export default {
category: CommandCategory.Moderation, category: CommandCategory.Moderation,
run: async (message: MessageCommandContext, args: string[]) => { run: async (message: MessageCommandContext, args: string[]) => {
try { try {
const serverConfig: ServerConfig = await client.db.get('servers').findOne({ id: message.serverContext._id }); const serverConfig = await dbs.SERVERS.findOne({ id: message.serverContext._id });
if (!serverConfig?.votekick?.enabled) return message.reply('Vote kick is not enabled for this server.'); if (!serverConfig?.votekick?.enabled) return message.reply('Vote kick is not enabled for this server.');
if (!message.member!.roles?.filter(r => serverConfig.votekick?.trustedRoles.includes(r)).length if (!message.member!.roles?.filter(r => serverConfig.votekick?.trustedRoles.includes(r)).length
&& !(await isModerator(message))) { && !(await isModerator(message))) {
@ -55,7 +55,7 @@ export default {
ignore: false, ignore: false,
} }
const votes: FindResult<VoteEntry> = await client.db.get('votekicks').find({ const votes = await dbs.VOTEKICKS.find({
server: message.serverContext._id, server: message.serverContext._id,
target: target._id, target: target._id,
time: { time: {
@ -66,7 +66,7 @@ export default {
if (votes.find(v => v.user == message.author_id)) return message.reply('You can\'t vote twice for this user.'); if (votes.find(v => v.user == message.author_id)) return message.reply('You can\'t vote twice for this user.');
await client.db.get('votekicks').insert(vote); await dbs.VOTEKICKS.insert(vote);
votes.push({ _id: '' as any, ...vote }); votes.push({ _id: '' as any, ...vote });
await logModAction( await logModAction(
@ -99,7 +99,7 @@ export default {
message.reply(`**${votes.length}/${serverConfig.votekick.votesRequired}** votes - ` message.reply(`**${votes.length}/${serverConfig.votekick.votesRequired}** votes - `
+ `Banned @${target.username} for ${serverConfig.votekick.banDuration} minutes.`); // Todo: display ban duration properly (Permban, kick, etc) + `Banned @${target.username} for ${serverConfig.votekick.banDuration} minutes.`); // Todo: display ban duration properly (Permban, kick, etc)
await client.db.get('votekicks').update({ await dbs.VOTEKICKS.update({
server: message.serverContext._id, server: message.serverContext._id,
target: target._id, target: target._id,
time: { $gt: Date.now() - 1000 * 60 * 30 }, time: { $gt: Date.now() - 1000 * 60 * 30 },
@ -115,3 +115,5 @@ export default {
} }
} }
} as SimpleCommand; } as SimpleCommand;
export { VoteEntry }

View file

@ -1,5 +1,5 @@
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import { client } from "../.."; import { client, dbs } 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, parseUserOrId, uploadFile } from "../util"; import { isModerator, NO_MANAGER_MSG, parseUserOrId, uploadFile } from "../util";
@ -21,8 +21,7 @@ export default {
run: async (message: MessageCommandContext, args: string[]) => { run: async (message: MessageCommandContext, args: string[]) => {
if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG); if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG);
let collection = client.db.get('infractions'); let infractions: Array<Infraction> = await dbs.INFRACTIONS.find({
let infractions: Array<Infraction> = await collection.find({
server: message.serverContext._id, server: message.serverContext._id,
}); });
let userInfractions: Map<string, Infraction[]> = new Map(); let userInfractions: Map<string, Infraction[]> = new Map();
@ -50,7 +49,7 @@ export default {
case 'del': case 'del':
let id = args[1]; let id = args[1];
if (!id) return message.reply('No infraction ID provided.'); if (!id) return message.reply('No infraction ID provided.');
let inf: Infraction|null = await client.db.get('infractions').findOneAndDelete({ let inf = await dbs.INFRACTIONS.findOneAndDelete({
_id: { $eq: id.toUpperCase() }, _id: { $eq: id.toUpperCase() },
server: message.serverContext._id server: message.serverContext._id
}); });

View file

@ -1,6 +1,5 @@
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
import { User } from "@janderedev/revolt.js/dist/maps/Users"; import { User } from "@janderedev/revolt.js/dist/maps/Users";
import { client } from "../.."; import { client, dbs } from "../..";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
@ -16,7 +15,8 @@ export default {
syntax: SYNTAX, syntax: SYNTAX,
category: CommandCategory.Config, category: CommandCategory.Config,
run: async (message: MessageCommandContext, args: string[]) => { run: async (message: MessageCommandContext, args: string[]) => {
let config: ServerConfig = await client.db.get('servers').findOne({ id: message.serverContext._id }) || {} let config: ServerConfig|null = await dbs.SERVERS.findOne({ id: message.serverContext._id })
if (!config) config = { id: message.channel!.server_id! };
if (!config.whitelist) config.whitelist = { users: [], roles: [], managers: true } if (!config.whitelist) config.whitelist = { users: [], roles: [], managers: true }
if (!isBotManager(message)) return message.reply(NO_MANAGER_MSG); if (!isBotManager(message)) return message.reply(NO_MANAGER_MSG);
@ -37,7 +37,7 @@ export default {
return message.reply('That role is already whitelisted.'); return message.reply('That role is already whitelisted.');
config.whitelist!.roles = [role, ...(config.whitelist!.roles ?? [])]; config.whitelist!.roles = [role, ...(config.whitelist!.roles ?? [])];
await client.db.get('servers').update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } }); await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } });
return message.reply(`Added role to whitelist!`); return message.reply(`Added role to whitelist!`);
} }
@ -48,7 +48,7 @@ export default {
return message.reply('That user is already whitelisted.'); return message.reply('That user is already whitelisted.');
config.whitelist!.users = [user._id, ...(config.whitelist!.users ?? [])]; config.whitelist!.users = [user._id, ...(config.whitelist!.users ?? [])];
await client.db.get('servers').update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } }); await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } });
return message.reply('Added user to whitelist!'); return message.reply('Added user to whitelist!');
break; break;
case 'rm': case 'rm':
@ -67,7 +67,7 @@ export default {
return message.reply('That role is not whitelisted.'); return message.reply('That role is not whitelisted.');
config.whitelist!.roles = config.whitelist!.roles.filter(r => r != role); config.whitelist!.roles = config.whitelist!.roles.filter(r => r != role);
await client.db.get('servers').update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } }); await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } });
return message.reply(`Removed role from whitelist!`); return message.reply(`Removed role from whitelist!`);
} }
@ -77,7 +77,7 @@ export default {
return message.reply('That user is not whitelisted.'); return message.reply('That user is not whitelisted.');
config.whitelist!.users = config.whitelist!.users.filter(u => u != user?._id); config.whitelist!.users = config.whitelist!.users.filter(u => u != user?._id);
await client.db.get('servers').update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } }); await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } });
return message.reply('Removed user from whitelist!'); return message.reply('Removed user from whitelist!');
break; break;
case 'l': case 'l':
@ -90,7 +90,7 @@ export default {
if (config.whitelist.users?.length) { if (config.whitelist.users?.length) {
config.whitelist.users?.forEach((u, index) => { config.whitelist.users?.forEach((u, index) => {
if (index < 15) str += `* [@${client.users.get(u)?.username || u}](/@${u})\n`; if (index < 15) str += `* [@${client.users.get(u)?.username || u}](/@${u})\n`;
if (index == 15) str += `**${index - 15} more user${config.whitelist?.users?.length == 16 ? '' : 's'}**\n`; if (index == 15) str += `**${index - 15} more user${config?.whitelist?.users?.length == 16 ? '' : 's'}**\n`;
}); });
} else str += `**No whitelisted users**\n`; } else str += `**No whitelisted users**\n`;
@ -101,7 +101,7 @@ export default {
?.map(r => message.serverContext.roles?.[r]?.name || `Unknown role (${r})`) ?.map(r => message.serverContext.roles?.[r]?.name || `Unknown role (${r})`)
.forEach((r, index) => { .forEach((r, index) => {
if (index < 15) str += `* ${r}\n`; if (index < 15) str += `* ${r}\n`;
if (index == 15) str += `**${config.whitelist!.roles!.length - 15} more role${config.whitelist?.roles?.length == 16 ? '' : 's'}**\n`; if (index == 15) str += `**${config!.whitelist!.roles!.length - 15} more role${config?.whitelist?.roles?.length == 16 ? '' : 's'}**\n`;
}); });
} else str += `**No whitelisted roles**\n`; } else str += `**No whitelisted roles**\n`;

View file

@ -1,6 +1,6 @@
import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
import { ulid } from "ulid"; import { ulid } from "ulid";
import { client } from "../.."; import { client, dbs } from "../..";
import AntispamRule from "../../struct/antispam/AntispamRule"; import AntispamRule from "../../struct/antispam/AntispamRule";
import Infraction from "../../struct/antispam/Infraction"; import Infraction from "../../struct/antispam/Infraction";
import InfractionType from "../../struct/antispam/InfractionType"; import InfractionType from "../../struct/antispam/InfractionType";
@ -17,8 +17,8 @@ let msgCountStore: Map<string, { users: any }> = new Map();
* @returns true if ok, false if spam rule triggered * @returns true if ok, false if spam rule triggered
*/ */
async function antispam(message: Message): Promise<boolean> { async function antispam(message: Message): Promise<boolean> {
let serverRules: ServerConfig = await client.db.get('servers').findOne({ id: message.channel?.server_id }) ?? {}; let serverRules = await dbs.SERVERS.findOne({ id: message.channel!.server_id! });
if (!serverRules.automodSettings) return true; if (!serverRules?.automodSettings) return true;
let ruleTriggered = false; let ruleTriggered = false;
@ -29,7 +29,7 @@ async function antispam(message: Message): Promise<boolean> {
if (message.author?.bot != null) break; if (message.author?.bot != null) break;
if (serverRules.whitelist?.users?.includes(message.author_id)) break; if (serverRules.whitelist?.users?.includes(message.author_id)) break;
if (message.member?.roles?.filter(r => serverRules.whitelist?.roles?.includes(r)).length) break; if (message.member?.roles?.filter(r => serverRules!.whitelist?.roles?.includes(r)).length) break;
if (serverRules.whitelist?.managers !== false && await isModerator(message)) break; if (serverRules.whitelist?.managers !== false && await isModerator(message)) break;
if (rule.channels?.length && rule.channels.indexOf(message.channel_id) == -1) break; if (rule.channels?.length && rule.channels.indexOf(message.channel_id) == -1) break;

View file

@ -1,6 +1,6 @@
import { Member } from "@janderedev/revolt.js/dist/maps/Members"; import { Member } from "@janderedev/revolt.js/dist/maps/Members";
import { User } from "@janderedev/revolt.js/dist/maps/Users"; import { User } from "@janderedev/revolt.js/dist/maps/Users";
import { client } from "../../.."; import { client, dbs } from "../../..";
import ServerConfig from "../../../struct/ServerConfig"; import ServerConfig from "../../../struct/ServerConfig";
import { getPermissionLevel } from "../../util"; import { getPermissionLevel } from "../../util";
import { wsEvents, WSResponse } from "../api_communication"; import { wsEvents, WSResponse } from "../api_communication";
@ -42,7 +42,7 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
return; return;
} }
const serverConfig: ServerConfig = await client.db.get('servers').findOne({ id: server._id }); const serverConfig = await dbs.SERVERS.findOne({ id: server._id });
// todo: remove unwanted keys from server config // todo: remove unwanted keys from server config
@ -55,8 +55,8 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
} }
const users = await Promise.allSettled([ const users = await Promise.allSettled([
...(serverConfig.botManagers?.map(u => fetchUser(u)) ?? []), ...(serverConfig?.botManagers?.map(u => fetchUser(u)) ?? []),
...(serverConfig.moderators?.map(u => fetchUser(u)) ?? []), ...(serverConfig?.moderators?.map(u => fetchUser(u)) ?? []),
fetchUser(user._id), fetchUser(user._id),
]); ]);
@ -67,7 +67,7 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
description: server.description ?? undefined, description: server.description ?? undefined,
bannerURL: server.generateBannerURL(), bannerURL: server.generateBannerURL(),
iconURL: server.generateIconURL(), iconURL: server.generateIconURL(),
serverConfig, serverConfig: (serverConfig as ServerConfig|undefined),
users: users.map( users: users.map(
u => u.status == 'fulfilled' u => u.status == 'fulfilled'
? { id: u.value._id, avatarURL: u.value.generateAvatarURL(), username: u.value.username } ? { id: u.value._id, avatarURL: u.value.generateAvatarURL(), username: u.value.username }

View file

@ -5,7 +5,7 @@
import ws from "ws"; import ws from "ws";
import logger from "../logger"; import logger from "../logger";
import crypto from 'crypto'; import crypto from 'crypto';
import { client as bot } from '../..'; import { client as bot, dbs } from '../..';
import { EventEmitter } from "events"; import { EventEmitter } from "events";
import { parseUser } from "../util"; import { parseUser } from "../util";
import PendingLogin from "../../struct/PendingLogin"; import PendingLogin from "../../struct/PendingLogin";
@ -102,7 +102,7 @@ wsEvents.on('req:requestLogin', async (data: any, cb: (data: WSResponse) => void
let code: string|null = null; let code: string|null = null;
while (!code) { while (!code) {
const c = crypto.randomBytes(8).toString('hex'); const c = crypto.randomBytes(8).toString('hex');
const found = await bot.db.get('pending_logins').find({ code: c, user: user._id, confirmed: false }); const found = await dbs.PENDING_LOGINS.find({ code: c, user: user._id, confirmed: false });
if (found.length > 0) continue; if (found.length > 0) continue;
code = c.substring(0, 8).toUpperCase(); code = c.substring(0, 8).toUpperCase();
} }
@ -112,13 +112,13 @@ wsEvents.on('req:requestLogin', async (data: any, cb: (data: WSResponse) => void
const nonce = ulid(); const nonce = ulid();
const [previousLogins, currentValidLogins] = await Promise.all([ const [previousLogins, currentValidLogins] = await Promise.all([
bot.db.get('pending_logins').find({ user: user._id, confirmed: true }), dbs.PENDING_LOGINS.find({ user: user._id, confirmed: true }),
bot.db.get('pending_logins').find({ user: user._id, confirmed: false, expires: { $gt: Date.now() } }), dbs.PENDING_LOGINS.find({ user: user._id, confirmed: false, expires: { $gt: Date.now() } }),
]); ]);
if (currentValidLogins.length >= 5) return cb({ success: false, statusCode: 403, error: 'Too many pending logins. Try again later.' }); if (currentValidLogins.length >= 5) return cb({ success: false, statusCode: 403, error: 'Too many pending logins. Try again later.' });
await bot.db.get('pending_logins').insert({ await dbs.PENDING_LOGINS.insert({
code, code,
expires: Date.now() + (1000 * 60 * 15), // Expires in 15 minutes expires: Date.now() + (1000 * 60 * 15), // Expires in 15 minutes
user: user._id, user: user._id,

View file

@ -1,6 +1,6 @@
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import logger from "../logger"; import logger from "../logger";
import { client } from "../../index"; import { client, dbs } from "../../index";
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import ServerConfig from "../../struct/ServerConfig"; import ServerConfig from "../../struct/ServerConfig";
@ -64,15 +64,15 @@ let commands: SimpleCommand[];
let args = msg.content.split(' '); let args = msg.content.split(' ');
let cmdName = args.shift() ?? ''; let cmdName = args.shift() ?? '';
let config: ServerConfig = (await client.db.get('servers').findOne({ 'id': msg.channel?.server_id })) ?? {}; let config = await dbs.SERVERS.findOne({ id: msg.channel!.server_id! });
let guildPrefix = config.prefix ?? DEFAULT_PREFIX; let guildPrefix = config?.prefix ?? DEFAULT_PREFIX;
if (cmdName.startsWith(`<@${client.user?._id}>`)) { if (cmdName.startsWith(`<@${client.user?._id}>`)) {
cmdName = cmdName.substring(`<@${client.user?._id}>`.length); cmdName = cmdName.substring(`<@${client.user?._id}>`.length);
if (!cmdName) cmdName = args.shift() ?? ''; // Space between mention and command name if (!cmdName) cmdName = args.shift() ?? ''; // Space between mention and command name
} else if (cmdName.startsWith(guildPrefix)) { } else if (cmdName.startsWith(guildPrefix)) {
cmdName = cmdName.substring(guildPrefix.length); cmdName = cmdName.substring(guildPrefix.length);
if (config.spaceAfterPrefix && !cmdName) cmdName = args.shift() ?? ''; if (config?.spaceAfterPrefix && !cmdName) cmdName = args.shift() ?? '';
} else return; } else return;
if (!cmdName) return; if (!cmdName) return;
@ -92,7 +92,7 @@ let commands: SimpleCommand[];
let serverCtx = msg.channel?.server; let serverCtx = msg.channel?.server;
if (config.linkedServer) { if (config?.linkedServer) {
try { try {
serverCtx = client.servers.get(config.linkedServer) serverCtx = client.servers.get(config.linkedServer)
|| await client.servers.fetch(config.linkedServer); || await client.servers.fetch(config.linkedServer);
@ -109,7 +109,7 @@ let commands: SimpleCommand[];
logger.info(`Command: ${message.author?.username} (${message.author?._id}) in ${message.channel?.server?.name} (${message.channel?.server?._id}): ${message.content}`); logger.info(`Command: ${message.author?.username} (${message.author?._id}) in ${message.channel?.server?.name} (${message.channel?.server?._id}): ${message.content}`);
// Create document for server in DB, if not already present // Create document for server in DB, if not already present
if (JSON.stringify(config) == '{}') await client.db.get('servers').insert({ id: message.channel?.server_id }); if (JSON.stringify(config) == '{}') await dbs.SERVERS.insert({ id: message.channel!.server_id! });
if (cmd.removeEmptyArgs !== false) { if (cmd.removeEmptyArgs !== false) {
args = args.filter(a => a.length > 0); args = args.filter(a => a.length > 0);

View file

@ -1,5 +1,5 @@
import { ulid } from "ulid"; import { ulid } from "ulid";
import { client } from "../.."; import { client, dbs } 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 logger from "../logger"; import logger from "../logger";
@ -25,10 +25,10 @@ client.on('message', async message => {
case 'user_kicked': case 'user_kicked':
case 'user_banned': case 'user_banned':
try { try {
let recentEvents = await client.db.get('infractions').findOne({ let recentEvents = await dbs.INFRACTIONS.findOne({
date: { $gt: Date.now() - 30000 }, date: { $gt: Date.now() - 30000 },
user: sysMsg.user?._id, user: sysMsg.user?._id,
server: message.channel?.server_id, server: message.channel!.server_id!,
actionType: sysMsg.type == 'user_kicked' ? 'kick' : 'ban', actionType: sysMsg.type == 'user_kicked' ? 'kick' : 'ban',
}); });

View file

@ -1,6 +1,6 @@
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 { client } from "../.."; import { client, dbs } from "../..";
import Infraction from "../../struct/antispam/Infraction"; import Infraction from "../../struct/antispam/Infraction";
import LogMessage from "../../struct/LogMessage"; import LogMessage from "../../struct/LogMessage";
import ServerConfig from "../../struct/ServerConfig"; import ServerConfig from "../../struct/ServerConfig";
@ -28,7 +28,7 @@ client.on('packet', async (packet) => {
let server = channel?.server; let server = channel?.server;
if (!server || !channel) return logger.warn('Received message update in unknown channel or server'); if (!server || !channel) return logger.warn('Received message update in unknown channel or server');
let config: ServerConfig = await client.db.get('servers').findOne({ id: server._id }) ?? {}; let config = await dbs.SERVERS.findOne({ id: server._id });
if (config?.logs?.messageUpdate) { if (config?.logs?.messageUpdate) {
const attachFullMessage = oldMsg.length > 800 || newMsg.length > 800; const attachFullMessage = oldMsg.length > 800 || newMsg.length > 800;
let embed: LogMessage = { let embed: LogMessage = {
@ -75,8 +75,8 @@ client.on('packet', async (packet) => {
let msgRaw = String(message.content ?? '(Unknown)'); let msgRaw = String(message.content ?? '(Unknown)');
let msg = sanitizeMessageContent(msgRaw); let msg = sanitizeMessageContent(msgRaw);
let config: ServerConfig = await client.db.get('servers').findOne({ id: message.channel?.server?._id }) ?? {}; let config = await dbs.SERVERS.findOne({ id: message.channel?.server?._id });
if (config.logs?.messageUpdate) { if (config?.logs?.messageUpdate) {
let embed: LogMessage = { let embed: LogMessage = {
title: `Message deleted in ${message.channel?.server?.name}`, title: `Message deleted in ${message.channel?.server?.name}`,
description: `[\\[#${channel.name}\\]](/server/${channel.server_id}/channel/${channel._id}) | ` description: `[\\[#${channel.name}\\]](/server/${channel.server_id}/channel/${channel._id}) | `
@ -116,15 +116,14 @@ client.on('packet', async (packet) => {
async function logModAction(type: 'warn'|'kick'|'ban'|'votekick', server: Server, mod: Member, target: string, reason: string|null, infractionID: string, extraText?: string): Promise<void> { async function logModAction(type: 'warn'|'kick'|'ban'|'votekick', server: Server, mod: Member, target: string, reason: string|null, infractionID: string, extraText?: string): Promise<void> {
try { try {
let config: ServerConfig = await client.db.get('servers').findOne({ id: server._id }) ?? {}; let config = await dbs.SERVERS.findOne({ id: server._id });
if (config.logs?.modAction) { if (config?.logs?.modAction) {
let aType = type == 'ban' ? 'banned' : type + 'ed'; let aType = type == 'ban' ? 'banned' : type + 'ed';
let embedColor = '#0576ff'; let embedColor = '#0576ff';
if (type == 'kick') embedColor = '#ff861d'; if (type == 'kick') embedColor = '#ff861d';
if (type == 'ban') embedColor = '#ff2f05'; if (type == 'ban') embedColor = '#ff2f05';
sendLogMessage(config.logs.modAction, { sendLogMessage(config.logs.modAction, {
title: `User ${aType}`, title: `User ${aType}`,
description: `\`@${mod.user?.username}\` **${aType}** \`` description: `\`@${mod.user?.username}\` **${aType}** \``

View file

@ -1,5 +1,5 @@
import { FindResult } from "monk"; import { FindResult } from "monk";
import { client } from "../.."; import { client, dbs } from "../..";
import TempBan from "../../struct/TempBan"; import TempBan from "../../struct/TempBan";
import logger from "../logger"; import logger from "../logger";
@ -8,7 +8,7 @@ let dontProcess: string[] = [];
let expired: string[] = []; let expired: string[] = [];
async function tick() { async function tick() {
let found: FindResult<TempBan> = await client.db.get('tempbans').find({ until: { $lt: Date.now() + 60000 } }); let found = await dbs.TEMPBANS.find({ until: { $lt: Date.now() + 60000 } });
for (const ban of found) { for (const ban of found) {
if (!dontProcess.includes(ban.id)) if (!dontProcess.includes(ban.id))
@ -36,12 +36,12 @@ async function processUnban(ban: TempBan) {
let promises = [ let promises = [
server.unbanUser(ban.bannedUser), server.unbanUser(ban.bannedUser),
client.db.get('tempbans').remove({ id: ban.id }), dbs.TEMPBANS.remove({ id: ban.id }),
]; ];
await Promise.allSettled(promises); await Promise.allSettled(promises);
} }
else client.db.get('tempbans').remove({ id: ban.id }); else dbs.TEMPBANS.remove({ id: ban.id });
} catch(e) { console.error(e) } } catch(e) { console.error(e) }
} }
@ -54,14 +54,15 @@ async function storeTempBan(ban: TempBan): Promise<void> {
}, ban.until - Date.now()); }, ban.until - Date.now());
} }
client.db.get('tempbans').insert(ban); dbs.TEMPBANS.insert(ban);
} }
async function removeTempBan(banID: string): Promise<TempBan> { async function removeTempBan(banID: string): Promise<TempBan> {
let ban: TempBan = await client.db.get('tempbans').findOneAndDelete({ id: banID }); let ban = await dbs.TEMPBANS.findOneAndDelete({ id: banID });
if (!ban) throw `Ban ${banID} does not exist; cannot delete`;
if (Date.now() >= ban.until - 120000) { if (Date.now() >= ban.until - 120000) {
expired.push(ban.id); expired.push(ban.id);
expired = expired.filter(id => id != ban.id); expired = expired.filter(id => id != ban!.id);
}; };
return ban; return ban;
} }

View file

@ -1,4 +1,4 @@
import { client } from "../.."; import { client, dbs } from "../..";
import fs from 'fs'; import fs from 'fs';
import { FindOneResult } from "monk"; import { FindOneResult } from "monk";
import ScannedUser from "../../struct/ScannedUser"; import ScannedUser from "../../struct/ScannedUser";
@ -18,13 +18,12 @@ let wordlist = USERSCAN_WORDLIST_PATH
if (wordlist) logger.info("Found word list; user scanning enabled"); if (wordlist) logger.info("Found word list; user scanning enabled");
let scannedUsers = client.db.get('scanned_users');
let serverConfig: Map<string, ServerConfig> = new Map(); let serverConfig: Map<string, ServerConfig> = new Map();
let userScanTimeout: Map<string, number> = new Map(); let userScanTimeout: Map<string, number> = new Map();
async function scanServer(id: string, userScanned: () => void, done: () => void) { async function scanServer(id: string, userScanned: () => void, done: () => void) {
if (!wordlist) return; if (!wordlist) return;
let conf: FindOneResult<ServerConfig> = await client.db.get('servers').findOne({ id: id }); let conf = await dbs.SERVERS.findOne({ id: id });
serverConfig.set(id, conf as ServerConfig); serverConfig.set(id, conf as ServerConfig);
if (!conf?.enableUserScan) return; if (!conf?.enableUserScan) return;
@ -50,7 +49,7 @@ async function scanUser(member: Member) {
try { try {
let dbEntry: FindOneResult<ScannedUser|undefined> let dbEntry: FindOneResult<ScannedUser|undefined>
= await scannedUsers.findOne({ id: member._id.user, server: member.server?._id }); = await dbs.SCANNED_USERS.findOne({ id: member._id.user, server: member.server?._id });
let user = member.user || await client.users.fetch(member._id.user); let user = member.user || await client.users.fetch(member._id.user);
let profile = await user.fetchProfile(); let profile = await user.fetchProfile();
let report = false; let report = false;
@ -68,19 +67,19 @@ async function scanUser(member: Member) {
if (report) { if (report) {
if (dbEntry) { if (dbEntry) {
await scannedUsers.update({ _id: dbEntry._id }, { await dbs.SCANNED_USERS.update({ _id: dbEntry._id }, {
$set: { $set: {
lastLog: Date.now(), lastLog: Date.now(),
lastLoggedProfile: { lastLoggedProfile: {
username: user.username, username: user.username,
nickname: member.nickname, nickname: member.nickname || undefined,
profile: profile.content, profile: profile.content,
status: user.status?.text, status: user.status?.text,
} }
} }
}); });
} else { } else {
await scannedUsers.insert({ await dbs.SCANNED_USERS.insert({
approved: false, approved: false,
id: user._id, id: user._id,
lastLog: Date.now(), lastLog: Date.now(),
@ -153,7 +152,7 @@ new Promise((res: (value: void) => void) => client.user ? res() : client.once('r
let server = client.servers.get(sid); let server = client.servers.get(sid);
if (!server) return; if (!server) return;
let conf: FindOneResult<ServerConfig> = await client.db.get('servers').findOne({ id: server._id }); let conf = await dbs.SERVERS.findOne({ id: server._id });
serverConfig.set(server._id, conf as ServerConfig); serverConfig.set(server._id, conf as ServerConfig);
if (conf?.enableUserScan) { if (conf?.enableUserScan) {
@ -178,7 +177,7 @@ new Promise((res: (value: void) => void) => client.user ? res() : client.once('r
let server = member.server || await client.servers.fetch(member._id.server); let server = member.server || await client.servers.fetch(member._id.server);
if (!server) return; if (!server) return;
let conf: FindOneResult<ServerConfig> = await client.db.get('servers').findOne({ id: server._id }); let conf: FindOneResult<ServerConfig> = await dbs.SERVERS.findOne({ id: server._id });
serverConfig.set(server._id, conf as ServerConfig); serverConfig.set(server._id, conf as ServerConfig);
if (conf?.enableUserScan) { if (conf?.enableUserScan) {

View file

@ -1,6 +1,6 @@
import { Member } from "@janderedev/revolt.js/dist/maps/Members"; import { Member } from "@janderedev/revolt.js/dist/maps/Members";
import { User } from "@janderedev/revolt.js/dist/maps/Users"; import { User } from "@janderedev/revolt.js/dist/maps/Users";
import { client } from ".."; import { client, dbs } from "..";
import Infraction from "../struct/antispam/Infraction"; import Infraction from "../struct/antispam/Infraction";
import ServerConfig from "../struct/ServerConfig"; import ServerConfig from "../struct/ServerConfig";
import FormData from 'form-data'; import FormData from 'form-data';
@ -77,18 +77,31 @@ async function parseUserOrId(text: string): Promise<User|{_id: string}|null> {
async function isModerator(message: Message) { async function isModerator(message: Message) {
let member = message.member!, server = message.channel!.server!; let member = message.member!, server = message.channel!.server!;
return hasPerm(member, 'KickMembers')
|| await isBotManager(message) if (hasPerm(member, 'KickMembers')) return true;
|| (((await client.db.get('servers').findOne({ id: server._id }) || {}) as ServerConfig)
.moderators?.indexOf(member.user?._id!) ?? -1) > -1 const [ isManager, mods, isSudo ] = await Promise.all([
|| await checkSudoPermission(message); isBotManager(message),
dbs.SERVERS.findOne({ id: server._id }),
checkSudoPermission(message),
]);
return isManager
|| (mods?.moderators?.indexOf(member.user?._id!) ?? -1) > -1
|| isSudo;
} }
async function isBotManager(message: Message) { async function isBotManager(message: Message) {
let member = message.member!, server = message.channel!.server!; let member = message.member!, server = message.channel!.server!;
return hasPerm(member, 'ManageServer')
|| (((await client.db.get('servers').findOne({ id: server._id }) || {}) as ServerConfig) if (hasPerm(member, 'ManageServer')) return true;
.botManagers?.indexOf(member.user?._id!) ?? -1) > -1
|| await checkSudoPermission(message); const [ managers, isSudo ] = await Promise.all([
dbs.SERVERS.findOne({ id: server._id }),
checkSudoPermission(message),
]);
return (managers?.botManagers?.indexOf(member.user?._id!) ?? -1) > -1
|| isSudo;
} }
async function checkSudoPermission(message: Message): Promise<boolean> { async function checkSudoPermission(message: Message): Promise<boolean> {
const hasPerm = isSudo(message.author!); const hasPerm = isSudo(message.author!);
@ -107,10 +120,10 @@ async function getPermissionLevel(user: User|Member, server: Server): Promise<0|
if (hasPerm(member, 'ManageServer')) return 3; if (hasPerm(member, 'ManageServer')) return 3;
const config = (await client.db.get('servers').findOne({ id: server._id }) || {}) as ServerConfig; const config = await dbs.SERVERS.findOne({ id: server._id });
if (config.botManagers?.includes(user._id)) return 2; if (config?.botManagers?.includes(user._id)) return 2;
if (config.moderators?.includes(user._id) || hasPerm(member, 'KickMembers')) return 1; if (config?.moderators?.includes(user._id) || hasPerm(member, 'KickMembers')) return 1;
return 0; return 0;
} }
@ -143,17 +156,14 @@ async function getOwnMemberInServer(server: Server): Promise<Member> {
} }
async function storeInfraction(infraction: Infraction): Promise<{ userWarnCount: number }> { async function storeInfraction(infraction: Infraction): Promise<{ userWarnCount: number }> {
let collection = client.db.get('infractions'); let r = await Promise.all([
let p = [ dbs.INFRACTIONS.insert(infraction, { castIds: false }),
collection.insert(infraction, { castIds: false }), dbs.INFRACTIONS.find({
collection.find({
server: infraction.server, server: infraction.server,
user: infraction.user, user: infraction.user,
_id: { $not: { $eq: infraction._id } } }, _id: { $not: { $eq: infraction._id } } },
), ),
]; ]);
let r = await Promise.all(p);
return { userWarnCount: (r[1].length ?? 0) + 1 } return { userWarnCount: (r[1].length ?? 0) + 1 }
} }

View file

@ -4,6 +4,13 @@ config();
import logger from './bot/logger'; import logger from './bot/logger';
import AutomodClient, { login } from './struct/AutomodClient'; import AutomodClient, { login } from './struct/AutomodClient';
import MongoDB from './bot/db'; import MongoDB from './bot/db';
import DbUser from './struct/DbUser';
import ServerConfig from './struct/ServerConfig';
import Infraction from './struct/antispam/Infraction';
import PendingLogin from './struct/PendingLogin';
import TempBan from './struct/TempBan';
import { VoteEntry } from './bot/commands/votekick';
import ScannedUser from './struct/ScannedUser';
logger.info('Initializing client'); logger.info('Initializing client');
@ -16,7 +23,18 @@ let client = new AutomodClient({
}, db); }, db);
login(client); login(client);
export { client } const dbs = {
SERVERS: db.get<ServerConfig>('servers'),
USERS: db.get<DbUser>('users'),
INFRACTIONS: db.get<Infraction>('infractions'),
PENDING_LOGINS: db.get<PendingLogin>('pending_logins'),
SESSIONS: db.get('sessions'),
TEMPBANS: db.get<TempBan>('tempbans'),
VOTEKICKS: db.get<VoteEntry>('votekicks'),
SCANNED_USERS: db.get<ScannedUser>('scanned_users'),
}
export { client, dbs }
(async () => { (async () => {
// Wait for a database query to succeed before loading the rest // Wait for a database query to succeed before loading the rest

11
bot/src/struct/DbUser.ts Normal file
View file

@ -0,0 +1,11 @@
// Stores global info about a particular user in the database
export default class DbUser {
// User ID
id: string;
// Blacklists the user from interacting with the bot
ignore?: boolean;
// Whether the user is globally marked as bad actor
globalBlacklist?: boolean;
}

View file

@ -2,29 +2,29 @@ import AutomodSettings from "./antispam/AutomodSettings";
import LogConfig from "./LogConfig"; import LogConfig from "./LogConfig";
class ServerConfig { class ServerConfig {
id: string | undefined; id: string;
prefix: string | undefined; prefix?: string;
spaceAfterPrefix: boolean | undefined; spaceAfterPrefix?: boolean;
automodSettings: AutomodSettings | undefined; automodSettings?: AutomodSettings;
botManagers: string[] | undefined; botManagers?: string[];
moderators: string[] | undefined; moderators?: string[];
votekick: { votekick?: {
enabled: boolean; enabled: boolean;
votesRequired: number; votesRequired: number;
banDuration: number; // -1: Only kick, 0: Permanent, >0: Ban duration in minutes banDuration: number; // -1: Only kick, 0: Permanent, >0: Ban duration in minutes
trustedRoles: string[]; trustedRoles: string[];
} | undefined; };
linkedServer: string | undefined; linkedServer?: string;
whitelist: { whitelist?: {
users: string[] | undefined, users?: string[],
roles: string[] | undefined, roles?: string[],
managers: boolean | undefined, managers?: boolean,
} | undefined; };
logs: { logs?: {
messageUpdate?: LogConfig, // Message edited or deleted messageUpdate?: LogConfig, // Message edited or deleted
modAction?: LogConfig, // User warned, kicked or banned modAction?: LogConfig, // User warned, kicked or banned
userScan?: LogConfig // User profile matched word list userScan?: LogConfig // User profile matched word list
} | undefined; };
enableUserScan?: boolean; enableUserScan?: boolean;
} }