revision.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // disable no-return-await for model functions
  2. /* eslint-disable no-return-await */
  3. module.exports = function(crowi) {
  4. // eslint-disable-next-line no-unused-vars
  5. const logger = require('@alias/logger')('growi:models:revision');
  6. const mongoose = require('mongoose');
  7. const ObjectId = mongoose.Schema.Types.ObjectId;
  8. const revisionSchema = new mongoose.Schema({
  9. path: { type: String, required: true },
  10. body: {
  11. type: String,
  12. required: true,
  13. get: (data) => {
  14. // replace CR/CRLF to LF above v3.1.5
  15. // see https://github.com/weseek/growi/issues/463
  16. return data ? data.replace(/\r\n?/g, '\n') : '';
  17. },
  18. },
  19. format: { type: String, default: 'markdown' },
  20. author: { type: ObjectId, ref: 'User' },
  21. createdAt: { type: Date, default: Date.now },
  22. hasDiffToPrev: { type: Boolean },
  23. });
  24. /*
  25. * preparation for https://github.com/weseek/growi/issues/216
  26. */
  27. // // create a XSS Filter instance
  28. // // TODO read options
  29. // this.xss = new Xss(true);
  30. // // prevent XSS when pre save
  31. // revisionSchema.pre('save', function(next) {
  32. // this.body = xss.process(this.body);
  33. // next();
  34. // });
  35. revisionSchema.statics.findRevisions = function(ids) {
  36. const Revision = this;
  37. const User = crowi.model('User');
  38. if (!Array.isArray(ids)) {
  39. return Promise.reject(new Error('The argument was not Array.'));
  40. }
  41. return new Promise(((resolve, reject) => {
  42. Revision
  43. .find({ _id: { $in: ids } })
  44. .sort({ createdAt: -1 })
  45. .populate('author', User.USER_PUBLIC_FIELDS)
  46. .exec((err, revisions) => {
  47. if (err) {
  48. return reject(err);
  49. }
  50. return resolve(revisions);
  51. });
  52. }));
  53. };
  54. revisionSchema.statics.findRevisionIdList = function(path) {
  55. return this.find({ path })
  56. .select('_id author createdAt hasDiffToPrev')
  57. .sort({ createdAt: -1 })
  58. .exec();
  59. };
  60. revisionSchema.statics.findRevisionList = function(path, options) {
  61. const Revision = this;
  62. const User = crowi.model('User');
  63. return new Promise(((resolve, reject) => {
  64. Revision.find({ path })
  65. .sort({ createdAt: -1 })
  66. .populate('author', User.USER_PUBLIC_FIELDS)
  67. .exec((err, data) => {
  68. if (err) {
  69. return reject(err);
  70. }
  71. return resolve(data);
  72. });
  73. }));
  74. };
  75. revisionSchema.statics.updateRevisionListByPath = function(path, updateData, options) {
  76. const Revision = this;
  77. return new Promise(((resolve, reject) => {
  78. Revision.update({ path }, { $set: updateData }, { multi: true }, (err, data) => {
  79. if (err) {
  80. return reject(err);
  81. }
  82. return resolve(data);
  83. });
  84. }));
  85. };
  86. revisionSchema.statics.prepareRevision = function(pageData, body, previousBody, user, options) {
  87. const Revision = this;
  88. if (!options) {
  89. // eslint-disable-next-line no-param-reassign
  90. options = {};
  91. }
  92. const format = options.format || 'markdown';
  93. if (!user._id) {
  94. throw new Error('Error: user should have _id');
  95. }
  96. const newRevision = new Revision();
  97. newRevision.path = pageData.path;
  98. newRevision.body = body;
  99. newRevision.format = format;
  100. newRevision.author = user._id;
  101. newRevision.createdAt = Date.now();
  102. if (pageData.revision != null) {
  103. newRevision.hasDiffToPrev = body !== previousBody;
  104. }
  105. return newRevision;
  106. };
  107. revisionSchema.statics.removeRevisionsByPath = function(path) {
  108. const Revision = this;
  109. return new Promise(((resolve, reject) => {
  110. Revision.remove({ path }, (err, data) => {
  111. if (err) {
  112. return reject(err);
  113. }
  114. return resolve(data);
  115. });
  116. }));
  117. };
  118. return mongoose.model('Revision', revisionSchema);
  119. };