From 36d662fc79c5ee63f3e0be3cd4e11a483429e8b9 Mon Sep 17 00:00:00 2001 From: Alexandre Bodin Date: Mon, 23 Dec 2019 16:38:42 +0100 Subject: [PATCH] Create a webhook model to perist them outside of the core_store --- packages/strapi-admin/controllers/Webhooks.js | 5 +- .../strapi-plugin-graphql/services/Loaders.js | 2 +- .../strapi-plugin-graphql/services/Schema.js | 2 +- packages/strapi/lib/Strapi.js | 6 +- packages/strapi/lib/services/core-store.js | 2 + .../strapi/lib/services/webhook-runner.js | 4 +- packages/strapi/lib/services/webhook-store.js | 147 ++++++++++-------- 7 files changed, 100 insertions(+), 68 deletions(-) diff --git a/packages/strapi-admin/controllers/Webhooks.js b/packages/strapi-admin/controllers/Webhooks.js index 79dcfd461d..66928b9549 100644 --- a/packages/strapi-admin/controllers/Webhooks.js +++ b/packages/strapi-admin/controllers/Webhooks.js @@ -16,7 +16,6 @@ module.exports = { url, headers, events, - isEnabled: true, }); strapi.webhookRunner.add(webhook); @@ -28,6 +27,10 @@ module.exports = { const { id } = ctx.params; const webhook = await strapi.webhookStore.findWebhook(id); + if (!webhook) { + return ctx.notFound('webhook.notFound'); + } + ctx.send({ data: webhook }); }, diff --git a/packages/strapi-plugin-graphql/services/Loaders.js b/packages/strapi-plugin-graphql/services/Loaders.js index a0325cf45c..34b6352157 100644 --- a/packages/strapi-plugin-graphql/services/Loaders.js +++ b/packages/strapi-plugin-graphql/services/Loaders.js @@ -17,7 +17,7 @@ module.exports = { // Create loaders for each relational field (exclude core models). Object.keys(strapi.models) - .filter(model => model !== 'core_store') + .filter(model => model.internal !== true) .forEach(modelKey => { const model = strapi.models[modelKey]; this.createLoader(model.uid); diff --git a/packages/strapi-plugin-graphql/services/Schema.js b/packages/strapi-plugin-graphql/services/Schema.js index aa63281219..a81de91a64 100644 --- a/packages/strapi-plugin-graphql/services/Schema.js +++ b/packages/strapi-plugin-graphql/services/Schema.js @@ -135,7 +135,7 @@ const schemaBuilder = { // build defaults schemas if shadowCRUD is enabled if (strapi.plugins.graphql.config.shadowCRUD !== false) { const modelCruds = Resolvers.buildShadowCRUD( - _.omit(strapi.models, ['core_store']) + _.omitBy(strapi.models, model => model.internal === true) ); shadowCRUD = Object.keys(strapi.plugins).reduce((acc, plugin) => { diff --git a/packages/strapi/lib/Strapi.js b/packages/strapi/lib/Strapi.js index b94888a947..618bbd21f3 100644 --- a/packages/strapi/lib/Strapi.js +++ b/packages/strapi/lib/Strapi.js @@ -31,7 +31,10 @@ const getPrefixedDeps = require('./utils/get-prefixed-dependencies'); const createEventHub = require('./services/event-hub'); const createWebhookRunner = require('./services/webhook-runner'); -const createWebhookStore = require('./services/webhook-store'); +const { + webhookModel, + createWebhookStore, +} = require('./services/webhook-store'); const { createCoreStore, coreStoreModel } = require('./services/core-store'); const { createDatabaseManager } = require('strapi-database'); @@ -366,6 +369,7 @@ class Strapi extends EventEmitter { // Init core store this.models['core_store'] = coreStoreModel; + this.models['strapi_webhooks'] = webhookModel; this.db = createDatabaseManager(this); await this.db.initialize(); diff --git a/packages/strapi/lib/services/core-store.js b/packages/strapi/lib/services/core-store.js index 819f64b538..ed227e1a06 100644 --- a/packages/strapi/lib/services/core-store.js +++ b/packages/strapi/lib/services/core-store.js @@ -1,6 +1,8 @@ 'use strict'; const coreStoreModel = { + uid: 'strapi::core-store', + internal: true, connection: 'default', info: { name: 'core_store', diff --git a/packages/strapi/lib/services/webhook-runner.js b/packages/strapi/lib/services/webhook-runner.js index a5df8cb49b..85b131b989 100644 --- a/packages/strapi/lib/services/webhook-runner.js +++ b/packages/strapi/lib/services/webhook-runner.js @@ -107,8 +107,8 @@ class WebhookRunner { update(webhook) { debug(`Refreshing webhook '${webhook.id}'`); - this.unregister(webhook); - this.register(webhook); + this.remove(webhook); + this.add(webhook); } remove(webhook) { diff --git a/packages/strapi/lib/services/webhook-store.js b/packages/strapi/lib/services/webhook-store.js index 378e38ed09..6d50393e64 100644 --- a/packages/strapi/lib/services/webhook-store.js +++ b/packages/strapi/lib/services/webhook-store.js @@ -3,81 +3,104 @@ */ 'use strict'; -const uuid = require('uuid'); - -module.exports = ({ db }) => ({ - async findWebhooks() { - const row = await db.query('core_store').findOne({ - key: 'webhooks', - }); - - return row ? JSON.parse(row.value) : []; +const webhookModel = { + uid: 'strapi::webhooks', + internal: true, + connection: 'default', + globalId: 'StrapiWebhooks', + collectionName: 'strapi_webhooks', + info: { + name: 'Strapi webhooks', + description: '', }, - - async findWebhook(id) { - const webhooks = await this.findWebhooks(); - return webhooks.find(hook => hook.id === id); + attributes: { + name: { + type: 'string', + }, + url: { + type: 'text', + }, + headers: { + type: 'json', + }, + events: { + type: 'json', + }, + enabled: { + type: 'boolean', + }, }, +}; - async createWebhook(data) { - const webhooks = await this.findWebhooks(); +const formatWebhookInfo = webhook => { + return { + id: webhook.id, + name: webhook.name, + url: webhook.url, + headers: webhook.headers, + events: webhook.events, + isEnabled: webhook.enabled, + }; +}; - const webhook = { - id: uuid(), - ...data, - }; +const createWebhookStore = ({ db }) => { + const webhookQueries = db.query('strapi_webhooks'); - const res = await db.query('core_store').findOne({ - key: 'webhooks', - }); + return { + async findWebhooks() { + const results = await webhookQueries.find(); - if (!res) { - await db - .query('core_store') - .create({ key: 'webhooks', value: JSON.stringify([webhook]) }); - } else { - await db - .query('core_store') - .update( - { key: 'webhooks' }, - { value: JSON.stringify(webhooks.concat(webhook)) } - ); - } + return results.map(formatWebhookInfo); + }, - return webhook; - }, + async findWebhook(id) { + const result = await webhookQueries.findOne({ id }); + return result ? formatWebhookInfo(result) : null; + }, - async updateWebhook(id, data) { - const oldWebhook = await this.findWebhook(id); - const webhooks = await this.findWebhooks(); + createWebhook(data) { + const { name, url, headers, events } = data; - const updatedWebhook = { - ...oldWebhook, - ...data, - }; + const webhook = { + name, + url, + headers, + events, + enabled: true, + }; - const updatedWebhooks = webhooks.map(webhook => { - if (webhook.id === id) { - return updatedWebhook; + return webhookQueries.create(webhook).then(formatWebhookInfo); + }, + + async updateWebhook(id, data) { + const oldWebhook = await this.findWebhook(id); + + if (!oldWebhook) { + throw new Error('webhook.notFound'); } - return webhook; - }); + const { name, url, headers, events, isEnabled } = data; - await db - .query('core_store') - .update({ key: 'webhooks' }, { value: JSON.stringify(updatedWebhooks) }); + const updatedWebhook = { + name, + url, + headers, + events, + enabled: isEnabled, + }; - return updatedWebhook; - }, + return webhookQueries + .update({ id }, updatedWebhook) + .then(formatWebhookInfo); + }, - async deleteWebhook(id) { - const webhooks = await this.findWebhooks(); + deleteWebhook(id) { + return webhookQueries.delete({ id }); + }, + }; +}; - const updatedWebhooks = webhooks.filter(webhook => webhook.id !== id); - - await db - .query('core_store') - .update({ key: 'webhooks' }, { value: JSON.stringify(updatedWebhooks) }); - }, -}); +module.exports = { + webhookModel, + createWebhookStore, +};