Просмотр исходного кода

refs 114274: validate requests to questionnaire endpoints

Futa Arai 3 лет назад
Родитель
Сommit
3cdd3d4fc2

+ 31 - 4
packages/app/src/server/routes/apiv3/questionnaire.ts

@@ -1,4 +1,5 @@
 import { Router, Request } from 'express';
 import { Router, Request } from 'express';
+import { body, validationResult } from 'express-validator';
 
 
 import { StatusType } from '~/interfaces/questionnaire/questionnaire-answer-status';
 import { StatusType } from '~/interfaces/questionnaire/questionnaire-answer-status';
 import Crowi from '~/server/crowi';
 import Crowi from '~/server/crowi';
@@ -21,6 +22,12 @@ module.exports = (crowi: Crowi): Router => {
   const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
   const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
   const loginRequired = require('../../middlewares/login-required')(crowi, true);
   const loginRequired = require('../../middlewares/login-required')(crowi, true);
 
 
+  const validators = {
+    proactiveAnswer: [body('satisfaction').exists().isNumeric(), body('commentText').exists().isString()],
+    answer: [body('questionnaireOrderId').exists().isString(), body('answers').exists().isArray({ min: 1 })],
+    skipDeny: [body('questionnaireOrderId').exists().isString()],
+  };
+
   const changeAnswerStatus = async(user, questionnaireOrderId, status) => {
   const changeAnswerStatus = async(user, questionnaireOrderId, status) => {
     const result = await QuestionnaireAnswerStatus.updateOne({
     const result = await QuestionnaireAnswerStatus.updateOne({
       user,
       user,
@@ -54,7 +61,7 @@ module.exports = (crowi: Crowi): Router => {
     }
     }
   });
   });
 
 
-  router.post('/proactive/answer', accessTokenParser, loginRequired, async(req: AuthorizedRequest, res: ApiV3Response) => {
+  router.post('/proactive/answer', accessTokenParser, loginRequired, validators.proactiveAnswer, async(req: AuthorizedRequest, res: ApiV3Response) => {
     const sendQuestionnaireAnswer = async() => {
     const sendQuestionnaireAnswer = async() => {
       const growiQuestionnaireServerOrigin = crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireServerOrigin');
       const growiQuestionnaireServerOrigin = crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireServerOrigin');
       const growiInfo = await crowi.questionnaireService!.getGrowiInfo();
       const growiInfo = await crowi.questionnaireService!.getGrowiInfo();
@@ -74,6 +81,11 @@ module.exports = (crowi: Crowi): Router => {
       await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer/proactive`, body);
       await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer/proactive`, body);
     };
     };
 
 
+    const errors = validationResult(req);
+    if (!errors.isEmpty()) {
+      return res.status(400).json({ errors: errors.array() });
+    }
+
     try {
     try {
       await sendQuestionnaireAnswer();
       await sendQuestionnaireAnswer();
       return res.apiv3({});
       return res.apiv3({});
@@ -84,7 +96,7 @@ module.exports = (crowi: Crowi): Router => {
     }
     }
   });
   });
 
 
-  router.put('/answer', accessTokenParser, loginRequired, async(req: AuthorizedRequest, res: ApiV3Response) => {
+  router.put('/answer', accessTokenParser, loginRequired, validators.answer, async(req: AuthorizedRequest, res: ApiV3Response) => {
     const sendQuestionnaireAnswer = async(user, answers) => {
     const sendQuestionnaireAnswer = async(user, answers) => {
       const growiQuestionnaireServerOrigin = crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireServerOrigin');
       const growiQuestionnaireServerOrigin = crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireServerOrigin');
       const growiInfo = await crowi.questionnaireService!.getGrowiInfo();
       const growiInfo = await crowi.questionnaireService!.getGrowiInfo();
@@ -100,6 +112,11 @@ module.exports = (crowi: Crowi): Router => {
       await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer`, questionnaireAnswer);
       await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer`, questionnaireAnswer);
     };
     };
 
 
+    const errors = validationResult(req);
+    if (!errors.isEmpty()) {
+      return res.status(400).json({ errors: errors.array() });
+    }
+
     try {
     try {
       await sendQuestionnaireAnswer(req.user ?? null, req.body.answers);
       await sendQuestionnaireAnswer(req.user ?? null, req.body.answers);
       const status = await changeAnswerStatus(req.user, req.body.questionnaireOrderId, StatusType.answered);
       const status = await changeAnswerStatus(req.user, req.body.questionnaireOrderId, StatusType.answered);
@@ -111,7 +128,12 @@ module.exports = (crowi: Crowi): Router => {
     }
     }
   });
   });
 
 
-  router.put('/skip', accessTokenParser, loginRequired, async(req: AuthorizedRequest, res: ApiV3Response) => {
+  router.put('/skip', accessTokenParser, loginRequired, validators.skipDeny, async(req: AuthorizedRequest, res: ApiV3Response) => {
+    const errors = validationResult(req);
+    if (!errors.isEmpty()) {
+      return res.status(400).json({ errors: errors.array() });
+    }
+
     try {
     try {
       const status = await changeAnswerStatus(req.user, req.body.questionnaireOrderId, StatusType.skipped);
       const status = await changeAnswerStatus(req.user, req.body.questionnaireOrderId, StatusType.skipped);
       return res.apiv3({}, status);
       return res.apiv3({}, status);
@@ -122,7 +144,12 @@ module.exports = (crowi: Crowi): Router => {
     }
     }
   });
   });
 
 
-  router.put('/deny', accessTokenParser, loginRequired, async(req: AuthorizedRequest, res: ApiV3Response) => {
+  router.put('/deny', accessTokenParser, loginRequired, validators.skipDeny, async(req: AuthorizedRequest, res: ApiV3Response) => {
+    const errors = validationResult(req);
+    if (!errors.isEmpty()) {
+      return res.status(400).json({ errors: errors.array() });
+    }
+
     try {
     try {
       const status = await changeAnswerStatus(req.user, req.body.questionnaireOrderId, StatusType.denied);
       const status = await changeAnswerStatus(req.user, req.body.questionnaireOrderId, StatusType.denied);
       return res.apiv3({}, status);
       return res.apiv3({}, status);

+ 1 - 1
packages/app/src/server/service/questionnaire.ts

@@ -82,7 +82,7 @@ class QuestionnaireService {
       questionnaireOrders = questionnaireOrders.filter((order) => {
       questionnaireOrders = questionnaireOrders.filter((order) => {
         const status = statuses.find(s => s.questionnaireOrderId.toString() === order._id.toString());
         const status = statuses.find(s => s.questionnaireOrderId.toString() === order._id.toString());
 
 
-        return status?.status === StatusType.not_answered;
+        return !status || status?.status === StatusType.not_answered;
       });
       });
     }
     }