strapi-plugin-comments 2.2.4 → 2.2.5

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.
Files changed (30) hide show
  1. package/README.md +3 -1
  2. package/admin/src/components/AdminAvatar/index.js +2 -2
  3. package/admin/src/components/AdminAvatar/styles.js +10 -2
  4. package/admin/src/components/Avatar/index.js +3 -6
  5. package/admin/src/components/DiscussionThreadItem/index.js +29 -2
  6. package/admin/src/components/DiscussionThreadItem/styles.d.ts +1 -0
  7. package/admin/src/components/DiscussionThreadItem/styles.js +14 -1
  8. package/admin/src/components/DiscussionThreadItemActions/index.js +13 -7
  9. package/admin/src/components/DiscussionThreadItemFooter/index.d.ts +2 -1
  10. package/admin/src/components/DiscussionThreadItemFooter/index.js +2 -2
  11. package/admin/src/components/ModeratorResponse/index.js +2 -1
  12. package/admin/src/components/PreviewWysiwyg/utils/satinizeHtml.d.ts +1 -1
  13. package/admin/src/components/PreviewWysiwyg/utils/satinizeHtml.js +2 -2
  14. package/admin/src/components/Wysiwyg/Editor.js +2 -1
  15. package/admin/src/components/Wysiwyg/WysiwygNav.js +1 -23
  16. package/admin/src/components/Wysiwyg/WysiwygStyles.js +1 -1
  17. package/admin/src/pages/Details/index.js +4 -3
  18. package/admin/src/pages/Discover/components/DiscoverTableRow/index.js +31 -2
  19. package/admin/src/pages/Settings/index.js +6 -2
  20. package/admin/src/translations/en.json +3 -1
  21. package/package.json +3 -3
  22. package/server/config/index.js +1 -0
  23. package/server/services/admin.js +12 -10
  24. package/server/services/client.js +6 -3
  25. package/server/services/common.js +11 -8
  26. package/server/services/utils/functions.d.ts +1 -1
  27. package/server/services/utils/functions.js +4 -2
  28. package/server/utils/constants.js +1 -0
  29. package/strapi-server.d.ts +1 -0
  30. package/tsconfig.tsbuildinfo +1 -1
package/README.md CHANGED
@@ -134,7 +134,7 @@ In our minimum support we're following [official Node.js releases timelines](htt
134
134
 
135
135
  **Supported Strapi versions**:
136
136
 
137
- - Strapi v4.5.5 (recently tested)
137
+ - Strapi v4.6.0 (recently tested)
138
138
  - Strapi v4.x
139
139
 
140
140
  > This plugin is designed for **Strapi v4** and is not working with v3.x. To get version for **Strapi v3** install version [v1.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments/tree/strapi-v3).
@@ -176,6 +176,7 @@ module.exports = ({ env }) => ({
176
176
  "*": ["Title", "title", "Name", "name", "Subject", "subject"],
177
177
  "api::page.page": ["MyField"],
178
178
  },
179
+ blockedAuthorProps: ["name", "email"],
179
180
  reportReasons: {
180
181
  MY_CUSTOM_REASON: "MY_CUSTOM_REASON",
181
182
  },
@@ -197,6 +198,7 @@ module.exports = ({ env }) => ({
197
198
  - `entryLabel` - ordered list of property names per Content Type to generate related entity label. Keys must be in format like `'api::<collection name>.<content type name>'`. Default formatting set as `*`.
198
199
  - `reportReasons` - set of enums you would like to use for issuing abuse reports. Provided by default `'BAD_LANGUAGE'`, `'DISCRIMINATION'` and `'OTHER'`.
199
200
  - `gql` - specific configuration for GraphQL. See [Additional GQL Configuration](#additional-gql-configuration)
201
+ - `blockedAuthorProps` - list of author's entity properties removed from a response for client side
200
202
 
201
203
  ## Additional GQL Configuration
202
204
 
@@ -9,9 +9,9 @@ const icons_1 = require("@strapi/icons");
9
9
  const Icon_1 = require("@strapi/design-system/Icon");
10
10
  const AdminAvatar = ({ children }) => {
11
11
  return (react_1.default.createElement(styles_1.AdminAvatarWrapper, null,
12
+ children,
12
13
  react_1.default.createElement(styles_1.AdminShield, null,
13
- react_1.default.createElement(Icon_1.Icon, { as: icons_1.Shield, color: "neutral800" })),
14
- children));
14
+ react_1.default.createElement(Icon_1.Icon, { as: icons_1.Shield, color: "neutral800" }))));
15
15
  };
16
16
  exports.default = AdminAvatar;
17
17
  //# sourceMappingURL=index.js.map
@@ -10,8 +10,16 @@ exports.AdminAvatarWrapper = (0, styled_components_1.default)(Box_1.Box) `
10
10
  position: relative;
11
11
  `;
12
12
  exports.AdminShield = (0, styled_components_1.default)(Box_1.Box) `
13
+ display: flex;
14
+ align-items: middle;
15
+
13
16
  position: absolute;
14
- right: -30%;
15
- top: -30%;
17
+ right: -35%;
18
+ top: -35%;
19
+
20
+ border-radius: 50%;
21
+ border: 2px #ffffff solid;
22
+
23
+ background: #ffffff;
16
24
  `;
17
25
  //# sourceMappingURL=styles.js.map
@@ -8,18 +8,15 @@ const lodash_1 = require("lodash");
8
8
  const Avatar_1 = require("@strapi/design-system/Avatar");
9
9
  const utils_1 = require("../../utils");
10
10
  const AdminAvatar_1 = __importDefault(require("../AdminAvatar"));
11
- ;
12
- const UserAvatar = ({ avatar, name, isAdminComment = false }) => {
11
+ const UserAvatar = ({ avatar, name, isAdminComment = false, }) => {
13
12
  if (avatar) {
14
13
  let image = avatar;
15
14
  if ((0, lodash_1.isObject)(avatar)) {
16
15
  image = avatar?.formats?.thumbnail.url || avatar.url;
17
16
  }
18
- return (isAdminComment ? react_1.default.createElement(AdminAvatar_1.default, null, image && (react_1.default.createElement(Avatar_1.Avatar, { src: image, alt: name })))
19
- : image && (react_1.default.createElement(Avatar_1.Avatar, { src: image, alt: name })));
17
+ return isAdminComment ? (react_1.default.createElement(AdminAvatar_1.default, null, image ? react_1.default.createElement(Avatar_1.Avatar, { src: image, alt: name }) : null)) : image ? (react_1.default.createElement(Avatar_1.Avatar, { src: image, alt: name })) : null;
20
18
  }
21
- return (isAdminComment ? react_1.default.createElement(AdminAvatar_1.default, null, name && (react_1.default.createElement(Avatar_1.Initials, null, (0, utils_1.renderInitials)(name))))
22
- : name && (react_1.default.createElement(Avatar_1.Initials, null, (0, utils_1.renderInitials)(name))));
19
+ return isAdminComment ? (react_1.default.createElement(AdminAvatar_1.default, null, name ? react_1.default.createElement(Avatar_1.Initials, null, (0, utils_1.renderInitials)(name)) : null)) : name ? (react_1.default.createElement(Avatar_1.Initials, null, (0, utils_1.renderInitials)(name))) : null;
23
20
  };
24
21
  exports.default = UserAvatar;
25
22
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -6,17 +29,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
29
  const Box_1 = require("@strapi/design-system/Box");
7
30
  const Flex_1 = require("@strapi/design-system/Flex");
8
31
  const Typography_1 = require("@strapi/design-system/Typography");
9
- const react_1 = __importDefault(require("react"));
32
+ const react_1 = __importStar(require("react"));
10
33
  const DiscussionThreadItemActions_1 = __importDefault(require("../DiscussionThreadItemActions"));
11
34
  const DiscussionThreadItemFooter_1 = __importDefault(require("../DiscussionThreadItemFooter"));
12
35
  const styles_1 = require("./styles");
36
+ const satinizeHtml_1 = __importDefault(require("./../PreviewWysiwyg/utils/satinizeHtml"));
37
+ const mdRenderer_1 = __importDefault(require("./../PreviewWysiwyg/utils/mdRenderer"));
13
38
  const DiscussionThreadItem = (props) => {
14
39
  const { as = "li", authorAvatar, authorName, content, isSelected, pinned, preview, root, } = props;
40
+ const sanitizedContent = (0, react_1.useMemo)(() => (0, satinizeHtml_1.default)(mdRenderer_1.default.render(content || '')), [content]);
15
41
  return (react_1.default.createElement(styles_1.DiscussionThreadFullsize, { as: as, marginBottom: preview ? 4 : 0 },
16
42
  react_1.default.createElement(styles_1.DiscussionThreadItemContainer, { as: Flex_1.Flex, direction: "column", alignItems: "flex-start", hasRadius: true, background: isSelected ? "neutral100" : null, paddingLeft: 2, paddingRight: 2, paddingTop: 4, paddingBottom: 4 },
17
43
  react_1.default.createElement(styles_1.DiscussionThreadItemContent, { as: Flex_1.Flex, paddingBottom: 2, direction: "row" },
18
44
  react_1.default.createElement(Box_1.Box, { as: Flex_1.Flex, grow: 1, alignItems: "center", marginTop: "6px" },
19
- react_1.default.createElement(Typography_1.Typography, { variant: "omega", textColor: "neutral800" }, content)),
45
+ react_1.default.createElement(Typography_1.Typography, { variant: "omega", textColor: "neutral800" },
46
+ react_1.default.createElement(styles_1.DiscussionThreadItemContentTypographyRenderer, { dangerouslySetInnerHTML: { __html: sanitizedContent } }))),
20
47
  !preview && (react_1.default.createElement(DiscussionThreadItemActions_1.default, { ...props, root: root || pinned, preview: preview }))),
21
48
  react_1.default.createElement(DiscussionThreadItemFooter_1.default, { ...props }))));
22
49
  };
@@ -1,4 +1,5 @@
1
1
  export declare const DiscussionThreadFullsize: import("styled-components").StyledComponent<any, any, object, string | number | symbol>;
2
2
  export declare const DiscussionThreadItemContent: import("styled-components").StyledComponent<any, any, object, string | number | symbol>;
3
3
  export declare const DiscussionThreadItemContainer: import("styled-components").StyledComponent<any, any, object, string | number | symbol>;
4
+ export declare const DiscussionThreadItemContentTypographyRenderer: import("styled-components").StyledComponent<"div", any, {}, never>;
4
5
  //# sourceMappingURL=styles.d.ts.map
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DiscussionThreadItemContainer = exports.DiscussionThreadItemContent = exports.DiscussionThreadFullsize = void 0;
6
+ exports.DiscussionThreadItemContentTypographyRenderer = exports.DiscussionThreadItemContainer = exports.DiscussionThreadItemContent = exports.DiscussionThreadFullsize = void 0;
7
7
  const styled_components_1 = __importDefault(require("styled-components"));
8
8
  const Box_1 = require("@strapi/design-system/Box");
9
9
  exports.DiscussionThreadFullsize = (0, styled_components_1.default)(Box_1.Box) `
@@ -15,4 +15,17 @@ exports.DiscussionThreadItemContent = (0, styled_components_1.default)(exports.D
15
15
  exports.DiscussionThreadItemContainer = (0, styled_components_1.default)(exports.DiscussionThreadFullsize) `
16
16
  align-items: flex-start;
17
17
  `;
18
+ exports.DiscussionThreadItemContentTypographyRenderer = styled_components_1.default.div `
19
+ strong {
20
+ font-weight: bold;
21
+ }
22
+
23
+ i, em {
24
+ font-style: italic;
25
+ }
26
+
27
+ u {
28
+ font-style: underline;
29
+ }
30
+ `;
18
31
  //# sourceMappingURL=styles.js.map
@@ -48,7 +48,7 @@ const styles_3 = require("../ActionButton/styles");
48
48
  const DiscussionThreadItemReviewAction_1 = __importDefault(require("../DiscussionThreadItemReviewAction"));
49
49
  const ModeratorResponseModal_1 = __importDefault(require("../ModeratorResponseModal/ModeratorResponseModal"));
50
50
  const DiscussionThreadItemActions = ({ allowedActions: { canModerate, canAccessReports, canReviewReports }, ...item }) => {
51
- const { id, blocked, removed, content, blockedThread, gotThread, threadFirstItemId, pinned, preview, reports = [], approvalStatus, author } = item;
51
+ const { id, blocked, removed, content, blockedThread, gotThread, threadFirstItemId, pinned, preview, reports = [], approvalStatus, author, isAdminComment, } = item;
52
52
  const user = helper_plugin_1.auth.get('userInfo');
53
53
  const [blockConfirmationVisible, setBlockConfirmationVisible] = (0, react_1.useState)(false);
54
54
  const [blockThreadConfirmationVisible, setBlockThreadConfirmationVisible] = (0, react_1.useState)(false);
@@ -85,8 +85,9 @@ const DiscussionThreadItemActions = ({ allowedActions: { canModerate, canAccessR
85
85
  const blockItemThreadMutation = (0, react_query_1.useMutation)(api_1.blockItemThread, mutationConfig("page.details.actions.thread.block.confirmation.success", setBlockThreadConfirmationVisible));
86
86
  const unblockItemThreadMutation = (0, react_query_1.useMutation)(api_1.unblockItemThread, mutationConfig("page.details.actions.thread.unblock.confirmation.success"));
87
87
  const deleteItemMutation = (0, react_query_1.useMutation)(api_1.deleteItem, mutationConfig("page.details.actions.comment.delete.confirmation.success"));
88
+ const isAdminAuthor = String(user?.id) === author?.id;
88
89
  const gotApprovalFlow = !(0, lodash_1.isNil)(approvalStatus);
89
- const needsApproval = gotApprovalFlow && approvalStatus === "PENDING";
90
+ const needsApproval = !isAdminComment && gotApprovalFlow && approvalStatus === "PENDING";
90
91
  const isBlocked = blocked || blockedThread;
91
92
  const isRejected = gotApprovalFlow && approvalStatus === "REJECTED";
92
93
  const openReports = reports?.filter((_) => !_.resolved);
@@ -94,7 +95,6 @@ const DiscussionThreadItemActions = ({ allowedActions: { canModerate, canAccessR
94
95
  const reviewFlowEnabled = (canAccessReports || canReviewReports) && hasReports;
95
96
  const hasActiveThread = gotThread && !(removed || preview || pinned || blockedThread);
96
97
  const isStatusBadgeVisible = isBlocked || reviewFlowEnabled;
97
- const isAdminAuthor = String(user.id) === author.id;
98
98
  const renderStatus = (props) => {
99
99
  const status = (0, utils_1.resolveCommentStatus)({ ...props, reviewFlowEnabled });
100
100
  const color = (0, utils_1.resolveCommentStatusColor)(status);
@@ -172,17 +172,22 @@ const DiscussionThreadItemActions = ({ allowedActions: { canModerate, canAccessR
172
172
  if (removed || isRejected || !canModerate) {
173
173
  return (react_1.default.createElement(styles_1.DiscussionThreadItemActionsWrapper, { as: Flex_1.Flex, direction: "row" }, renderStatus(item)));
174
174
  }
175
+ const isBlockEnabled = !blockedThread && !(blocked || needsApproval);
176
+ const isUnblockEnabled = !blockedThread && blocked;
177
+ const isRemovable = !blockedThread && !blocked && isAdminAuthor;
178
+ const isThreadStartEnabled = !hasActiveThread && !pinned && (!blockedThread && !blocked);
175
179
  return (react_1.default.createElement(react_1.default.Fragment, null,
176
180
  react_1.default.createElement(styles_1.DiscussionThreadItemActionsWrapper, { as: Flex_1.Flex, direction: "row" },
177
181
  isStatusBadgeVisible && renderStatus(item),
178
182
  !blockedThread && (gotThread || pinned) && (react_1.default.createElement(styles_3.ActionButton, { onClick: handleBlockThreadClick, startIcon: icons_2.lock, loading: blockItemThreadMutation.isLoading, variant: "danger" }, (0, utils_1.getMessage)("page.details.actions.thread.block", "Block thread"))),
179
183
  blockedThread && (gotThread || pinned) && (react_1.default.createElement(styles_3.ActionButton, { onClick: handleUnblockThreadClick, startIcon: icons_2.unlock, loading: unblockItemThreadMutation.isLoading, variant: "success" }, (0, utils_1.getMessage)("page.details.actions.thread.unblock", "Unblock thread"))),
180
184
  anyGroupButtonsVisible && (react_1.default.createElement(styles_2.IconButtonGroupStyled, { isSingle: true, withMargin: true },
181
- !blockedThread && !(blocked || needsApproval) && (react_1.default.createElement(IconButton_1.IconButton, { onClick: handleBlockClick, loading: blockItemMutation.isLoading, icon: icons_2.lock, label: (0, utils_1.getMessage)("page.details.actions.comment.block", "Block") })),
182
- !blockedThread && blocked && (react_1.default.createElement(IconButton_1.IconButton, { onClick: handleUnblockClick, loading: unblockItemMutation.isLoading, icon: icons_2.unlock, label: (0, utils_1.getMessage)("page.details.actions.comment.unblock", "Unblock") })),
185
+ !isAdminComment && (react_1.default.createElement(react_1.default.Fragment, null,
186
+ isBlockEnabled && (react_1.default.createElement(IconButton_1.IconButton, { onClick: handleBlockClick, loading: blockItemMutation.isLoading, icon: icons_2.lock, label: (0, utils_1.getMessage)("page.details.actions.comment.block", "Block") })),
187
+ isUnblockEnabled && (react_1.default.createElement(IconButton_1.IconButton, { onClick: handleUnblockClick, loading: unblockItemMutation.isLoading, icon: icons_2.unlock, label: (0, utils_1.getMessage)("page.details.actions.comment.unblock", "Unblock") })))),
183
188
  needsApproval && (react_1.default.createElement(DiscussionThreadItemApprovalFlowActions_1.default, { id: id, allowedActions: { canModerate }, queryToInvalidate: "get-details-data" })),
184
- !blockedThread && !blocked && isAdminAuthor && (react_1.default.createElement(IconButton_1.IconButton, { onClick: handleDeleteClick, loading: deleteItemMutation.isLoading, icon: icons_1.trash, label: (0, utils_1.getMessage)("page.details.actions.comment.delete", "Delete comment") })),
185
189
  isAdminAuthor && !isBlocked && (react_1.default.createElement(IconButton_1.IconButton, { onClick: toggleUpdateCommentVisibility, icon: icons_1.pencil, label: (0, utils_1.getMessage)("page.details.actions.thread.modal.update.comment") })),
190
+ isRemovable && (react_1.default.createElement(IconButton_1.IconButton, { onClick: handleDeleteClick, loading: deleteItemMutation.isLoading, icon: icons_1.trash, label: (0, utils_1.getMessage)("page.details.actions.comment.delete", "Delete comment") })),
186
191
  react_1.default.createElement(DiscussionThreadItemReviewAction_1.default, { item: item, queryToInvalidate: "get-details-data", allowedActions: {
187
192
  canModerate,
188
193
  canAccessReports,
@@ -192,7 +197,8 @@ const DiscussionThreadItemActions = ({ allowedActions: { canModerate, canAccessR
192
197
  react_1.default.createElement(IconButton_1.IconButton, { onClick: handleDrilldownClick, icon: icons_2.eye, label: (0, utils_1.getMessage)("page.details.panel.discussion.nav.drilldown", "Drilldown thread"), style: blocked && !blockedThread
193
198
  ? { marginTop: "1px", marginRight: ".5rem" }
194
199
  : {} }))),
195
- react_1.default.createElement(styles_2.IconButtonGroupStyled, null, !hasActiveThread && !pinned && (!blockedThread && !blocked) && (react_1.default.createElement(IconButton_1.IconButton, { onClick: toggleStartThreadVisibility, icon: icons_1.plus, label: (0, utils_1.getMessage)("page.details.actions.thread.modal.start.thread") })))),
200
+ isThreadStartEnabled && (react_1.default.createElement(styles_2.IconButtonGroupStyled, { isSingle: true, withMargin: true },
201
+ react_1.default.createElement(IconButton_1.IconButton, { onClick: toggleStartThreadVisibility, icon: icons_1.plus, label: (0, utils_1.getMessage)("page.details.actions.thread.modal.start.thread") })))),
196
202
  startThreadVisible &&
197
203
  react_1.default.createElement(ModeratorResponseModal_1.default, { content: "", id: id, title: (0, utils_1.getMessage)("page.details.actions.thread.modal.start.thread"), onClose: toggleStartThreadVisibility }),
198
204
  updateCommentVisible &&
@@ -1,8 +1,9 @@
1
1
  /// <reference types="react" />
2
2
  import PropTypes from "prop-types";
3
3
  declare const DiscussionThreadItemFooter: {
4
- ({ author, children, createdAt, updatedAt, }: {
4
+ ({ author, isAdminComment, children, createdAt, updatedAt, }: {
5
5
  author: any;
6
+ isAdminComment: any;
6
7
  children: any;
7
8
  createdAt: any;
8
9
  updatedAt: any;
@@ -11,7 +11,7 @@ const Typography_1 = require("@strapi/design-system/Typography");
11
11
  const styles_1 = require("./styles");
12
12
  const Avatar_1 = __importDefault(require("../Avatar"));
13
13
  const utils_1 = require("../../utils");
14
- const DiscussionThreadItemFooter = ({ author, children, createdAt, updatedAt, }) => {
14
+ const DiscussionThreadItemFooter = ({ author, isAdminComment, children, createdAt, updatedAt, }) => {
15
15
  const { formatDate } = (0, react_intl_1.useIntl)();
16
16
  const dateTime = formatDate(updatedAt || createdAt, {
17
17
  dateStyle: "medium",
@@ -20,7 +20,7 @@ const DiscussionThreadItemFooter = ({ author, children, createdAt, updatedAt, })
20
20
  const { name, avatar } = author || {};
21
21
  return (react_1.default.createElement(styles_1.DiscussionThreadItemFooterStyled, { as: Box_1.Box, paddingTop: 2, direction: "row" },
22
22
  react_1.default.createElement(styles_1.DiscussionThreadItemFooterMeta, { size: 3, horizontal: true },
23
- avatar && react_1.default.createElement(Avatar_1.default, { avatar: avatar, name: name }),
23
+ author && react_1.default.createElement(Avatar_1.default, { avatar: avatar, name: name, isAdminComment: isAdminComment }),
24
24
  react_1.default.createElement(Typography_1.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800" }, name || (0, utils_1.getMessage)("compontents.author.unknown")),
25
25
  react_1.default.createElement(Typography_1.Typography, { variant: "pi", textColor: "neutral600" }, dateTime)),
26
26
  children));
@@ -61,6 +61,7 @@ const ModeratorResponse = ({ rootThread, }) => {
61
61
  message: `${pluginId_1.pluginId}.${message}`,
62
62
  });
63
63
  stateAction(false);
64
+ setCommentField('');
64
65
  unlockApp();
65
66
  };
66
67
  const onError = (err) => {
@@ -102,7 +103,7 @@ const ModeratorResponse = ({ rootThread, }) => {
102
103
  react_1.default.createElement(Wysiwyg_1.default, { name: "", value: commentField, onChange: handleCommentChange, intlLabel: intlLabel })),
103
104
  react_1.default.createElement(Flex_1.Flex, { direction: "row", justifyContent: "flex-end", gap: 2 },
104
105
  blockedThread && (react_1.default.createElement(Button_1.Button, { variant: "secondary", onClick: handleReopen, disabled: isFieldEmpty }, (0, utils_1.getMessage)("page.details.panel.discussion.reopen", "Re-open"))),
105
- react_1.default.createElement(Button_1.Button, { variant: "tertiary", onClick: handleSave, disabled: isFieldEmpty }, (0, utils_1.getMessage)("page.details.panel.discussion.send", "Send"))))));
106
+ react_1.default.createElement(Button_1.Button, { variant: "primary", onClick: handleSave, disabled: isFieldEmpty }, (0, utils_1.getMessage)("page.details.panel.discussion.send", "Send"))))));
106
107
  };
107
108
  exports.default = ModeratorResponse;
108
109
  //# sourceMappingURL=index.js.map
@@ -1,3 +1,3 @@
1
- declare const clean: (dirty: any) => any;
1
+ declare const clean: (dirty: any, options?: any) => any;
2
2
  export default clean;
3
3
  //# sourceMappingURL=satinizeHtml.d.ts.map
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const sanitize_html_1 = __importDefault(require("sanitize-html"));
7
- const options = {
7
+ const defaultOptions = {
8
8
  ...sanitize_html_1.default.defaults,
9
9
  allowedTags: false,
10
10
  allowedAttributes: {
@@ -13,6 +13,6 @@ const options = {
13
13
  source: ['src', 'type'],
14
14
  },
15
15
  };
16
- const clean = dirty => (0, sanitize_html_1.default)(dirty, options);
16
+ const clean = (dirty, options = defaultOptions) => (0, sanitize_html_1.default)(dirty, options);
17
17
  exports.default = clean;
18
18
  //# sourceMappingURL=satinizeHtml.js.map
@@ -27,6 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const react_1 = __importStar(require("react"));
30
+ const lodash_1 = require("lodash");
30
31
  const codemirror_1 = __importDefault(require("codemirror"));
31
32
  require("codemirror/addon/display/placeholder");
32
33
  const PreviewWysiwyg_1 = __importDefault(require("../PreviewWysiwyg"));
@@ -55,7 +56,7 @@ const Editor = ({ disabled, editorRef, error, isPreviewMode, isExpandMode, name,
55
56
  });
56
57
  }, [editorRef, textareaRef, name, placeholder]);
57
58
  (0, react_1.useEffect)(() => {
58
- if (value && !editorRef.current.state.focused) {
59
+ if ((0, lodash_1.isString)(value) && !editorRef.current.state.focused) {
59
60
  editorRef.current.setValue(value);
60
61
  }
61
62
  }, [editorRef, value]);
@@ -32,7 +32,6 @@ const FocusTrap_1 = require("@strapi/design-system/FocusTrap");
32
32
  const Box_1 = require("@strapi/design-system/Box");
33
33
  const Button_1 = require("@strapi/design-system/Button");
34
34
  const IconButton_1 = require("@strapi/design-system/IconButton");
35
- const Select_1 = require("@strapi/design-system/Select");
36
35
  const Popover_1 = require("@strapi/design-system/Popover");
37
36
  const Flex_1 = require("@strapi/design-system/Flex");
38
37
  const Bold_1 = __importDefault(require("@strapi/icons/Bold"));
@@ -45,15 +44,10 @@ const Code_1 = __importDefault(require("@strapi/icons/Code"));
45
44
  const Picture_1 = __importDefault(require("@strapi/icons/Picture"));
46
45
  const Link_1 = __importDefault(require("@strapi/icons/Link"));
47
46
  const Quote_1 = __importDefault(require("@strapi/icons/Quote"));
48
- const More_1 = __importDefault(require("@strapi/icons/More"));
49
47
  const WysiwygStyles_1 = require("./WysiwygStyles");
50
48
  const WysiwygNav = ({ disabled, editorRef, isExpandMode, isPreviewMode, onActionClick, onToggleMediaLib, onTogglePreviewMode, }) => {
51
49
  const [visiblePopover, setVisiblePopover] = (0, react_1.useState)(false);
52
50
  const { formatMessage } = (0, react_intl_1.useIntl)();
53
- const selectPlaceholder = formatMessage({
54
- id: 'components.Wysiwyg.selectOptions.title',
55
- defaultMessage: 'Add a title',
56
- });
57
51
  const buttonMoreRef = (0, react_1.useRef)();
58
52
  const handleTogglePopover = () => {
59
53
  setVisiblePopover(prev => !prev);
@@ -62,18 +56,10 @@ const WysiwygNav = ({ disabled, editorRef, isExpandMode, isPreviewMode, onAction
62
56
  return (react_1.default.createElement(Box_1.Box, { padding: 2, background: "neutral100" },
63
57
  react_1.default.createElement(Flex_1.Flex, { justifyContent: "space-between" },
64
58
  react_1.default.createElement(Flex_1.Flex, null,
65
- react_1.default.createElement(Select_1.Select, { disabled: true, id: "selectTitle", placeholder: selectPlaceholder, size: "S", "aria-label": selectPlaceholder },
66
- react_1.default.createElement(Select_1.Option, { value: "h1" }, "h1"),
67
- react_1.default.createElement(Select_1.Option, { value: "h2" }, "h2"),
68
- react_1.default.createElement(Select_1.Option, { value: "h3" }, "h3"),
69
- react_1.default.createElement(Select_1.Option, { value: "h4" }, "h4"),
70
- react_1.default.createElement(Select_1.Option, { value: "h5" }, "h5"),
71
- react_1.default.createElement(Select_1.Option, { value: "h6" }, "h6")),
72
59
  react_1.default.createElement(WysiwygStyles_1.MainButtons, null,
73
60
  react_1.default.createElement(WysiwygStyles_1.CustomIconButton, { disabled: true, id: "Bold", label: "Bold", name: "Bold", icon: react_1.default.createElement(Bold_1.default, null) }),
74
61
  react_1.default.createElement(WysiwygStyles_1.CustomIconButton, { disabled: true, id: "Italic", label: "Italic", name: "Italic", icon: react_1.default.createElement(Italic_1.default, null) }),
75
- react_1.default.createElement(WysiwygStyles_1.CustomIconButton, { disabled: true, id: "Underline", label: "Underline", name: "Underline", icon: react_1.default.createElement(Underline_1.default, null) })),
76
- react_1.default.createElement(WysiwygStyles_1.MoreButton, { disabled: true, id: "more", label: "More", icon: react_1.default.createElement(More_1.default, null) })),
62
+ react_1.default.createElement(WysiwygStyles_1.CustomIconButton, { disabled: true, id: "Underline", label: "Underline", name: "Underline", icon: react_1.default.createElement(Underline_1.default, null) }))),
77
63
  !isExpandMode && (react_1.default.createElement(Button_1.Button, { onClick: onTogglePreviewMode, variant: "tertiary", id: "preview" }, formatMessage({
78
64
  id: 'components.Wysiwyg.ToggleMode.markdown-mode',
79
65
  defaultMessage: 'Markdown mode',
@@ -82,18 +68,10 @@ const WysiwygNav = ({ disabled, editorRef, isExpandMode, isPreviewMode, onAction
82
68
  return (react_1.default.createElement(Box_1.Box, { padding: 2, background: "neutral100" },
83
69
  react_1.default.createElement(Flex_1.Flex, { justifyContent: "space-between" },
84
70
  react_1.default.createElement(Flex_1.Flex, null,
85
- react_1.default.createElement(Select_1.Select, { id: "selectTitle", placeholder: selectPlaceholder, size: "S", onChange: (value) => onActionClick(value, editorRef) },
86
- react_1.default.createElement(Select_1.Option, { value: "h1" }, "h1"),
87
- react_1.default.createElement(Select_1.Option, { value: "h2" }, "h2"),
88
- react_1.default.createElement(Select_1.Option, { value: "h3" }, "h3"),
89
- react_1.default.createElement(Select_1.Option, { value: "h4" }, "h4"),
90
- react_1.default.createElement(Select_1.Option, { value: "h5" }, "h5"),
91
- react_1.default.createElement(Select_1.Option, { value: "h6" }, "h6")),
92
71
  react_1.default.createElement(WysiwygStyles_1.MainButtons, null,
93
72
  react_1.default.createElement(WysiwygStyles_1.CustomIconButton, { onClick: () => onActionClick('Bold', editorRef), id: "Bold", label: "Bold", name: "Bold", icon: react_1.default.createElement(Bold_1.default, null) }),
94
73
  react_1.default.createElement(WysiwygStyles_1.CustomIconButton, { onClick: () => onActionClick('Italic', editorRef), id: "Italic", label: "Italic", name: "Italic", icon: react_1.default.createElement(Italic_1.default, null) }),
95
74
  react_1.default.createElement(WysiwygStyles_1.CustomIconButton, { onClick: () => onActionClick('Underline', editorRef), id: "Underline", label: "Underline", name: "Underline", icon: react_1.default.createElement(Underline_1.default, null) })),
96
- react_1.default.createElement(WysiwygStyles_1.MoreButton, { ref: buttonMoreRef, onClick: handleTogglePopover, id: "more", label: "More", icon: react_1.default.createElement(More_1.default, null) }),
97
75
  visiblePopover && (react_1.default.createElement(Popover_1.Popover, { centered: true, source: buttonMoreRef, spacing: 4, id: "popover" },
98
76
  react_1.default.createElement(FocusTrap_1.FocusTrap, { onEscape: handleTogglePopover, restoreFocus: false },
99
77
  react_1.default.createElement(Flex_1.Flex, null,
@@ -24,7 +24,7 @@ exports.CustomLinkIconButton = (0, styled_components_1.default)(exports.CustomIc
24
24
  }
25
25
  `;
26
26
  exports.MainButtons = (0, styled_components_1.default)(IconButton_1.IconButtonGroup) `
27
- margin-left: ${({ theme }) => theme.spaces[4]};
27
+
28
28
  `;
29
29
  exports.MoreButton = (0, styled_components_1.default)(IconButton_1.IconButton) `
30
30
  margin: ${({ theme }) => `0 ${theme.spaces[2]}`};
@@ -44,10 +44,11 @@ const getMessage_1 = __importDefault(require("../../utils/getMessage"));
44
44
  const api_1 = require("../utils/api");
45
45
  const permissions_1 = __importDefault(require("../../permissions"));
46
46
  const utils_1 = require("../../utils");
47
+ const Nav_1 = __importDefault(require("../../components/Nav"));
47
48
  const DetailsEntity_1 = __importDefault(require("./components/DetailsEntity"));
48
49
  const DiscussionThread_1 = __importDefault(require("../../components/DiscussionThread"));
49
50
  const selectors_1 = __importDefault(require("../App/reducer/selectors"));
50
- const index_1 = __importDefault(require("../../components/ModeratorResponse/index"));
51
+ const ModeratorResponse_1 = __importDefault(require("../../components/ModeratorResponse"));
51
52
  const Details = ({ config }) => {
52
53
  (0, helper_plugin_1.useFocusWhenNavigate)();
53
54
  const { params: { id }, } = (0, react_router_dom_1.useRouteMatch)((0, utils_1.getUrl)(`discover/:id`));
@@ -77,7 +78,7 @@ const Details = ({ config }) => {
77
78
  const isLoading = isLoadingForData || isFetching;
78
79
  if (canAccess) {
79
80
  return (react_1.default.createElement(Box_1.Box, { background: "neutral100" },
80
- react_1.default.createElement(Layout_1.Layout, null, (isLoading || isLoadingForPermissions) && (0, lodash_1.isEmpty)(data) ? (react_1.default.createElement(helper_plugin_1.LoadingIndicatorPage, null)) : (react_1.default.createElement(react_1.default.Fragment, null,
81
+ react_1.default.createElement(Layout_1.Layout, { sideNav: react_1.default.createElement(Nav_1.default, { visible: true }) }, (isLoading || isLoadingForPermissions) && (0, lodash_1.isEmpty)(data) ? (react_1.default.createElement(helper_plugin_1.LoadingIndicatorPage, null)) : (react_1.default.createElement(react_1.default.Fragment, null,
81
82
  react_1.default.createElement(Layout_1.HeaderLayout, { navigationAction: react_1.default.createElement(Link_1.Link, { startIcon: icons_1.arrowLeft, to: (0, utils_1.getUrl)(`discover`) }, (0, getMessage_1.default)("HeaderLayout.link.go-back", "Back", false)), title: (0, getMessage_1.default)("page.details.header"), subtitle: (0, getMessage_1.default)("page.details.header.description"), as: "h2" }),
82
83
  react_1.default.createElement(Layout_1.ContentLayout, null,
83
84
  react_1.default.createElement(Layout_1.TwoColsLayout, { startCol: react_1.default.createElement(react_1.default.Fragment, null,
@@ -86,7 +87,7 @@ const Details = ({ config }) => {
86
87
  canAccessReports,
87
88
  canReviewReports,
88
89
  } }),
89
- selected?.threadOf && (react_1.default.createElement(index_1.default, { rootThread: { ...selected.threadOf } }))), endCol: react_1.default.createElement(DetailsEntity_1.default, { data: entity, schema: contentTypeData?.schema, config: config, filters: filters, onFiltersChange: handleChangeFilters }) })))))));
90
+ selected?.threadOf && (react_1.default.createElement(ModeratorResponse_1.default, { rootThread: { ...selected.threadOf } }))), endCol: react_1.default.createElement(DetailsEntity_1.default, { data: entity, schema: contentTypeData?.schema, config: config, filters: filters, onFiltersChange: handleChangeFilters }) })))))));
90
91
  }
91
92
  return null;
92
93
  };
@@ -1,9 +1,32 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const react_1 = __importDefault(require("react"));
29
+ const react_1 = __importStar(require("react"));
7
30
  const prop_types_1 = __importDefault(require("prop-types"));
8
31
  const react_intl_1 = require("react-intl");
9
32
  const lodash_1 = require("lodash");
@@ -22,6 +45,8 @@ const StatusBadge_1 = __importDefault(require("../../../../components/StatusBadg
22
45
  const styles_2 = require("../../../../components/IconButton/styles");
23
46
  const DiscussionThreadItemReviewAction_1 = __importDefault(require("../../../../components/DiscussionThreadItemReviewAction"));
24
47
  const Avatar_1 = __importDefault(require("../../../../components/Avatar"));
48
+ const satinizeHtml_1 = __importDefault(require("../../../../components/PreviewWysiwyg/utils/satinizeHtml"));
49
+ const mdRenderer_1 = __importDefault(require("../../../../components/PreviewWysiwyg/utils/mdRenderer"));
25
50
  const DiscoverTableRow = ({ config, item, allowedActions: { canModerate, canAccessReports, canReviewReports }, onClick, }) => {
26
51
  const { reports } = item;
27
52
  const { formatDate } = (0, react_intl_1.useIntl)();
@@ -48,6 +73,10 @@ const DiscoverTableRow = ({ config, item, allowedActions: { canModerate, canAcce
48
73
  actionItemsCount = 2;
49
74
  }
50
75
  const { author, isAdminComment, id, content, threadOf, related, createdAt, updatedAt } = item;
76
+ const sanitizedContent = (0, react_1.useMemo)(() => (0, satinizeHtml_1.default)(mdRenderer_1.default.render(content || ''), {
77
+ allowedTags: [],
78
+ allowedAttributes: {}
79
+ }), [content]);
51
80
  return (react_1.default.createElement(Table_1.Tr, { key: id },
52
81
  react_1.default.createElement(Table_1.Td, null,
53
82
  react_1.default.createElement(Typography_1.Typography, { textColor: "neutral800", fontWeight: "bold" },
@@ -58,7 +87,7 @@ const DiscoverTableRow = ({ config, item, allowedActions: { canModerate, canAcce
58
87
  author && (react_1.default.createElement(Avatar_1.default, { avatar: author.avatar, name: author.name, isAdminComment: isAdminComment })),
59
88
  react_1.default.createElement(Typography_1.Typography, { textColor: "neutral800", variant: "pi" }, author?.name || (0, utils_1.getMessage)('compontents.author.unknown')))),
60
89
  react_1.default.createElement(Table_1.Td, { style: { maxWidth: "30vw" } },
61
- react_1.default.createElement(Typography_1.Typography, { textColor: "neutral800", ellipsis: true }, content)),
90
+ react_1.default.createElement(Typography_1.Typography, { textColor: "neutral800", ellipsis: true }, sanitizedContent)),
62
91
  react_1.default.createElement(Table_1.Td, null, threadOf?.id ? (react_1.default.createElement(Link_1.Link, { to: renderDetailsUrl(threadOf) }, (0, utils_1.getMessage)({
63
92
  id: "page.discover.table.cell.thread",
64
93
  props: { id: threadOf.id },
@@ -116,6 +116,7 @@ const Settings = () => {
116
116
  const moderatorRoles = configData?.moderatorRoles?.filter((code) => allRoles.find((_) => _.code === code)) || [];
117
117
  const clientUrl = configData?.client?.url;
118
118
  const clientEmail = configData?.client?.contactEmail;
119
+ const blockedAuthorProps = configData?.blockedAuthorProps ?? [];
119
120
  const changeApprovalFlowFor = (uid, current, value) => {
120
121
  const currentSet = new Set(current);
121
122
  if (value) {
@@ -180,6 +181,7 @@ const Settings = () => {
180
181
  clientEmail,
181
182
  clientUrl,
182
183
  gqlAuthEnabled,
184
+ blockedAuthorProps,
183
185
  }, enableReinitialize: true, onSubmit: handleUpdateConfiguration }, ({ handleSubmit, setFieldValue, values }) => (react_1.default.createElement(helper_plugin_1.Form, { noValidate: true, onSubmit: handleSubmit },
184
186
  react_1.default.createElement(Layout_1.HeaderLayout, { title: (0, utils_1.getMessage)("page.settings.header.title"), subtitle: (0, utils_1.getMessage)("page.settings.header.description"), primaryAction: react_1.default.createElement(helper_plugin_1.CheckPermissions, { permissions: permissions_1.default.settingsChange },
185
187
  react_1.default.createElement(Button_1.Button, { type: "submit", startIcon: icons_1.check, disabled: restartRequired }, (0, utils_1.getMessage)("page.settings.actions.submit"))) }),
@@ -213,9 +215,11 @@ const Settings = () => {
213
215
  react_1.default.createElement(Stack_1.Stack, { size: 4 },
214
216
  react_1.default.createElement(Typography_1.Typography, { variant: "delta", as: "h2" }, (0, utils_1.getMessage)("page.settings.section.additional")),
215
217
  react_1.default.createElement(Grid_1.Grid, { gap: 4 },
216
- react_1.default.createElement(Grid_1.GridItem, { col: 6, xs: 12 },
218
+ react_1.default.createElement(Grid_1.GridItem, { col: 4, xs: 12 },
217
219
  react_1.default.createElement(ToggleInput_1.ToggleInput, { name: "badWords", label: (0, utils_1.getMessage)("page.settings.form.badWords.label"), hint: (0, utils_1.getMessage)("page.settings.form.badWords.hint"), checked: values.badWords, onChange: ({ target: { checked } }) => setFieldValue("badWords", checked, false), onLabel: (0, utils_1.getMessage)("compontents.toogle.enabled"), offLabel: (0, utils_1.getMessage)("compontents.toogle.disabled"), disabled: restartRequired })),
218
- isGQLPluginEnabled && (react_1.default.createElement(Grid_1.GridItem, { col: 6, xs: 12 },
220
+ react_1.default.createElement(Grid_1.GridItem, { col: 4, xs: 12 },
221
+ react_1.default.createElement(TextInput_1.TextInput, { type: "text", name: "blockedAuthorProps", label: (0, utils_1.getMessage)("page.settings.form.author.blockedProps.label"), hint: (0, utils_1.getMessage)("page.settings.form.author.blockedProps.hint"), value: values.blockedAuthorProps.join(", "), onChange: ({ target: { value } }) => setFieldValue("blockedAuthorProps", value.split(', ').map(_ => _.trim()), false), disabled: restartRequired })),
222
+ isGQLPluginEnabled && (react_1.default.createElement(Grid_1.GridItem, { col: 4, xs: 12 },
219
223
  react_1.default.createElement(ToggleInput_1.ToggleInput, { name: "gqlAuthEnabled", label: (0, utils_1.getMessage)("page.settings.form.gqlAuth.label"), hint: (0, utils_1.getMessage)("page.settings.form.gqlAuth.hint"), checked: values.gqlAuthEnabled, onChange: ({ target: { checked } }) => setFieldValue("gqlAuthEnabled", checked, false), onLabel: (0, utils_1.getMessage)("compontents.toogle.enabled"), offLabel: (0, utils_1.getMessage)("compontents.toogle.disabled"), disabled: restartRequired })))))),
220
224
  react_1.default.createElement(Box_1.Box, { ...boxDefaultProps },
221
225
  react_1.default.createElement(Stack_1.Stack, { size: 4 },
@@ -78,7 +78,7 @@
78
78
  "page.details.panel.discussion.status.blocked": "Blocked",
79
79
  "page.details.panel.discussion.reply":"Reply",
80
80
  "page.details.panel.discussion.reopen":"Re-open",
81
- "page.details.panel.discussion.send":"Send",
81
+ "page.details.panel.discussion.send":"Send Moderator response",
82
82
  "page.details.actions.comment.post.confirmation": "Comment has been posted",
83
83
  "page.details.actions.comment.update.confirmation": "Comment has been updated",
84
84
  "page.details.panel.entity": "Entity details",
@@ -157,6 +157,8 @@
157
157
  "page.settings.notification.restart.success": "Application has been restarted successfully",
158
158
  "page.settings.notification.restart.error": "Failed to restart your application. Try to do it manually.",
159
159
  "page.settings.loading": "Fetching configuration...",
160
+ "page.settings.form.author.blockedProps.label": "Blocked author details",
161
+ "page.settings.form.author.blockedProps.hint": "Specified properties will be filtered out from author's details (comma-separated)",
160
162
  "compontents.confirmation.dialog.header": "Confirmation",
161
163
  "compontents.confirmation.dialog.description": "Do you really want to perform this action?",
162
164
  "compontents.confirmation.dialog.button.confirm": "Yes, I do",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-comments",
3
- "version": "2.2.4",
3
+ "version": "2.2.5",
4
4
  "description": "Strapi - Comments plugin",
5
5
  "strapi": {
6
6
  "name": "comments",
@@ -14,8 +14,8 @@
14
14
  "url": "https://github.com/VirtusLab-Open-Source/strapi-plugin-comments"
15
15
  },
16
16
  "dependencies": {
17
- "@strapi/plugin-graphql": "^4.5.5",
18
- "@strapi/utils": "^4.5.5",
17
+ "@strapi/plugin-graphql": "^4.6.0",
18
+ "@strapi/utils": "^4.6.0",
19
19
  "@types/axios": "^0.14.0",
20
20
  "@types/react-intl": "^3.0.0",
21
21
  "@types/react-query": "^1.2.9",
@@ -13,6 +13,7 @@ const config = {
13
13
  DISCRIMINATION: "DISCRIMINATION",
14
14
  OTHER: "OTHER",
15
15
  },
16
+ blockedAuthorProps: [],
16
17
  },
17
18
  };
18
19
  exports.default = config;