From e7855abd6a3b75f234ff380b7d8d425be43e937a Mon Sep 17 00:00:00 2001 From: Declan Chidlow Date: Fri, 10 Jul 2026 21:49:42 +0800 Subject: [PATCH] A preliminary clean --- bun.lock | 6 +- packages/api/src/middlewares/cors.ts | 2 +- packages/api/src/middlewares/log.ts | 4 +- packages/api/src/middlewares/ratelimit.ts | 3 +- .../api/src/middlewares/updateTokenExpiry.ts | 6 +- .../api/src/routes/dash/server-automod.ts | 8 +-- packages/api/src/routes/dash/server.ts | 55 ++++++++++--------- packages/api/src/routes/dash/servers.ts | 8 +-- packages/api/src/routes/login.ts | 12 ++-- packages/api/src/routes/root.ts | 2 +- packages/api/src/routes/stats.ts | 5 +- packages/api/src/utils.ts | 14 ++--- packages/api/tsconfig.json | 2 +- packages/bot/package.json | 4 +- .../bot/src/bot/commands/moderation/role.ts | 2 +- packages/bot/src/index.ts | 22 ++++---- packages/bot/tsconfig.json | 1 + 17 files changed, 82 insertions(+), 74 deletions(-) diff --git a/bun.lock b/bun.lock index 5c3e664..03e66d9 100644 --- a/bun.lock +++ b/bun.lock @@ -28,10 +28,10 @@ "dependencies": { "automod-lib": "workspace:*", "axios": "^1.16.1", - "bson": "7.2.0", + "bson": "~7.2.0", "dayjs": "^1.11.20", "form-data": "^4.0.5", - "mongodb": "^7.2.0", + "mongodb": "~7.2.0", "prom-client": "^15.1.3", "stoat-api": "0.8.9-4", "stoat.js": "^7.3.6", @@ -338,7 +338,7 @@ "agent-base/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - "automod-bot/mongodb": ["mongodb@7.4.0", "", { "dependencies": { "@mongodb-js/saslprep": "^1.3.0", "bson": "^7.2.0", "mongodb-connection-string-url": "^7.0.0" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.806.0", "@mongodb-js/zstd": "^7.0.0", "gcp-metadata": "^7.0.1", "kerberos": "^7.0.0", "mongodb-client-encryption": ">=7.0.0 <7.1.0", "snappy": "^7.3.2", "socks": "^2.8.6" }, "optionalPeers": ["@aws-sdk/credential-providers", "@mongodb-js/zstd", "gcp-metadata", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-giySkkdYiwoBFo/oCc8nzov3xOYZ/sB8OpAYk5GINRLEjVw0LDsm8xgQL0XMTyU4extQlDZjhdUr1ZEwKFaazw=="], + "automod-bot/mongodb": ["mongodb@7.2.0", "", { "dependencies": { "@mongodb-js/saslprep": "^1.3.0", "bson": "^7.2.0", "mongodb-connection-string-url": "^7.0.0" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.806.0", "@mongodb-js/zstd": "^7.0.0", "gcp-metadata": "^7.0.1", "kerberos": "^7.0.0", "mongodb-client-encryption": ">=7.0.0 <7.1.0", "snappy": "^7.3.2", "socks": "^2.8.6" }, "optionalPeers": ["@aws-sdk/credential-providers", "@mongodb-js/zstd", "gcp-metadata", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-F/2+BMZtLVhY30ioZp0dAmZ+IRZMBqI+nrv6t5+9/1AIwCa8sMRC3jBf81lpxMhnZgqq8CoUD503Z1oZWq1/sw=="], "automod-bot/ulid": ["ulid@3.0.2", "", { "bin": { "ulid": "dist/cli.js" } }, "sha512-yu26mwteFYzBAot7KVMqFGCVpsF6g8wXfJzQUHvu1no3+rRRSFcSV2nKeYvNPLD2J4b08jYBDhHUjeH0ygIl9w=="], diff --git a/packages/api/src/middlewares/cors.ts b/packages/api/src/middlewares/cors.ts index 0e8ceb5..108bce9 100644 --- a/packages/api/src/middlewares/cors.ts +++ b/packages/api/src/middlewares/cors.ts @@ -1,4 +1,4 @@ -import { Request, Response, NextFunction } from "express"; +import type { Request, Response, NextFunction } from "express"; import { app } from ".."; app.use("*", (req: Request, res: Response, next: NextFunction) => { diff --git a/packages/api/src/middlewares/log.ts b/packages/api/src/middlewares/log.ts index 77b9734..db10897 100644 --- a/packages/api/src/middlewares/log.ts +++ b/packages/api/src/middlewares/log.ts @@ -1,7 +1,7 @@ -import { Request, Response, NextFunction } from "express"; +import type { Request, Response, NextFunction } from "express"; import { app } from ".."; -app.use("*", (req: Request, res: Response, next: NextFunction) => { +app.use("*", (req: Request, _res: Response, next: NextFunction) => { console.debug(`${req.method} ${req.url}`); next(); }); diff --git a/packages/api/src/middlewares/ratelimit.ts b/packages/api/src/middlewares/ratelimit.ts index fc3e22a..682e0e6 100644 --- a/packages/api/src/middlewares/ratelimit.ts +++ b/packages/api/src/middlewares/ratelimit.ts @@ -1,4 +1,4 @@ -import { Request, Response, NextFunction } from "express"; +import type { Request, Response, NextFunction } from "express"; import { ulid } from "ulid"; import { app } from ".."; import { redis } from "../db"; @@ -19,6 +19,7 @@ class RateLimiter { try { const ip = req.ip; const reqId = ulid(); + if (!ip) { next(); return; } // ratelimit:ip_address_base64:route_base64 const redisKey = `ratelimit:${Buffer.from(ip).toString("base64")}:${Buffer.from(this.route).toString("base64")}`; diff --git a/packages/api/src/middlewares/updateTokenExpiry.ts b/packages/api/src/middlewares/updateTokenExpiry.ts index 542de89..0cc65c4 100644 --- a/packages/api/src/middlewares/updateTokenExpiry.ts +++ b/packages/api/src/middlewares/updateTokenExpiry.ts @@ -1,5 +1,5 @@ -import { Request, Response, NextFunction } from "express"; -import { Collection, Db } from "mongodb"; +import type { Request, Response, NextFunction } from "express"; +import type { Collection, Db } from "mongodb"; import { app, SESSION_LIFETIME } from ".."; let sessionsCollection: Collection; @@ -8,7 +8,7 @@ export function initializeSessionsMiddleware(db: Db) { sessionsCollection = db.collection("sessions"); } -app.use("*", async (req: Request, res: Response, next: NextFunction) => { +app.use("*", async (req: Request, _res: Response, next: NextFunction) => { next(); const user = req.header("x-auth-user"); diff --git a/packages/api/src/routes/dash/server-automod.ts b/packages/api/src/routes/dash/server-automod.ts index d9214aa..2c0aae7 100644 --- a/packages/api/src/routes/dash/server-automod.ts +++ b/packages/api/src/routes/dash/server-automod.ts @@ -1,8 +1,8 @@ import { app } from "../.."; -import { Request, Response } from "express"; +import type { Request, Response } from "express"; import { badRequest, ensureObjectStructure, isAuthenticated, requireAuth, unauthorized } from "../../utils"; import { botReq } from "../internal/ws"; -import { Collection, Db } from "mongodb"; +import type { Collection, Db } from "mongodb"; import { ulid } from "ulid"; let serversCollection: Collection; @@ -136,7 +136,7 @@ app.post("/dash/server/:server/automod", requireAuth({ permission: 2 }), async ( message: rule.message ?? null, }, }, - }, + } as any, ); res.status(200).send({ success: result.modifiedCount > 0, id: id }); @@ -164,7 +164,7 @@ app.delete("/dash/server/:server/automod/:ruleid", requireAuth({ permission: 2 } $pull: { "automodSettings.spam": { id: ruleid }, }, - }, + } as any, ); } catch (e) { console.error(e); diff --git a/packages/api/src/routes/dash/server.ts b/packages/api/src/routes/dash/server.ts index 1d36796..7aca994 100644 --- a/packages/api/src/routes/dash/server.ts +++ b/packages/api/src/routes/dash/server.ts @@ -1,5 +1,5 @@ import { app, db } from "../.."; -import { Request, Response } from "express"; +import type { Request, Response } from "express"; import { badRequest, getPermissionLevel, isAuthenticated, requireAuth, unauthorized } from "../../utils"; import { botReq } from "../internal/ws"; @@ -33,9 +33,9 @@ app.get("/dash/server/:server", requireAuth({ permission: 0 }), async (req: Requ return res.status(response.statusCode ?? 500).send({ error: response.error }); } - if (!response.server) return res.status(404).send({ error: "Not found" }); + if (!response["server"]) return res.status(404).send({ error: "Not found" }); - const s: ServerDetails = response.server; + const s: ServerDetails = response["server"]; res.send({ server: s }); }); @@ -51,11 +51,12 @@ app.put("/dash/server/:server/:option", async (req: Request, res: Response) => { const permissionLevelRes = await getPermissionLevel(user, server); if (!permissionLevelRes.success) return res.status(permissionLevelRes.statusCode || 500).send({ error: permissionLevelRes.error }); - const servers = db.get("servers"); - const permissionLevel: 0 | 1 | 2 | 3 = permissionLevelRes.level; + const dbInstance = await db; + const servers = dbInstance.collection("servers"); + const permissionLevel: 0 | 1 | 2 | 3 = permissionLevelRes["level"]; const settings = await servers.findOne({ id: server }); - switch (req.params.option) { + switch (req.params["option"]) { case "managers": { if (!item || typeof item != "string") return badRequest(res); if (permissionLevel < 3) return res.status(403).send({ error: "You are not allowed to add other bot managers." }); @@ -65,16 +66,16 @@ app.put("/dash/server/:server/:option", async (req: Request, res: Response) => { return res.status(404).send({ error: "User could not be found" }); } - if (settings.botManagers?.includes(userRes.user.id) === true) { + if (settings?.["botManagers"]?.includes(userRes["user"]["id"]) === true) { return res.status(400).send({ error: "This user is already manager" }); } - const newManagers = [...(settings.botManagers ?? []), userRes.user.id]; - await servers.update({ id: server }, { $set: { botManagers: newManagers } }); + const newManagers = [...(settings?.["botManagers"] ?? []), userRes["user"]["id"]]; + await servers.updateOne({ id: server }, { $set: { botManagers: newManagers } }); res.send({ success: true, managers: newManagers, - users: [userRes.user], + users: [userRes["user"]], }); return; } @@ -88,16 +89,16 @@ app.put("/dash/server/:server/:option", async (req: Request, res: Response) => { return res.status(404).send({ error: "User could not be found" }); } - if (settings.moderators?.includes(userRes.user.id) === true) { + if (settings?.["moderators"]?.includes(userRes["user"]["id"]) === true) { return res.status(400).send({ error: "This user is already moderator" }); } - const newMods = [...(settings.moderators ?? []), userRes.user.id]; - await servers.update({ id: server }, { $set: { moderators: newMods } }); + const newMods = [...(settings?.["moderators"] ?? []), userRes["user"]["id"]]; + await servers.updateOne({ id: server }, { $set: { moderators: newMods } }); res.send({ success: true, mods: newMods, - users: [userRes.user], + users: [userRes["user"]], }); return; } @@ -136,7 +137,8 @@ app.put("/dash/server/:server/:option", async (req: Request, res: Response) => { const body: RequestBody = req.body; - await db.get("servers").update( + const dbInstance2 = await db; + await dbInstance2.collection("servers").updateOne( { id: server }, { $set: JSON.parse( @@ -174,20 +176,21 @@ app.delete("/dash/server/:server/:option/:target", async (req: Request, res: Res const permissionLevelRes = await getPermissionLevel(user, server); if (!permissionLevelRes.success) return res.status(permissionLevelRes.statusCode || 500).send({ error: permissionLevelRes.error }); - const servers = db.get("servers"); - const permissionLevel: 0 | 1 | 2 | 3 = permissionLevelRes.level; - const settings = await servers.findOne({ id: server }); + const dbInstance3 = await db; + const servers3 = dbInstance3.collection("servers"); + const permissionLevel3: 0 | 1 | 2 | 3 = permissionLevelRes["level"]; + const settings3 = await servers3.findOne({ id: server }); switch (option) { case "managers": { - if (permissionLevel < 3) return res.status(403).send({ error: "You are not allowed to remove bot managers." }); + if (permissionLevel3 < 3) return res.status(403).send({ error: "You are not allowed to remove bot managers." }); - if (!settings.botManagers?.includes(target)) { + if (!settings3?.["botManagers"]?.includes(target)) { return res.status(400).send({ error: "This user is not manager" }); } - const newManagers = (settings.botManagers ?? []).filter((i: string) => i != target); - await servers.update({ id: server }, { $set: { botManagers: newManagers } }); + const newManagers = (settings3?.["botManagers"] ?? []).filter((i: string) => i != target); + await servers3.updateOne({ id: server }, { $set: { botManagers: newManagers } }); res.send({ success: true, managers: newManagers, @@ -195,14 +198,14 @@ app.delete("/dash/server/:server/:option/:target", async (req: Request, res: Res return; } case "mods": { - if (permissionLevel < 2) return res.status(403).send({ error: "You are not allowed to remove moderators." }); + if (permissionLevel3 < 2) return res.status(403).send({ error: "You are not allowed to remove moderators." }); - if (!settings.moderators?.includes(target)) { + if (!settings3?.["moderators"]?.includes(target)) { return res.status(400).send({ error: "This user is not moderator" }); } - const newMods = (settings.moderators ?? []).filter((i: string) => i != target); - await servers.update({ id: server }, { $set: { moderators: newMods } }); + const newMods = (settings3?.["moderators"] ?? []).filter((i: string) => i != target); + await servers3.updateOne({ id: server }, { $set: { moderators: newMods } }); res.send({ success: true, mods: newMods, diff --git a/packages/api/src/routes/dash/servers.ts b/packages/api/src/routes/dash/servers.ts index 75145dc..631d774 100644 --- a/packages/api/src/routes/dash/servers.ts +++ b/packages/api/src/routes/dash/servers.ts @@ -1,6 +1,6 @@ import { app } from "../.."; -import { Request, Response } from "express"; -import { isAuthenticated, requireAuth, unauthorized } from "../../utils"; +import type { Request, Response } from "express"; +import { isAuthenticated, requireAuth } from "../../utils"; import { botReq } from "../internal/ws"; type Server = { id: string; perms: 0 | 1 | 2 | 3; name: string; iconURL?: string; bannerURL?: string }; @@ -14,8 +14,8 @@ app.get("/dash/servers", requireAuth({ requireLogin: true }), async (req: Reques return res.status(response.statusCode ?? 500).send({ error: response.error }); } - if (!response.servers) return res.status(404).send({ error: "Not found" }); + if (!response["servers"]) return res.status(404).send({ error: "Not found" }); - const servers: Server[] = response.servers; + const servers: Server[] = response["servers"]; res.send({ servers }); }); diff --git a/packages/api/src/routes/login.ts b/packages/api/src/routes/login.ts index f04bf4d..2259642 100644 --- a/packages/api/src/routes/login.ts +++ b/packages/api/src/routes/login.ts @@ -1,8 +1,8 @@ import crypto from "crypto"; import { app, SESSION_LIFETIME } from ".."; -import { Request, Response } from "express"; +import type { Request, Response } from "express"; import { botReq } from "./internal/ws"; -import { Collection, Db } from "mongodb"; +import type { Collection, Db } from "mongodb"; import { badRequest, isAuthenticated, requireAuth } from "../utils"; import { RateLimiter } from "../middlewares/ratelimit"; @@ -15,13 +15,13 @@ export function initializeAuthAPI(database: Db) { } class BeginReqBody { - user: string; + user!: string; } class CompleteReqBody { - user: string; - nonce: string; - code: string; + user!: string; + nonce!: string; + code!: string; } const beginRatelimiter = new RateLimiter("/login/begin", { limit: 10, timeframe: 300 }); diff --git a/packages/api/src/routes/root.ts b/packages/api/src/routes/root.ts index 1a5f4c4..a85768c 100644 --- a/packages/api/src/routes/root.ts +++ b/packages/api/src/routes/root.ts @@ -1,5 +1,5 @@ import { app } from ".."; -import { Request, Response } from "express"; +import type { Request, Response } from "express"; import { getSessionInfo, isAuthenticated } from "../utils"; app.get("/", async (req: Request, res: Response) => { diff --git a/packages/api/src/routes/stats.ts b/packages/api/src/routes/stats.ts index 4a5e01f..635c0ca 100644 --- a/packages/api/src/routes/stats.ts +++ b/packages/api/src/routes/stats.ts @@ -1,7 +1,8 @@ import { app, db } from ".."; -import { Response } from "express"; +import type { Response } from "express"; import { botReq } from "./internal/ws"; -import { WithId, Document, ObjectId } from "mongodb"; +import type { WithId, Document } from "mongodb"; +import { ObjectId } from "mongodb"; let SERVER_COUNT = 0; diff --git a/packages/api/src/utils.ts b/packages/api/src/utils.ts index 99b2de9..75c852d 100644 --- a/packages/api/src/utils.ts +++ b/packages/api/src/utils.ts @@ -1,5 +1,5 @@ -import { Request, Response } from "express"; -import { Collection, Db } from "mongodb"; +import type { Request, Response } from "express"; +import type { Collection, Db } from "mongodb"; import { botReq } from "./routes/internal/ws"; let sessionsCollection: Collection; @@ -9,11 +9,11 @@ export function initializeSessionAuthentication(db: Db) { } class Session { - user: string; - token: string; - nonce: string; - expires: number; - invalid: boolean; + user!: string; + token!: string; + nonce!: string; + expires!: number; + invalid!: boolean; } /** diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index f55442a..571a334 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -26,7 +26,7 @@ "forceConsistentCasingInFileNames": true, "isolatedModules": true, "useDefineForClassFields": true, - "types": ["bun-types"] + "types": ["bun"] }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] diff --git a/packages/bot/package.json b/packages/bot/package.json index dbf5bf4..bad5411 100644 --- a/packages/bot/package.json +++ b/packages/bot/package.json @@ -11,10 +11,10 @@ "dependencies": { "automod-lib": "workspace:*", "axios": "^1.16.1", - "bson": "7.2.0", + "bson": "~7.2.0", "dayjs": "^1.11.20", "form-data": "^4.0.5", - "mongodb": "^7.2.0", + "mongodb": "~7.2.0", "prom-client": "^15.1.3", "stoat-api": "0.8.9-4", "stoat.js": "^7.3.6", diff --git a/packages/bot/src/bot/commands/moderation/role.ts b/packages/bot/src/bot/commands/moderation/role.ts index 971f3b9..d46b8de 100644 --- a/packages/bot/src/bot/commands/moderation/role.ts +++ b/packages/bot/src/bot/commands/moderation/role.ts @@ -71,7 +71,7 @@ export default { return message.reply(`Reaction role added! Reacting to message \`${messageId}\` with ${displayEmoji} will now grant the role.`); } catch (e) { console.error("Could not add initial reaction:", e); - return message.reply(`Failed to add reaction role. Ensure the message ID is correct, the emoji is valid, and you're sending the command in the same channel as the message.`); + return message.reply(`Failed to add reaction role. Check that the message ID is correct, the emoji is valid, you're sending the command in the same channel as the message, and the bot has permission to read messages and add reactions in this channel.`); } } diff --git a/packages/bot/src/index.ts b/packages/bot/src/index.ts index 067769a..b943e92 100644 --- a/packages/bot/src/index.ts +++ b/packages/bot/src/index.ts @@ -61,16 +61,18 @@ console.info(`\ await login(client); - await import("./bot/modules/command_handler"); - await import("./bot/modules/mod_logs"); - await import("./bot/modules/event_handler"); - await import("./bot/modules/tempbans"); - await import("./bot/modules/reaction_roles"); - await import("./bot/modules/api_communication"); - await import("./bot/modules/metrics"); - await import("./bot/modules/bot_status"); - await import("./bot/modules/fetch_all"); - await import("./bot/modules/raid_detection"); + await Promise.all([ + import("./bot/modules/command_handler"), + import("./bot/modules/mod_logs"), + import("./bot/modules/event_handler"), + import("./bot/modules/tempbans"), + import("./bot/modules/reaction_roles"), + import("./bot/modules/api_communication"), + import("./bot/modules/metrics"), + import("./bot/modules/bot_status"), + import("./bot/modules/fetch_all"), + import("./bot/modules/raid_detection"), + ]); } catch (error) { console.error("Failed to start application:", error); process.exit(1); diff --git a/packages/bot/tsconfig.json b/packages/bot/tsconfig.json index 2f1987b..c2a158b 100644 --- a/packages/bot/tsconfig.json +++ b/packages/bot/tsconfig.json @@ -6,6 +6,7 @@ "module": "ESNext", "moduleDetection": "force", "allowJs": true, + "types": ["bun"], // Bundler mode "moduleResolution": "Bundler", // Best practices -- 2.51.2