reiji-h 1 год назад
Родитель
Сommit
b16ae12b8b

+ 14 - 1
apps/app/src/server/routes/apiv3/personal-setting/delete-access-token.ts

@@ -1,10 +1,12 @@
 import { ErrorV3 } from '@growi/core/dist/models';
 import type { Request, RequestHandler } from 'express';
+import { body } from 'express-validator';
 
 import { SupportedAction } from '~/interfaces/activity';
 import type Crowi from '~/server/crowi';
 import { accessTokenParser } from '~/server/middlewares/access-token-parser';
 import { generateAddActivityMiddleware } from '~/server/middlewares/add-activity';
+import { apiV3FormValidator } from '~/server/middlewares/apiv3-form-validator';
 import { AccessToken } from '~/server/models/access-token';
 import loggerFactory from '~/utils/logger';
 
@@ -20,6 +22,14 @@ type DeleteAccessTokenRequest = Request<undefined, ApiV3Response, ReqBody>;
 
 type DeleteAccessTokenHandlersFactory = (crowi: Crowi) => RequestHandler[];
 
+const validator = [
+  body('tokenId')
+    .exists()
+    .withMessage('tokenId is required')
+    .isString()
+    .withMessage('tokenId must be a string'),
+];
+
 export const deleteAccessTokenHandlersFactory: DeleteAccessTokenHandlersFactory = (crowi) => {
 
   const loginRequiredStrictly = require('../../../middlewares/login-required')(crowi);
@@ -27,8 +37,11 @@ export const deleteAccessTokenHandlersFactory: DeleteAccessTokenHandlersFactory
   const activityEvent = crowi.event('activity');
 
   return [
-    accessTokenParser, loginRequiredStrictly,
+    accessTokenParser,
+    loginRequiredStrictly,
     addActivity,
+    validator,
+    apiV3FormValidator,
     async(req: DeleteAccessTokenRequest, res: ApiV3Response) => {
       const { body } = req;
       const { tokenId } = body;

+ 43 - 3
apps/app/src/server/routes/apiv3/personal-setting/generate-access-token.ts

@@ -1,9 +1,9 @@
-
 import type {
   IUserHasId,
 } from '@growi/core/dist/interfaces';
 import { ErrorV3 } from '@growi/core/dist/models';
 import type { Request, RequestHandler } from 'express';
+import { body } from 'express-validator';
 
 import { SupportedAction } from '~/interfaces/activity';
 import type Crowi from '~/server/crowi';
@@ -11,6 +11,7 @@ import { generateAddActivityMiddleware } from '~/server/middlewares/add-activity
 import { AccessToken } from '~/server/models/access-token';
 import loggerFactory from '~/utils/logger';
 
+import { apiV3FormValidator } from '../../../middlewares/apiv3-form-validator';
 import type { ApiV3Response } from '../interfaces/apiv3-response';
 
 const logger = loggerFactory('growi:routes:apiv3:personal-setting:generate-access-tokens');
@@ -25,9 +26,45 @@ interface GenerateAccessTokenRequest extends Request<undefined, ApiV3Response, R
   user: IUserHasId,
 }
 
-
 type GenerateAccessTokenHandlerFactory = (crowi: Crowi) => RequestHandler[];
 
+const validator = [
+  body('expiredAt')
+    .exists()
+    .withMessage('expiredAt is required')
+    .custom((value) => {
+      const expiredAt = new Date(value);
+      const now = new Date();
+
+      // Check if date is valid
+      if (Number.isNaN(expiredAt.getTime())) {
+        throw new Error('Invalid date format');
+      }
+
+      // Check if date is in the future
+      if (expiredAt <= now) {
+        throw new Error('Expiration date must be in the future');
+      }
+
+      return true;
+    }),
+
+  body('description')
+    .optional()
+    .isString()
+    .withMessage('description must be a string')
+    .isLength({ max: 200 })
+    .withMessage('description must be less than or equal to 200 characters'),
+
+  body('scope')
+    .optional()
+    .isArray()
+    .withMessage('scope must be an array')
+    .custom(() => {
+      // TODO: Check if all values are valid
+    }),
+];
+
 export const generateAccessTokenHandlerFactory: GenerateAccessTokenHandlerFactory = (crowi) => {
 
   const loginRequiredStrictly = require('../../../middlewares/login-required')(crowi);
@@ -36,7 +73,10 @@ export const generateAccessTokenHandlerFactory: GenerateAccessTokenHandlerFactor
 
 
   return [
-    loginRequiredStrictly, addActivity,
+    loginRequiredStrictly,
+    addActivity,
+    validator,
+    apiV3FormValidator,
     async(req: GenerateAccessTokenRequest, res: ApiV3Response) => {
 
       const { user, body } = req;