From baaf13006b4d0fded498f5df3a76a7c4c456bfc4 Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:40:38 +0200 Subject: [PATCH] unbanshare --- src/webserver.ts | 5 ++ src/webserver/unbanshare.ts | 163 ++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 src/webserver/unbanshare.ts diff --git a/src/webserver.ts b/src/webserver.ts index 8238109..cc62aa0 100644 --- a/src/webserver.ts +++ b/src/webserver.ts @@ -2,6 +2,7 @@ import express from 'express'; import { handleGithubWebhook } from './webserver/github'; import { client } from './index'; import { handleBanShare } from './webserver/banshare'; +import { handleUnbanShare } from './webserver/unbanshare'; const app = express(); @@ -19,6 +20,10 @@ app.post('/banshare', function (req, res) { handleBanShare(client, req, res); }); +app.post('/unbanshare', function (req, res) { + handleUnbanShare(client, req, res); +}); + const port = process.env.WEBSERVER_PORT || 3000; app.listen(port); console.log(`Webserver is running on port: ${port}`); diff --git a/src/webserver/unbanshare.ts b/src/webserver/unbanshare.ts new file mode 100644 index 0000000..bd79d6a --- /dev/null +++ b/src/webserver/unbanshare.ts @@ -0,0 +1,163 @@ +import { Request, Response } from 'express'; +import { + ButtonStyle, + Client, + Colors, + EmbedBuilder, + ActionRowBuilder, + ButtonBuilder, + ModalActionRowComponentBuilder, + TextInputBuilder, + PermissionsBitField, + TextInputStyle, + GuildMember, +} from 'discord.js'; +import { Button } from '../handlers/button.handler'; +import { Modal } from '../handlers/modal.handler'; + +const unbanModal = new Modal( + 'unban-banshare', + async (interaction, data: { userId: string }) => { + try { + await interaction.guild?.bans.remove( + data.userId, + interaction.components[0].components[0].value + ); + await interaction.reply({ + content: `<@${data.userId}> (\`${data.userId}\`) was unbanned.`, + ephemeral: true, + }); + if (interaction.message) { + await interaction.message.edit({ + components: [ + new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId('fakeUnbanButton') + .setLabel('Unban') + .setStyle(ButtonStyle.Danger) + .setDisabled(true) + ), + ], + }); + } + } catch (error) { + console.error(error); + await interaction.reply({ + content: `Couldn't unban <@${data.userId}>`, + ephemeral: true, + }); + } + } +); + +const unbanButton = new Button( + 'unban-banshare', + async (interaction, data: { userId: string }) => { + const user = await interaction.client.users.fetch(data.userId); + if ( + !(interaction.member as GuildMember)?.permissions.has( + PermissionsBitField.Flags.BanMembers + ) + ) { + return await interaction.reply({ + content: 'You do not have permission to unban this user', + ephemeral: true, + }); + } + + const reason = `${ + interaction.message.embeds[0].fields[4].value ?? 'Simulated' + } Unban share: ${ + interaction.message.embeds[0].fields[3].value ?? + 'no reason provided' + }`; + + const modal = unbanModal.modal( + { + title: `Ban ${user.username}`, + components: [ + new ActionRowBuilder().addComponents( + new TextInputBuilder() + .setCustomId('unbanReason') + .setLabel('Unban reason') + .setStyle(TextInputStyle.Paragraph) + .setValue(reason) + ), + ], + }, + { userId: data.userId } + ); + + await interaction.showModal(modal); + } +); + +export const handleUnbanShare = ( + client: Client, + req: Request, + res: Response +) => { + if (!verify_signature(req)) { + res.status(401).send('Unauthorized'); + return; + } + + if ( + req.body === undefined || + req.body.server === undefined || + req.body.userid === undefined || + req.body.reason === undefined + ) { + return res.status(400).send('Invalid request body'); + } + + handleUnban(client, req); + + res.status(200).send('Webhook received successfully'); +}; + +const handleUnban = async (client: Client, req: Request) => { + const channel = client.channels.cache.get( + process.env.SIMULATED_BAN_SHARE_LOGS_CHANNEL + ); + const server = req.body.server; + const userId = req.body.userid; + const reason = req.body.reason; + + const user = await client.users.fetch(userId); + + const guild = client.guilds.cache.get(process.env.SERVER_ID); + const guildMember = await guild?.members.fetch(userId); + + const embed = new EmbedBuilder() + .setTitle(`Incoming unban from ${server}`) + .addFields( + { name: 'User', value: `<@!${user.id}>` }, + { name: 'Username', value: user.username }, + { name: 'User ID', value: user.id }, + { name: 'Reason', value: reason }, + { name: 'Unbanned From', value: server } + ) + .setColor(Colors.Red) + .setTimestamp(); + channel?.isTextBased() && + (await channel.send({ + embeds: [embed], + components: [ + new ActionRowBuilder().addComponents( + unbanButton.button( + { + label: 'Unban', + style: ButtonStyle.Danger, + disabled: guildMember ? true : false, + }, + { userId } + ) + ), + ], + })); +}; + +const verify_signature = (req: Request) => { + return process.env.SIMULATED_BAN_SHARE_KEY === req.headers['x-api-key']; +};