mirror of
https://github.com/strapi/strapi.git
synced 2025-11-02 10:55:37 +00:00
Add validators
This commit is contained in:
parent
36d662fc79
commit
74d25bb459
@ -1,28 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const { yup, formatYupErrors } = require('strapi-utils');
|
||||
|
||||
const ALLOWED_EVENTS = [
|
||||
'entry.create',
|
||||
'entry.update',
|
||||
'entry.delete',
|
||||
'media.create',
|
||||
'media.delete',
|
||||
];
|
||||
|
||||
const webhookValidator = yup
|
||||
.object({
|
||||
name: yup.string().required(),
|
||||
url: yup.string().required(),
|
||||
headers: yup.lazy(data => {
|
||||
if (typeof data !== 'object') {
|
||||
return yup.object().required();
|
||||
}
|
||||
|
||||
return yup
|
||||
.object(
|
||||
_.mapValues(data, () => {
|
||||
yup
|
||||
.string()
|
||||
.min(1)
|
||||
.required();
|
||||
})
|
||||
)
|
||||
.required();
|
||||
}),
|
||||
events: yup
|
||||
.array()
|
||||
.of(
|
||||
yup
|
||||
.string()
|
||||
.oneOf(ALLOWED_EVENTS)
|
||||
.required()
|
||||
)
|
||||
.min(1)
|
||||
.required(),
|
||||
})
|
||||
.noUnknown();
|
||||
|
||||
const updateWebhookValidator = webhookValidator.shape({
|
||||
isEnabled: yup.boolean(),
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
async listWebhooks(ctx) {
|
||||
const webhooks = await strapi.webhookStore.findWebhooks();
|
||||
ctx.send({ data: webhooks });
|
||||
},
|
||||
|
||||
async createWebhook(ctx) {
|
||||
const { name, url, headers, events } = ctx.request.body;
|
||||
|
||||
// TODO: validate input
|
||||
|
||||
const webhook = await strapi.webhookStore.createWebhook({
|
||||
name,
|
||||
url,
|
||||
headers,
|
||||
events,
|
||||
});
|
||||
|
||||
strapi.webhookRunner.add(webhook);
|
||||
|
||||
ctx.created({ data: webhook });
|
||||
},
|
||||
|
||||
async getWebhook(ctx) {
|
||||
const { id } = ctx.params;
|
||||
const webhook = await strapi.webhookStore.findWebhook(id);
|
||||
@ -34,26 +65,63 @@ module.exports = {
|
||||
ctx.send({ data: webhook });
|
||||
},
|
||||
|
||||
async createWebhook(ctx) {
|
||||
const { body } = ctx.request;
|
||||
|
||||
try {
|
||||
await webhookValidator.validate(body, {
|
||||
strict: true,
|
||||
abortEarly: false,
|
||||
});
|
||||
} catch (error) {
|
||||
return ctx.send(
|
||||
{
|
||||
statusCode: 400,
|
||||
message: 'ValidationError',
|
||||
error: formatYupErrors(error),
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
const webhook = await strapi.webhookStore.createWebhook(body);
|
||||
|
||||
strapi.webhookRunner.add(webhook);
|
||||
|
||||
ctx.created({ data: webhook });
|
||||
},
|
||||
|
||||
async updateWebhook(ctx) {
|
||||
const { id } = ctx.params;
|
||||
const { body } = ctx.request;
|
||||
|
||||
const webhook = await strapi.webhookStore.findWebhook(id);
|
||||
|
||||
// TODO: validate input
|
||||
|
||||
if (!webhook) {
|
||||
return ctx.send({ error: 'webhook.notFound' }, 404);
|
||||
try {
|
||||
await updateWebhookValidator.validate(body, {
|
||||
strict: true,
|
||||
abortEarly: false,
|
||||
});
|
||||
} catch (error) {
|
||||
return ctx.badRequest('ValidationError', {
|
||||
error: formatYupErrors(error),
|
||||
});
|
||||
}
|
||||
|
||||
const updatedWebhook = {
|
||||
const webhook = await strapi.webhookStore.findWebhook(id);
|
||||
|
||||
if (!webhook) {
|
||||
return ctx.notFound('webhook.notFound');
|
||||
}
|
||||
|
||||
const updatedWebhook = await strapi.webhookStore.updateWebhook(id, {
|
||||
...webhook,
|
||||
...body,
|
||||
};
|
||||
});
|
||||
|
||||
await strapi.webhookStore.updateWebhook(id, updatedWebhook);
|
||||
if (!updatedWebhook) {
|
||||
return ctx.notFound('webhook.notFound');
|
||||
}
|
||||
|
||||
strapi.webhookRunner.update(webhook);
|
||||
strapi.webhookRunner.update(updatedWebhook);
|
||||
|
||||
ctx.send({ data: updatedWebhook });
|
||||
},
|
||||
@ -63,7 +131,7 @@ module.exports = {
|
||||
const webhook = await strapi.webhookStore.findWebhook(id);
|
||||
|
||||
if (!webhook) {
|
||||
return ctx.send({ error: 'webhook.notFound' }, 404);
|
||||
return ctx.notFound('webhook.notFound');
|
||||
}
|
||||
|
||||
await strapi.webhookStore.deleteWebhook(id);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const yup = require('yup');
|
||||
const formatYupErrors = require('./yup-formatter');
|
||||
const { formatYupErrors } = require('strapi-utils');
|
||||
|
||||
const { isValidCategoryName } = require('./common');
|
||||
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
const _ = require('lodash');
|
||||
const yup = require('yup');
|
||||
const { formatYupErrors } = require('strapi-utils');
|
||||
|
||||
const { isValidCategoryName, isValidIcon } = require('./common');
|
||||
const formatYupErrors = require('./yup-formatter');
|
||||
const createSchema = require('./model-schema');
|
||||
const { modelTypes, DEFAULT_TYPES } = require('./constants');
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
const _ = require('lodash');
|
||||
const yup = require('yup');
|
||||
const formatYupErrors = require('./yup-formatter');
|
||||
const { formatYupErrors } = require('strapi-utils');
|
||||
|
||||
const createSchema = require('./model-schema');
|
||||
const { nestedComponentSchema } = require('./component');
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const yup = require('yup');
|
||||
const formatYupErrors = require('../yup-formatter');
|
||||
const { formatYupErrors } = require('../validators');
|
||||
|
||||
describe('Format yup errors', () => {
|
||||
test('Format single errors', async () => {
|
||||
@ -9,13 +9,21 @@ const buildQuery = require('./buildQuery');
|
||||
const parseMultipartData = require('./parse-multipart');
|
||||
const sanitizeEntity = require('./sanitize-entity');
|
||||
const parseType = require('./parse-type');
|
||||
const finder = require('./finder');
|
||||
const logger = require('./logger');
|
||||
const models = require('./models');
|
||||
const policy = require('./policy');
|
||||
const templateConfiguration = require('./templateConfiguration');
|
||||
const { yup, formatYupErrors } = require('./validators');
|
||||
|
||||
module.exports = {
|
||||
finder: require('./finder'),
|
||||
logger: require('./logger'),
|
||||
models: require('./models'),
|
||||
policy: require('./policy'),
|
||||
templateConfiguration: require('./templateConfiguration'),
|
||||
yup,
|
||||
formatYupErrors,
|
||||
finder,
|
||||
logger,
|
||||
models,
|
||||
policy,
|
||||
templateConfiguration,
|
||||
convertRestQueryParams,
|
||||
buildQuery,
|
||||
parseMultipartData,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { ValidationError } = require('yup');
|
||||
const yup = require('yup');
|
||||
const { ValidationError } = yup;
|
||||
|
||||
/**
|
||||
* Returns a formatted error for http responses
|
||||
@ -22,4 +23,7 @@ const formatYupErrors = validationError => {
|
||||
}, {});
|
||||
};
|
||||
|
||||
module.exports = formatYupErrors;
|
||||
module.exports = {
|
||||
yup,
|
||||
formatYupErrors,
|
||||
};
|
||||
@ -23,7 +23,8 @@
|
||||
"lodash": "^4.17.11",
|
||||
"pino": "^4.7.1",
|
||||
"pluralize": "^7.0.0",
|
||||
"shelljs": "^0.8.3"
|
||||
"shelljs": "^0.8.3",
|
||||
"yup": "^0.28.0"
|
||||
},
|
||||
"author": {
|
||||
"email": "hi@strapi.io",
|
||||
|
||||
@ -78,15 +78,22 @@ class WebhookRunner {
|
||||
},
|
||||
timeout: 10000,
|
||||
})
|
||||
.then(res => {
|
||||
.then(async res => {
|
||||
if (res.ok) {
|
||||
return {
|
||||
statusCode: res.status,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
statusCode: res.status,
|
||||
message: await res.text(),
|
||||
};
|
||||
})
|
||||
.catch(err => {
|
||||
return {
|
||||
statusCode: err.status,
|
||||
body: err.body,
|
||||
statusCode: 500,
|
||||
message: err.message,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@ -32,14 +32,24 @@ const webhookModel = {
|
||||
},
|
||||
};
|
||||
|
||||
const formatWebhookInfo = webhook => {
|
||||
const toDBObject = data => {
|
||||
return {
|
||||
id: webhook.id,
|
||||
name: webhook.name,
|
||||
url: webhook.url,
|
||||
headers: webhook.headers,
|
||||
events: webhook.events,
|
||||
isEnabled: webhook.enabled,
|
||||
name: data.name,
|
||||
url: data.url,
|
||||
headers: data.headers,
|
||||
events: data.events,
|
||||
enabled: data.isEnabled,
|
||||
};
|
||||
};
|
||||
|
||||
const fromDBObject = row => {
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
url: row.url,
|
||||
headers: row.headers,
|
||||
events: row.events,
|
||||
isEnabled: row.enabled,
|
||||
};
|
||||
};
|
||||
|
||||
@ -50,52 +60,28 @@ const createWebhookStore = ({ db }) => {
|
||||
async findWebhooks() {
|
||||
const results = await webhookQueries.find();
|
||||
|
||||
return results.map(formatWebhookInfo);
|
||||
return results.map(fromDBObject);
|
||||
},
|
||||
|
||||
async findWebhook(id) {
|
||||
const result = await webhookQueries.findOne({ id });
|
||||
return result ? formatWebhookInfo(result) : null;
|
||||
return result ? fromDBObject(result) : null;
|
||||
},
|
||||
|
||||
createWebhook(data) {
|
||||
const { name, url, headers, events } = data;
|
||||
|
||||
const webhook = {
|
||||
name,
|
||||
url,
|
||||
headers,
|
||||
events,
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
return webhookQueries.create(webhook).then(formatWebhookInfo);
|
||||
return webhookQueries
|
||||
.create(toDBObject({ ...data, isEnabled: true }))
|
||||
.then(fromDBObject);
|
||||
},
|
||||
|
||||
async updateWebhook(id, data) {
|
||||
const oldWebhook = await this.findWebhook(id);
|
||||
|
||||
if (!oldWebhook) {
|
||||
throw new Error('webhook.notFound');
|
||||
}
|
||||
|
||||
const { name, url, headers, events, isEnabled } = data;
|
||||
|
||||
const updatedWebhook = {
|
||||
name,
|
||||
url,
|
||||
headers,
|
||||
events,
|
||||
enabled: isEnabled,
|
||||
};
|
||||
|
||||
return webhookQueries
|
||||
.update({ id }, updatedWebhook)
|
||||
.then(formatWebhookInfo);
|
||||
const webhook = await webhookQueries.update({ id }, toDBObject(data));
|
||||
return webhook ? fromDBObject(webhook) : null;
|
||||
},
|
||||
|
||||
deleteWebhook(id) {
|
||||
return webhookQueries.delete({ id });
|
||||
async deleteWebhook(id) {
|
||||
const webhook = await webhookQueries.delete({ id });
|
||||
return webhook ? fromDBObject(webhook) : null;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
12
yarn.lock
12
yarn.lock
@ -18129,6 +18129,18 @@ yup@^0.27.0:
|
||||
synchronous-promise "^2.0.6"
|
||||
toposort "^2.0.2"
|
||||
|
||||
yup@^0.28.0:
|
||||
version "0.28.0"
|
||||
resolved "https://registry.yarnpkg.com/yup/-/yup-0.28.0.tgz#fdc04d1a495465c83d3757a80c47616884baeddc"
|
||||
integrity sha512-9ZmsB/PT6/m+oUKF8rT9lWhMMGfx5s/aNCCf8pMu/GEQA0Ro2tLOc+aX12GjfL67Vif5a3c7eZVuxGFqFScnJQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.0.0"
|
||||
fn-name "~2.0.1"
|
||||
lodash "^4.17.11"
|
||||
property-expr "^1.5.0"
|
||||
synchronous-promise "^2.0.6"
|
||||
toposort "^2.0.2"
|
||||
|
||||
zen-observable-ts@^0.8.20:
|
||||
version "0.8.20"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.20.tgz#44091e335d3fcbc97f6497e63e7f57d5b516b163"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user