aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--backend/src/api/routes/quotes.ts46
-rw-r--r--backend/src/middlewares/api-utils.ts35
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) {