Skip to content

Commit

Permalink
Check for permissions in all admin commands, update /ec and README.
Browse files Browse the repository at this point in the history
  • Loading branch information
retrixe committed Jul 11, 2020
1 parent b2698fb commit fbe72a5
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 48 deletions.
85 changes: 47 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,73 @@ The bot that created the iPhone X. It's strictly private. You may run it locally

**Requires Node.js 8.5.0 or higher.**

It includes many different and useful commands, from games to tools, utilities, fun commands and moderation. It also uses Next.js to provide a web dashboard as part of the bot itself.

It's planned to have some nifty commands like /assistant which directly communicates with the Google Assistant gRPC API. You heard that, Google Assistant in a Discord bot.

2.0 is built upon Next.js with administrative commands and a web dashboard. 3.0 in development uses Eris and is a rewritten and refined codebase focused on stability and a framework for further enhancements.
1.0 and 2.0 used discord.io while 3.0 uses Eris and is much more refined and full-featured. It is highly recommended to use 3.0 as older versions are unsupported and may not connect to Discord's API gateway anymore.

<hr />
<details><summary>Commands</summary>

<br />

\`/halp\` and \`/help\` - The most innovative help.
`/halp` and `/help` - The most innovative help.

**Games.**

- \`/gunfight\`
- \`/random\`
- \`/randomword\`
- \`/choose\`
- \`/reverse\`
- \`/8ball\`
- \`/repeat\`
- \`/calculate\`
- \`/distort\`
- `/gunfight`
- `/random`
- `/randomword`
- `/choose`
- `/reverse`
- `/8ball`
- `/repeat`
- `/calculate`
- `/distort`

**Random searches.**

- \`/urban\`
- \`/cat\` and \`/dog\`
- \`/robohash\`
- \`/zalgo\` \`/dezalgo\`
- \`/namemc\`
- \`/astronomy-picture-of-the-day\` or \`/apod\`
- \`/currency\`
- `/urban`
- `/cat` and `/dog`
- `/robohash`
- `/zalgo` `/dezalgo`
- `/namemc`
- `/astronomy-picture-of-the-day` or `/apod`
- `/currency`
- `/xkcd`
- `/httpcat`

**Utilities.**

- \`/request\` (for test pilots)
- \`/token\`
- \`/weather\`
- \`/say\` | \`/type\`
- \`/editLastSay\`
- \`/remindme\`
- \`/leave\`
- \`/ocr\`
- \`/avatar\`
- \`/userinfo\`
- \`/serverinfo\`
- \`/about\`, \`/ping\`, \`/uptime\` and \`/version\`
- \`/giverole\` and \`/takerole\`
- `/request`
- `/token`
- `/weather`
- `/say` | `/type`
- `/editLastSay`
- `/remindme`
- `/leave`
- `/ocr`
- `/avatar`
- `/userinfo`
- `/serverinfo`
- `/creationtime`
- `/about`, `/ping`, `/uptime` and `/version`
- `/emojiImage`
- `/giverole` and `/takerole`
- `/notify`

**Administrative commands.**

- \`/deleteChannel\` and \`/editChannel\`
- \`/changeserverregion\` and \`/listserverregions\`
- \`/ban\`, \`/unban\`, \`/kick\`, \`/mute\` and \`/unmute\`
- \`/warn\` and \`/warnings\` | \`/clearwarns\` and \`/removewarn\`
- \`/addEmoji\`, \`/deleteEmoji\`, \`/emojiImage\` and \`/editEmoji\`
- \`/purge\`
- \`/slowmode\`
- `/deleteChannel` and `/editChannel`
- `/changeserverregion` and `/listserverregions`
- `/ban`, `/unban`, `/kick`, `/mute` and `/unmute`
- `/warn` and `/warnings` | `/clearwarns` and `/removewarn`
- `/addEmoji`, `/deleteEmoji` and `/editEmoji`
- `/purge`
- `/slowmode`

[Complete list of commands along with their descriptions available here.](https://github.com/retrixe/IveBot/blob/master/server/bot/commands/help.ts#L6)

</details>
<hr />
Expand Down
4 changes: 4 additions & 0 deletions server/bot/commands/admin/ban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ export const handleUnban: Command = {
requirements: { permissions: { 'banMembers': true } }
},
generator: async (message, args, { client }) => {
// Check bot for permissions.
if (!message.member.guild.members.get(client.user.id).permission.has('banMembers')) {
return `I lack permission to unban members, you ${getInsult()}.`
}
// Find the user ID.
const userSpecified = args.shift()
let user: User
Expand Down
20 changes: 15 additions & 5 deletions server/bot/commands/admin/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@ export const handleDeletechannel: Command = {
guildOnly: true,
requirements: { permissions: { 'manageChannels': true } }
},
generator: async (message, args) => {
generator: async (message, args, { client }) => {
// Get the channel ID.
const channel = getChannel(message, args.shift())
if (!channel) return `Specify a valid channel, you ${getInsult()}!`
// If no permission to manage channels, say it.
if (!message.member.guild.members.get(client.user.id).permission.has('manageChannels')) {
return 'I can\'t even delete that channel, you ' + getInsult() + '.'
}
// Delete it.
await channel.delete(args.join(' '))
try {
await channel.delete(args.join(' '))
} catch (e) { return 'I was unable to delete that channel >_<' }
// Confirm the delete.
return `Channel \`${channel.name}\` deleted.`
}
Expand All @@ -36,10 +42,14 @@ export const handleEditchannel: Command = {
guildOnly: true,
requirements: { permissions: { 'manageChannels': true } }
},
generator: async (message, args) => {
generator: async (message, args, { client }) => {
// Get the channel ID.
const channel = getChannel(message, args.shift())
if (!channel) return `Specify a valid channel, you ${getInsult()}!`
// If no permission to manage channel, say it.
if (!channel.permissionsOf(client.user.id).has('manageChannels')) {
return 'I can\'t edit that channel, you ' + getInsult() + '.'
}
// Get the operations.
const ops: string[] = args.join(' ').split('|')
// Now iterate over each operation and execute them.
Expand Down Expand Up @@ -69,8 +79,8 @@ export const handleEditchannel: Command = {
})
} else if (name === 'nsfw' && value !== 'true' && value !== 'false') {
failedOps.push({ name: `❌ ${operation}`, value: 'NSFW must be either true or false.' })
} else if (name === 'bitrate' && (isNaN(+value) || +value < 8 || +value > 96)) {
failedOps.push({ name: `❌ ${operation}`, value: 'bitrate must be a number between 8-96.' })
} else if (name === 'bitrate' && (isNaN(+value) || +value < 8 || +value > 384)) {
failedOps.push({ name: `❌ ${operation}`, value: 'bitrate must be a number between 8-384.' })
} else if (name === 'userLimit' && (isNaN(+value) || +value > 99 || +value < 0)) {
failedOps.push({ name: `❌ ${operation}`, value: 'userLimit must be a number between 0-99.' })
// Now we edit the channel.
Expand Down
12 changes: 10 additions & 2 deletions server/bot/commands/admin/emoji.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ export const handleDeleteemoji: Command = {
guildOnly: true,
requirements: { permissions: { 'manageEmojis': true } }
},
generator: async (message, args) => {
generator: async (message, args, { client }) => {
// Check bot permissions.
if (!message.member.guild.members.get(client.user.id).permission.has('manageEmojis')) {
return `I don't even have permissions to do that, you ${getInsult()}.`
}
// Try deleting it, else throw an error.
try {
const emoji = message.member.guild.emojis.find(
Expand All @@ -98,9 +102,13 @@ export const handleEditemoji: Command = {
guildOnly: true,
requirements: { permissions: { 'manageEmojis': true } }
},
generator: async (message, args) => {
generator: async (message, args, { client }) => {
// Check if enough arguments were provided.
if (args.length !== 2) return 'Correct usage: /editEmoji <emoji by ID/mention/name> <new name>'
// Check bot permissions.
if (!message.member.guild.members.get(client.user.id).permission.has('manageEmojis')) {
return `I don't even have permissions to do that, you ${getInsult()}.`
}
// Try editing it, else throw an error.
try {
const emoji = message.member.guild.emojis.find(
Expand Down
15 changes: 13 additions & 2 deletions server/bot/commands/admin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export const handlePurge: Command = {
if (
isNaN(+args[0]) || args.length !== 1 || +args[0] <= 0 || +args[0] > 100
) { return 'Correct usage: /purge <number greater than 0 and less than 100>' }
// Check bot for permissions.
const permission = message.member.guild.channels.get(message.channel.id).permissionsOf(client.user.id)
if (!permission.has('manageMessages')) {
return `I lack permission to purge messages in this channel, you ${getInsult()}.`
}
// Pre-defined variables.
let messages: Array<Message>
// Get the list of messages.
Expand Down Expand Up @@ -130,16 +135,22 @@ export const handleSlowmode: Command = {
permissions: { 'manageChannels': true },
custom: (message) => (
message.member.guild.channels.get(message.channel.id)
.permissionsOf(message.author.id).has('manageChannels')
.permissionsOf(message.author.id).has('manageChannels') ||
message.member.guild.channels.get(message.channel.id)
.permissionsOf(message.author.id).has('manageMessages')
)
}
},
generator: async (message, args, { client }) => {
// Check user for permissions.
const t = +args[0]
if (
(isNaN(t) && args[0] !== 'off') || !args[0] || t < 0 || t > 120 || args.length > 1
) { return 'Correct usage: /slowmode <number in seconds, max: 120 or off>' }
// Check bot for permissions.
const permission = message.member.guild.channels.get(message.channel.id).permissionsOf(client.user.id)
if (!permission.has('manageMessages') && !permission.has('manageChannels')) {
return `I lack permission to set slowmode in this channel, you ${getInsult()}.`
}
// Set slowmode.
try {
await client.editChannel(message.channel.id, { rateLimitPerUser: isNaN(t) ? 0 : t })
Expand Down
5 changes: 5 additions & 0 deletions server/bot/commands/admin/mute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ export const handleMute: Command = {
})
} catch (e) { return 'I cannot set permissions for the Muted role.' }
}
// Can the bot manage this role?
if (
role.position >= checkRolePosition(message.member.guild.members.get(client.user.id)) ||
!message.member.guild.members.get(client.user.id).permission.has('manageRoles')
) return `I lack permissions to mute people with the role, you ${getInsult()}.`
// Mute person.
try {
await client.addGuildMemberRole(message.member.guild.id, user.id, role.id, args.join(' '))
Expand Down
18 changes: 17 additions & 1 deletion server/bot/commands/admin/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ export const handleGiverole: Command = {
// Can the user manage this role?
if (role.position >= checkRolePosition(message.member) && !isPublicRole
) return `You cannot give this role. Pfft, overestimating their own powers now.`
// Can the bot manage this role?
if (
role.position >= checkRolePosition(message.member.guild.members.get(client.user.id)) ||
!message.member.guild.members.get(client.user.id).permission.has('manageRoles')
) return `I lack permissions to give this role, you ${getInsult()}.`
// Give the role.
const rolesOfMember = user.id !== message.author.id // Ternary statement.
? message.member.guild.members.find(a => a.id === user.id).roles
Expand Down Expand Up @@ -86,6 +91,11 @@ export const handleTakerole: Command = {
// Can the user manage this role?
if (role.position >= checkRolePosition(message.member) && !isPublicRole
) return `You cannot take this role. Pfft, overestimating their own powers now.`
// Can the bot manage this role?
if (
role.position >= checkRolePosition(message.member.guild.members.get(client.user.id)) ||
!message.member.guild.members.get(client.user.id).permission.has('manageRoles')
) return `I lack permissions to take this role, you ${getInsult()}.`
// Give the role.
const rolesOfMember = user.id !== message.author.id // Ternary statement.
? message.member.guild.members.find(a => a.id === user.id).roles
Expand Down Expand Up @@ -119,7 +129,7 @@ export const handleNotify: Command = {
deleteCommand: true,
requirements: { permissions: { 'manageRoles': true } }
},
generator: async (message, args) => {
generator: async (message, args, { client }) => {
// Find the role.
const arg = args.shift()
const role = message.member.guild.roles.find(
Expand All @@ -129,6 +139,12 @@ export const handleNotify: Command = {
// Can the user manage this role?
if (role.position >= checkRolePosition(message.member) && !role.mentionable
) return `You cannot notify this role, you ${getInsult()}.`
// Can the bot manage this role?
if (
(role.position >= checkRolePosition(message.member.guild.members.get(client.user.id)) ||
!message.member.guild.members.get(client.user.id).permission.has('manageRoles')) &&
!role.mentionable
) return `I cannot notify this role, you ${getInsult()}.`
// Edit the role.
const wasMentionable = role.mentionable
if (!wasMentionable) await role.edit({ mentionable: true })
Expand Down

0 comments on commit fbe72a5

Please sign in to comment.