diff --git a/services/web/app/src/infrastructure/Validation.js b/services/web/app/src/infrastructure/Validation.js index eafb82cda4..672978e546 100644 --- a/services/web/app/src/infrastructure/Validation.js +++ b/services/web/app/src/infrastructure/Validation.js @@ -1,5 +1,13 @@ +// @ts-check + const { Joi: CelebrateJoi, celebrate, errors } = require('celebrate') const { ObjectId } = require('mongodb-legacy') +const { NotFoundError } = require('../Features/Errors/Errors') + +/** + * @import { ZodType } from 'zod' + * @import { Request } from 'express' + */ const objectIdValidator = { type: 'objectId', @@ -24,11 +32,31 @@ const objectIdValidator = { const Joi = CelebrateJoi.extend(objectIdValidator) const errorMiddleware = errors() -module.exports = { Joi, validate, errorMiddleware } - /** * Validation middleware */ function validate(schema) { return celebrate(schema, { allowUnknown: true }) } + +/** + * Validate a request against a zod schema + * + * @template T + * @param {Request} req + * @param {ZodType} schema + * @return {T} + */ +function validateReq(req, schema) { + const parsed = schema.safeParse(req) + if (parsed.success) { + return parsed.data + } else if (parsed.error.issues.some(issue => issue.path[0] === 'params')) { + // Parts of the URL path failed to validate; throw a 404 rather than a 400 + throw new NotFoundError('Not found').withCause(parsed.error) + } else { + throw parsed.error + } +} + +module.exports = { Joi, validate, errorMiddleware, validateReq }