comment.js 4.8 KB

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