revision.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. module.exports = function(crowi) {
  2. var debug = require('debug')('crowi:models:revision')
  3. , mongoose = require('mongoose')
  4. , xss = require('xss')
  5. , ObjectId = mongoose.Schema.Types.ObjectId
  6. , revisionSchema;
  7. revisionSchema = new mongoose.Schema({
  8. path: { type: String, required: true },
  9. body: { type: String, required: true },
  10. format: { type: String, default: 'markdown' },
  11. author: { type: ObjectId, ref: 'User' },
  12. createdAt: { type: Date, default: Date.now }
  13. });
  14. // create a XSS Filter instance
  15. const myxss = new xss.FilterXSS({
  16. stripIgnoreTag: true,
  17. css: false,
  18. // allow all attributes
  19. onTagAttr: function (tag, name, value, isWhiteAttr) {
  20. return `${name}="${value}"`;
  21. }
  22. });
  23. // prevent XSS when pre save
  24. revisionSchema.pre('save', function(next) {
  25. this.body = myxss.process(this.body);
  26. next();
  27. });
  28. revisionSchema.statics.findLatestRevision = function(path, cb) {
  29. this.find({path: path})
  30. .sort({createdAt: -1})
  31. .limit(1)
  32. .exec(function(err, data) {
  33. cb(err, data.shift());
  34. });
  35. };
  36. revisionSchema.statics.findRevision = function(id) {
  37. var Revision = this;
  38. return new Promise(function(resolve, reject) {
  39. Revision.findById(id)
  40. .populate('author')
  41. .exec(function(err, data) {
  42. if (err) {
  43. return reject(err);
  44. }
  45. return resolve(data);
  46. });
  47. });
  48. };
  49. revisionSchema.statics.findRevisions = function(ids) {
  50. var Revision = this,
  51. User = crowi.model('User');
  52. if (!Array.isArray(ids)) {
  53. return Promise.reject('The argument was not Array.');
  54. }
  55. return new Promise(function(resolve, reject) {
  56. Revision
  57. .find({ _id: { $in: ids }})
  58. .sort({createdAt: -1})
  59. .populate('author', User.USER_PUBLIC_FIELDS)
  60. .exec(function(err, revisions) {
  61. if (err) {
  62. return reject(err);
  63. }
  64. return resolve(revisions);
  65. });
  66. });
  67. };
  68. revisionSchema.statics.findRevisionIdList = function(path) {
  69. return this.find({path: path})
  70. .select('_id author createdAt')
  71. .sort({createdAt: -1})
  72. .exec();
  73. };
  74. revisionSchema.statics.findRevisionList = function(path, options) {
  75. var Revision = this,
  76. User = crowi.model('User');
  77. return new Promise(function(resolve, reject) {
  78. Revision.find({path: path})
  79. .sort({createdAt: -1})
  80. .populate('author', User.USER_PUBLIC_FIELDS)
  81. .exec(function(err, data) {
  82. if (err) {
  83. return reject(err);
  84. }
  85. return resolve(data);
  86. });
  87. });
  88. };
  89. revisionSchema.statics.updateRevisionListByPath = function(path, updateData, options) {
  90. var Revision = this;
  91. return new Promise(function(resolve, reject) {
  92. Revision.update({path: path}, {$set: updateData}, {multi: true}, function(err, data) {
  93. if (err) {
  94. return reject(err);
  95. }
  96. return resolve(data);
  97. });
  98. });
  99. };
  100. revisionSchema.statics.prepareRevision = function(pageData, body, user, options) {
  101. var Revision = this;
  102. if (!options) {
  103. options = {};
  104. }
  105. var format = options.format || 'markdown';
  106. if (!user._id) {
  107. throw new Error('Error: user should have _id');
  108. }
  109. var newRevision = new Revision();
  110. newRevision.path = pageData.path;
  111. newRevision.body = body;
  112. newRevision.format = format;
  113. newRevision.author = user._id;
  114. newRevision.createdAt = Date.now();
  115. return newRevision;
  116. };
  117. revisionSchema.statics.removeRevisionsByPath = function(path) {
  118. var Revision = this;
  119. return new Promise(function(resolve, reject) {
  120. Revision.remove({path: path}, function(err, data) {
  121. if (err) {
  122. return reject(err);
  123. }
  124. return resolve(data);
  125. });
  126. });
  127. };
  128. revisionSchema.statics.updatePath = function(pathName) {
  129. };
  130. return mongoose.model('Revision', revisionSchema);
  131. };