revision.js 3.9 KB

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