Add verification system

Signed-off-by: Ethan Lane <ethan@vylpes.com>
This commit is contained in:
Ethan Lane 2022-03-20 15:59:23 +00:00
parent 5d629c3b8f
commit 4c7208c192
Signed by: Vylpes
GPG key ID: EED233CC06D12504
10 changed files with 205 additions and 5 deletions

View file

@ -18,4 +18,9 @@ embed.colour.error: The HEX value of the error embeds (Default: "0xd52803")
channels.logs.message: The channel message events will be logged to (Default: "message-logs") channels.logs.message: The channel message events will be logged to (Default: "message-logs")
channels.logs.member: The channel member events will be logged to (Default: "member-logs") channels.logs.member: The channel member events will be logged to (Default: "member-logs")
channels.logs.mod: The channel mod events will be logged to (Default: "mod-logs") channels.logs.mod: The channel mod events will be logged to (Default: "mod-logs")
verification.enabled: Enables/Disables the verification feature (Default: "false")
verification.channel: The channel to listen to for entry codes (Default: "entry")
verification.role: The server access role (Default: "Entry")
verification.code: The entry code for the channel (Default: "")

94
src/commands/code.ts Normal file
View file

@ -0,0 +1,94 @@
import { CommandResponse } from "../constants/CommandResponse";
import { ICommandContext } from "../contracts/ICommandContext";
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
import PublicEmbed from "../helpers/embeds/PublicEmbed";
import SettingsHelper from "../helpers/SettingsHelper";
import StringTools from "../helpers/StringTools";
import { Command } from "../type/command";
export default class Code extends Command {
constructor() {
super();
super._category = "Moderation";
super._roles = [
"moderator"
];
}
public override async precheckAsync(context: ICommandContext): Promise<CommandResponse> {
if (!context.message.guild){
return CommandResponse.NotInServer;
}
const isEnabled = await SettingsHelper.GetSetting("verification.enabled", context.message.guild?.id);
if (!isEnabled) {
return CommandResponse.FeatureDisabled;
}
if (isEnabled.toLocaleLowerCase() != 'true') {
return CommandResponse.FeatureDisabled;
}
return CommandResponse.Ok;
}
public override async execute(context: ICommandContext) {
const action = context.args[0];
switch (action) {
case "randomise":
await this.Randomise(context);
break;
case "embed":
await this.SendEmbed(context);
break;
default:
await this.SendUsage(context);
}
}
private async SendUsage(context: ICommandContext) {
const description = [
"USAGE: <randomise|embed>",
"",
"randomise: Sets the server's entry code to a random code",
"embed: Sends an embed with the server's entry code"
].join("\n");
const embed = new PublicEmbed(context, "", description);
embed.SendToCurrentChannel();
}
private async Randomise(context: ICommandContext) {
if (!context.message.guild) {
return;
}
const randomCode = StringTools.RandomString(5);
await SettingsHelper.SetSetting("verification.code", context.message.guild.id, randomCode);
const embed = new PublicEmbed(context, "Code", `Entry code has been set to \`${randomCode}\``);
embed.SendToCurrentChannel();
}
private async SendEmbed(context: ICommandContext) {
if (!context.message.guild) {
return;
}
const code = await SettingsHelper.GetSetting("verification.code", context.message.guild.id);
if (!code || code == "") {
const errorEmbed = new ErrorEmbed(context, "There is no code for this server setup.");
errorEmbed.SendToCurrentChannel();
return;
}
const embed = new PublicEmbed(context, "Entry Code", code!);
embed.SendToCurrentChannel();
}
}

View file

@ -2,4 +2,6 @@ export enum CommandResponse {
Ok, Ok,
Unauthorised, Unauthorised,
ServerNotSetup, ServerNotSetup,
NotInServer,
FeatureDisabled,
} }

View file

@ -39,6 +39,12 @@ export default class DefaultValues {
this.values.push({ Key: "channels.logs.message", Value: "message-logs" }); this.values.push({ Key: "channels.logs.message", Value: "message-logs" });
this.values.push({ Key: "channels.logs.member", Value: "member-logs" }); this.values.push({ Key: "channels.logs.member", Value: "member-logs" });
this.values.push({ Key: "channels.logs.mod", Value: "mod-logs" }); this.values.push({ Key: "channels.logs.mod", Value: "mod-logs" });
// Verification
this.values.push({ Key: "verification.enabled", Value: "false" });
this.values.push({ Key: "verification.channel", Value: "entry" });
this.values.push({ Key: "verification.role", Value: "Entry" });
this.values.push({ Key: "verification.code", Value: "" });
} }
} }
} }

View file

@ -7,6 +7,8 @@ export default class ErrorMessages {
public static readonly UserUnauthorised = "You are not authorised to use this command"; public static readonly UserUnauthorised = "You are not authorised to use this command";
public static readonly ServerNotSetup = "This server hasn't been setup yet, please run the setup command"; public static readonly ServerNotSetup = "This server hasn't been setup yet, please run the setup command";
public static readonly NotInServer = "This command requires to be ran inside of a server";
public static readonly FeatureDisabled = "This feature is currently disabled by a server moderator";
public static GetErrorMessage(response: CommandResponse): string { public static GetErrorMessage(response: CommandResponse): string {
switch (response) { switch (response) {
@ -14,6 +16,10 @@ export default class ErrorMessages {
return this.UserUnauthorised; return this.UserUnauthorised;
case CommandResponse.ServerNotSetup: case CommandResponse.ServerNotSetup:
return this.ServerNotSetup; return this.ServerNotSetup;
case CommandResponse.NotInServer:
return this.NotInServer;
case CommandResponse.FeatureDisabled:
return this.FeatureDisabled;
default: default:
return ""; return "";
} }

View file

@ -2,6 +2,8 @@ import { Event } from "../type/event";
import { Message } from "discord.js"; import { Message } from "discord.js";
import EventEmbed from "../helpers/embeds/EventEmbed"; import EventEmbed from "../helpers/embeds/EventEmbed";
import IEventReturnContext from "../contracts/IEventReturnContext"; import IEventReturnContext from "../contracts/IEventReturnContext";
import SettingsHelper from "../helpers/SettingsHelper";
import OnMessage from "./MessageEvents/OnMessage";
export default class MessageEvents extends Event { export default class MessageEvents extends Event {
constructor() { constructor() {
@ -68,4 +70,15 @@ export default class MessageEvents extends Event {
embeds: [embed] embeds: [embed]
}; };
} }
public override async message(message: Message) {
if (!message.guild) return;
if (message.author.bot) return;
const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id);
if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") {
await OnMessage.VerificationCheck(message);
}
}
} }

View file

@ -0,0 +1,59 @@
import { Message as Message } from "discord.js";
import SettingsHelper from "../../helpers/SettingsHelper";
export default class OnMessage {
public static async VerificationCheck(message: Message) {
if (!message.guild) return;
const verificationChannel = await SettingsHelper.GetSetting("verification.channel", message.guild.id);
if (!verificationChannel) {
return;
}
const channel = message.guild.channels.cache.find(x => x.name == verificationChannel);
if (!channel) {
return;
}
const currentChannel = message.guild.channels.cache.find(x => x == message.channel);
if (!currentChannel || currentChannel.name != verificationChannel) {
return;
}
const verificationCode = await SettingsHelper.GetSetting("verification.code", message.guild.id);
if (!verificationCode || verificationCode == "") {
await message.reply("`verification.code` is not set inside of the server's config. Please contact the server's mod team.");
await message.delete();
return;
}
const verificationRoleName = await SettingsHelper.GetSetting("verification.role", message.guild.id);
if (!verificationRoleName) {
await message.reply("`verification.role` is not set inside of the server's config. Please contact the server's mod team.");
await message.delete();
return;
}
const role = message.guild.roles.cache.find(x => x.name == verificationRoleName);
if (!role) {
await message.reply("The entry role configured for this server does not exist. Please contact the server's mod team.");
await message.delete();
return;
}
if (message.content.toLocaleLowerCase() != verificationCode.toLocaleLowerCase()) {
await message.delete();
return;
}
await message.member?.roles.add(role);
await message.delete();
}
}

View file

@ -12,4 +12,17 @@ export default class StringTools {
return result.join(" "); return result.join(" ");
} }
public static RandomString(length: number) {
let result = "";
const characters = 'abcdefghkmnpqrstuvwxyz23456789';
const charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
} }

View file

@ -2,6 +2,7 @@ import { CoreClient } from "./client/client";
import About from "./commands/about"; import About from "./commands/about";
import Ban from "./commands/ban"; import Ban from "./commands/ban";
import Clear from "./commands/clear"; import Clear from "./commands/clear";
import Code from "./commands/code";
import Config from "./commands/config"; import Config from "./commands/config";
import Evaluate from "./commands/eval"; import Evaluate from "./commands/eval";
import Help from "./commands/help"; import Help from "./commands/help";
@ -16,7 +17,7 @@ import Warn from "./commands/warn";
import MemberEvents from "./events/MemberEvents"; import MemberEvents from "./events/MemberEvents";
import MessageEvents from "./events/MessageEvents"; import MessageEvents from "./events/MessageEvents";
export default class Register { export default class Registry {
public static RegisterCommands(client: CoreClient) { public static RegisterCommands(client: CoreClient) {
client.RegisterCommand("about", new About()); client.RegisterCommand("about", new About());
client.RegisterCommand("ban", new Ban()); client.RegisterCommand("ban", new Ban());
@ -32,6 +33,7 @@ export default class Register {
client.RegisterCommand("warn", new Warn()); client.RegisterCommand("warn", new Warn());
client.RegisterCommand("setup", new Setup()); client.RegisterCommand("setup", new Setup());
client.RegisterCommand("config", new Config()); client.RegisterCommand("config", new Config());
client.RegisterCommand("code", new Code());
} }
public static RegisterEvents(client: CoreClient) { public static RegisterEvents(client: CoreClient) {

View file

@ -1,6 +1,6 @@
import { CoreClient } from "./client/client"; import { CoreClient } from "./client/client";
import * as dotenv from "dotenv"; import * as dotenv from "dotenv";
import Register from "./Register"; import registry from "./registry";
dotenv.config(); dotenv.config();
@ -15,7 +15,7 @@ requiredConfigs.forEach(config => {
const client = new CoreClient(); const client = new CoreClient();
Register.RegisterCommands(client); registry.RegisterCommands(client);
Register.RegisterEvents(client); registry.RegisterEvents(client);
client.start(); client.start();