From 3df69caa97cf3e867a6194830ea5522bdc3eefb1 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Sun, 30 Jan 2022 15:29:24 +0000 Subject: [PATCH] If a banned user is making a request, all requests should 403. --- server/src/external/mongo/indexes.ts | 1 + server/src/server/middleware/auth.ts | 21 ++++++++++++++++++- .../src/server/middleware/request-logger.ts | 5 +++++ server/src/server/server.ts | 4 ++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/server/src/external/mongo/indexes.ts b/server/src/external/mongo/indexes.ts index c3717106a..49d715f17 100644 --- a/server/src/external/mongo/indexes.ts +++ b/server/src/external/mongo/indexes.ts @@ -54,6 +54,7 @@ const staticIndexes: Partial> = { ], users: [ index({ id: 1 }, UNIQUE), + index({ id: 1, authLevel: 1 }, UNIQUE), index({ username: 1 }, UNIQUE), index({ usernameLowercase: 1 }, UNIQUE), ], diff --git a/server/src/server/middleware/auth.ts b/server/src/server/middleware/auth.ts index 7f82cbb0c..aa0c0b431 100644 --- a/server/src/server/middleware/auth.ts +++ b/server/src/server/middleware/auth.ts @@ -2,8 +2,9 @@ import { RequestHandler } from "express"; import db from "external/mongo/db"; import { SYMBOL_TachiAPIAuth } from "lib/constants/tachi"; import { SplitAuthorizationHeader } from "utils/misc"; -import { APITokenDocument, APIPermissions } from "tachi-common"; +import { APITokenDocument, APIPermissions, UserAuthLevels } from "tachi-common"; import CreateLogCtx from "lib/logger/logger"; +import { TachiConfig } from "lib/setup/config"; const logger = CreateLogCtx(__filename); @@ -186,3 +187,21 @@ const CreateRequireNotGuest = export const RequireNotGuest: RequestHandler = CreateRequireNotGuest("description"); export const FervidexStyleRequireNotGuest: RequestHandler = CreateRequireNotGuest("error"); + +export const RejectIfBanned: RequestHandler = async (req, res, next) => { + if (req.session?.tachi?.user.id) { + const isBanned = await db.users.findOne({ + id: req.session.tachi.user.id, + authLevel: UserAuthLevels.BANNED, + }); + + if (isBanned) { + return res.status(403).json({ + success: false, + description: `You are banned from ${TachiConfig.NAME}`, + }); + } + } + + next(); +}; diff --git a/server/src/server/middleware/request-logger.ts b/server/src/server/middleware/request-logger.ts index 6800a7883..9aee8fa0e 100644 --- a/server/src/server/middleware/request-logger.ts +++ b/server/src/server/middleware/request-logger.ts @@ -1,6 +1,7 @@ import CreateLogCtx from "lib/logger/logger"; import { RequestHandler, Response } from "express-serve-static-core"; import { SYMBOL_TachiAPIAuth } from "lib/constants/tachi"; +import { TachiConfig } from "lib/setup/config"; const logger = CreateLogCtx(__filename); @@ -60,6 +61,10 @@ export const RequestLoggerMiddleware: RequestHandler = (req, res, next) => { return; } + if (contents.body.description === `You are banned from ${TachiConfig.NAME}.`) { + return; + } + if (res.statusCode < 400 || res.statusCode === 404) { logger.verbose( `(${req.method} ${req.originalUrl}) Returned ${res.statusCode}.`, diff --git a/server/src/server/server.ts b/server/src/server/server.ts index 4f62cd32d..f29b1d47e 100644 --- a/server/src/server/server.ts +++ b/server/src/server/server.ts @@ -8,6 +8,7 @@ import { SYMBOL_TachiAPIAuth } from "lib/constants/tachi"; import CreateLogCtx from "lib/logger/logger"; import { Environment, ServerConfig, TachiConfig } from "lib/setup/config"; import { integer } from "tachi-common"; +import { RejectIfBanned } from "./middleware/auth"; import { RequestLoggerMiddleware } from "./middleware/request-logger"; import mainRouter from "./router/router"; @@ -96,6 +97,8 @@ process.on("unhandledRejection", (reason, promise) => { app.use(express.json({ limit: "4mb" })); app.use((req, res, next) => { + // Always mount an empty req body. We operate under the assumption that req.body is + // always defined. if (req.method !== "GET" && !req.body) { req.body = {}; } @@ -104,6 +107,7 @@ app.use((req, res, next) => { }); app.use(RequestLoggerMiddleware); +app.use(RejectIfBanned); app.use("/", mainRouter);