From 1d29ecef66993c501b36e6af880a7657d77ca1db Mon Sep 17 00:00:00 2001 From: IThundxr Date: Wed, 27 Dec 2023 16:19:06 -0500 Subject: [PATCH] banshare (#11) Co-authored-by: Szedann <65607498+Szedann@users.noreply.github.com> --- .env.example | 4 +- src/types/environment.d.ts | 2 + src/webserver.ts | 9 ++++- src/webserver/banshare.ts | 82 ++++++++++++++++++++++++++++++++++++++ src/webserver/github.ts | 6 ++- 5 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 src/webserver/banshare.ts diff --git a/.env.example b/.env.example index a443930..2d3fd83 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ # These are needed no matter what DISCORD_TOKEN= +SERVER_ID= SAY_LOGS_CHANNEL= LOGS_CHANNEL= @@ -11,4 +12,5 @@ LOADING_EMOJI= SUCCESS_EMOJI= FAIL_EMOJI= WEBSERVER_PORT= -DATABASE_URL= \ No newline at end of file +DATABASE_URL= +SIMULATED_BAN_SHARE_KEY= \ No newline at end of file diff --git a/src/types/environment.d.ts b/src/types/environment.d.ts index 3100f81..5ccc5dd 100644 --- a/src/types/environment.d.ts +++ b/src/types/environment.d.ts @@ -4,6 +4,7 @@ declare global { namespace NodeJS { interface ProcessEnv { DISCORD_TOKEN: string; + SERVER_ID: string; SAY_LOGS_CHANNEL: string; LOGS_CHANNEL: string; MAVEN_REPO: string; @@ -14,6 +15,7 @@ declare global { FAIL_EMOJI: string; WEBSERVER_PORT: string; DATABASE_URL: string; + SIMULATED_BAN_SHARE_KEY: string; NODE_ENV: 'development' | 'dev-prod' | 'production'; } } diff --git a/src/webserver.ts b/src/webserver.ts index b0a3ecc..15bae2b 100644 --- a/src/webserver.ts +++ b/src/webserver.ts @@ -1,6 +1,7 @@ import express from 'express'; -import { handleWebhook } from './webserver/github'; +import { handleGithubWebhook } from './webserver/github'; import { client } from './index'; +import { handleBanShare } from './webserver/banshare'; const app = express(); @@ -11,7 +12,11 @@ app.get('/', function (req, res) { }); app.post('/github-webhook', function (req, res) { - handleWebhook(client, req, res); + handleGithubWebhook(client, req, res); +}); + +app.post('/banshare', function (req, res) { + handleBanShare(client, req, res); }); const port = process.env.WEBSERVER_PORT || 3000; diff --git a/src/webserver/banshare.ts b/src/webserver/banshare.ts new file mode 100644 index 0000000..1666d0c --- /dev/null +++ b/src/webserver/banshare.ts @@ -0,0 +1,82 @@ +import { Request, Response } from 'express'; +import { ButtonStyle, Client, Colors, EmbedBuilder } from 'discord.js'; +import { Button } from '../handlers/button.handler'; +import { string, object } from 'valibot'; +import { ActionRowBuilder, ButtonBuilder } from '@discordjs/builders'; + +const banButton = new Button( + 'Ban', + object({ userId: string() }), + (interaction, data) => { + const reason = + 'aero banshare: ' + + (interaction.message.embeds[0].fields[3].value ?? + 'no reason provided'); + interaction.guild?.bans.create(data.userId, { reason: reason }); + interaction.reply(`<@${data.userId}> (\`${data.userId}\`) was banned.`); + } +); + +export const handleBanShare = (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'); + } + + handleBan(client, req); + + res.status(200).send('Webhook received successfully'); +}; + +const handleBan = async (client: Client, req: Request) => { + const channel = client.channels.cache.get(process.env.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 present = guildMember !== undefined; + + const embed = new EmbedBuilder() + .setTitle(`Incoming ban from ${server}`) + .addFields( + { name: 'Username', value: user.username }, + { name: 'User ID', value: user.id }, + { name: 'Present in server', value: `${present}` }, + { name: 'Reason', value: reason }, + { name: 'Banned From', value: server } + ) + .setColor(Colors.Red) + .setTimestamp(); + channel?.isTextBased() && + (await channel.send({ + embeds: [embed], + components: [ + new ActionRowBuilder().addComponents( + banButton.button( + { + label: 'Ban', + style: ButtonStyle.Danger, + }, + { userId } + ) + ), + ], + })); +}; + +const verify_signature = (req: Request) => { + return process.env.SIMULATED_BAN_SHARE_KEY === req.headers['x-api-key']; +}; diff --git a/src/webserver/github.ts b/src/webserver/github.ts index 3d976d4..6f91ee2 100644 --- a/src/webserver/github.ts +++ b/src/webserver/github.ts @@ -14,7 +14,11 @@ const WEBHOOK_SECRET: string = process.env.GITHUB_SECRET; const commitMap = new Map(); const githubMap = new Map(); -export const handleWebhook = (client: Client, req: Request, res: Response) => { +export const handleGithubWebhook = ( + client: Client, + req: Request, + res: Response +) => { if (!verify_signature(req)) { res.status(401).send('Unauthorized'); return;