Răsfoiți Sursa

Merge pull request #16218 from overleaf/csh-issue-11625-mongo-ug-5-project-history

Upgrade mongodb module for project-history

GitOrigin-RevId: 18782896b46b2b0512a1ce50215bb98ac3d46cea
Christopher Hoskin 2 ani în urmă
părinte
comite
ced8a923c0
28 a modificat fișierele cu 130 adăugiri și 193 ștergeri
  1. 2 82
      package-lock.json
  2. 2 2
      services/project-history/app/js/HealthChecker.js
  3. 7 7
      services/project-history/app/js/LabelsManager.js
  4. 3 3
      services/project-history/app/js/SyncManager.js
  5. 3 2
      services/project-history/app/js/mongodb.js
  6. 1 1
      services/project-history/package.json
  7. 3 3
      services/project-history/scripts/clear_deleted.js
  8. 1 1
      services/project-history/scripts/clear_deleted_history.js
  9. 2 2
      services/project-history/scripts/clear_filestore_404.js
  10. 2 2
      services/project-history/scripts/clear_project_version_out_of_order.js
  11. 1 1
      services/project-history/scripts/force_resync.js
  12. 4 3
      services/project-history/test/acceptance/js/DeleteProjectTests.js
  13. 4 3
      services/project-history/test/acceptance/js/DiffTests.js
  14. 5 4
      services/project-history/test/acceptance/js/DiscardingUpdatesTests.js
  15. 4 3
      services/project-history/test/acceptance/js/FileTreeDiffTests.js
  16. 6 5
      services/project-history/test/acceptance/js/FlushManagerTests.js
  17. 4 3
      services/project-history/test/acceptance/js/HealthCheckTests.js
  18. 7 6
      services/project-history/test/acceptance/js/LabelsTests.js
  19. 4 3
      services/project-history/test/acceptance/js/ReadingASnapshotTests.js
  20. 6 5
      services/project-history/test/acceptance/js/RetryTests.js
  21. 16 15
      services/project-history/test/acceptance/js/SendingUpdatesTests.js
  22. 4 3
      services/project-history/test/acceptance/js/SummarisedUpdatesTests.js
  23. 6 5
      services/project-history/test/acceptance/js/SyncTests.js
  24. 2 2
      services/project-history/test/acceptance/js/helpers/ProjectHistoryClient.js
  25. 4 3
      services/project-history/test/unit/js/HttpController/HttpControllerTests.js
  26. 17 16
      services/project-history/test/unit/js/LabelsManager/LabelsManagerTests.js
  27. 2 1
      services/project-history/test/unit/js/RetryManager/RetryManagerTests.js
  28. 8 7
      services/project-history/test/unit/js/SyncManager/SyncManagerTests.js

+ 2 - 82
package-lock.json

@@ -45761,7 +45761,7 @@
         "line-reader": "^0.2.4",
         "lodash": "^4.17.20",
         "mongo-uri": "^0.1.2",
-        "mongodb": "^4.11.0",
+        "mongodb-legacy": "^6.0.1",
         "overleaf-editor-core": "*",
         "redis": "~0.10.1",
         "request": "^2.88.2",
@@ -45804,40 +45804,6 @@
         "@hapi/hoek": "^8.3.0"
       }
     },
-    "services/project-history/node_modules/bson": {
-      "version": "4.7.2",
-      "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz",
-      "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==",
-      "dependencies": {
-        "buffer": "^5.6.0"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "services/project-history/node_modules/buffer": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "dependencies": {
-        "base64-js": "^1.3.1",
-        "ieee754": "^1.1.13"
-      }
-    },
     "services/project-history/node_modules/celebrate": {
       "version": "10.1.0",
       "resolved": "https://registry.npmjs.org/celebrate/-/celebrate-10.1.0.tgz",
@@ -45883,23 +45849,6 @@
         "node": ">=0.3.1"
       }
     },
-    "services/project-history/node_modules/mongodb": {
-      "version": "4.17.1",
-      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.17.1.tgz",
-      "integrity": "sha512-MBuyYiPUPRTqfH2dV0ya4dcr2E5N52ocBuZ8Sgg/M030nGF78v855B3Z27mZJnp8PxjnUquEnAtjOsphgMZOlQ==",
-      "dependencies": {
-        "bson": "^4.7.2",
-        "mongodb-connection-string-url": "^2.6.0",
-        "socks": "^2.7.1"
-      },
-      "engines": {
-        "node": ">=12.9.0"
-      },
-      "optionalDependencies": {
-        "@aws-sdk/credential-providers": "^3.186.0",
-        "@mongodb-js/saslprep": "^1.1.0"
-      }
-    },
     "services/project-history/node_modules/nock": {
       "version": "12.0.3",
       "resolved": "https://registry.npmjs.org/nock/-/nock-12.0.3.tgz",
@@ -54735,7 +54684,7 @@
         "lodash": "^4.17.20",
         "mocha": "^10.2.0",
         "mongo-uri": "^0.1.2",
-        "mongodb": "^4.11.0",
+        "mongodb-legacy": "^6.0.1",
         "nock": "^12.0.3",
         "overleaf-editor-core": "*",
         "redis": "~0.10.1",
@@ -54770,23 +54719,6 @@
             "@hapi/hoek": "^8.3.0"
           }
         },
-        "bson": {
-          "version": "4.7.2",
-          "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz",
-          "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==",
-          "requires": {
-            "buffer": "^5.6.0"
-          }
-        },
-        "buffer": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-          "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-          "requires": {
-            "base64-js": "^1.3.1",
-            "ieee754": "^1.1.13"
-          }
-        },
         "celebrate": {
           "version": "10.1.0",
           "resolved": "https://registry.npmjs.org/celebrate/-/celebrate-10.1.0.tgz",
@@ -54820,18 +54752,6 @@
           "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
           "dev": true
         },
-        "mongodb": {
-          "version": "4.17.1",
-          "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.17.1.tgz",
-          "integrity": "sha512-MBuyYiPUPRTqfH2dV0ya4dcr2E5N52ocBuZ8Sgg/M030nGF78v855B3Z27mZJnp8PxjnUquEnAtjOsphgMZOlQ==",
-          "requires": {
-            "@aws-sdk/credential-providers": "^3.186.0",
-            "@mongodb-js/saslprep": "^1.1.0",
-            "bson": "^4.7.2",
-            "mongodb-connection-string-url": "^2.6.0",
-            "socks": "^2.7.1"
-          }
-        },
         "nock": {
           "version": "12.0.3",
           "resolved": "https://registry.npmjs.org/nock/-/nock-12.0.3.tgz",

+ 2 - 2
services/project-history/app/js/HealthChecker.js

@@ -6,7 +6,7 @@
  * DS207: Consider shorter variations of null checks
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  */
-import { ObjectId } from 'mongodb'
+import { ObjectId } from './mongodb.js'
 import request from 'request'
 import async from 'async'
 import settings from '@overleaf/settings'
@@ -17,7 +17,7 @@ import * as LockManager from './LockManager.js'
 const { port } = settings.internal.history
 
 export function check(callback) {
-  const projectId = ObjectId(settings.history.healthCheck.project_id)
+  const projectId = new ObjectId(settings.history.healthCheck.project_id)
   const url = `http://localhost:${port}/project/${projectId}`
   logger.debug({ projectId }, 'running health check')
   const jobs = [

+ 7 - 7
services/project-history/app/js/LabelsManager.js

@@ -20,7 +20,7 @@ export function getLabels(projectId, callback) {
       return callback(OError.tag(error))
     }
     return db.projectHistoryLabels
-      .find({ project_id: ObjectId(projectId) })
+      .find({ project_id: new ObjectId(projectId) })
       .toArray(function (error, labels) {
         if (error != null) {
           return callback(OError.tag(error))
@@ -64,10 +64,10 @@ export function createLabel(
       createdAt = createdAt != null ? new Date(createdAt) : new Date()
 
       const label = {
-        project_id: ObjectId(projectId),
+        project_id: new ObjectId(projectId),
         comment,
         version,
-        user_id: ObjectId(userId),
+        user_id: new ObjectId(userId),
         created_at: createdAt,
       }
       db.projectHistoryLabels.insertOne(label, function (error, confirmation) {
@@ -92,9 +92,9 @@ export function deleteLabel(projectId, userId, labelId, callback) {
       }
       return db.projectHistoryLabels.deleteOne(
         {
-          _id: ObjectId(labelId),
-          project_id: ObjectId(projectId),
-          user_id: ObjectId(userId),
+          _id: new ObjectId(labelId),
+          project_id: new ObjectId(projectId),
+          user_id: new ObjectId(userId),
         },
         callback
       )
@@ -128,7 +128,7 @@ function _toObjectId(...args1) {
   const args = args1.slice(0, adjustedLength - 1)
   const callback = args1[adjustedLength - 1]
   try {
-    const ids = args.map(ObjectId)
+    const ids = args.map(id => new ObjectId(id))
     return callback(null, ...Array.from(ids))
   } catch (error) {
     return callback(error)

+ 3 - 3
services/project-history/app/js/SyncManager.js

@@ -131,7 +131,7 @@ function _startResyncWithoutLock(projectId, options, callback) {
 function _getResyncState(projectId, callback) {
   db.projectHistorySyncState.findOne(
     {
-      project_id: ObjectId(projectId.toString()),
+      project_id: new ObjectId(projectId.toString()),
     },
     function (error, rawSyncState) {
       if (error) {
@@ -172,7 +172,7 @@ export function setResyncState(projectId, syncState, callback) {
   // apply the update
   db.projectHistorySyncState.updateOne(
     {
-      project_id: ObjectId(projectId),
+      project_id: new ObjectId(projectId),
     },
     update,
     {
@@ -185,7 +185,7 @@ export function setResyncState(projectId, syncState, callback) {
 export function clearResyncState(projectId, callback) {
   db.projectHistorySyncState.deleteOne(
     {
-      project_id: ObjectId(projectId.toString()),
+      project_id: new ObjectId(projectId.toString()),
     },
     callback
   )

+ 3 - 2
services/project-history/app/js/mongodb.js

@@ -1,8 +1,9 @@
 import Metrics from '@overleaf/metrics'
 import Settings from '@overleaf/settings'
-import { MongoClient } from 'mongodb'
+import mongodb from 'mongodb-legacy'
+const { MongoClient, ObjectId } = mongodb
 
-export { ObjectId } from 'mongodb'
+export { ObjectId }
 
 export const mongoClient = new MongoClient(Settings.mongo.url)
 const mongoDb = mongoClient.db()

+ 1 - 1
services/project-history/package.json

@@ -38,7 +38,7 @@
     "line-reader": "^0.2.4",
     "lodash": "^4.17.20",
     "mongo-uri": "^0.1.2",
-    "mongodb": "^4.11.0",
+    "mongodb-legacy": "^6.0.1",
     "overleaf-editor-core": "*",
     "redis": "~0.10.1",
     "request": "^2.88.2",

+ 3 - 3
services/project-history/scripts/clear_deleted.js

@@ -20,7 +20,7 @@ function checkAndClear(project, callback) {
   const projectId = project.project_id
   function checkDeleted(cb) {
     db.projects.findOne(
-      { _id: ObjectId(projectId) },
+      { _id: new ObjectId(projectId) },
       { projection: { _id: 1 } },
       (err, result) => {
         if (err) {
@@ -40,9 +40,9 @@ function checkAndClear(project, callback) {
     db.deletedProjects.findOne(
       {
         // this condition makes use of the index
-        'deleterData.deletedProjectId': ObjectId(projectId),
+        'deleterData.deletedProjectId': new ObjectId(projectId),
         // this condition checks if the deleted project has expired
-        'project._id': ObjectId(projectId),
+        'project._id': new ObjectId(projectId),
       },
       { projection: { _id: 1 } },
       (err, result) => {

+ 1 - 1
services/project-history/scripts/clear_deleted_history.js

@@ -35,7 +35,7 @@ function checkAndClear(project, callback) {
 
   function checkDeleted(cb) {
     db.projects.findOne(
-      { _id: ObjectId(projectId) },
+      { _id: new ObjectId(projectId) },
       { projection: { overleaf: true } },
       (err, result) => {
         console.log(

+ 2 - 2
services/project-history/scripts/clear_filestore_404.js

@@ -37,7 +37,7 @@ function checkAndClear(project, callback) {
 
   function checkNotV1Project(cb) {
     db.projects.findOne(
-      { _id: ObjectId(projectId) },
+      { _id: new ObjectId(projectId) },
       { projection: { overleaf: true } },
       (err, result) => {
         console.log(
@@ -67,7 +67,7 @@ function checkAndClear(project, callback) {
       console.log('2. deleting overleaf.history.id in mongo project', projectId)
       // Accessing mongo projects collection directly - BE CAREFUL!
       db.projects.updateOne(
-        { _id: ObjectId(projectId) },
+        { _id: new ObjectId(projectId) },
         { $unset: { 'overleaf.history.id': '' } },
         (err, result) => {
           console.log(' - got result from remove', err, result)

+ 2 - 2
services/project-history/scripts/clear_project_version_out_of_order.js

@@ -39,7 +39,7 @@ function checkAndClear(project, callback) {
 
   function checkNotV1Project(cb) {
     db.projects.findOne(
-      { _id: ObjectId(projectId) },
+      { _id: new ObjectId(projectId) },
       { projection: { overleaf: true } },
       (err, result) => {
         console.log(
@@ -106,7 +106,7 @@ function checkAndClear(project, callback) {
       console.log('2. deleting overleaf.history.id in mongo project', projectId)
       // Accessing mongo projects collection directly - BE CAREFUL!
       db.projects.updateOne(
-        { _id: ObjectId(projectId) },
+        { _id: new ObjectId(projectId) },
         { $rename: { 'overleaf.history.id': 'overleaf.history.deleted_id' } },
         (err, result) => {
           console.log(' - got result from remove', err, result)

+ 1 - 1
services/project-history/scripts/force_resync.js

@@ -40,7 +40,7 @@ function checkAndClear(project, callback) {
 
   function checkNotV1Project(cb) {
     db.projects.findOne(
-      { _id: ObjectId(projectId) },
+      { _id: new ObjectId(projectId) },
       { projection: { overleaf: true } },
       (err, result) => {
         console.log(

+ 4 - 3
services/project-history/test/acceptance/js/DeleteProjectTests.js

@@ -1,8 +1,9 @@
 import { expect } from 'chai'
 import nock from 'nock'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockWeb = () => nock('http://localhost:3000')
@@ -10,8 +11,8 @@ const fixture = path => new URL(`../fixtures/${path}`, import.meta.url)
 
 describe('Deleting project', function () {
   beforeEach(function (done) {
-    this.projectId = ObjectId().toString()
-    this.historyId = ObjectId().toString()
+    this.projectId = new ObjectId().toString()
+    this.historyId = new ObjectId().toString()
     MockWeb()
       .get(`/project/${this.projectId}/details`)
       .reply(200, {

+ 4 - 3
services/project-history/test/acceptance/js/DiffTests.js

@@ -1,10 +1,11 @@
 import { expect } from 'chai'
 import request from 'request'
 import crypto from 'crypto'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import nock from 'nock'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockWeb = () => nock('http://localhost:3000')
@@ -25,8 +26,8 @@ describe('Diffs', function () {
         throw error
       }
 
-      this.historyId = ObjectId().toString()
-      this.projectId = ObjectId().toString()
+      this.historyId = new ObjectId().toString()
+      this.projectId = new ObjectId().toString()
 
       MockHistoryStore().post('/api/projects').reply(200, {
         projectId: this.historyId,

+ 5 - 4
services/project-history/test/acceptance/js/DiscardingUpdatesTests.js

@@ -15,10 +15,11 @@ import sinon from 'sinon'
 import { expect } from 'chai'
 import Settings from '@overleaf/settings'
 import assert from 'assert'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import nock from 'nock'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockWeb = () => nock('http://localhost:3000')
@@ -31,9 +32,9 @@ describe('DiscardingUpdates', function () {
       if (error != null) {
         throw error
       }
-      this.user_id = ObjectId().toString()
-      this.project_id = ObjectId().toString()
-      this.doc_id = ObjectId().toString()
+      this.user_id = new ObjectId().toString()
+      this.project_id = new ObjectId().toString()
+      this.doc_id = new ObjectId().toString()
 
       MockHistoryStore().post('/api/projects').reply(200, {
         projectId: 0,

+ 4 - 3
services/project-history/test/acceptance/js/FileTreeDiffTests.js

@@ -17,11 +17,12 @@ import request from 'request'
 import assert from 'assert'
 import Path from 'path'
 import crypto from 'crypto'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import nock from 'nock'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
 import * as HistoryId from './helpers/HistoryId.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockFileStore = () => nock('http://localhost:3009')
@@ -36,8 +37,8 @@ describe('FileTree Diffs', function () {
         throw error
       }
 
-      this.historyId = ObjectId().toString()
-      this.projectId = ObjectId().toString()
+      this.historyId = new ObjectId().toString()
+      this.projectId = new ObjectId().toString()
 
       MockHistoryStore().post('/api/projects').reply(200, {
         projectId: this.historyId,

+ 6 - 5
services/project-history/test/acceptance/js/FlushManagerTests.js

@@ -3,15 +3,16 @@ import nock from 'nock'
 import { expect } from 'chai'
 import request from 'request'
 import assert from 'assert'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockWeb = () => nock('http://localhost:3000')
 
 describe('Flushing old queues', function () {
-  const historyId = ObjectId().toString()
+  const historyId = new ObjectId().toString()
 
   beforeEach(function (done) {
     this.timestamp = new Date()
@@ -20,9 +21,9 @@ describe('Flushing old queues', function () {
       if (error) {
         throw error
       }
-      this.projectId = ObjectId().toString()
-      this.docId = ObjectId().toString()
-      this.fileId = ObjectId().toString()
+      this.projectId = new ObjectId().toString()
+      this.docId = new ObjectId().toString()
+      this.fileId = new ObjectId().toString()
 
       MockHistoryStore().post('/api/projects').reply(200, {
         projectId: historyId,

+ 4 - 3
services/project-history/test/acceptance/js/HealthCheckTests.js

@@ -12,18 +12,19 @@
 import { expect } from 'chai'
 import settings from '@overleaf/settings'
 import request from 'request'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import nock from 'nock'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockWeb = () => nock('http://localhost:3000')
 
 describe('Health Check', function () {
   beforeEach(function (done) {
-    const projectId = ObjectId()
-    const historyId = ObjectId().toString()
+    const projectId = new ObjectId()
+    const historyId = new ObjectId().toString()
     settings.history.healthCheck = { project_id: projectId }
     return ProjectHistoryApp.ensureRunning(error => {
       if (error != null) {

+ 7 - 6
services/project-history/test/acceptance/js/LabelsTests.js

@@ -13,10 +13,11 @@
 import sinon from 'sinon'
 import { expect } from 'chai'
 import Settings from '@overleaf/settings'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import nock from 'nock'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockFileStore = () => nock('http://localhost:3009')
@@ -31,7 +32,7 @@ describe('Labels', function () {
         throw error
       }
 
-      this.historyId = ObjectId().toString()
+      this.historyId = new ObjectId().toString()
       MockHistoryStore().post('/api/projects').reply(200, {
         projectId: this.historyId,
       })
@@ -42,7 +43,7 @@ describe('Labels', function () {
           if (error != null) {
             throw error
           }
-          this.project_id = ObjectId().toString()
+          this.project_id = new ObjectId().toString()
           MockWeb()
             .get(`/project/${this.project_id}/details`)
             .reply(200, {
@@ -65,7 +66,7 @@ describe('Labels', function () {
 
           this.comment = 'a saved version comment'
           this.comment2 = 'another saved version comment'
-          this.user_id = ObjectId().toString()
+          this.user_id = new ObjectId().toString()
           this.created_at = new Date(1)
           return done()
         }
@@ -138,8 +139,8 @@ describe('Labels', function () {
   })
 
   it('can transfer ownership of labels', function (done) {
-    const fromUser = ObjectId().toString()
-    const toUser = ObjectId().toString()
+    const fromUser = new ObjectId().toString()
+    const toUser = new ObjectId().toString()
     return ProjectHistoryClient.createLabel(
       this.project_id,
       fromUser,

+ 4 - 3
services/project-history/test/acceptance/js/ReadingASnapshotTests.js

@@ -1,8 +1,9 @@
 import { expect } from 'chai'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import nock from 'nock'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockWeb = () => nock('http://localhost:3000')
@@ -16,7 +17,7 @@ describe('ReadSnapshot', function () {
         throw error
       }
 
-      this.historyId = ObjectId().toString()
+      this.historyId = new ObjectId().toString()
       MockHistoryStore().post('/api/projects').reply(200, {
         projectId: this.historyId,
       })
@@ -27,7 +28,7 @@ describe('ReadSnapshot', function () {
           if (error) {
             throw error
           }
-          this.projectId = ObjectId().toString()
+          this.projectId = new ObjectId().toString()
           MockWeb()
             .get(`/project/${this.projectId}/details`)
             .reply(200, {

+ 6 - 5
services/project-history/test/acceptance/js/RetryTests.js

@@ -3,9 +3,10 @@ import nock from 'nock'
 import { expect } from 'chai'
 import request from 'request'
 import assert from 'assert'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockWeb = () => nock('http://localhost:3000')
@@ -13,7 +14,7 @@ const MockWeb = () => nock('http://localhost:3000')
 const MockCallback = () => nock('http://localhost')
 
 describe('Retrying failed projects', function () {
-  const historyId = ObjectId().toString()
+  const historyId = new ObjectId().toString()
 
   beforeEach(function (done) {
     this.timestamp = new Date()
@@ -22,9 +23,9 @@ describe('Retrying failed projects', function () {
       if (error) {
         throw error
       }
-      this.project_id = ObjectId().toString()
-      this.doc_id = ObjectId().toString()
-      this.file_id = ObjectId().toString()
+      this.project_id = new ObjectId().toString()
+      this.doc_id = new ObjectId().toString()
+      this.file_id = new ObjectId().toString()
 
       MockHistoryStore().post('/api/projects').reply(200, {
         projectId: historyId,

+ 16 - 15
services/project-history/test/acceptance/js/SendingUpdatesTests.js

@@ -3,10 +3,11 @@ import Settings from '@overleaf/settings'
 import assert from 'assert'
 import async from 'async'
 import crypto from 'crypto'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import nock from 'nock'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockFileStore = () => nock('http://localhost:3009')
@@ -172,7 +173,7 @@ function olAddFileUpdate(file, userId, ts, fileHash) {
 }
 
 describe('Sending Updates', function () {
-  const historyId = ObjectId().toString()
+  const historyId = new ObjectId().toString()
 
   beforeEach(function (done) {
     this.timestamp = new Date()
@@ -181,9 +182,9 @@ describe('Sending Updates', function () {
       if (error) {
         return done(error)
       }
-      this.userId = ObjectId().toString()
-      this.projectId = ObjectId().toString()
-      this.docId = ObjectId().toString()
+      this.userId = new ObjectId().toString()
+      this.projectId = new ObjectId().toString()
+      this.docId = new ObjectId().toString()
 
       this.doc = {
         id: this.docId,
@@ -432,7 +433,7 @@ describe('Sending Updates', function () {
 
     it('should send add file updates to the history store', function (done) {
       const file = {
-        id: ObjectId().toString(),
+        id: new ObjectId().toString(),
         pathname: '/test.png',
         contents: Buffer.from([1, 2, 3]),
         hash: 'aed2973e4b8a7ff1b30ff5c4751e5a2b38989e74',
@@ -507,7 +508,7 @@ describe('Sending Updates', function () {
         .digest('hex')
 
       const file = {
-        id: ObjectId().toString(),
+        id: new ObjectId().toString(),
         pathname: '/large.png',
         contents: fileContents,
         hash: fileHash,
@@ -940,8 +941,8 @@ describe('Sending Updates', function () {
     })
 
     it('should not concat updates with different user_ids', function (done) {
-      const userId1 = ObjectId().toString()
-      const userId2 = ObjectId().toString()
+      const userId1 = new ObjectId().toString()
+      const userId2 = new ObjectId().toString()
 
       const createChange = MockHistoryStore()
         .post(`/api/projects/${historyId}/legacy_changes`, body => {
@@ -994,12 +995,12 @@ describe('Sending Updates', function () {
 
     it('should not concat updates with different docs', function (done) {
       const doc1 = {
-        id: ObjectId().toString(),
+        id: new ObjectId().toString(),
         pathname: '/doc1.tex',
         length: 10,
       }
       const doc2 = {
-        id: ObjectId().toString(),
+        id: new ObjectId().toString(),
         pathname: '/doc2.tex',
         length: 10,
       }
@@ -1224,7 +1225,7 @@ describe('Sending Updates', function () {
 
     it('should not concat text updates across project structure ops', function (done) {
       const newDoc = {
-        id: ObjectId().toString(),
+        id: new ObjectId().toString(),
         pathname: '/main.tex',
         hash: '0a207c060e61f3b88eaee0a8cd0696f46fb155eb',
         docLines: 'a\nb',
@@ -1628,7 +1629,7 @@ describe('Sending Updates', function () {
 
     it('should return a 500 if the filestore returns a 500', function (done) {
       const file = {
-        id: ObjectId().toString(),
+        id: new ObjectId().toString(),
         pathname: '/test.png',
         contents: Buffer.from([1, 2, 3]),
         hash: 'aed2973e4b8a7ff1b30ff5c4751e5a2b38989e74',
@@ -1704,7 +1705,7 @@ describe('Sending Updates', function () {
 
     it('should return a 500 if the filestore request errors', function (done) {
       const file = {
-        id: ObjectId().toString(),
+        id: new ObjectId().toString(),
         pathname: '/test.png',
         contents: Buffer.from([1, 2, 3]),
         hash: 'aed2973e4b8a7ff1b30ff5c4751e5a2b38989e74',
@@ -1798,7 +1799,7 @@ describe('Sending Updates', function () {
       const newDoc = []
       for (let i = 0; i <= 2; i++) {
         newDoc[i] = {
-          id: ObjectId().toString(),
+          id: new ObjectId().toString(),
           pathname: `/main${i}.tex`,
           hash: '0a207c060e61f3b88eaee0a8cd0696f46fb155eb',
           docLines: 'a\nb',

+ 4 - 3
services/project-history/test/acceptance/js/SummarisedUpdatesTests.js

@@ -15,10 +15,11 @@ import { expect } from 'chai'
 import Settings from '@overleaf/settings'
 import request from 'request'
 import assert from 'assert'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import nock from 'nock'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const MockHistoryStore = () => nock('http://localhost:3100')
 const MockFileStore = () => nock('http://localhost:3009')
@@ -28,8 +29,8 @@ const fixture = path => new URL(`../fixtures/${path}`, import.meta.url)
 
 describe('Summarized updates', function () {
   beforeEach(function (done) {
-    this.projectId = ObjectId().toString()
-    this.historyId = ObjectId().toString()
+    this.projectId = new ObjectId().toString()
+    this.historyId = new ObjectId().toString()
     return ProjectHistoryApp.ensureRunning(error => {
       if (error != null) {
         throw error

+ 6 - 5
services/project-history/test/acceptance/js/SyncTests.js

@@ -3,9 +3,10 @@ import nock from 'nock'
 import { expect } from 'chai'
 import request from 'request'
 import assert from 'assert'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
 import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
+const { ObjectId } = mongodb
 
 const EMPTY_FILE_HASH = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'
 
@@ -14,7 +15,7 @@ const MockFileStore = () => nock('http://localhost:3009')
 const MockWeb = () => nock('http://localhost:3000')
 
 describe('Syncing with web and doc-updater', function () {
-  const historyId = ObjectId().toString()
+  const historyId = new ObjectId().toString()
 
   beforeEach(function (done) {
     this.timestamp = new Date()
@@ -23,9 +24,9 @@ describe('Syncing with web and doc-updater', function () {
       if (error) {
         throw error
       }
-      this.project_id = ObjectId().toString()
-      this.doc_id = ObjectId().toString()
-      this.file_id = ObjectId().toString()
+      this.project_id = new ObjectId().toString()
+      this.doc_id = new ObjectId().toString()
+      this.file_id = new ObjectId().toString()
 
       MockHistoryStore().post('/api/projects').reply(200, {
         projectId: historyId,

+ 2 - 2
services/project-history/test/acceptance/js/helpers/ProjectHistoryClient.js

@@ -250,13 +250,13 @@ export function deleteLabel(projectId, userId, labelId, callback) {
 }
 
 export function setFailure(failureEntry, callback) {
-  db.projectHistoryFailures.remove(
+  db.projectHistoryFailures.deleteOne(
     { project_id: { $exists: true } },
     (err, result) => {
       if (err) {
         return callback(err)
       }
-      db.projectHistoryFailures.insert(failureEntry, callback)
+      db.projectHistoryFailures.insertOne(failureEntry, callback)
     }
   )
 }

+ 4 - 3
services/project-history/test/unit/js/HttpController/HttpControllerTests.js

@@ -1,6 +1,7 @@
 import sinon from 'sinon'
 import { strict as esmock } from 'esmock'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
+const { ObjectId } = mongodb
 
 const MODULE_PATH = '../../../../app/js/HttpController.js'
 
@@ -106,7 +107,7 @@ describe('HttpController', function () {
 
   describe('initializeProject', function () {
     beforeEach(function () {
-      this.historyId = ObjectId().toString()
+      this.historyId = new ObjectId().toString()
       this.req = { body: { historyId: this.historyId } }
       this.HistoryStoreManager.initializeProject.yields(null, this.historyId)
       this.HttpController.initializeProject(this.req, this.res, this.next)
@@ -478,7 +479,7 @@ describe('HttpController', function () {
         params: {
           project_id: this.projectId,
           user_id: this.userId,
-          label_id: (this.label_id = ObjectId()),
+          label_id: (this.label_id = new ObjectId()),
         },
       }
       this.HttpController.deleteLabel(this.req, this.res, this.next)

+ 17 - 16
services/project-history/test/unit/js/LabelsManager/LabelsManagerTests.js

@@ -11,9 +11,10 @@
  */
 import sinon from 'sinon'
 import { expect } from 'chai'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import tk from 'timekeeper'
 import { strict as esmock } from 'esmock'
+const { ObjectId } = mongodb
 
 const MODULE_PATH = '../../../../app/js/LabelsManager.js'
 
@@ -62,10 +63,10 @@ describe('LabelsManager', function () {
   describe('getLabels', function () {
     beforeEach(function () {
       this.label = {
-        _id: ObjectId(),
+        _id: new ObjectId(),
         comment: 'some comment',
         version: 123,
-        user_id: ObjectId(),
+        user_id: new ObjectId(),
         created_at: new Date(),
       }
 
@@ -82,7 +83,7 @@ describe('LabelsManager', function () {
       it('gets the labels state from mongo', function () {
         return expect(
           this.db.projectHistoryLabels.find
-        ).to.have.been.calledWith({ project_id: ObjectId(this.project_id) })
+        ).to.have.been.calledWith({ project_id: new ObjectId(this.project_id) })
       })
 
       return it('returns formatted labels', function () {
@@ -119,7 +120,7 @@ describe('LabelsManager', function () {
       beforeEach(function () {
         this.createdAt = new Date(1)
         this.db.projectHistoryLabels.insertOne.yields(null, {
-          insertedId: ObjectId(this.label_id),
+          insertedId: new ObjectId(this.label_id),
         })
         return this.LabelsManager.createLabel(
           this.project_id,
@@ -155,10 +156,10 @@ describe('LabelsManager', function () {
           this.db.projectHistoryLabels.insertOne
         ).to.have.been.calledWith(
           sinon.match({
-            project_id: ObjectId(this.project_id),
+            project_id: new ObjectId(this.project_id),
             comment: this.comment,
             version: this.version,
-            user_id: ObjectId(this.user_id),
+            user_id: new ObjectId(this.user_id),
             created_at: this.createdAt,
           }),
           sinon.match.any
@@ -167,10 +168,10 @@ describe('LabelsManager', function () {
 
       return it('returns the label', function () {
         return expect(this.callback).to.have.been.calledWith(null, {
-          id: ObjectId(this.label_id),
+          id: new ObjectId(this.label_id),
           comment: this.comment,
           version: this.version,
-          user_id: ObjectId(this.user_id),
+          user_id: new ObjectId(this.user_id),
           created_at: this.createdAt,
         })
       })
@@ -179,7 +180,7 @@ describe('LabelsManager', function () {
     describe('without createdAt', function () {
       beforeEach(function () {
         this.db.projectHistoryLabels.insertOne.yields(null, {
-          insertedId: ObjectId(this.label_id),
+          insertedId: new ObjectId(this.label_id),
         })
         return this.LabelsManager.createLabel(
           this.project_id,
@@ -197,10 +198,10 @@ describe('LabelsManager', function () {
           this.db.projectHistoryLabels.insertOne
         ).to.have.been.calledWith(
           sinon.match({
-            project_id: ObjectId(this.project_id),
+            project_id: new ObjectId(this.project_id),
             comment: this.comment,
             version: this.version,
-            user_id: ObjectId(this.user_id),
+            user_id: new ObjectId(this.user_id),
             created_at: this.now,
           })
         )
@@ -211,7 +212,7 @@ describe('LabelsManager', function () {
       beforeEach(function () {
         this.createdAt = new Date(1)
         this.db.projectHistoryLabels.insertOne.yields(null, {
-          insertedId: ObjectId(this.label_id),
+          insertedId: new ObjectId(this.label_id),
         })
         return this.LabelsManager.createLabel(
           this.project_id,
@@ -247,9 +248,9 @@ describe('LabelsManager', function () {
         this.db.projectHistoryLabels.deleteOne
       ).to.have.been.calledWith(
         {
-          _id: ObjectId(this.label_id),
-          project_id: ObjectId(this.project_id),
-          user_id: ObjectId(this.user_id),
+          _id: new ObjectId(this.label_id),
+          project_id: new ObjectId(this.project_id),
+          user_id: new ObjectId(this.user_id),
         },
         this.callback
       )

+ 2 - 1
services/project-history/test/unit/js/RetryManager/RetryManagerTests.js

@@ -1,7 +1,8 @@
 import sinon from 'sinon'
 import { expect } from 'chai'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import { strict as esmock } from 'esmock'
+const { ObjectId } = mongodb
 
 const MODULE_PATH = '../../../../app/js/RetryManager.js'
 

+ 8 - 7
services/project-history/test/unit/js/SyncManager/SyncManagerTests.js

@@ -1,8 +1,9 @@
 import sinon from 'sinon'
 import { expect } from 'chai'
-import { ObjectId } from 'mongodb'
+import mongodb from 'mongodb-legacy'
 import tk from 'timekeeper'
 import { strict as esmock } from 'esmock'
+const { ObjectId } = mongodb
 
 const MODULE_PATH = '../../../../app/js/SyncManager.js'
 
@@ -125,7 +126,7 @@ describe('SyncManager', function () {
 
       it('gets the sync state from mongo', function () {
         expect(this.db.projectHistorySyncState.findOne).to.have.been.calledWith(
-          { project_id: ObjectId(this.projectId) }
+          { project_id: new ObjectId(this.projectId) }
         )
       })
 
@@ -140,7 +141,7 @@ describe('SyncManager', function () {
           this.db.projectHistorySyncState.updateOne
         ).to.have.been.calledWith(
           {
-            project_id: ObjectId(this.projectId),
+            project_id: new ObjectId(this.projectId),
           },
           sinon.match({
             $set: {
@@ -219,7 +220,7 @@ describe('SyncManager', function () {
               this.db.projectHistorySyncState.updateOne
             ).to.have.been.calledWith(
               {
-                project_id: ObjectId(this.projectId),
+                project_id: new ObjectId(this.projectId),
               },
               sinon.match({
                 $set: this.syncState.toRaw(),
@@ -261,7 +262,7 @@ describe('SyncManager', function () {
               this.db.projectHistorySyncState.updateOne
             ).to.have.been.calledWith(
               {
-                project_id: ObjectId(this.projectId),
+                project_id: new ObjectId(this.projectId),
               },
               sinon.match({
                 $set: {
@@ -621,7 +622,7 @@ describe('SyncManager', function () {
       it('queues blank doc additions for missing docs', function () {
         const newDoc = {
           path: 'another.tex',
-          doc: ObjectId().toString(),
+          doc: new ObjectId().toString(),
         }
         const updates = [
           resyncProjectStructureUpdate(
@@ -919,7 +920,7 @@ describe('SyncManager', function () {
         this.UpdateCompressor.diffAsShareJsOps.returns([{ i: 'a', p: 0 }])
         const newDoc = {
           path: 'another.tex',
-          doc: ObjectId().toString(),
+          doc: new ObjectId().toString(),
           content: 'a',
         }
         const updates = [