Skip to content

Commit

Permalink
feat: Add "Manage Server Guard" that checks for "Manage Server" permi…
Browse files Browse the repository at this point in the history
…ssion in favor of administrator guard for all commands
  • Loading branch information
jurienhamaker committed Jul 14, 2024
1 parent 4c0d0c2 commit b1baa29
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 19 deletions.
8 changes: 4 additions & 4 deletions apps/hoshi/src/modules/settings/commands/settings.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, Logger, UseFilters, UseGuards } from '@nestjs/common';
import { Settings } from '@prisma/hoshi';
import {
ForbiddenExceptionFilter,
GuildAdminGuard,
ManageServerGuard,
GuildModeratorGuard,
} from '@yugen/shared';
import { TextChannel } from 'discord.js';
Expand Down Expand Up @@ -75,7 +75,7 @@ export class SettingsCommands {
return this._settings.showSettings(interaction);
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@Subcommand({
name: 'reset',
description: "Reset a hoshi setting to it's default value.",
Expand Down Expand Up @@ -117,7 +117,7 @@ export class SettingsCommands {
});
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@Subcommand({
name: 'treshold',
description: 'Set starboard threshold',
Expand All @@ -143,7 +143,7 @@ export class SettingsCommands {
});
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@Subcommand({
name: 'author-starring',
description: 'Set whether message author starring counts',
Expand Down
6 changes: 3 additions & 3 deletions apps/kazu/src/modules/game/commands/leaderboard.commants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable, UseFilters, UseGuards } from '@nestjs/common';
import { ForbiddenExceptionFilter, GuildAdminGuard } from '@yugen/shared';
import { ForbiddenExceptionFilter, ManageServerGuard } from '@yugen/shared';
import { getEmbedFooter } from '@yugen/util';
import {
ActionRowBuilder,
Expand Down Expand Up @@ -66,7 +66,7 @@ export class GameLeaderboardCommands {
return this._listLeaderboard(interaction, page);
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@SlashCommand({
name: 'reset-leaderboard',
Expand Down Expand Up @@ -101,7 +101,7 @@ export class GameLeaderboardCommands {
});
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@Button('RESET_LEADERBOARD/:type')
public async resetButton(
Expand Down
4 changes: 2 additions & 2 deletions apps/kazu/src/modules/settings/commands/settings.command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable, UseFilters, UseGuards } from '@nestjs/common';
import { Settings } from '@prisma/kazu';
import { ForbiddenExceptionFilter, GuildAdminGuard } from '@yugen/shared';
import { ForbiddenExceptionFilter, ManageServerGuard } from '@yugen/shared';
import { ChannelType, Role, TextChannel } from 'discord.js';
import {
BooleanOption,
Expand Down Expand Up @@ -82,7 +82,7 @@ class SettingsSetShameRoleOptions {
role: Role;
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@SettingsCommandDecorator()
@Injectable()
Expand Down
6 changes: 3 additions & 3 deletions apps/koto/src/modules/game/commands/leaderboard.commants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
StringOption,
} from 'necord';
import { GamePointsService } from '../services/points.service';
import { ForbiddenExceptionFilter, GuildAdminGuard } from '@yugen/shared';
import { ForbiddenExceptionFilter, ManageServerGuard } from '@yugen/shared';

class GameLeaderboardOptions {
@StringOption({
Expand Down Expand Up @@ -71,7 +71,7 @@ export class GameLeaderboardCommands {
return this._listLeaderboard(interaction, type ?? 'points', page);
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@SlashCommand({
name: 'reset-leaderboard',
Expand Down Expand Up @@ -105,7 +105,7 @@ export class GameLeaderboardCommands {
})
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@Button('RESET_LEADERBOARD/:type')
public async resetButton(
Expand Down
4 changes: 2 additions & 2 deletions apps/koto/src/modules/settings/commands/settings.command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable, UseFilters, UseGuards } from '@nestjs/common';
import { Settings } from '@prisma/koto';
import { ForbiddenExceptionFilter, GuildAdminGuard } from '@yugen/shared';
import { ForbiddenExceptionFilter, ManageServerGuard } from '@yugen/shared';
import { formatMinutes } from '@yugen/util';
import { ChannelType, Role, TextChannel } from 'discord.js';
import {
Expand Down Expand Up @@ -121,7 +121,7 @@ class SettingsResetOptions {
setting: keyof Settings;
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@SettingsCommandDecorator()
@Injectable()
Expand Down
6 changes: 3 additions & 3 deletions apps/kusari/src/modules/game/commands/leaderboard.commants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
SlashCommandContext,
} from 'necord';
import { GamePointsService } from '../services/points.service';
import { ForbiddenExceptionFilter, GuildAdminGuard } from '@yugen/shared';
import { ForbiddenExceptionFilter, ManageServerGuard } from '@yugen/shared';

class GameLeaderboardOptions {
// @StringOption({
Expand Down Expand Up @@ -66,7 +66,7 @@ export class GameLeaderboardCommands {
return this._listLeaderboard(interaction, 'points', page);
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@SlashCommand({
name: 'reset-leaderboard',
Expand Down Expand Up @@ -100,7 +100,7 @@ export class GameLeaderboardCommands {
})
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@Button('RESET_LEADERBOARD/:type')
public async resetButton(
Expand Down
4 changes: 2 additions & 2 deletions apps/kusari/src/modules/settings/commands/settings.command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable, UseFilters, UseGuards } from '@nestjs/common';
import { Settings } from '@prisma/kusari';
import { ForbiddenExceptionFilter, GuildAdminGuard } from '@yugen/shared';
import { ForbiddenExceptionFilter, ManageServerGuard } from '@yugen/shared';
import { ChannelType, TextChannel } from 'discord.js';
import {
ChannelOption,
Expand Down Expand Up @@ -54,7 +54,7 @@ class SettingsSetCooldownOptions {
minutes: number | undefined;
}

@UseGuards(GuildAdminGuard)
@UseGuards(ManageServerGuard)
@UseFilters(ForbiddenExceptionFilter)
@SettingsCommandDecorator()
@Injectable()
Expand Down
1 change: 1 addition & 0 deletions libs/shared/src/lib/guards/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './admin.guard';
export * from './guild-admin.guard';
export * from './guild-moderator.guard';
export * from './manage-server.guard';
54 changes: 54 additions & 0 deletions libs/shared/src/lib/guards/manage-server.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {
CanActivate,
ExecutionContext,
Injectable,
Logger,
} from '@nestjs/common';
import { Client, PermissionsBitField } from 'discord.js';
import { NecordExecutionContext } from 'necord';

@Injectable()
export class ManageServerGuard implements CanActivate {
private readonly _logger = new Logger(ManageServerGuard.name);

constructor(private _client: Client) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const ctx = NecordExecutionContext.create(context);
const [interaction] = ctx.getContext<'interactionCreate'>();

if (!interaction) {
return true;
}

if (
interaction.isUserContextMenuCommand() ||
interaction.isContextMenuCommand()
) {
return false;
}

const admins = process.env['OWNER_IDS']!.split(',');
if (admins.includes(interaction?.user?.id)) {
return true;
}

const guild = await this._client.guilds.fetch(interaction.guildId!);
const member = await guild.members.fetch(interaction.user.id);

const hasAdminPermissions = member.permissions.has(
PermissionsBitField.Flags.Administrator,
);
if (hasAdminPermissions) {
return true;
}

const hasPermission = member.permissions.has(
PermissionsBitField.Flags.ManageGuild,
);
if (hasPermission) {
return true;
}

return false;
}
}

0 comments on commit b1baa29

Please sign in to comment.