ProjectHistoryHandler.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. const { Project } = require('../../models/Project')
  2. const ProjectDetailsHandler = require('./ProjectDetailsHandler')
  3. const HistoryManager = require('../History/HistoryManager')
  4. const ProjectEntityUpdateHandler = require('./ProjectEntityUpdateHandler')
  5. const { callbackify } = require('util')
  6. const ProjectHistoryHandler = {
  7. async setHistoryId(projectId, historyId) {
  8. // reject invalid history ids
  9. if (historyId == null) {
  10. throw new Error('missing history id')
  11. }
  12. // use $exists:false to prevent overwriting any existing history id, atomically
  13. const result = await Project.updateOne(
  14. { _id: projectId, 'overleaf.history.id': { $exists: false } },
  15. { 'overleaf.history.id': historyId }
  16. )
  17. if (result.matchedCount === 0) {
  18. throw new Error('history exists')
  19. }
  20. },
  21. async getHistoryId(projectId) {
  22. const project = await ProjectDetailsHandler.promises.getDetails(projectId)
  23. return project?.overleaf?.history?.id
  24. },
  25. async ensureHistoryExistsForProject(projectId) {
  26. // We can only set a history id for a project that doesn't have one. The
  27. // history id is cached in the project history service, and changing an
  28. // existing value corrupts the history, leaving it in an irrecoverable
  29. // state. Setting a history id when one wasn't present before is ok,
  30. // because undefined history ids aren't cached.
  31. let historyId = await ProjectHistoryHandler.getHistoryId(projectId)
  32. if (historyId != null) {
  33. return
  34. }
  35. historyId = await HistoryManager.promises.initializeProject(projectId)
  36. if (historyId == null) {
  37. throw new Error('failed to initialize history id')
  38. }
  39. await ProjectHistoryHandler.setHistoryId(projectId, historyId)
  40. await ProjectEntityUpdateHandler.promises.resyncProjectHistory(
  41. projectId,
  42. {}
  43. )
  44. await HistoryManager.promises.flushProject(projectId)
  45. },
  46. }
  47. module.exports = {
  48. setHistoryId: callbackify(ProjectHistoryHandler.setHistoryId),
  49. getHistoryId: callbackify(ProjectHistoryHandler.getHistoryId),
  50. ensureHistoryExistsForProject: callbackify(
  51. ProjectHistoryHandler.ensureHistoryExistsForProject
  52. ),
  53. promises: ProjectHistoryHandler,
  54. }