You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
4.3 KiB

  1. const Model = require('objection').Model
  2. const validate = require('validate.js')
  3. const _ = require('lodash')
  4. /* global WIKI */
  5. /**
  6. * Comments model
  7. */
  8. module.exports = class Comment extends Model {
  9. static get tableName() { return 'comments' }
  10. static get jsonSchema () {
  11. return {
  12. type: 'object',
  13. required: [],
  14. properties: {
  15. id: {type: 'integer'},
  16. content: {type: 'string'},
  17. render: {type: 'string'},
  18. name: {type: 'string'},
  19. email: {type: 'string'},
  20. ip: {type: 'string'},
  21. createdAt: {type: 'string'},
  22. updatedAt: {type: 'string'}
  23. }
  24. }
  25. }
  26. static get relationMappings() {
  27. return {
  28. author: {
  29. relation: Model.BelongsToOneRelation,
  30. modelClass: require('./users'),
  31. join: {
  32. from: 'comments.authorId',
  33. to: 'users.id'
  34. }
  35. },
  36. page: {
  37. relation: Model.BelongsToOneRelation,
  38. modelClass: require('./pages'),
  39. join: {
  40. from: 'comments.pageId',
  41. to: 'pages.id'
  42. }
  43. }
  44. }
  45. }
  46. $beforeUpdate() {
  47. this.updatedAt = new Date().toISOString()
  48. }
  49. $beforeInsert() {
  50. this.createdAt = new Date().toISOString()
  51. this.updatedAt = new Date().toISOString()
  52. }
  53. /**
  54. * Post New Comment
  55. */
  56. static async postNewComment ({ pageId, replyTo, content, guestName, guestEmail, user, ip }) {
  57. // -> Input validation
  58. if (user.id === 2) {
  59. const validation = validate({
  60. email: _.toLower(guestEmail),
  61. name: guestName
  62. }, {
  63. email: {
  64. email: true,
  65. length: {
  66. maximum: 255
  67. }
  68. },
  69. name: {
  70. presence: {
  71. allowEmpty: false
  72. },
  73. length: {
  74. minimum: 2,
  75. maximum: 255
  76. }
  77. }
  78. }, { format: 'flat' })
  79. if (validation && validation.length > 0) {
  80. throw new WIKI.Error.InputInvalid(validation[0])
  81. }
  82. }
  83. content = _.trim(content)
  84. if (content.length < 2) {
  85. throw new WIKI.Error.CommentContentMissing()
  86. }
  87. // -> Load Page
  88. const page = await WIKI.models.pages.getPageFromDb(pageId)
  89. if (page) {
  90. if (!WIKI.auth.checkAccess(user, ['write:comments'], {
  91. path: page.path,
  92. locale: page.localeCode,
  93. tags: page.tags
  94. })) {
  95. throw new WIKI.Error.CommentPostForbidden()
  96. }
  97. } else {
  98. throw new WIKI.Error.PageNotFound()
  99. }
  100. // -> Process by comment provider
  101. return WIKI.data.commentProvider.create({
  102. page,
  103. replyTo,
  104. content,
  105. user: {
  106. ...user,
  107. ...(user.id === 2) ? {
  108. name: guestName,
  109. email: guestEmail
  110. } : {},
  111. ip
  112. }
  113. })
  114. }
  115. /**
  116. * Update an Existing Comment
  117. */
  118. static async updateComment ({ id, content, user, ip }) {
  119. // -> Load Page
  120. const pageId = await WIKI.data.commentProvider.getPageIdFromCommentId(id)
  121. if (!pageId) {
  122. throw new WIKI.Error.CommentNotFound()
  123. }
  124. const page = await WIKI.models.pages.getPageFromDb(pageId)
  125. if (page) {
  126. if (!WIKI.auth.checkAccess(user, ['manage:comments'], {
  127. path: page.path,
  128. locale: page.localeCode,
  129. tags: page.tags
  130. })) {
  131. throw new WIKI.Error.CommentManageForbidden()
  132. }
  133. } else {
  134. throw new WIKI.Error.PageNotFound()
  135. }
  136. // -> Process by comment provider
  137. return WIKI.data.commentProvider.update({
  138. id,
  139. content,
  140. page,
  141. user: {
  142. ...user,
  143. ip
  144. }
  145. })
  146. }
  147. /**
  148. * Delete an Existing Comment
  149. */
  150. static async deleteComment ({ id, user, ip }) {
  151. // -> Load Page
  152. const pageId = await WIKI.data.commentProvider.getPageIdFromCommentId(id)
  153. if (!pageId) {
  154. throw new WIKI.Error.CommentNotFound()
  155. }
  156. const page = await WIKI.models.pages.getPageFromDb(pageId)
  157. if (page) {
  158. if (!WIKI.auth.checkAccess(user, ['manage:comments'], {
  159. path: page.path,
  160. locale: page.localeCode,
  161. tags: page.tags
  162. })) {
  163. throw new WIKI.Error.CommentManageForbidden()
  164. }
  165. } else {
  166. throw new WIKI.Error.PageNotFound()
  167. }
  168. // -> Process by comment provider
  169. await WIKI.data.commentProvider.remove({
  170. id,
  171. page,
  172. user: {
  173. ...user,
  174. ip
  175. }
  176. })
  177. }
  178. }