From 92181d960f962723995a769e3e26d491d545346b Mon Sep 17 00:00:00 2001 From: wancat Date: Sun, 12 Nov 2023 00:46:26 +0800 Subject: [PATCH] feat: check if a quest is unlocked before creating session --- server/src/api/controllers/sessionController.js | 17 +++++++++++++---- server/src/api/validators/questValidator.js | 4 ---- server/src/game/sessionManager.js | 15 +++++++++++++++ server/swagger.yaml | 4 ++++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/server/src/api/controllers/sessionController.js b/server/src/api/controllers/sessionController.js index 9cb8d18..5ae0d53 100644 --- a/server/src/api/controllers/sessionController.js +++ b/server/src/api/controllers/sessionController.js @@ -3,6 +3,7 @@ import { Session } from '@linux-odyssey/models' import { createNewSession, getOrCreateActiveSession, + isQuestUnlocked, } from '../../game/sessionManager.js' import { asyncHandler } from '../../middleware/error.js' @@ -39,8 +40,12 @@ export const getSessionList = asyncHandler(async (req, res) => { export const createSession = asyncHandler(async (req, res) => { const { questId } = matchedData(req) - const session = await createNewSession(req.user, questId) - res.status(201).json(sessionDetail(session)) + if (await isQuestUnlocked(req.user, questId)) { + const session = await createNewSession(req.user, questId) + res.status(201).json(sessionDetail(session)) + } else { + res.status(403).json({ message: 'Quest is locked.' }) + } }) export const getSessionById = asyncHandler(async (req, res) => { @@ -60,6 +65,10 @@ export const getSessionById = asyncHandler(async (req, res) => { export const getOrCreateSession = asyncHandler(async (req, res) => { const { questId } = matchedData(req) - const session = await getOrCreateActiveSession(req.user, questId) - res.json(sessionDetail(session)) + if (await isQuestUnlocked(req.user, questId)) { + const session = await getOrCreateActiveSession(req.user, questId) + res.json(sessionDetail(session)) + } else { + res.status(403).json({ message: 'Quest is locked.' }) + } }) diff --git a/server/src/api/validators/questValidator.js b/server/src/api/validators/questValidator.js index be610a8..a4f00bd 100644 --- a/server/src/api/validators/questValidator.js +++ b/server/src/api/validators/questValidator.js @@ -5,7 +5,3 @@ export const checkQuestId = () => check('questId').notEmpty().isString().isAlphanumeric().isLength({ max: 64 }) export const questIdValidator = [checkQuestId(), noError] - -export default { - questIdValidator, -} diff --git a/server/src/game/sessionManager.js b/server/src/game/sessionManager.js index 6fe800e..19e79c8 100644 --- a/server/src/game/sessionManager.js +++ b/server/src/game/sessionManager.js @@ -99,3 +99,18 @@ export async function finishSession(session) { } await userProfile.save() } + +export async function isQuestUnlocked(user, questId) { + const userProfile = await UserProfile.findOne({ user: user._id }) + if (!userProfile) { + throw new Error(`UserProfile ${user._id} not found`) + } + const quest = await Quest.findById(questId) + if (!quest) { + throw new Error(`Quest ${questId} not found`) + } + return quest.requirements.every((requiredQuestId) => { + const progress = userProfile.progress.get(requiredQuestId) + return progress && progress.completed + }) +} diff --git a/server/swagger.yaml b/server/swagger.yaml index bae7705..dfadfc2 100644 --- a/server/swagger.yaml +++ b/server/swagger.yaml @@ -79,6 +79,8 @@ paths: properties: message: type: string + '403': + description: This quest is locked. /sessions/active: post: @@ -108,6 +110,8 @@ paths: $ref: '#/components/schemas/Session' 400: description: 'Bad Request. The request is invalid or malformed.' + 403: + description: This quest is locked. 500: description: 'Internal Server Error.'