diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs index c5d8344922..94bcefad0b 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs @@ -11,6 +11,7 @@ import EditorRealTimeController from '../Editor/EditorRealTimeController.js' import AnalyticsManager from '../Analytics/AnalyticsManager.js' import SessionManager from '../Authentication/SessionManager.js' import { RateLimiter } from '../../infrastructure/RateLimiter.js' +import { z, zz, validateReq } from '../../infrastructure/Validation.js' import { expressify } from '@overleaf/promise-utils' import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs' import Errors from '../Errors/Errors.js' @@ -80,9 +81,24 @@ async function _checkRateLimit(userId) { return true } +const inviteToProjectSchema = z.object({ + params: z.object({ + Project_id: zz.objectId(), + }), + body: z.object({ + email: z.string(), + privileges: z.enum([ + PrivilegeLevels.READ_ONLY, + PrivilegeLevels.READ_AND_WRITE, + PrivilegeLevels.REVIEW, + ]), + }), +}) + async function inviteToProject(req, res) { - const projectId = req.params.Project_id - let { email, privileges } = req.body + const { params, body } = validateReq(req, inviteToProjectSchema) + const projectId = params.Project_id + let { email, privileges } = body const sendingUser = SessionManager.getSessionUser(req.session) const sendingUserId = sendingUser._id req.logger.addFields({ email, sendingUserId }) diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsRouter.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsRouter.mjs index 7260e3e4db..b38f80d1f0 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsRouter.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsRouter.mjs @@ -1,13 +1,11 @@ import CollaboratorsController from './CollaboratorsController.mjs' import AuthenticationController from '../Authentication/AuthenticationController.js' import AuthorizationMiddleware from '../Authorization/AuthorizationMiddleware.mjs' -import PrivilegeLevels from '../Authorization/PrivilegeLevels.js' import CollaboratorsInviteController from './CollaboratorsInviteController.mjs' import { RateLimiter } from '../../infrastructure/RateLimiter.js' import RateLimiterMiddleware from '../Security/RateLimiterMiddleware.js' import CaptchaMiddleware from '../Captcha/CaptchaMiddleware.mjs' import AnalyticsRegistrationSourceMiddleware from '../Analytics/AnalyticsRegistrationSourceMiddleware.js' -import { Joi, validate } from '../../infrastructure/Validation.js' const rateLimiters = { inviteToProjectByProjectId: new RateLimiter( @@ -80,18 +78,6 @@ export default { }), CaptchaMiddleware.validateCaptcha('invite'), AuthenticationController.requireLogin(), - validate({ - body: Joi.object({ - email: Joi.string().required(), - privileges: Joi.string() - .valid( - PrivilegeLevels.READ_ONLY, - PrivilegeLevels.READ_AND_WRITE, - PrivilegeLevels.REVIEW - ) - .required(), - }), - }), AuthorizationMiddleware.ensureUserCanAdminProject, CollaboratorsInviteController.inviteToProject )