diff options
-rw-r--r-- | backend/src/api/routes/quotes.ts | 46 | ||||
-rw-r--r-- | backend/src/middlewares/api-utils.ts | 35 |
2 files changed, 57 insertions, 24 deletions
diff --git a/backend/src/api/routes/quotes.ts b/backend/src/api/routes/quotes.ts index 4fec59a1d..65a6836b5 100644 --- a/backend/src/api/routes/quotes.ts +++ b/backend/src/api/routes/quotes.ts @@ -46,21 +46,23 @@ router.post( }), authenticateRequest(), RateLimit.newQuotesAdd, - validateRequest({ - body: { - text: joi.string().min(60).required(), - source: joi.string().required(), - language: joi - .string() - .regex(/^[\w+]+$/) - .required(), - captcha: joi - .string() - .regex(/[\w-_]+/) - .required(), + validateRequest( + { + body: { + text: joi.string().min(60).required(), + source: joi.string().required(), + language: joi + .string() + .regex(/^[\w+]+$/) + .required(), + captcha: joi + .string() + .regex(/[\w-_]+/) + .required(), + }, }, - validationErrorMessage: "Please fill all the fields", - }), + { validationErrorMessage: "Please fill all the fields" } + ), asyncHandler(QuoteController.addQuote) ); @@ -68,14 +70,16 @@ router.post( "/approve", authenticateRequest(), RateLimit.newQuotesAction, - validateRequest({ - body: { - quoteId: joi.string().required(), - editText: joi.string().allow(null), - editSource: joi.string().allow(null), + validateRequest( + { + body: { + quoteId: joi.string().required(), + editText: joi.string().allow(null), + editSource: joi.string().allow(null), + }, }, - validationErrorMessage: "Please fill all the fields", - }), + { validationErrorMessage: "Please fill all the fields" } + ), checkIfUserIsQuoteMod, asyncHandler(QuoteController.approveQuote) ); diff --git a/backend/src/middlewares/api-utils.ts b/backend/src/middlewares/api-utils.ts index 83e0a76c7..e2a993602 100644 --- a/backend/src/middlewares/api-utils.ts +++ b/backend/src/middlewares/api-utils.ts @@ -129,11 +129,37 @@ interface ValidationSchema { body?: object; query?: object; params?: object; + headers?: object; +} + +interface ValidationSchemaOption { + allowUnknown?: boolean; +} + +interface ValidationHandlingOptions { validationErrorMessage?: string; } -function validateRequest(validationSchema: ValidationSchema): RequestHandler { - const { validationErrorMessage } = validationSchema; +type ValidationSchemaOptions = { + [schema in keyof ValidationSchema]?: ValidationSchemaOption; +} & ValidationHandlingOptions; + +const VALIDATION_SCHEMA_DEFAULT_OPTIONS: ValidationSchemaOptions = { + body: { allowUnknown: false }, + headers: { allowUnknown: true }, + params: { allowUnknown: false }, + query: { allowUnknown: false }, +}; + +function validateRequest( + validationSchema: ValidationSchema, + validationOptions: ValidationSchemaOptions = VALIDATION_SCHEMA_DEFAULT_OPTIONS +): RequestHandler { + const options = { + ...VALIDATION_SCHEMA_DEFAULT_OPTIONS, + ...validationOptions, + }; + const { validationErrorMessage } = options; const normalizedValidationSchema: ValidationSchema = _.omit( validationSchema, "validationErrorMessage" @@ -143,7 +169,10 @@ function validateRequest(validationSchema: ValidationSchema): RequestHandler { _.each( normalizedValidationSchema, (schema: object, key: keyof ValidationSchema) => { - const joiSchema = joi.object().keys(schema); + const joiSchema = joi + .object() + .keys(schema) + .unknown(options[key]?.allowUnknown); const { error } = joiSchema.validate(req[key] ?? {}); if (error) { |