From 808f5e3b1c7fa676b4131306f378b8a8f9da0ba6 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 1 Mar 2024 17:31:29 +0000 Subject: [PATCH 1/4] Resolve undici version to fix vulnerability --- package.json | 3 ++- yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 702c3b7..163572b 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,8 @@ "typeorm": "0.3.17" }, "resolutions": { - "**/semver": "^7.5.2" + "**/semver": "^7.5.2", + "**/undici": "^5.28.3" }, "devDependencies": { "@types/node": "^20.0.0", diff --git a/yarn.lock b/yarn.lock index 5513d2c..1bb5d02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4746,10 +4746,10 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici@5.27.2: - version "5.27.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.27.2.tgz#a270c563aea5b46cc0df2550523638c95c5d4411" - integrity sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ== +undici@5.27.2, undici@^5.28.3: + version "5.28.3" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.3.tgz#a731e0eff2c3fcfd41c1169a869062be222d1e5b" + integrity sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA== dependencies: "@fastify/busboy" "^2.0.0" From 5f054b02a576459516b1766bd80e5f356298b587 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 1 Mar 2024 18:25:24 +0000 Subject: [PATCH 2/4] Add cache helper to update user cache every 30 minutes --- .dev.env | 2 ++ .prod.env | 2 ++ .stage.env | 2 ++ .../Up/01-Server.sql | 2 ++ package.json | 1 + src/client/client.ts | 5 ++++ src/database/entities/Server.ts | 10 ++++++- .../3.2.1/1709316734401-AddServerCacheDate.ts | 15 +++++++++++ src/events/MemberEvents/GuildMemberAdd.ts | 3 +++ src/events/MemberEvents/GuildMemberRemove.ts | 3 +++ src/events/MemberEvents/GuildMemberUpdate.ts | 5 +++- src/events/MessageEvents/MessageCreate.ts | 3 +++ src/events/MessageEvents/MessageDelete.ts | 3 +++ src/events/MessageEvents/MessageUpdate.ts | 4 +++ src/helpers/CacheHelper.ts | 27 +++++++++++++++++++ 15 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 database/3.2.1/1709316734401-AddServerCacheDate/Up/01-Server.sql create mode 100644 src/database/migrations/3.2.1/1709316734401-AddServerCacheDate.ts create mode 100644 src/helpers/CacheHelper.ts diff --git a/.dev.env b/.dev.env index a0df6c9..f56117b 100644 --- a/.dev.env +++ b/.dev.env @@ -15,6 +15,8 @@ BOT_CLIENTID=682942374040961060 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app +CACHE_INTERVAL=1800000 # 30 minutes + DB_HOST=127.0.0.1 DB_PORT=3101 DB_NAME=vylbot diff --git a/.prod.env b/.prod.env index 6c9b8c9..cfd1ab7 100644 --- a/.prod.env +++ b/.prod.env @@ -15,6 +15,8 @@ BOT_CLIENTID=680083120896081954 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app +CACHE_INTERVAL=1800000 # 30 minutes + DB_HOST=127.0.0.1 DB_PORT=3121 DB_NAME=vylbot diff --git a/.stage.env b/.stage.env index 6e29629..e95f113 100644 --- a/.stage.env +++ b/.stage.env @@ -15,6 +15,8 @@ BOT_CLIENTID=1016767908740857949 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app +CACHE_INTERVAL=1800000 # 30 minutes + DB_HOST=127.0.0.1 DB_PORT=3111 DB_NAME=vylbot diff --git a/database/3.2.1/1709316734401-AddServerCacheDate/Up/01-Server.sql b/database/3.2.1/1709316734401-AddServerCacheDate/Up/01-Server.sql new file mode 100644 index 0000000..a3b92b9 --- /dev/null +++ b/database/3.2.1/1709316734401-AddServerCacheDate/Up/01-Server.sql @@ -0,0 +1,2 @@ +ALTER TABLE server +ADD LastCached datetime NOT NULL DEFAULT '2024-03-01 18:10:04'; \ No newline at end of file diff --git a/package.json b/package.json index 163572b..5e99935 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "test": "echo true", "db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js", "db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js", + "db:create": "typeorm migration:create ./src/database/migrations", "release": "np --no-publish" }, "repository": { diff --git a/src/client/client.ts b/src/client/client.ts index 415d645..c1ce5da 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -11,6 +11,7 @@ import { Util } from "./util"; import AppDataSource from "../database/dataSources/appDataSource"; import ButtonEventItem from "../contracts/ButtonEventItem"; import { ButtonEvent } from "../type/buttonEvent"; +import CacheHelper from "../helpers/CacheHelper"; export class CoreClient extends Client { private static _commandItems: ICommandItem[]; @@ -59,6 +60,10 @@ export class CoreClient extends Client { await super.login(process.env.BOT_TOKEN); + this.guilds.cache.forEach(async (guild) => { + await CacheHelper.UpdateServerCache(guild); + }); + this._util.loadEvents(this, CoreClient._eventItems); this._util.loadSlashCommands(this); } diff --git a/src/database/entities/Server.ts b/src/database/entities/Server.ts index 211ea9c..623f816 100644 --- a/src/database/entities/Server.ts +++ b/src/database/entities/Server.ts @@ -1,4 +1,4 @@ -import { Entity, OneToMany } from "typeorm"; +import { Column, Entity, OneToMany } from "typeorm"; import BaseEntity from "../../contracts/BaseEntity"; import Role from "./Role"; import Setting from "./Setting"; @@ -9,14 +9,22 @@ export default class Server extends BaseEntity { super(); this.Id = serverId; + this.LastCached = new Date(); } + @Column({ default: "2024-03-01 18:10:04" }) + LastCached: Date; + @OneToMany(() => Setting, x => x.Server) Settings: Setting[]; @OneToMany(() => Role, x => x.Server) Roles: Role[]; + public UpdateLastCached(lastCached: Date) { + this.LastCached = lastCached; + } + public AddSettingToServer(setting: Setting) { this.Settings.push(setting); } diff --git a/src/database/migrations/3.2.1/1709316734401-AddServerCacheDate.ts b/src/database/migrations/3.2.1/1709316734401-AddServerCacheDate.ts new file mode 100644 index 0000000..5104655 --- /dev/null +++ b/src/database/migrations/3.2.1/1709316734401-AddServerCacheDate.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from "typeorm" +import MigrationHelper from "../../../helpers/MigrationHelper" + +export class AddServerCacheDate1709316734401 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + MigrationHelper.Up('1709316734401-AddServerCacheDate', '3.2.1', [ + "01-Server", + ], queryRunner); + } + + public async down(queryRunner: QueryRunner): Promise { + } + +} diff --git a/src/events/MemberEvents/GuildMemberAdd.ts b/src/events/MemberEvents/GuildMemberAdd.ts index 025be0b..55f91a1 100644 --- a/src/events/MemberEvents/GuildMemberAdd.ts +++ b/src/events/MemberEvents/GuildMemberAdd.ts @@ -1,10 +1,13 @@ import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; import SettingsHelper from "../../helpers/SettingsHelper"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function GuildMemberAdd(member: GuildMember) { if (!member.guild) return; + await CacheHelper.UpdateServerCache(member.guild); + const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; diff --git a/src/events/MemberEvents/GuildMemberRemove.ts b/src/events/MemberEvents/GuildMemberRemove.ts index bf6ae96..0f24f47 100644 --- a/src/events/MemberEvents/GuildMemberRemove.ts +++ b/src/events/MemberEvents/GuildMemberRemove.ts @@ -1,10 +1,13 @@ import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; import SettingsHelper from "../../helpers/SettingsHelper"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function GuildMemberRemove(member: GuildMember) { if (!member.guild) return; + await CacheHelper.UpdateServerCache(member.guild); + const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; diff --git a/src/events/MemberEvents/GuildMemberUpdate.ts b/src/events/MemberEvents/GuildMemberUpdate.ts index 0a7bbb1..cd26953 100644 --- a/src/events/MemberEvents/GuildMemberUpdate.ts +++ b/src/events/MemberEvents/GuildMemberUpdate.ts @@ -1,8 +1,11 @@ import { GuildMember } from "discord.js"; import NicknameChanged from "./GuildMemberUpdate/NicknameChanged"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function GuildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) { - if (oldMember.nickname != newMember.nickname) { // Nickname change + await CacheHelper.UpdateServerCache(newMember.guild); + + if (oldMember.nickname !== newMember.nickname) { // Nickname change await NicknameChanged(oldMember, newMember); } } \ No newline at end of file diff --git a/src/events/MessageEvents/MessageCreate.ts b/src/events/MessageEvents/MessageCreate.ts index a91250d..1dac122 100644 --- a/src/events/MessageEvents/MessageCreate.ts +++ b/src/events/MessageEvents/MessageCreate.ts @@ -1,11 +1,14 @@ import { Message } from "discord.js"; import SettingsHelper from "../../helpers/SettingsHelper"; import VerificationCheck from "./MessageCreate/VerificationCheck"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function MessageCreate(message: Message) { if (!message.guild) return; if (message.author.bot) return; + await CacheHelper.UpdateServerCache(message.guild); + const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id); if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") { diff --git a/src/events/MessageEvents/MessageDelete.ts b/src/events/MessageEvents/MessageDelete.ts index 5f66300..f24ec5d 100644 --- a/src/events/MessageEvents/MessageDelete.ts +++ b/src/events/MessageEvents/MessageDelete.ts @@ -2,11 +2,14 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; import IgnoredChannel from "../../database/entities/IgnoredChannel"; import SettingsHelper from "../../helpers/SettingsHelper"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function MessageDelete(message: Message) { if (!message.guild) return; if (message.author.bot) return; + await CacheHelper.UpdateServerCache(message.guild); + const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; diff --git a/src/events/MessageEvents/MessageUpdate.ts b/src/events/MessageEvents/MessageUpdate.ts index 7564a2f..27369a4 100644 --- a/src/events/MessageEvents/MessageUpdate.ts +++ b/src/events/MessageEvents/MessageUpdate.ts @@ -2,10 +2,14 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; import IgnoredChannel from "../../database/entities/IgnoredChannel"; import SettingsHelper from "../../helpers/SettingsHelper"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function MessageUpdate(oldMessage: Message, newMessage: Message) { if (!newMessage.guild) return; if (newMessage.author.bot) return; + + await CacheHelper.UpdateServerCache(newMessage.guild); + if (oldMessage.content == newMessage.content) return; const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id); diff --git a/src/helpers/CacheHelper.ts b/src/helpers/CacheHelper.ts new file mode 100644 index 0000000..22b6fd7 --- /dev/null +++ b/src/helpers/CacheHelper.ts @@ -0,0 +1,27 @@ +import { Guild } from "discord.js"; +import Server from "../database/entities/Server"; + +export default class CacheHelper { + public static async UpdateServerCache(guild: Guild) { + const cacheInterval = process.env.CACHE_INTERVAL; + + if (!cacheInterval) return; + + let server = await Server.FetchOneById(Server, guild.id); + + if (!server) { + server = new Server(guild.id); + await server.Save(Server, server); + + await CacheHelper.UpdateCache(guild); + } else if (server.LastCached.getTime() + Number(cacheInterval) < Date.now()) { + await CacheHelper.UpdateCache(guild); + } + } + + private static async UpdateCache(guild: Guild) { + console.log(`Updating cache for ${guild.name} (${guild.id})`); + + await guild.members.fetch(); + } +} \ No newline at end of file From c83a2329cc7d97a1e6e2e3b7410ceec9c42c2ed1 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 1 Mar 2024 18:26:31 +0000 Subject: [PATCH 3/4] 3.2.1 --- .dev.env | 2 +- .prod.env | 2 +- .stage.env | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.dev.env b/.dev.env index f56117b..674b0f8 100644 --- a/.dev.env +++ b/.dev.env @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=3.2 DEV +BOT_VER=3.2.1 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 diff --git a/.prod.env b/.prod.env index cfd1ab7..c5ef2af 100644 --- a/.prod.env +++ b/.prod.env @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=3.2 +BOT_VER=3.2.1 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=680083120896081954 diff --git a/.stage.env b/.stage.env index e95f113..aed681a 100644 --- a/.stage.env +++ b/.stage.env @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=3.2 BETA +BOT_VER=3.2.1 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=1016767908740857949 From ad2e4d8f9bab6def21479d37d8c7b4daa2011092 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 1 Mar 2024 18:26:37 +0000 Subject: [PATCH 4/4] v3.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5e99935..d5c0360 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vylbot-app", - "version": "3.2.0", + "version": "3.2.1", "description": "A discord bot made for Vylpes' Den", "main": "./dist/vylbot", "typings": "./dist",