From cff8fd904149ab993df73ec144490e16d17a926b Mon Sep 17 00:00:00 2001 From: Victor LAMBERT Date: Sat, 16 Nov 2019 01:05:21 +0100 Subject: [PATCH 1/7] Populate only role relation to authorize user --- .../config/policies/permissions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/strapi-plugin-users-permissions/config/policies/permissions.js b/packages/strapi-plugin-users-permissions/config/policies/permissions.js index 55ae6bf4ad..e4fd13b294 100644 --- a/packages/strapi-plugin-users-permissions/config/policies/permissions.js +++ b/packages/strapi-plugin-users-permissions/config/policies/permissions.js @@ -16,11 +16,11 @@ module.exports = async (ctx, next) => { if (isAdmin) { ctx.state.admin = await strapi .query('administrator', 'admin') - .findOne({ id }); + .findOne({ id }, ['role']); } else { ctx.state.user = await strapi .query('user', 'users-permissions') - .findOne({ id }); + .findOne({ id }, ['role']); } } catch (err) { return handleErrors(ctx, err, 'unauthorized'); From aa6955324627f6ed1fd5170f4970c630da3e8234 Mon Sep 17 00:00:00 2001 From: Anand Chowdhary Date: Wed, 4 Dec 2019 11:53:44 -0800 Subject: [PATCH 2/7] Change "Mac O/S" to "macOS" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f91a0e382c..41c8629b0a 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Complete installation requirements can be found in the documentation under Date: Thu, 5 Dec 2019 10:48:30 +0800 Subject: [PATCH 3/7] Update model.template Wrong description of beforeSave and afterSave for model, since updating will not trigger these two hooks --- .../strapi-generate-model/templates/mongoose/model.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/strapi-generate-model/templates/mongoose/model.template b/packages/strapi-generate-model/templates/mongoose/model.template index 300dc5a200..30172b433f 100644 --- a/packages/strapi-generate-model/templates/mongoose/model.template +++ b/packages/strapi-generate-model/templates/mongoose/model.template @@ -6,11 +6,11 @@ module.exports = { // Before saving a value. - // Fired before an `insert` or `update` query. + // Fired before an `insert`. // beforeSave: async (model) => {}, // After saving a value. - // Fired after an `insert` or `update` query. + // Fired after an `insert`. // afterSave: async (model, result) => {}, // Before fetching all values. From d1356a2a505ff63de471c90ab63e1421ade72e1c Mon Sep 17 00:00:00 2001 From: Pouya Miralayi <53266765+pouyamiralayi@users.noreply.github.com> Date: Thu, 5 Dec 2019 16:47:15 +0330 Subject: [PATCH 4/7] Update upload.md --- docs/3.0.0-beta.x/plugins/upload.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/3.0.0-beta.x/plugins/upload.md b/docs/3.0.0-beta.x/plugins/upload.md index 090eb04c64..2cd257ee06 100644 --- a/docs/3.0.0-beta.x/plugins/upload.md +++ b/docs/3.0.0-beta.x/plugins/upload.md @@ -76,7 +76,7 @@ You have to send FormData in your request body ## Upload files related to an entry -To upload files that will be liked to an specific entry. +To upload files that will be linked to an specific entry. ### Request parameters From 959472231f8c0df68b44d46c1dd0040b08889623 Mon Sep 17 00:00:00 2001 From: Jim LAURIE Date: Fri, 6 Dec 2019 19:00:00 +0100 Subject: [PATCH 5/7] Add guide to create a draft system --- docs/.vuepress/config.js | 1 + docs/3.0.0-beta.x/guides/draft.md | 119 ++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 docs/3.0.0-beta.x/guides/draft.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index bf94fa8d9a..733f58b3a1 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -200,6 +200,7 @@ module.exports = { '/3.0.0-beta.x/guides/external-data', '/3.0.0-beta.x/guides/custom-data-response', '/3.0.0-beta.x/guides/custom-admin', + '/3.0.0-beta.x/guides/draft', '/3.0.0-beta.x/guides/slug', '/3.0.0-beta.x/guides/webhooks', ], diff --git a/docs/3.0.0-beta.x/guides/draft.md b/docs/3.0.0-beta.x/guides/draft.md new file mode 100644 index 0000000000..1030671045 --- /dev/null +++ b/docs/3.0.0-beta.x/guides/draft.md @@ -0,0 +1,119 @@ +# Draft system + +This guide will explain how to create draft system. That will you manage draft, published, archive status. + +## Introduction + +What we want here is to fetch only data that have a `published` status. + +But we don't want to use [parameters](../content-api/parameters.md) (eg. /articles?status=published) because you can easily fake the params. + +To be able to do that, you have first to understand some concepts. + +When you create a content type, it generates an API with the following list of [endpoints](../content-api/endpoint.md). + +Each of these endpoint triggers a controller action. Here is the list of [controller actions](../concepts/controller.md) that exist by default when a content type is created. + +If you check the controller file of your generated API `./api/{content-type}/controller/{Content-Type}.js`, you will see an empty file. It is because all the default logic is managed by Strapi. But you can override these actions with your own code. + +And that is what we will do to filter to `published` status by default. + +## Example + +In our example we will use an Article content type. By default when you fetch articles, you will got all articles. +Let's consider you don't want to expose articles that are in `draft` or `archive` status. + +To enforce this rule we will customize the action that fetchs all articles to just fetch `published` articles. + +To follow the example your will have to create a content type `articles` and add the following field definition: + +- `string` attribute named `title` +- `text` attribute named `content` +- `enumeration` attribute named `status` with `draft`, `published`, `archive` + +Then add some data with different `status`. + +## Override controller action + +To customize the function that fetch all our articles we will have to override the `find` function. + +First, to see the difference, let's request `GET /articles`. You will see all the data you created. +Now let's start the customization. + +**Path —** `./api/article/controller/Article.js` + +```js +module.exports = { + async find() { + return 'strapi'; + }, +}; +``` + +After saving the new function, let's restart the `GET /articles` request. We will see `strapi` as response. + +## Get the data back + +We now know the function we have to update, but we just want to customize the returned article values. + +In the [controller documentation](../concepts/controllers.html#extending-a-model-controller) you will find the default implementation of every actions. It will help you overwrite the fetch logic. + +**Path —** `./api/article/controller/Article.js` + +```js +const { sanitizeEntity } = require('strapi-utils'); + +module.exports = { + async find(ctx) { + let entities; + if (ctx.query._q) { + entities = await strapi.services.article.search(ctx.query); + } else { + entities = await strapi.services.article.find(ctx.query); + } + + return entities.map(entity => + sanitizeEntity(entity, { model: strapi.models.article }) + ); + }, +}; +``` + +And now the data is back on `GET /articles` + +## Apply our changes + +We can see the `find` function returns the result of the `map`. And the map function just sanitizes all entries. + +So instead of just return the sanitized entry, we will also remove the chef email of each restaurant. + +**Path —** `./api/restaurant/controller/Restaurant.js` + +```js +const { sanitizeEntity } = require('strapi-utils'); + +module.exports = { + async find(ctx) { + let entities; + + ctx.query.status = 'published'; + + if (ctx.query._q) { + entities = await strapi.services.article.search(ctx.query); + } else { + entities = await strapi.services.article.find(ctx.query); + } + + return entities.map(entity => + sanitizeEntity(entity, { model: strapi.models.article }) + ); + }, +}; +``` + +And tada! Draft and archived articles disapeared. + +::: tip +This guide can be applied to any other controller action. +::: + From 344f825778c4095c34ee1487811135c88c6e96d2 Mon Sep 17 00:00:00 2001 From: Jim LAURIE Date: Fri, 6 Dec 2019 19:05:15 +0100 Subject: [PATCH 6/7] Fix typo --- docs/3.0.0-beta.x/guides/draft.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/3.0.0-beta.x/guides/draft.md b/docs/3.0.0-beta.x/guides/draft.md index 1030671045..16d28802c2 100644 --- a/docs/3.0.0-beta.x/guides/draft.md +++ b/docs/3.0.0-beta.x/guides/draft.md @@ -83,9 +83,10 @@ And now the data is back on `GET /articles` ## Apply our changes -We can see the `find` function returns the result of the `map`. And the map function just sanitizes all entries. +Here we want force to fetch articles that have status equal to `published`. -So instead of just return the sanitized entry, we will also remove the chef email of each restaurant. +The way to do that is to set `ctx.query.status` to `published`. +It will force the filter of the query. **Path —** `./api/restaurant/controller/Restaurant.js` @@ -96,7 +97,10 @@ module.exports = { async find(ctx) { let entities; - ctx.query.status = 'published'; + ctx.query = { + ...ctx.query, + status: 'published + }; if (ctx.query._q) { entities = await strapi.services.article.search(ctx.query); From fcdbc4fbe3e7ea9167f0ca306317aec6594df8af Mon Sep 17 00:00:00 2001 From: Mathijs Nelemans Date: Sat, 7 Dec 2019 12:40:05 +0100 Subject: [PATCH 7/7] Wrap tsvector attributes with coalesce before join Fixed a bug where joining multiple tsvector attributes results in NULL because one of the columns contains NULL. The expected behaviour is to ignore that column instead, which is achieved by setting it to an empty string --- packages/strapi-hook-bookshelf/lib/queries.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/strapi-hook-bookshelf/lib/queries.js b/packages/strapi-hook-bookshelf/lib/queries.js index 1867648bdb..82e7dfefd6 100644 --- a/packages/strapi-hook-bookshelf/lib/queries.js +++ b/packages/strapi-hook-bookshelf/lib/queries.js @@ -546,8 +546,8 @@ const buildSearchQuery = (qb, model, params) => { case 'pg': { const searchQuery = searchText.map(attribute => _.toLower(attribute) === attribute - ? `to_tsvector(${attribute})` - : `to_tsvector("${attribute}")` + ? `to_tsvector(coalesce(${attribute}, ''))` + : `to_tsvector(coalesce("${attribute}", ''))` ); qb.orWhereRaw(`${searchQuery.join(' || ')} @@ plainto_tsquery(?)`, query);