diff --git a/README.md b/README.md index f2189f0..a84d975 100644 --- a/README.md +++ b/README.md @@ -51,4 +51,4 @@ Built with [NestJs](https://github.com/nestjs) | Tests | Builds | Version | | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| [![tests](https://github.com/blvckleg/bingusboingus/actions/workflows/docker-test.yml/badge.svg)](https://github.com/blvckleg/bingusboingus/actions/workflows/docker-test.yml) | [![build](https://github.com/blvckleg/bingusboingus/actions/workflows/docker-dev.yml/badge.svg)](https://github.com/blvckleg/bingusboingus/actions/workflows/docker-dev.yml) | ![version-latest](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2FBingusBoingus-Developer-Team%2FBingusBoingus%2Fraw%2Fmaster%2Fpackage.json&query=%24.version&label=latest) | +| [![tests](https://github.com/blvckleg/bingusboingus/actions/workflows/docker-test.yml/badge.svg)](https://github.com/blvckleg/bingusboingus/actions/workflows/docker-test.yml) | [![build](https://github.com/blvckleg/bingusboingus/actions/workflows/docker-dev.yml/badge.svg)](https://github.com/blvckleg/bingusboingus/actions/workflows/docker-dev.yml) | ![version-latest](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2FBingusBoingus-Developer-Team%2FBingusBoingus%2Fraw%2Fmaster%2Fpackage.json&query=%24.version&label=latest) | \ No newline at end of file diff --git a/src/common/decoratos/role.decorator.ts b/src/common/decoratos/role.decorator.ts new file mode 100644 index 0000000..1cea156 --- /dev/null +++ b/src/common/decoratos/role.decorator.ts @@ -0,0 +1,34 @@ +import { CommandInteraction } from 'discord.js'; + +// Role decorator factory +export function Role(requiredRole: CommandAccessLevel) { + return function ( + target, + propertyKey: string, + descriptor: PropertyDescriptor, + ) { + const originalMethod = descriptor.value; + + descriptor.value = async function (...args) { + const interaction: CommandInteraction = args[0]; + const roles = interaction.guild.roles.cache; + if ( + !roles.has(requiredRole) && + requiredRole !== CommandAccessLevel.member + ) { + await interaction.reply({ + content: 'You do not have the required role to execute this command.', + ephemeral: true, + }); + return false; + } + return originalMethod.apply(this, args); + }; + }; +} + +export enum CommandAccessLevel { + Developer = '1265375756637180027', + vip = '484479705148293120', + member = '484479403817173002', +} diff --git a/src/modules/command/commands/activate-birthday-shoutout.ts b/src/modules/command/commands/activate-birthday-shoutout.ts index 3ce4648..83b501a 100644 --- a/src/modules/command/commands/activate-birthday-shoutout.ts +++ b/src/modules/command/commands/activate-birthday-shoutout.ts @@ -1,41 +1,43 @@ -import { - CacheType, - CommandInteraction, - SlashCommandBuilder, - } from 'discord.js'; - import { ACommand } from '../command.abstract'; - import { Inject } from '@nestjs/common'; +import { CacheType, CommandInteraction, SlashCommandBuilder } from 'discord.js'; +import { ACommand } from '../command.abstract'; +import { Inject } from '@nestjs/common'; import { BirthdayEntryService } from '../../models/birthday/service/birthday-entry.service'; import { CreateOrUpdateBirthdayEntryDto } from '../../models/birthday/dto/create-or-update-birthday-entry.dto'; - - export default class ActivateBirthdayEntryShoutoutCommand extends ACommand { - constructor( - @Inject(BirthdayEntryService) - private readonly birthdayEntryService: BirthdayEntryService, - ) { - super(); - } - data = new SlashCommandBuilder() - .setName('activate-birthday-shoutout') - .setDescription( - 'Use this if you want Bingus to shout you out on your birthday (default)!', - ); - - async execute(arg: CommandInteraction): Promise { - await arg.deferReply(); - const instance: CreateOrUpdateBirthdayEntryDto ={ - username: arg.user.username, - secName: arg.user.displayName, - active: true - }; - const inactive = - await this.birthdayEntryService.updateBirthdayEntry(instance); - if (!inactive) { - await arg.editReply({ content: 'I don\'t know your birthday yet! πŸŽ‰'}); - } else { - await arg.editReply({ content: 'You will now receive a birthday shoutout from Bingus! πŸŽ‰'}); - } - return true; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; + +export default class ActivateBirthdayEntryShoutoutCommand extends ACommand { + constructor( + @Inject(BirthdayEntryService) + private readonly birthdayEntryService: BirthdayEntryService, + ) { + super(); + } + data = new SlashCommandBuilder() + .setName('activate-birthday-shoutout') + .setDescription( + 'Use this if you want Bingus to shout you out on your birthday (default)!', + ); + + @Role(CommandAccessLevel.member) + async execute(arg: CommandInteraction): Promise { + await arg.deferReply(); + const instance: CreateOrUpdateBirthdayEntryDto = { + username: arg.user.username, + secName: arg.user.displayName, + active: true, + }; + const inactive = + await this.birthdayEntryService.updateBirthdayEntry(instance); + if (!inactive) { + await arg.editReply({ content: "I don't know your birthday yet! πŸŽ‰" }); + } else { + await arg.editReply({ + content: 'You will now receive a birthday shoutout from Bingus! πŸŽ‰', + }); } + return true; } - \ No newline at end of file +} diff --git a/src/modules/command/commands/add-birthday-entry.ts b/src/modules/command/commands/add-birthday-entry.ts index 7d03fa3..245d998 100644 --- a/src/modules/command/commands/add-birthday-entry.ts +++ b/src/modules/command/commands/add-birthday-entry.ts @@ -8,6 +8,10 @@ import { ACommand } from '../command.abstract'; import { Inject } from '@nestjs/common'; import { BirthdayEntryService } from '../../models/birthday/service/birthday-entry.service'; import { CreateOrUpdateBirthdayEntryDto } from '../../models/birthday/dto/create-or-update-birthday-entry.dto'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; export default class AddBirthdayEntryCommand extends ACommand { constructor( @@ -31,6 +35,7 @@ export default class AddBirthdayEntryCommand extends ACommand { option.setName('year').setDescription('your year of birth'), ); + @Role(CommandAccessLevel.member) async execute(arg: CommandInteraction): Promise { const day = arg.options.get('day'); const month = arg.options.get('month'); diff --git a/src/modules/command/commands/bug.ts b/src/modules/command/commands/bug.ts index 5bc0526..fe9a930 100644 --- a/src/modules/command/commands/bug.ts +++ b/src/modules/command/commands/bug.ts @@ -1,11 +1,18 @@ import { Injectable } from '@nestjs/common'; import { SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class BugReport extends ACommand { - data = new SlashCommandBuilder().setName('bug').setDescription('report a bug to my maintainers!'); + data = new SlashCommandBuilder() + .setName('bug') + .setDescription('report a bug to my maintainers!'); + @Role(CommandAccessLevel.member) async execute(interaction) { return this.run(async () => { await interaction.reply( diff --git a/src/modules/command/commands/cbd.ts b/src/modules/command/commands/cbd.ts index 656aeb4..bdba301 100644 --- a/src/modules/command/commands/cbd.ts +++ b/src/modules/command/commands/cbd.ts @@ -1,11 +1,18 @@ import { Injectable } from '@nestjs/common'; import { SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class CBDCommand extends ACommand { - data = new SlashCommandBuilder().setName('cbd').setDescription('der hurensohn!'); + data = new SlashCommandBuilder() + .setName('cbd') + .setDescription('der hurensohn!'); + @Role(CommandAccessLevel.vip) async execute(interaction) { return this.run(async () => { await interaction.reply('Wenn der Hurensohn nur wΓΌsste...'); diff --git a/src/modules/command/commands/coinflip.ts b/src/modules/command/commands/coinflip.ts index dd0f6f0..7f0f059 100644 --- a/src/modules/command/commands/coinflip.ts +++ b/src/modules/command/commands/coinflip.ts @@ -1,11 +1,18 @@ import { Injectable } from '@nestjs/common'; import { SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class CoinflipCommand extends ACommand { - data = new SlashCommandBuilder().setName('coinflip').setDescription('Bingus flips a coin for you'); + data = new SlashCommandBuilder() + .setName('coinflip') + .setDescription('Bingus flips a coin for you'); + @Role(CommandAccessLevel.member) async execute(interaction) { return this.run(async () => { await interaction.reply(this.coinflip()); diff --git a/src/modules/command/commands/deactivate-birthday-shoutout.ts b/src/modules/command/commands/deactivate-birthday-shoutout.ts index d16c295..deaded2 100644 --- a/src/modules/command/commands/deactivate-birthday-shoutout.ts +++ b/src/modules/command/commands/deactivate-birthday-shoutout.ts @@ -3,6 +3,10 @@ import { ACommand } from '../command.abstract'; import { Inject } from '@nestjs/common'; import { BirthdayEntryService } from '../../models/birthday/service/birthday-entry.service'; import { CreateOrUpdateBirthdayEntryDto } from '../../models/birthday/dto/create-or-update-birthday-entry.dto'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; export default class DeactivateBirthdayEntryShoutoutCommand extends ACommand { constructor( @@ -17,6 +21,7 @@ export default class DeactivateBirthdayEntryShoutoutCommand extends ACommand { "Use this if you don't want Bingus to shout you out on your birthday!", ); + @Role(CommandAccessLevel.member) async execute(arg: CommandInteraction): Promise { await arg.deferReply(); const instance: CreateOrUpdateBirthdayEntryDto = { diff --git a/src/modules/command/commands/get-a-quote.ts b/src/modules/command/commands/get-a-quote.ts index 35c1372..5cb8476 100644 --- a/src/modules/command/commands/get-a-quote.ts +++ b/src/modules/command/commands/get-a-quote.ts @@ -7,6 +7,10 @@ import { import { ACommand } from '../command.abstract'; import { Inject } from '@nestjs/common'; import { SomeoneOnceSaidService } from '../../models/someone-once-said/service/someone-once-said.service'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; export default class GetRandomQuote extends ACommand { constructor( @@ -19,6 +23,7 @@ export default class GetRandomQuote extends ACommand { .setName('randomquote') .setDescription('get a random quote of a user'); + @Role(CommandAccessLevel.member) async execute(arg: CommandInteraction): Promise { const someoneOnceSaid = await this.someoneonceSaidService.getRandomQuote(); if (!someoneOnceSaid) return; diff --git a/src/modules/command/commands/gold.ts b/src/modules/command/commands/gold.ts index fb77736..7e7a49b 100644 --- a/src/modules/command/commands/gold.ts +++ b/src/modules/command/commands/gold.ts @@ -1,11 +1,18 @@ import { Injectable } from '@nestjs/common'; import { SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class GoldCommand extends ACommand { - data = new SlashCommandBuilder().setName('gold').setDescription('schweigen ist gold!'); + data = new SlashCommandBuilder() + .setName('gold') + .setDescription('schweigen ist gold!'); + @Role(CommandAccessLevel.vip) public execute(arg: any /*Interaction*/): Promise { return this.run(async () => { await arg.reply({ diff --git a/src/modules/command/commands/hello.ts b/src/modules/command/commands/hello.ts index 232754b..db21ce6 100644 --- a/src/modules/command/commands/hello.ts +++ b/src/modules/command/commands/hello.ts @@ -1,6 +1,10 @@ import { Injectable } from '@nestjs/common'; import { SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class HelloCommand extends ACommand { @@ -8,6 +12,7 @@ export class HelloCommand extends ACommand { .setName('hello') .setDescription('Hello World!'); + @Role(CommandAccessLevel.Developer) async execute(interaction) { return this.run(async () => { await interaction.reply('moin!'); diff --git a/src/modules/command/commands/pingpong.ts b/src/modules/command/commands/pingpong.ts index 74e1436..e2c7c00 100644 --- a/src/modules/command/commands/pingpong.ts +++ b/src/modules/command/commands/pingpong.ts @@ -1,6 +1,10 @@ import { Injectable } from '@nestjs/common'; import { SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class PingPongCommand extends ACommand { @@ -8,6 +12,7 @@ export class PingPongCommand extends ACommand { .setName('ping') .setDescription('Replies with Pong!'); + @Role(CommandAccessLevel.Developer) public execute(arg: any /*Interaction*/): Promise { return this.run(async () => { await arg.reply('Pong!'); diff --git a/src/modules/command/commands/poll.ts b/src/modules/command/commands/poll.ts index 005f78a..12ba1ce 100644 --- a/src/modules/command/commands/poll.ts +++ b/src/modules/command/commands/poll.ts @@ -1,15 +1,11 @@ import { Inject, Injectable } from '@nestjs/common'; -import { - ActionRowBuilder, - ButtonBuilder, - ButtonStyle, - CacheType, - CommandInteraction, - EmbedBuilder, - SlashCommandBuilder, -} from 'discord.js'; +import { CacheType, CommandInteraction, SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; import { PollService } from '../../models/poll/service/poll.service'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class PollCommand extends ACommand { @@ -31,6 +27,7 @@ export class PollCommand extends ACommand { .setRequired(true), ); + @Role(CommandAccessLevel.member) public execute(arg: CommandInteraction): Promise { return this.run(async () => { this.pollService.create(arg); diff --git a/src/modules/command/commands/reported.ts b/src/modules/command/commands/reported.ts index 5ab4d29..6ee3d89 100644 --- a/src/modules/command/commands/reported.ts +++ b/src/modules/command/commands/reported.ts @@ -1,11 +1,18 @@ import { Injectable } from '@nestjs/common'; import { SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class ReportedCommand extends ACommand { - data = new SlashCommandBuilder().setName('reported').setDescription('swag reports someone'); + data = new SlashCommandBuilder() + .setName('reported') + .setDescription('swag reports someone'); + @Role(CommandAccessLevel.member) public execute(arg: any /*Interaction*/): Promise { return this.run(async () => { await arg.reply({ diff --git a/src/modules/command/commands/someone-once-said.ts b/src/modules/command/commands/someone-once-said.ts index 2117992..d6d8bc3 100644 --- a/src/modules/command/commands/someone-once-said.ts +++ b/src/modules/command/commands/someone-once-said.ts @@ -8,6 +8,10 @@ import { ACommand } from '../command.abstract'; import { Inject } from '@nestjs/common'; import { SomeoneOnceSaid } from '../../../schemas/someone-once-said.schema'; import { SomeoneOnceSaidService } from '../../models/someone-once-said/service/someone-once-said.service'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; export default class SomeoneOnceSaidCommand extends ACommand { constructor( @@ -23,6 +27,7 @@ export default class SomeoneOnceSaidCommand extends ACommand { option.setName('phrase').setDescription('What was said'), ); + @Role(CommandAccessLevel.vip) async execute(arg: CommandInteraction): Promise { const phrase = arg.options.get('phrase'); if (!phrase) { diff --git a/src/modules/command/commands/version.ts b/src/modules/command/commands/version.ts index 2d86931..b612ce1 100644 --- a/src/modules/command/commands/version.ts +++ b/src/modules/command/commands/version.ts @@ -2,6 +2,10 @@ import { Inject, Injectable } from '@nestjs/common'; import { SlashCommandBuilder } from 'discord.js'; import { ACommand } from '../command.abstract'; import { VersionService } from '../../models/version/service/version.service'; +import { + CommandAccessLevel, + Role, +} from '../../../common/decoratos/role.decorator'; @Injectable() export class VersionCommand extends ACommand { @@ -16,6 +20,7 @@ export class VersionCommand extends ACommand { 'show the version of the currently running bingus instance', ); + @Role(CommandAccessLevel.Developer) async execute(interaction) { const version = await this.versionService.getVersion(); return this.run(async () => {