chore: separate validation between webhook service and controller

This commit is contained in:
Jamie Howard 2023-05-26 14:27:44 +01:00
parent 5547c788eb
commit 4020a96da6
2 changed files with 36 additions and 33 deletions

View File

@ -1,5 +1,33 @@
'use strict';
const _ = require('lodash');
const { yup, validateYupSchema } = require('@strapi/utils');
const urlRegex =
/^(?:([a-z0-9+.-]+):\/\/)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9_]-*)*[a-z\u00a1-\uffff0-9_]+)(?:\.(?:[a-z\u00a1-\uffff0-9_]-*)*[a-z\u00a1-\uffff0-9_]+)*\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/;
const webhookValidator = yup.object({
name: yup.string().required(),
url: yup.string().matches(urlRegex, 'url must be a valid URL').required(),
headers: yup.lazy((data) => {
if (typeof data !== 'object') {
return yup.object().required();
}
return yup
.object(
_.mapValues(data, () => {
yup.string().min(1).required();
})
)
.required();
}),
});
const updateWebhookValidator = webhookValidator.shape({
isEnabled: yup.boolean(),
});
module.exports = {
async listWebhooks(ctx) {
const webhooks = await strapi.webhookStore.findWebhooks();
@ -20,6 +48,8 @@ module.exports = {
async createWebhook(ctx) {
const { body } = ctx.request;
await validateYupSchema(webhookValidator)(body);
const webhook = await strapi.webhookStore.createWebhook(body);
strapi.webhookRunner.add(webhook);
@ -31,6 +61,8 @@ module.exports = {
const { id } = ctx.params;
const { body } = ctx.request;
await validateYupSchema(updateWebhookValidator)(body);
const webhook = await strapi.webhookStore.findWebhook(id);
if (!webhook) {

View File

@ -4,7 +4,6 @@
'use strict';
const { mapValues } = require('lodash/fp');
const { yup, validateYupSchema } = require('@strapi/utils');
const webhookModel = {
@ -50,36 +49,8 @@ const fromDBObject = (row) => {
};
};
const urlRegex =
/^(?:([a-z0-9+.-]+):\/\/)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9_]-*)*[a-z\u00a1-\uffff0-9_]+)(?:\.(?:[a-z\u00a1-\uffff0-9_]-*)*[a-z\u00a1-\uffff0-9_]+)*\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/;
const webhookValidator = (allowedEvents) =>
yup
.object({
name: yup.string().required(),
url: yup.string().matches(urlRegex, 'url must be a valid URL').required(),
headers: yup.lazy((data) => {
if (typeof data !== 'object') {
return yup.object().required();
}
return yup
.object(
mapValues(() => {
yup.string().min(1).required();
}, data)
)
.required();
}),
events: yup.array().of(yup.string().oneOf(Array.from(allowedEvents.values())).required()),
})
.noUnknown();
const updateWebhookValidator = (allowedEvents) =>
webhookValidator(allowedEvents).shape({
id: yup.number().required(),
isEnabled: yup.boolean().required(),
});
const webhookEventValidator = (allowedEvents) =>
yup.array().of(yup.string().oneOf(Array.from(allowedEvents.values())).required());
const createWebhookStore = ({ db }) => {
const webhookQueries = db.query('webhook');
@ -106,7 +77,7 @@ const createWebhookStore = ({ db }) => {
},
async createWebhook(data) {
await validateYupSchema(webhookValidator(allowedEvents))(data);
await validateYupSchema(webhookEventValidator(allowedEvents))(data.events);
return webhookQueries
.create({
@ -116,7 +87,7 @@ const createWebhookStore = ({ db }) => {
},
async updateWebhook(id, data) {
await validateYupSchema(updateWebhookValidator(allowedEvents))(data);
await validateYupSchema(webhookEventValidator(allowedEvents))(data.events);
const webhook = await webhookQueries.update({
where: { id },