diff --git a/server/src/server/router/api/v1/scores/_scoreID/middleware.ts b/server/src/server/router/api/v1/scores/_scoreID/middleware.ts index 312f79b27..8da816bf9 100644 --- a/server/src/server/router/api/v1/scores/_scoreID/middleware.ts +++ b/server/src/server/router/api/v1/scores/_scoreID/middleware.ts @@ -1,7 +1,11 @@ import { RequestHandler } from "express"; import db from "external/mongo/db"; import { SYMBOL_TachiAPIAuth, SYMBOL_TachiData } from "lib/constants/tachi"; +import CreateLogCtx from "lib/logger/logger"; import { AssignToReqTachiData } from "utils/req-tachi-data"; +import { IsRequesterAdmin } from "utils/user"; + +const logger = CreateLogCtx(__filename); export const GetScoreFromParam: RequestHandler = async (req, res, next) => { const score = await db.scores.findOne({ scoreID: req.params.scoreID }); @@ -18,7 +22,7 @@ export const GetScoreFromParam: RequestHandler = async (req, res, next) => { return next(); }; -export const RequireOwnershipOfScore: RequestHandler = (req, res, next) => { +export const RequireOwnershipOfScoreOrAdmin: RequestHandler = async (req, res, next) => { const score = req[SYMBOL_TachiData]!.scoreDoc!; const userID = req[SYMBOL_TachiAPIAuth].userID; @@ -30,6 +34,11 @@ export const RequireOwnershipOfScore: RequestHandler = (req, res, next) => { } if (score.userID !== userID) { + if (await IsRequesterAdmin(req[SYMBOL_TachiAPIAuth])) { + logger.info(`Admin ${userID} interacted with someone elses .`); + return next(); + } + return res.status(403).json({ success: false, description: `You are not authorised to perform this action.`, diff --git a/server/src/server/router/api/v1/scores/_scoreID/router.ts b/server/src/server/router/api/v1/scores/_scoreID/router.ts index 39ddefc4b..9f85ad2d0 100644 --- a/server/src/server/router/api/v1/scores/_scoreID/router.ts +++ b/server/src/server/router/api/v1/scores/_scoreID/router.ts @@ -7,7 +7,7 @@ import p from "prudence"; import { RequirePermissions } from "server/middleware/auth"; import prValidate from "server/middleware/prudence-validate"; import { GetUserWithID } from "utils/user"; -import { GetScoreFromParam, RequireOwnershipOfScore } from "./middleware"; +import { GetScoreFromParam, RequireOwnershipOfScoreOrAdmin } from "./middleware"; const router: Router = Router({ mergeParams: true }); @@ -80,7 +80,7 @@ interface ModifiableScoreProps { */ router.patch( "/", - RequireOwnershipOfScore, + RequireOwnershipOfScoreOrAdmin, RequirePermissions("customise_score"), prValidate({ comment: p.optional(p.nullable(p.isBoundedString(1, 120))), @@ -143,7 +143,7 @@ router.patch( */ router.delete( "/", - RequireOwnershipOfScore, + RequireOwnershipOfScoreOrAdmin, RequirePermissions("delete_score"), async (req, res) => { const score = req[SYMBOL_TachiData]!.scoreDoc!;