diff --git a/backend/src/data/GuildMutes.ts b/backend/src/data/GuildMutes.ts index 94cfb28f..f761008f 100644 --- a/backend/src/data/GuildMutes.ts +++ b/backend/src/data/GuildMutes.ts @@ -34,7 +34,7 @@ export class GuildMutes extends BaseGuildRepository { return mute != null; } - async addMute(userId, expiryTime): Promise { + async addMute(userId, expiryTime, rolesToRestore?: string[]): Promise { const expiresAt = expiryTime ? moment() .add(expiryTime, "ms") @@ -45,6 +45,7 @@ export class GuildMutes extends BaseGuildRepository { guild_id: this.guildId, user_id: userId, expires_at: expiresAt, + roles_to_restore: rolesToRestore ?? [], }); return this.mutes.findOne({ where: result.identifiers[0] }); diff --git a/backend/src/data/entities/Mute.ts b/backend/src/data/entities/Mute.ts index 023416c4..d9ac2f4b 100644 --- a/backend/src/data/entities/Mute.ts +++ b/backend/src/data/entities/Mute.ts @@ -16,5 +16,5 @@ export class Mute { @Column() case_id: number; - @Column() roles_to_restore: string[]; + @Column("simple-array") roles_to_restore: string[]; } diff --git a/backend/src/plugins/Mutes.ts b/backend/src/plugins/Mutes.ts index e291ae8e..ee7ad827 100644 --- a/backend/src/plugins/Mutes.ts +++ b/backend/src/plugins/Mutes.ts @@ -1,4 +1,4 @@ -import { Member, Message, TextChannel, User } from "eris"; +import { Member, Message, TextChannel, User, MemberOptions } from "eris"; import { GuildCases } from "../data/GuildCases"; import moment from "moment-timezone"; import { ZeppelinPlugin } from "./ZeppelinPlugin"; @@ -175,6 +175,31 @@ export class MutesPlugin extends ZeppelinPlugin { const config = this.getMatchingConfig({ member, userId }); if (member) { + // remove and store any roles to be removed/restored + const currentUserRoles = member.roles; + const memberOptions: MemberOptions = {}; + let rolesToRestore = []; + + // remove roles + if (!Array.isArray(config.remove_roles_on_mute)) { + if (config.remove_roles_on_mute) { + memberOptions.roles = []; + await member.edit(memberOptions); + } + } else { + memberOptions.roles = currentUserRoles.filter(x => !(config.remove_roles_on_mute).includes(x)); + await member.edit(memberOptions); + } + + // set roles to be restored + if (!Array.isArray(config.restore_roles_on_mute)) { + if (config.restore_roles_on_mute) { + rolesToRestore = currentUserRoles; + } + } else { + rolesToRestore = currentUserRoles.filter(x => (config.restore_roles_on_mute).includes(x)); + } + // Apply mute role if it's missing if (!member.roles.includes(muteRole)) { await member.addRole(muteRole); @@ -188,11 +213,6 @@ export class MutesPlugin extends ZeppelinPlugin { await member.edit({ channelID: moveToVoiceChannelId }); } catch (e) {} // tslint:disable-line } - if (config.remove_roles_on_mute) { - if (config.remove_roles_on_mute === true) { - return; - } - } // If the user is already muted, update the duration of their existing mute const existingMute = await this.mutes.findExistingMuteForUserId(user.id); @@ -201,7 +221,7 @@ export class MutesPlugin extends ZeppelinPlugin { if (existingMute) { await this.mutes.updateExpiryTime(user.id, muteTime); } else { - await this.mutes.addMute(user.id, muteTime); + await this.mutes.addMute(user.id, muteTime, rolesToRestore); } const template = existingMute @@ -329,6 +349,15 @@ export class MutesPlugin extends ZeppelinPlugin { if (member.roles.includes(muteRole)) { await member.removeRole(muteRole); } + + // restore roles if appropriate + if (existingMute.roles_to_restore) { + const memberOptions: MemberOptions = {}; + memberOptions.roles = Array.from( + new Set([...existingMute.roles_to_restore, ...member.roles.filter(x => x !== muteRole)]), + ); + member.edit(memberOptions); + } } else { logger.warn( `Member ${userId} not found in guild ${this.guild.name} (${this.guildId}) when attempting to unmute`,