ProjectHistoryHandler.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* eslint-disable
  2. camelcase,
  3. node/handle-callback-err,
  4. max-len,
  5. no-unused-vars,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS102: Remove unnecessary code created because of implicit returns
  12. * DS103: Rewrite code to no longer use __guard__
  13. * DS207: Consider shorter variations of null checks
  14. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  15. */
  16. const { Project } = require('../../models/Project')
  17. const ProjectDetailsHandler = require('./ProjectDetailsHandler')
  18. const logger = require('logger-sharelatex')
  19. const settings = require('@overleaf/settings')
  20. const HistoryManager = require('../History/HistoryManager')
  21. const ProjectEntityUpdateHandler = require('./ProjectEntityUpdateHandler')
  22. const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
  23. const { promisifyAll } = require('../../util/promises')
  24. const ProjectHistoryHandler = {
  25. setHistoryId(project_id, history_id, callback) {
  26. // reject invalid history ids
  27. if (callback == null) {
  28. callback = function (err) {}
  29. }
  30. if (!history_id || typeof history_id !== 'number') {
  31. return callback(new Error('invalid history id'))
  32. }
  33. // use $exists:false to prevent overwriting any existing history id, atomically
  34. return Project.updateOne(
  35. { _id: project_id, 'overleaf.history.id': { $exists: false } },
  36. { 'overleaf.history.id': history_id },
  37. function (err, result) {
  38. if (err != null) {
  39. return callback(err)
  40. }
  41. if ((result != null ? result.n : undefined) === 0) {
  42. return callback(new Error('history exists'))
  43. }
  44. return callback()
  45. }
  46. )
  47. },
  48. getHistoryId(project_id, callback) {
  49. if (callback == null) {
  50. callback = function (err, result) {}
  51. }
  52. return ProjectDetailsHandler.getDetails(
  53. project_id,
  54. function (err, project) {
  55. if (err != null) {
  56. return callback(err)
  57. } // n.b. getDetails returns an error if the project doesn't exist
  58. return callback(
  59. null,
  60. __guard__(
  61. __guard__(
  62. project != null ? project.overleaf : undefined,
  63. x1 => x1.history
  64. ),
  65. x => x.id
  66. )
  67. )
  68. }
  69. )
  70. },
  71. upgradeHistory(project_id, callback) {
  72. // project must have an overleaf.history.id before allowing display of new history
  73. if (callback == null) {
  74. callback = function (err, result) {}
  75. }
  76. return Project.updateOne(
  77. { _id: project_id, 'overleaf.history.id': { $exists: true } },
  78. {
  79. 'overleaf.history.display': true,
  80. 'overleaf.history.upgradedAt': new Date(),
  81. },
  82. function (err, result) {
  83. if (err != null) {
  84. return callback(err)
  85. }
  86. // return an error if overleaf.history.id wasn't present
  87. if ((result != null ? result.n : undefined) === 0) {
  88. return callback(new Error('history not upgraded'))
  89. }
  90. return callback()
  91. }
  92. )
  93. },
  94. downgradeHistory(project_id, callback) {
  95. if (callback == null) {
  96. callback = function (err, result) {}
  97. }
  98. return Project.updateOne(
  99. { _id: project_id, 'overleaf.history.upgradedAt': { $exists: true } },
  100. {
  101. 'overleaf.history.display': false,
  102. $unset: { 'overleaf.history.upgradedAt': 1 },
  103. },
  104. function (err, result) {
  105. if (err != null) {
  106. return callback(err)
  107. }
  108. if ((result != null ? result.n : undefined) === 0) {
  109. return callback(new Error('history not downgraded'))
  110. }
  111. return callback()
  112. }
  113. )
  114. },
  115. ensureHistoryExistsForProject(project_id, callback) {
  116. // We can only set a history id for a project that doesn't have one. The
  117. // history id is cached in the project history service, and changing an
  118. // existing value corrupts the history, leaving it in an irrecoverable
  119. // state. Setting a history id when one wasn't present before is ok,
  120. // because undefined history ids aren't cached.
  121. if (callback == null) {
  122. callback = function (err) {}
  123. }
  124. return ProjectHistoryHandler.getHistoryId(
  125. project_id,
  126. function (err, history_id) {
  127. if (err != null) {
  128. return callback(err)
  129. }
  130. if (history_id != null) {
  131. return callback()
  132. } // history already exists, success
  133. return HistoryManager.flushProject(project_id, function (err) {
  134. if (err != null) {
  135. return callback(err)
  136. }
  137. return HistoryManager.initializeProject(function (err, history) {
  138. if (err != null) {
  139. return callback(err)
  140. }
  141. if (!history || !history.overleaf_id) {
  142. return callback(new Error('failed to initialize history id'))
  143. }
  144. return ProjectHistoryHandler.setHistoryId(
  145. project_id,
  146. history.overleaf_id,
  147. function (err) {
  148. if (err != null) {
  149. return callback(err)
  150. }
  151. return DocumentUpdaterHandler.flushProjectToMongoAndDelete(
  152. project_id,
  153. function (err) {
  154. if (err != null) {
  155. return callback(err)
  156. }
  157. return HistoryManager.forceResyncProject(
  158. project_id,
  159. function (err) {
  160. if (err != null) {
  161. return callback(err)
  162. }
  163. return HistoryManager.flushProject(project_id, callback)
  164. }
  165. )
  166. }
  167. )
  168. }
  169. )
  170. })
  171. })
  172. }
  173. )
  174. },
  175. }
  176. function __guard__(value, transform) {
  177. return typeof value !== 'undefined' && value !== null
  178. ? transform(value)
  179. : undefined
  180. }
  181. ProjectHistoryHandler.promises = promisifyAll(ProjectHistoryHandler)
  182. module.exports = ProjectHistoryHandler