comment.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. module.exports = function(crowi, app) {
  2. const logger = require('@alias/logger')('growi:routes:comment');
  3. const Comment = crowi.model('Comment');
  4. const User = crowi.model('User');
  5. const Page = crowi.model('Page');
  6. const ApiResponse = require('../util/apiResponse');
  7. const globalNotificationService = crowi.getGlobalNotificationService();
  8. const actions = {};
  9. const api = {};
  10. actions.api = api;
  11. /**
  12. * @api {get} /comments.get Get comments of the page of the revision
  13. * @apiName GetComments
  14. * @apiGroup Comment
  15. *
  16. * @apiParam {String} page_id Page Id.
  17. * @apiParam {String} revision_id Revision Id.
  18. */
  19. api.get = async function(req, res) {
  20. const pageId = req.query.page_id;
  21. const revisionId = req.query.revision_id;
  22. // check whether accessible
  23. const isAccessible = await Page.isAccessiblePageByViewer(pageId, req.user);
  24. if (!isAccessible) {
  25. return res.json(ApiResponse.error('Current user is not accessible to this page.'));
  26. }
  27. let fetcher = null;
  28. try {
  29. if (revisionId) {
  30. fetcher = Comment.getCommentsByRevisionId(revisionId);
  31. }
  32. else {
  33. fetcher = Comment.getCommentsByPageId(pageId);
  34. }
  35. }
  36. catch (err) {
  37. return res.json(ApiResponse.error(err));
  38. }
  39. const comments = await fetcher.populate(
  40. { path: 'creator', select: User.USER_PUBLIC_FIELDS, populate: User.IMAGE_POPULATION },
  41. );
  42. res.json(ApiResponse.success({ comments }));
  43. };
  44. /**
  45. * @api {post} /comments.add Post comment for the page
  46. * @apiName PostComment
  47. * @apiGroup Comment
  48. *
  49. * @apiParam {String} page_id Page Id.
  50. * @apiParam {String} revision_id Revision Id.
  51. * @apiParam {String} comment Comment body
  52. * @apiParam {Number} comment_position=-1 Line number of the comment
  53. */
  54. api.add = async function(req, res) {
  55. const commentForm = req.form.commentForm;
  56. const slackNotificationForm = req.form.slackNotificationForm;
  57. if (!req.form.isValid) {
  58. // return res.json(ApiResponse.error('Invalid comment.'));
  59. return res.json(ApiResponse.error('コメントを入力してください。'));
  60. }
  61. const pageId = commentForm.page_id;
  62. const revisionId = commentForm.revision_id;
  63. const comment = commentForm.comment;
  64. const position = commentForm.comment_position || -1;
  65. const isMarkdown = commentForm.is_markdown;
  66. // check whether accessible
  67. const isAccessible = await Page.isAccessiblePageByViewer(pageId, req.user);
  68. if (!isAccessible) {
  69. return res.json(ApiResponse.error('Current user is not accessible to this page.'));
  70. }
  71. const createdComment = await Comment.create(pageId, req.user._id, revisionId, comment, position, isMarkdown)
  72. .catch((err) => {
  73. return res.json(ApiResponse.error(err));
  74. });
  75. // update page
  76. const page = await Page.findOneAndUpdate({ _id: pageId }, {
  77. lastUpdateUser: req.user,
  78. updatedAt: new Date(),
  79. });
  80. res.json(ApiResponse.success({ comment: createdComment }));
  81. const path = page.path;
  82. // global notification
  83. globalNotificationService.notifyComment(createdComment, path);
  84. // slack notification
  85. if (slackNotificationForm.isSlackEnabled) {
  86. const user = await User.findUserByUsername(req.user.username);
  87. const channels = slackNotificationForm.slackChannels;
  88. if (channels) {
  89. page.updateSlackChannel(channels).catch((err) => {
  90. logger.error('Error occured in updating slack channels: ', err);
  91. });
  92. const promises = channels.split(',').map((chan) => {
  93. return crowi.slack.postComment(createdComment, user, chan, path);
  94. });
  95. Promise.all(promises)
  96. .catch((err) => {
  97. logger.error('Error occured in sending slack notification: ', err);
  98. });
  99. }
  100. }
  101. };
  102. /**
  103. * @api {post} /comments.remove Remove specified comment
  104. * @apiName RemoveComment
  105. * @apiGroup Comment
  106. *
  107. * @apiParam {String} comment_id Comment Id.
  108. */
  109. api.remove = async function(req, res) {
  110. const commentId = req.body.comment_id;
  111. if (!commentId) {
  112. return Promise.resolve(res.json(ApiResponse.error('\'comment_id\' is undefined')));
  113. }
  114. try {
  115. const comment = await Comment.findById(commentId).exec();
  116. if (comment == null) {
  117. throw new Error('This comment does not exist.');
  118. }
  119. // check whether accessible
  120. const pageId = comment.page;
  121. const isAccessible = await Page.isAccessiblePageByViewer(pageId, req.user);
  122. if (!isAccessible) {
  123. throw new Error('Current user is not accessible to this page.');
  124. }
  125. await comment.remove();
  126. await Page.updateCommentCount(comment.page);
  127. }
  128. catch (err) {
  129. return res.json(ApiResponse.error(err));
  130. }
  131. return res.json(ApiResponse.success({}));
  132. };
  133. return actions;
  134. };