diff --git a/server/src/server/middleware/auth.test.ts b/server/src/server/middleware/auth.test.ts index 30313e60f..910d93b85 100644 --- a/server/src/server/middleware/auth.test.ts +++ b/server/src/server/middleware/auth.test.ts @@ -2,6 +2,7 @@ import expMiddlewareMock from "express-request-mock"; import db from "external/mongo/db"; import { SYMBOL_TachiAPIAuth } from "lib/constants/tachi"; import t from "tap"; +import mockApi from "test-utils/mock-api"; import ResetDBState from "test-utils/resets"; import { AllPermissions, SetRequestPermissions } from "./auth"; @@ -119,3 +120,27 @@ t.test("#SetRequestPermissions", (t) => { t.end(); }); + +t.test("#RejectIfBanned", (t) => { + t.test("Should stop banned users from doing anything.", async (t) => { + await db.users.update({ id: 1 }, { $set: { authLevel: 0 } }); + + await db["api-tokens"].insert({ + userID: 1, + identifier: "Mock API Token", + permissions: { + customise_profile: true, + }, + token: "mock_token", + fromAPIClient: null, + }); + + const res = await mockApi.get("/api/v1/status").set("Authorization", "Bearer mock_token"); + + t.equal(res.statusCode, 403, "Should return 403 on benign endpoints."); + + t.end(); + }); + + t.end(); +}); diff --git a/server/src/server/middleware/auth.ts b/server/src/server/middleware/auth.ts index 7f82cbb0c..d3bc0f4aa 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[SYMBOL_TachiAPIAuth].userID) { + const isBanned = await db.users.findOne({ + id: req[SYMBOL_TachiAPIAuth].userID!, + 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..657bf4ea5 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/router/router.ts b/server/src/server/router/router.ts index 10088693c..c9c6d04d4 100644 --- a/server/src/server/router/router.ts +++ b/server/src/server/router/router.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import { UpdateLastSeen } from "server/middleware/update-last-seen"; -import { SetRequestPermissions } from "../middleware/auth"; +import { RejectIfBanned, SetRequestPermissions } from "../middleware/auth"; import { NormalRateLimitMiddleware } from "../middleware/rate-limiter"; import apiRouterV1 from "./api/v1/router"; import irRouter from "./ir/router"; @@ -13,6 +13,7 @@ router.use("/ir", NormalRateLimitMiddleware, irRouter); // but also may require custom authentication. router.use(SetRequestPermissions); router.use(UpdateLastSeen); +router.use(RejectIfBanned); router.use("/api/v1", apiRouterV1);