diff --git a/services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs b/services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs index 0c6070fe12..ddd3dba691 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs @@ -10,6 +10,7 @@ import { expressify } from '@overleaf/promise-utils' import Modules from '../../infrastructure/Modules.js' import UserGetter from '../User/UserGetter.js' import { Subscription } from '../../models/Subscription.js' +import { z, validateReq } from '../../infrastructure/Validation.js' import { isProfessionalGroupPlan } from './PlansHelper.mjs' import { MissingBillingInfoError, @@ -22,6 +23,9 @@ import { PaymentActionRequiredError, } from './Errors.js' +const MAX_NUMBER_OF_USERS = 20 +const MAX_NUMBER_OF_PO_NUMBER_CHARACTERS = 50 + /** * @import { Subscription } from "../../../../types/subscription/dashboard/subscription.js" */ @@ -198,18 +202,26 @@ async function addSeatsToGroupSubscription(req, res) { } } +const previewAddSeatsSubscriptionChangeSchema = z.object({ + body: z.object({ + adding: z.number().int().min(1).max(MAX_NUMBER_OF_USERS), + poNumber: z.string().max(MAX_NUMBER_OF_PO_NUMBER_CHARACTERS).optional(), + }), +}) + /** * @param {import("express").Request} req * @param {import("express").Response} res * @returns {Promise} */ async function previewAddSeatsSubscriptionChange(req, res) { + const { body } = validateReq(req, previewAddSeatsSubscriptionChangeSchema) try { const userId = SessionManager.getLoggedInUserId(req.session) const preview = await SubscriptionGroupHandler.promises.previewAddSeatsSubscriptionChange( userId, - req.body.adding + body.adding ) res.json(preview) @@ -227,7 +239,7 @@ async function previewAddSeatsSubscriptionChange(req, res) { if (error instanceof SubtotalLimitExceededError) { return res.status(422).json({ code: 'subtotal_limit_exceeded', - adding: req.body.adding, + adding: body.adding, }) } diff --git a/services/web/app/src/Features/Subscription/SubscriptionRouter.mjs b/services/web/app/src/Features/Subscription/SubscriptionRouter.mjs index 6cc83bf232..b6ea664f07 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionRouter.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionRouter.mjs @@ -19,14 +19,6 @@ const subscriptionRateLimiter = new RateLimiter('subscription', { }) const MAX_NUMBER_OF_USERS = 20 -const MAX_NUMBER_OF_PO_NUMBER_CHARACTERS = 50 - -const addSeatsValidateSchema = { - body: Joi.object({ - adding: Joi.number().integer().min(1).max(MAX_NUMBER_OF_USERS).required(), - poNumber: Joi.string().max(MAX_NUMBER_OF_PO_NUMBER_CHARACTERS), - }), -} export default { apply(webRouter, privateApiRouter, publicApiRouter) { @@ -74,7 +66,6 @@ export default { webRouter.post( '/user/subscription/group/add-users/preview', AuthenticationController.requireLogin(), - validate(addSeatsValidateSchema), RateLimiterMiddleware.rateLimit(subscriptionRateLimiter), SubscriptionGroupController.previewAddSeatsSubscriptionChange ) @@ -82,7 +73,6 @@ export default { webRouter.post( '/user/subscription/group/add-users/create', AuthenticationController.requireLogin(), - validate(addSeatsValidateSchema), RateLimiterMiddleware.rateLimit(subscriptionRateLimiter), SubscriptionGroupController.createAddSeatsSubscriptionChange )