ProjectHistoryHandler.js 5.9 KB

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