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.
- package/.husky/pre-commit +4 -0
- package/README.md +14 -1
- package/__mocks__/initSetup.js +31 -2
- package/admin/src/hooks/useConfig.js +43 -0
- package/admin/src/index.js +31 -2
- package/admin/src/pages/Details/index.js +5 -2
- package/admin/src/pages/Settings/index.js +342 -0
- package/admin/src/pages/Settings/utils/api.js +50 -0
- package/admin/src/permissions.js +3 -0
- package/admin/src/translations/en.json +37 -1
- package/admin/src/utils/index.js +2 -1
- package/admin/src/utils/parseRegExp.js +10 -0
- package/package.json +7 -4
- package/server/bootstrap.js +24 -0
- package/server/config/index.js +1 -0
- package/server/controllers/admin.js +33 -8
- package/server/graphql/index.js +7 -8
- package/server/graphql/resolvers-config.js +2 -4
- package/server/graphql/types/report-reason.js +10 -10
- package/server/register.js +1 -3
- package/server/routes/admin.js +24 -0
- package/server/services/__tests__/common.test.js +95 -14
- package/server/services/admin.js +60 -6
- package/server/services/client.js +13 -8
- package/server/services/common.js +37 -9
- package/server/services/utils/__tests__/functions.test.js +12 -1
- package/server/services/utils/functions.js +9 -1
- package/server/utils/constants.js +9 -0
- package/strapi-server.js +12 -5
package/admin/src/utils/index.js
CHANGED
|
@@ -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';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-comments",
|
|
3
|
-
"version": "2.0.
|
|
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
|
|
36
|
-
"email": "
|
|
38
|
+
"name": "VirtusLab",
|
|
39
|
+
"email": "strapi@virtuslab.com",
|
|
37
40
|
"url": "https://virtuslab.com"
|
|
38
41
|
},
|
|
39
42
|
"maintainers": [
|
package/server/bootstrap.js
CHANGED
|
@@ -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);
|
package/server/config/index.js
CHANGED
|
@@ -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]) => (
|
package/server/graphql/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
+
};
|
package/server/register.js
CHANGED
package/server/routes/admin.js
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
30
|
-
|
|
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
|
});
|
package/server/services/admin.js
CHANGED
|
@@ -21,19 +21,73 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
21
21
|
},
|
|
22
22
|
|
|
23
23
|
// Config
|
|
24
|
-
async config() {
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
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,
|
|
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(
|
|
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(
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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, '
|
|
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
|
-
|
|
206
|
-
const
|
|
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
|
});
|