strapi-plugin-comments 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,4 +7,5 @@ export { default as getRelatedGroups } from './getRelatedGroups';
7
7
  export { default as renderEntryTitle } from './renderEntryTitle';
8
8
  export { default as renderInitials } from './renderInitials';
9
9
  export { default as resolveCommentStatus } from './resolveCommentStatus';
10
- export { default as resolveCommentStatusColor } from './resolveCommentStatusColor';
10
+ export { default as resolveCommentStatusColor } from './resolveCommentStatusColor';
11
+ export { default as parseRegExp } from './parseRegExp';
@@ -0,0 +1,10 @@
1
+
2
+ const parseRegExp = (regexpString) => {
3
+ const [value, flags] = regexpString.split('/').filter(_ => _.length > 0);
4
+ return {
5
+ value,
6
+ flags,
7
+ };
8
+ }
9
+
10
+ export default parseRegExp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-comments",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "Strapi - Comments plugin",
5
5
  "strapi": {
6
6
  "name": "comments",
@@ -9,6 +9,7 @@
9
9
  "kind": "plugin"
10
10
  },
11
11
  "scripts": {
12
+ "prepare": "husky install",
12
13
  "publish": "npm publish --tag latest",
13
14
  "test:unit": "jest --verbose --coverage"
14
15
  },
@@ -26,14 +27,16 @@
26
27
  "jest": "^26.0.1",
27
28
  "jest-cli": "^26.0.1",
28
29
  "jest-styled-components": "^7.0.2",
29
- "koa": "2.13.3"
30
+ "koa": "2.13.3",
31
+ "husky": "7.0.4",
32
+ "prettier": "2.5.1"
30
33
  },
31
34
  "peerDependencies": {
32
35
  "@strapi/strapi": "4.x"
33
36
  },
34
37
  "author": {
35
- "name": "VirtusLab // Mateusz Ziarko",
36
- "email": "mziarko@virtuslab.com",
38
+ "name": "VirtusLab",
39
+ "email": "strapi@virtuslab.com",
37
40
  "url": "https://virtuslab.com"
38
41
  },
39
42
  "maintainers": [
@@ -1,8 +1,20 @@
1
1
  'use strict';
2
2
 
3
+ const { isEmpty } = require('lodash');
3
4
  const permissions = require('./../permissions');
5
+ const { getPluginService } = require('./utils/functions');
4
6
 
5
7
  module.exports = async ({ strapi }) => {
8
+
9
+ // Provide GQL support
10
+ if (strapi.plugin('graphql')) {
11
+ const config = await getPluginService('common').getConfig();
12
+ const { enabledCollections } = config;
13
+ if (!isEmpty(enabledCollections)) {
14
+ await require('./graphql')({ strapi, config });
15
+ }
16
+ }
17
+
6
18
  // Check if the plugin users-permissions is installed because the navigation needs it
7
19
  if (Object.keys(strapi.plugins).indexOf("users-permissions") === -1) {
8
20
  throw new Error(
@@ -35,6 +47,18 @@ module.exports = async ({ strapi }) => {
35
47
  uid: permissions.reports.action,
36
48
  pluginName: "comments",
37
49
  },
50
+ {
51
+ section: "plugins",
52
+ displayName: "Settings: Read",
53
+ uid: permissions.settings.read,
54
+ pluginName: "comments",
55
+ },
56
+ {
57
+ section: "plugins",
58
+ displayName: "Settings: Change",
59
+ uid: permissions.settings.change,
60
+ pluginName: "comments",
61
+ },
38
62
  ];
39
63
 
40
64
  await strapi.admin.services.permission.actionProvider.registerMany(actions);
@@ -2,6 +2,7 @@
2
2
 
3
3
  module.exports = {
4
4
  default: {
5
+ enabledCollections: [],
5
6
  moderatorRoles: [],
6
7
  approvalFlow: [],
7
8
  entryLabel: {
@@ -10,6 +10,39 @@ module.exports = {
10
10
  return getPluginService(name);
11
11
  },
12
12
 
13
+ async config(ctx) {
14
+ try {
15
+ return await this.getService().config();
16
+ } catch (e) {
17
+ throwError(ctx, e);
18
+ }
19
+ },
20
+
21
+ async settingsConfig(ctx) {
22
+ try {
23
+ return this.getService().config(true);
24
+ } catch (e) {
25
+ throwError(ctx, e);
26
+ }
27
+ },
28
+
29
+ async settingsUpdateConfig(ctx) {
30
+ try {
31
+ const { request: { body } } = ctx;
32
+ return this.getService().updateConfig(body);
33
+ } catch (e) {
34
+ throwError(ctx, e);
35
+ }
36
+ },
37
+
38
+ async settingsRestoreConfig(ctx) {
39
+ try {
40
+ return this.getService().restoreConfig();
41
+ } catch (e) {
42
+ throwError(ctx, e);
43
+ }
44
+ },
45
+
13
46
  async findAll(ctx) {
14
47
  return this.getService()
15
48
  .findAll(ctx.query);
@@ -101,14 +134,6 @@ module.exports = {
101
134
  }
102
135
  },
103
136
 
104
- async config(ctx) {
105
- try {
106
- return await this.getService().config();
107
- } catch (e) {
108
- throwError(ctx, e);
109
- }
110
- },
111
-
112
137
  getContentsTypes() {
113
138
  return Object.entries(strapi.contentTypes)
114
139
  .filter(([, contentType]) => (
@@ -6,17 +6,16 @@ const getMutations = require('./mutations');
6
6
  const getResolversConfig = require('./resolvers-config');
7
7
  const { getModelUid } = require('../services/utils/functions');
8
8
 
9
- module.exports = () => {
9
+ module.exports = async ({ strapi, config}) => {
10
10
  const extensionService = strapi.plugin('graphql').service('extension');
11
-
12
11
  extensionService.shadowCRUD(getModelUid('comment')).disable();
13
12
  extensionService.shadowCRUD(getModelUid('comment-report')).disable();
14
-
15
- extensionService.use(({ nexus }) => {
16
- const types = getTypes({ strapi, nexus });
17
- const queries = getQueries({ strapi, nexus });
18
- const mutations = getMutations({ strapi, nexus });
19
- const resolversConfig = getResolversConfig({ strapi });
13
+
14
+ extensionService.use(({ strapi, nexus }) => {
15
+ const types = getTypes({ strapi, nexus, config });
16
+ const queries = getQueries({ strapi, nexus, config });
17
+ const mutations = getMutations({ strapi, nexus, config });
18
+ const resolversConfig = getResolversConfig({ strapi, config });
20
19
 
21
20
  return {
22
21
  types: [types, queries, mutations],
@@ -1,9 +1,7 @@
1
1
  'use strict'
2
2
 
3
- const { getPluginService } = require("../utils/functions");
4
-
5
- module.exports = () => {
6
- const auth = getPluginService('common').getConfig('gql.auth', false);
3
+ module.exports = ({ config }) => {
4
+ const { gql: { auth = false } = {}} = config;
7
5
  return {
8
6
  'Query.findAllFlat': { auth },
9
7
  'Query.findAllInHierarchy': { auth },
@@ -1,10 +1,10 @@
1
- const { getPluginService } = require("../../utils/functions");
2
-
3
-
4
- module.exports = ({ nexus }) => nexus.enumType({
5
- name: "ReportReason",
6
- description: 'Reason of abuse report',
7
- members: {
8
- ...getPluginService('common').getConfig('reportReasons', {})
9
- },
10
- })
1
+ module.exports = ({ nexus, config }) => {
2
+ const { reportReasons } = config;
3
+ return nexus.enumType({
4
+ name: "ReportReason",
5
+ description: 'Reason of abuse report',
6
+ members: {
7
+ ...reportReasons
8
+ },
9
+ })
10
+ };
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
3
  module.exports = ({ strapi }) => {
4
- if (strapi.plugin('graphql')) {
5
- require('./graphql')({ strapi });
6
- }
4
+ // register phase
7
5
  };
@@ -89,4 +89,28 @@ module.exports = [
89
89
  policies: [],
90
90
  },
91
91
  },
92
+ {
93
+ method: 'GET',
94
+ path: '/settings/config',
95
+ handler: 'admin.settingsConfig',
96
+ config: {
97
+ policies: [],
98
+ },
99
+ },
100
+ {
101
+ method: 'PUT',
102
+ path: '/settings/config',
103
+ handler: 'admin.settingsUpdateConfig',
104
+ config: {
105
+ policies: [],
106
+ },
107
+ },
108
+ {
109
+ method: 'DELETE',
110
+ path: '/settings/config',
111
+ handler: 'admin.settingsRestoreConfig',
112
+ config: {
113
+ policies: [],
114
+ },
115
+ },
92
116
  ];
@@ -1,3 +1,4 @@
1
+ const { CONFIG_PARAMS } = require('../../utils/constants');
1
2
  const PluginError = require('../../utils/error');
2
3
  const { getPluginService } = require('../../utils/functions');
3
4
 
@@ -16,18 +17,48 @@ afterEach(() => {
16
17
  })
17
18
 
18
19
  describe('Test Comments service functions utils', () => {
20
+ describe('Get plugin store', () => {
21
+ beforeEach(() => setup());
19
22
 
20
- describe('Get plugin config', () => {
21
- beforeEach(() => setup({
22
- test: 'sample',
23
- }));
23
+ test('Should return store', async () => {
24
+ const pluginStore = await getPluginService('common').getPluginStore();
25
+ expect(pluginStore).toHaveProperty('get');
26
+ expect(pluginStore).toHaveProperty('set');
27
+ expect(pluginStore).toHaveProperty('delete');
28
+ });
29
+ });
24
30
 
25
- test('Should return config value', () => {
26
- expect(getPluginService('common').getConfig('test')).toEqual('sample');
31
+ describe('Get plugin config', () => {
32
+ describe('Local config', () => {
33
+ beforeEach(() => setup({
34
+ test: 'sample',
35
+ }));
36
+
37
+ test('Should return config value', async () => {
38
+ const result = await getPluginService('common').getConfig('test');
39
+ expect(result).toEqual('sample');
40
+ });
41
+
42
+ test('Should return default config prop value if not set', async () => {
43
+ const result = await getPluginService('common').getConfig('another', 'defaultValue');
44
+ expect(result).toEqual('defaultValue');
45
+ });
27
46
  });
28
47
 
29
- test('Should return default config prop value if not set', () => {
30
- expect(getPluginService('common').getConfig('another', 'defaultValue')).toEqual('defaultValue');
48
+ describe('Store config', () => {
49
+ beforeEach(() => setup({
50
+ test: 'sample',
51
+ }, true));
52
+
53
+ test('Should return config value', async () => {
54
+ const result = await getPluginService('common').getConfig('test');
55
+ expect(result).toEqual('sample');
56
+ });
57
+
58
+ test('Should return default config prop value if not set', async () => {
59
+ const result = await getPluginService('common').getConfig('another', 'defaultValue');
60
+ expect(result).toEqual('defaultValue');
61
+ });
31
62
  });
32
63
  });
33
64
 
@@ -131,12 +162,12 @@ describe('Test Comments service functions utils', () => {
131
162
 
132
163
  const text = 'Lorem ipsum dolor sit fuck amet';
133
164
 
134
- test('Should find bad words usage and throw error PluginError', () => {
165
+ test('Should find bad words usage and throw error PluginError', async () => {
135
166
  expect.assertions(7);
136
167
  try {
137
- getPluginService('common').checkBadWords(text);
168
+ await getPluginService('common').checkBadWords(text);
138
169
  } catch (e) {
139
- expect(getPluginService('common').getConfig('badWords')).toEqual(undefined);
170
+ expect(await getPluginService('common').getConfig('badWords')).toEqual(undefined);
140
171
  expect(e).toBeInstanceOf(PluginError);
141
172
  expect(e).toHaveProperty('status', 400);
142
173
  expect(e).toHaveProperty('name', 'Strapi:Plugin:Comments');
@@ -157,9 +188,59 @@ describe('Test Comments service functions utils', () => {
157
188
 
158
189
  const text = 'Lorem ipsum dolor sit fuck amet';
159
190
 
160
- test('Should skip bad words filtering because of configuration change', () => {
161
- expect(getPluginService('common').getConfig('badWords')).toEqual(false);
162
- expect(getPluginService('common').checkBadWords(text)).toEqual(text);
191
+ test('Should skip bad words filtering because of configuration change', async () => {
192
+ expect(await getPluginService('common').getConfig('badWords')).toEqual(false);
193
+ expect(await getPluginService('common').checkBadWords(text)).toEqual(text);
194
+ });
195
+ });
196
+
197
+ describe('Parse relation string (store config)', () => {
198
+ const [uid, id] = ['api::my-collection.my-content-type', '1'];
199
+ const validCollection = `${uid}:${id}`;
200
+
201
+ const [wrongUid, wrongId] = ['api::wrong.type', '2'];
202
+ const testCollection = `${wrongUid}:${wrongId}`;
203
+
204
+ describe('Store config', () => {
205
+ beforeEach(() => setup({ enabledCollections: [uid] }, true));
206
+
207
+ test('Should pass', async () => {
208
+ expect(await getPluginService('common').parseRelationString(validCollection));
209
+ expect(await getPluginService('common').getConfig(CONFIG_PARAMS.ENABLED_COLLECTIONS)).toContain(uid);
210
+ });
211
+
212
+ test('Should fail with 403', async () => {
213
+
214
+ try {
215
+ await getPluginService('common').parseRelationString(testCollection);
216
+ } catch(e) {
217
+ expect(await getPluginService('common').getConfig(CONFIG_PARAMS.ENABLED_COLLECTIONS)).toContain(uid);
218
+ expect(await getPluginService('common').getConfig(CONFIG_PARAMS.ENABLED_COLLECTIONS)).not.toContain(wrongUid);
219
+ expect(e).toBeInstanceOf(PluginError);
220
+ expect(e).toHaveProperty('status', 403);
221
+ }
222
+ });
223
+ });
224
+
225
+ describe('Local config', () => {
226
+ beforeEach(() => setup({ enabledCollections: [uid] }));
227
+
228
+ test('Should pass', async () => {
229
+ expect(await getPluginService('common').parseRelationString(validCollection));
230
+ expect(await getPluginService('common').getConfig(CONFIG_PARAMS.ENABLED_COLLECTIONS)).toContain(uid);
231
+ });
232
+
233
+ test('Should fail with 403', async () => {
234
+
235
+ try {
236
+ await getPluginService('common').parseRelationString(testCollection);
237
+ } catch(e) {
238
+ expect(await getPluginService('common').getConfig(CONFIG_PARAMS.ENABLED_COLLECTIONS)).toContain(uid);
239
+ expect(await getPluginService('common').getConfig(CONFIG_PARAMS.ENABLED_COLLECTIONS)).not.toContain(wrongUid);
240
+ expect(e).toBeInstanceOf(PluginError);
241
+ expect(e).toHaveProperty('status', 403);
242
+ }
243
+ });
163
244
  });
164
245
  });
165
246
  });
@@ -21,19 +21,73 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
21
21
  },
22
22
 
23
23
  // Config
24
- async config() {
25
- const entryLabel = this.getCommonService().getConfig('entryLabel');
26
- const approvalFlow = this.getCommonService().getConfig('approvalFlow');
27
- return {
28
- entryLabel,
29
- approvalFlow,
24
+ async config(viaSettingsPage = false) {
25
+ const pluginStore = await this.getCommonService().getPluginStore();
26
+ const config = await pluginStore.get({ key: 'config' });
27
+ const additionalConfiguration = {
30
28
  regex: Object.keys(REGEX).reduce((prev, curr) => ({
31
29
  ...prev,
32
30
  [curr]: REGEX[curr].toString(),
33
31
  }), {}),
34
32
  };
33
+
34
+ const isGQLPluginEnabled = !isNil(strapi.plugin('graphql'));
35
+
36
+ if (config) {
37
+ return {
38
+ ...config,
39
+ ...additionalConfiguration,
40
+ isGQLPluginEnabled: viaSettingsPage ? isGQLPluginEnabled : undefined,
41
+ };
42
+ }
43
+
44
+ const entryLabel = this.getCommonService().getLocalConfig('entryLabel');
45
+ const approvalFlow = this.getCommonService().getLocalConfig('approvalFlow');
46
+ const reportReasons = this.getCommonService().getLocalConfig('reportReasons');
47
+ const result = {
48
+ entryLabel,
49
+ approvalFlow,
50
+ reportReasons,
51
+ ...additionalConfiguration,
52
+ };
53
+
54
+ if (viaSettingsPage) {
55
+ const enabledCollections = this.getCommonService().getLocalConfig('enabledCollections');
56
+ const moderatorRoles = this.getCommonService().getLocalConfig('moderatorRoles');
57
+ return {
58
+ ...result,
59
+ enabledCollections,
60
+ moderatorRoles,
61
+ isGQLPluginEnabled,
62
+ };
63
+ }
64
+
65
+ return result;
35
66
  },
36
67
 
68
+ async updateConfig(body) {
69
+ const pluginStore = await this.getCommonService().getPluginStore();
70
+
71
+ await pluginStore.set({ key: 'config', value: body });
72
+
73
+ return this.config();
74
+ },
75
+
76
+ async restoreConfig() {
77
+ const pluginStore = await this.getCommonService().getPluginStore();
78
+ const defaultConfig = this.getCommonService().getLocalConfig();
79
+
80
+ await pluginStore.delete({key: 'config'})
81
+ await pluginStore.set({
82
+ key: 'config',
83
+ value: {
84
+ ...defaultConfig,
85
+ }
86
+ });
87
+
88
+ return this.config();
89
+ },
90
+
37
91
  // Find all comments
38
92
  async findAll({ related, entity, ...query }) {
39
93
  const { _q, orderBy, pageSize = 10, page = 1, filters, ...rest } = parseParams(query);
@@ -10,7 +10,7 @@ const {
10
10
  getRelatedGroups,
11
11
  resolveUserContextError,
12
12
  } = require('./utils/functions');
13
- const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
13
+ const { APPROVAL_STATUS, REGEX, CONFIG_PARAMS } = require('./../utils/constants')
14
14
 
15
15
  /**
16
16
  * Comments Plugin - Client services
@@ -31,16 +31,14 @@ module.exports = ({ strapi }) => ({
31
31
  throw new PluginError(400, `Field "related" got incorrect format, use format like "api::<collection name>.<content type name>:<entity id>"`);
32
32
  }
33
33
 
34
- const [ uid, relatedStringId ] = getRelatedGroups(relation);
35
- const parsedRelatedId = parseInt(relatedStringId);
36
- const relatedId = isNumber(parsedRelatedId) ? parsedRelatedId : relatedStringId;
34
+ const [ uid, relatedId ] = await this.getCommonService().parseRelationString(relation);
37
35
 
38
36
  const relatedEntity = await strapi.db.query(uid).findOne(relatedId);
39
37
  if (!relatedEntity) {
40
38
  throw new PluginError(400, `Relation for field "related" does not exist. Check your payload please.`);
41
39
  }
42
40
 
43
- const isApprovalFlowEnabled = this.getCommonService().getConfig('approvalFlow', []).includes(uid) ||
41
+ const isApprovalFlowEnabled = await this.getCommonService().getConfig(CONFIG_PARAMS.APPROVAL_FLOW, []).includes(uid) ||
44
42
  relatedEntity.requireCommentsApproval;
45
43
 
46
44
  const linkToThread = !isNil(threadOf) ? await this.getCommonService().findOne({
@@ -57,7 +55,7 @@ module.exports = ({ strapi }) => ({
57
55
  throw resolveUserContextError(user);
58
56
  }
59
57
 
60
- if (this.getCommonService().checkBadWords(content) && singleRelationFulfilled) {
58
+ if (await this.getCommonService().checkBadWords(content) && singleRelationFulfilled) {
61
59
  const { author = {}, ...rest } = data;
62
60
  let authorData = {};
63
61
  if (validContext && user) {
@@ -115,6 +113,8 @@ module.exports = ({ strapi }) => ({
115
113
  throw new PluginError(400, `Request property "relation" got incorrect format, use format like "api::<collection name>.<content type name>:<entity id>"`);
116
114
  }
117
115
 
116
+ await this.getCommonService().parseRelationString(relation);
117
+
118
118
  const existingEntity = await this.getCommonService().findOne({
119
119
  id,
120
120
  related: relation,
@@ -127,7 +127,7 @@ module.exports = ({ strapi }) => ({
127
127
  }
128
128
 
129
129
  if (isEqualEntity(existingEntity, data, user) && content) {
130
- if (this.getCommonService().checkBadWords(content)) {
130
+ if (await this.getCommonService().checkBadWords(content)) {
131
131
  const entity = await strapi.db.query(getModelUid('comment')).update({
132
132
  where: { id },
133
133
  data: { content },
@@ -144,6 +144,9 @@ module.exports = ({ strapi }) => ({
144
144
  if (!this.getCommonService().isValidUserContext(user)) {
145
145
  throw resolveUserContextError(user);
146
146
  }
147
+
148
+ await this.getCommonService().parseRelationString(relation);
149
+
147
150
  const reportAgainstEntity = await this.getCommonService().findOne({
148
151
  id,
149
152
  related: relation,
@@ -185,6 +188,8 @@ module.exports = ({ strapi }) => ({
185
188
  throw new PluginError(403, `You're not allowed to take an action on that entity. Make sure that you've provided proper "authorId" or authenticated your request properly.`);
186
189
  }
187
190
 
191
+ await this.getCommonService().parseRelationString(relation);
192
+
188
193
  let entity;
189
194
  try {
190
195
  const byAuthor = user?.id ? {
@@ -216,7 +221,7 @@ module.exports = ({ strapi }) => ({
216
221
  },
217
222
 
218
223
  async sendAbuseReportEmail(reason, content) {
219
- const rolesToBeNotified = this.getCommonService().getConfig('moderatorRoles') || ['strapi-super-admin'];
224
+ const rolesToBeNotified = await this.getCommonService().getConfig(CONFIG_PARAMS.MODERATOR_ROLES) || ['strapi-super-admin'];
220
225
 
221
226
  const adminUserModel = strapi.db.query('admin::user');
222
227
  const emails = await adminUserModel.findMany({
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const BadWordsFilter = require('bad-words');
4
- const { isArray, isNumber, isObject, isNil, isString, first, parseInt, set } = require('lodash');
5
- const { REGEX } = require('../utils/constants');
4
+ const { isArray, isNumber, isObject, isNil, isString, first, parseInt, set, get } = require('lodash');
5
+ const { REGEX, CONFIG_PARAMS } = require('../utils/constants');
6
6
  const PluginError = require('./../utils/error');
7
7
  const {
8
8
  getModelUid,
@@ -10,6 +10,7 @@ const {
10
10
  buildNestedStructure,
11
11
  filterOurResolvedReports,
12
12
  buildAuthorModel,
13
+ buildConfigQueryProp,
13
14
  } = require('./utils/functions');
14
15
 
15
16
  /**
@@ -18,11 +19,26 @@ const {
18
19
 
19
20
  module.exports = ({ strapi }) => ({
20
21
 
21
- getConfig(prop, defaultValue) {
22
- let queryProp = prop;
23
- if (prop && isArray(prop)) {
24
- queryProp = prop.join('.');
22
+ async getConfig(prop, defaultValue, useLocal = false) {
23
+ const queryProp = buildConfigQueryProp(prop);
24
+ const pluginStore = await this.getPluginStore();
25
+ const config = await pluginStore.get({ key: 'config' });
26
+
27
+ let result;
28
+ if (config && !useLocal) {
29
+ result = queryProp ? get(config, queryProp) : config;;
30
+ } else {
31
+ result = this.getLocalConfig(queryProp, defaultValue);
25
32
  }
33
+ return isNil(result) ? defaultValue : result;
34
+ },
35
+
36
+ async getPluginStore() {
37
+ return strapi.store({ type: 'plugin', name: 'comments' });
38
+ },
39
+
40
+ getLocalConfig(prop, defaultValue) {
41
+ const queryProp = buildConfigQueryProp(prop);
26
42
  const result = strapi.config.get(`plugin.comments${ queryProp ? '.' + queryProp : ''}`);
27
43
  return isNil(result) ? defaultValue : result;
28
44
  },
@@ -124,7 +140,7 @@ module.exports = ({ strapi }) => ({
124
140
  },
125
141
  });
126
142
  if (!entity){
127
- throw new PluginError(404, 'Not found');
143
+ throw new PluginError(404, 'Comment does not exist. Check your payload please.');
128
144
  }
129
145
  return filterOurResolvedReports(this.sanitizeCommentEntity(entity));
130
146
  },
@@ -202,8 +218,20 @@ module.exports = ({ strapi }) => ({
202
218
  return user ? !isNil(user?.id) : true;
203
219
  },
204
220
 
205
- checkBadWords(content) {
206
- const config = this.getConfig('badWords', true);
221
+ async parseRelationString(relation) {
222
+ const [ uid, relatedStringId ] = getRelatedGroups(relation);
223
+ const parsedRelatedId = parseInt(relatedStringId);
224
+ const relatedId = isNumber(parsedRelatedId) ? parsedRelatedId : relatedStringId;
225
+
226
+ const enabledCollections = await this.getConfig(CONFIG_PARAMS.ENABLED_COLLECTIONS, []);
227
+ if (!enabledCollections.includes(uid)) {
228
+ throw new PluginError(403, `Action not allowed for collection '${uid}'. Use one of: ${ enabledCollections.join(', ') }`);
229
+ }
230
+ return [ uid, relatedId];
231
+ },
232
+
233
+ async checkBadWords(content) {
234
+ const config = await this.getConfig(CONFIG_PARAMS.BAD_WORDS, true);
207
235
  if (config) {
208
236
  const filter = new BadWordsFilter(isObject(config) ? config : undefined);
209
237
  if (content && filter.isProfane(content)) {
@@ -1,5 +1,5 @@
1
1
  const PluginError = require('../../../utils/error');
2
- const { resolveUserContextError, getModelUid } = require('../functions');
2
+ const { resolveUserContextError, getModelUid, buildConfigQueryProp } = require('../functions');
3
3
 
4
4
  beforeEach(() => {
5
5
  Object.defineProperty(global, 'strapi', {
@@ -39,4 +39,15 @@ describe('Test service functions utils', () => {
39
39
  }
40
40
  });
41
41
  });
42
+
43
+ describe('Building config query props', () => {
44
+ test('Should return prop as is', () => {
45
+ expect(buildConfigQueryProp('my.sample.prop')).toBe('my.sample.prop');
46
+ });
47
+
48
+ test('Should build query prop with \'.\'', () => {
49
+ expect(buildConfigQueryProp(['my', 'sample', 'prop'])).toBe('my.sample.prop');
50
+ });
51
+ });
52
+
42
53
  });