diff --git a/src/structure/components/observers/Automoderation.js b/src/structure/components/observers/Automoderation.js index 2169d80..036d3d0 100644 --- a/src/structure/components/observers/Automoderation.js +++ b/src/structure/components/observers/Automoderation.js @@ -5,7 +5,6 @@ const { stripIndents } = require('common-tags'); const { Observer } = require('../../interfaces'); const { BinaryTree, Util, FilterUtil } = require('../../../utilities'); -const { FilterPresets } = require('../../../constants'); const { Warn, Mute, Kick, Softban, Ban } = require('../infractions'); const CONSTANTS = { @@ -30,7 +29,7 @@ const CONSTANTS = { }; // TODO: -// Clean up commented out code once testing of new code is done +// Clean up commented out code once testing of new code is done -- done // Implement missing automod features -- done @@ -47,19 +46,17 @@ module.exports = class AutoModeration extends Observer { this.hooks = [ ['messageCreate', this.filterWords.bind(this)], ['messageUpdate', this.filterWords.bind(this)], + ['messageCreate', this.filterInvites.bind(this)], + ['messageUpdate', this.filterInvites.bind(this)], ['messageCreate', this.flagMessages.bind(this)], ['messageUpdate', this.flagMessages.bind(this)], ['messageCreate', this.filterLinks.bind(this)], ['messageUpdate', this.filterLinks.bind(this)], - ['messageCreate', this.filterInvites.bind(this)], - ['messageUpdate', this.filterInvites.bind(this)], ['messageCreate', this.filterMentions.bind(this)], ['interactionCreate', this.flagAction.bind(this)] ]; this.topLevelDomains = null; - // Moved to FilterUtil - // this.whitelist = new BinaryTree(this.client, FilterPresets.whitelist); this.executing = {}; this.regex = { @@ -135,6 +132,12 @@ module.exports = class AutoModeration extends Observer { if (!enabled || roles.some((r) => bypass.includes(r)) || ignore.includes(channel.id)) return; + const missing = channel.permissionsFor(guild.me).missing('MANAGE_MESSAGES'); + if (missing.length) { + this.client.emit('filterMissingPermissions', { channel, guild: wrapper, filter: 'word', permissions: missing }); + return; + } + // Which message obj to work with const msg = edited || message; if (!msg.content) return; @@ -212,9 +215,10 @@ module.exports = class AutoModeration extends Observer { res.delete?.().catch(() => { /**/ }); }, 10000); } - this.client.rateLimiter.queueDelete(msg.channel, msg).catch((err) => { - this.logger.error(err.stack); - }); + this.client.rateLimiter.queueDelete(msg.channel, msg).catch(() => null); + // .catch((err) => { + // this.logger.error(err.stack); + // }); // 6. Automated actions if (actions.length) { @@ -229,13 +233,11 @@ module.exports = class AutoModeration extends Observer { return act.trigger === 'generic'; }); - if (action) { log += `\nSanctioned`; await this._moderate(action, wrapper, channel, member, wrapper.format('W_FILTER_ACTION'), filterResult); } - } this.logger.debug(`${guild.name} WF DEBUG: ${log}`); @@ -428,6 +430,12 @@ module.exports = class AutoModeration extends Observer { const roles = member?.roles.cache.map((r) => r.id) || []; if (roles.some((r) => bypass.includes(r)) || ignore.includes(channel.id)) return; + + const missing = channel.permissionsFor(guild.me).missing('MANAGE_MESSAGES'); + if (missing.length) { + this.client.emit('filterMissingPermissions', { channel, guild: wrapper, filter: 'link', permissions: missing }); + return; + } const msg = edited || message; if (!msg.content) return; @@ -484,7 +492,6 @@ module.exports = class AutoModeration extends Observer { } log += `\nFilter result: ${inspect(filterResult)}\nRemove: ${remove}`; - this.logger.debug(log); if (!remove) return; msg.filtered = filterResult; @@ -499,6 +506,8 @@ module.exports = class AutoModeration extends Observer { }, 10000); } + this.client.rateLimiter.queueDelete(msg.channel, msg); + if (actions.length) { let action = actions.find((act) => { @@ -511,16 +520,14 @@ module.exports = class AutoModeration extends Observer { return act.trigger === 'generic'; }); - if (!action) this.client.rateLimiter.queueDelete(msg.channel, msg); + if (action) { + log += `\nSanctioned`; + await this._moderate(action, guild, channel, member, wrapper.format('L_FILTER_ACTION', { domain: filterResult.match }), filterResult); + } - // msg.filtered.sanctioned = true; - this.client.rateLimiter.queueDelete(msg.channel, msg); - //msg.delete(); + } - filterResult.filter = 'link'; - await this._moderate(action, guild, channel, member, wrapper.format('L_FILTER_ACTION', { domain: filterResult.match }), filterResult); - - } else this.client.rateLimiter.queueDelete(msg.channel, msg); //msg.delete(); + this.logger.debug(log); } @@ -532,11 +539,17 @@ module.exports = class AutoModeration extends Observer { const member = message.member || await guild.members.fetch(author.id).catch(() => null); const settings = await wrapper.settings(); const { invitefilter: setting } = settings; - const { bypass, ignore, actions, silent, enabled } = setting; + const { bypass, ignore, actions, silent, enabled, whitelist } = setting; if (!enabled) return; const roles = member?.roles.cache.map((r) => r.id) || []; if (roles.some((r) => bypass.includes(r)) || ignore.includes(channel.id)) return; + + const missing = channel.permissionsFor(guild.me).missing('MANAGE_MESSAGES'); + if (missing.length) { + this.client.emit('filterMissingPermissions', { channel, guild: wrapper, filter: 'invite', permissions: missing }); + return; + } const msg = edited || message; const { content } = msg; @@ -546,6 +559,9 @@ module.exports = class AutoModeration extends Observer { if (!match) return; const result = await wrapper.checkInvite(match.groups.code); + const invite = await this.client.fetchInvite(match.groups.code); + if (whitelist.includes(invite.guild.id)) return; + if (!result) { // Doesn't resolve to the origin server let action = null; @@ -586,6 +602,12 @@ module.exports = class AutoModeration extends Observer { if (!enabled || roles.some((r) => bypass.includes(r)) || ignore.includes(channel.id)) return; + const missing = channel.permissionsFor(guild.me).missing('MANAGE_MESSAGES'); + if (missing.length) { + this.client.emit('filterMissingPermissions', { channel, guild: wrapper, filter: 'mention', permissions: missing }); + return; + } + const { content } = message; if (!content) return;