diff --git a/src/client/ClientDataResolver.js b/src/client/ClientDataResolver.js index 3b0c8d553..b588ff277 100644 --- a/src/client/ClientDataResolver.js +++ b/src/client/ClientDataResolver.js @@ -38,7 +38,7 @@ class ClientDataResolver { if (user instanceof User) { return user; } else if ($string(user)) { - return this.client.users.get(user.id); + return this.client.users.get(user); } else if (user instanceof Message) { return user.author; } else if (user instanceof Guild) { diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 0f2038e54..7dc22e105 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -284,6 +284,14 @@ class RESTMethods { }); } + setChannelOverwrite(channel, payload) { + return new Promise((resolve, reject) => { + this.rest.makeRequest('put', `${Constants.Endpoints.channelPermissions(channel.id)}/${payload.id}`, true, payload) + .then(resolve) + .catch(reject); + }); + } + updateGuildRole(role, _data) { return new Promise((resolve, reject) => { /* diff --git a/src/structures/GuildChannel.js b/src/structures/GuildChannel.js index a9779fe2c..603c665a7 100644 --- a/src/structures/GuildChannel.js +++ b/src/structures/GuildChannel.js @@ -1,5 +1,6 @@ const Channel = require('./Channel'); const PermissionOverwrites = require('./PermissionOverwrites'); +const Role = require('./Role'); const EvaluatedPermissions = require('./EvaluatedPermissions'); const Constants = require('../util/Constants'); @@ -56,13 +57,13 @@ class GuildChannel extends Channel { this.lastMessageID = data.last_message_id; this.ow = data.permission_overwrites; /** - * A list of permission overwrites in this channel for roles and users. - * @type {Array} + * A map of permission overwrites in this channel for roles and users. + * @type {Map} */ - this.permissionOverwrites = []; + this.permissionOverwrites = new Map(); if (data.permission_overwrites) { for (const overwrite of data.permission_overwrites) { - this.permissionOverwrites.push(new PermissionOverwrites(this, overwrite)); + this.permissionOverwrites.set(overwrite.id, new PermissionOverwrites(this, overwrite)); } } } @@ -84,7 +85,7 @@ class GuildChannel extends Channel { if (base) { if (other.permission_overwrites) { - const thisIDSet = this.permissionOverwrites.map(overwrite => overwrite.id); + const thisIDSet = Array.from(this.permissionOverwrites.keys()); const otherIDSet = other.permission_overwrites.map(overwrite => overwrite.id); if (arraysEqual(thisIDSet, otherIDSet)) { base = true; @@ -161,6 +162,68 @@ class GuildChannel extends Channel { return []; } + /** + * An object mapping permission flags to `true` (enabled) or `false` (disabled) + * ```js + * { + * 'SEND_MESSAGES': true, + * 'ATTACH_FILES': false, + * } + * ``` + * @typedef {(number|string)} PermissionOverwriteOptions + * @example + * // overwrite permissions for a message author + * message.channel.overwritePermissions(message.author, { + * SEND_MESSAGES: false + * }) + * .then(() => console.log('Done!')) + * .catch(console.log); + */ + + /** + * Overwrites the permissions for a user or role in this channel. + * @param {Role|UserResolvable} userOrRole the user or role to update + * @param {PermissionOverwriteOptions} config the configuration for the update + * @returns {Promise} + */ + overwritePermissions(userOrRole, options) { + const payload = { + allow: 0, + deny: 0, + }; + + if (userOrRole instanceof Role) { + payload.type = 'role'; + } else { + userOrRole = this.client.resolver.resolveUser(userOrRole); + payload.type = 'member'; + if (!userOrRole) { + return Promise.reject('supplied parameter was neither a user or a role'); + } + } + + payload.id = userOrRole.id; + + const prevOverwrite = this.permissionOverwrites.get(userOrRole.id); + + if (prevOverwrite) { + payload.allow = prevOverwrite.allow; + payload.deny = prevOverwrite.deny; + } + + for (const perm in options) { + if (options[perm] === true) { + payload.allow |= (Constants.PermissionFlags[perm] || 0); + payload.deny &= ~(Constants.PermissionFlags[perm] || 0); + } else if (options[perm] === false) { + payload.allow &= ~(Constants.PermissionFlags[perm] || 0); + payload.deny |= (Constants.PermissionFlags[perm] || 0); + } + } + + return this.client.rest.methods.setChannelOverwrite(this, payload); + } + edit(data) { return this.client.rest.methods.updateChannel(this, data); } diff --git a/test/random.js b/test/random.js index 7a8cb622f..0404a83d5 100644 --- a/test/random.js +++ b/test/random.js @@ -181,5 +181,15 @@ client.on('message', message => { if (message.content === '?perms?') { console.log(message.author.username, 'asked for perms in', message.channel.name, ':'); console.log(message.channel.permissionsFor(message.author).serialize()); + } else if (message.content === '???test???') { + message.channel.overwritePermissions('', { + SEND_MESSAGES: false, + }) + .then(() => { + message.channel.overwritePermissions('', { + SEND_MESSAGES: true, + }); + }) + .catch(console.log); } });