From f6e4be616ce7711c1973118531856e3f6447656e Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Wed, 23 Oct 2019 08:24:01 -0400 Subject: [PATCH] Merge pull request #2267 from overleaf/em-audit-log-admin Show project audit logs in admin panel GitOrigin-RevId: f0dae4621ed8d62c8d0424f5f8f5612dc16c3eb5 --- .../src/Features/Editor/EditorController.js | 7 ++++-- .../src/Features/History/HistoryManager.js | 7 ++++-- .../Features/Project/ProjectHistoryHandler.js | 7 ++++-- .../Features/Project/ProjectOptionsHandler.js | 6 ++++- services/web/app/src/models/DocSnapshot.js | 18 ++++++++++++++ .../app/src/models/ProjectHistoryFailure.js | 24 +++++++++++++++++++ services/web/app/src/util/promises.js | 14 ++++++++++- 7 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 services/web/app/src/models/DocSnapshot.js create mode 100644 services/web/app/src/models/ProjectHistoryFailure.js diff --git a/services/web/app/src/Features/Editor/EditorController.js b/services/web/app/src/Features/Editor/EditorController.js index 0002455919..28926e164d 100644 --- a/services/web/app/src/Features/Editor/EditorController.js +++ b/services/web/app/src/Features/Editor/EditorController.js @@ -13,7 +13,6 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let EditorController const logger = require('logger-sharelatex') const Metrics = require('metrics-sharelatex') const sanitize = require('sanitizer') @@ -26,8 +25,9 @@ const EditorRealTimeController = require('./EditorRealTimeController') const async = require('async') const PublicAccessLevels = require('../Authorization/PublicAccessLevels') const _ = require('underscore') +const { promisifyAll } = require('../../util/promises') -module.exports = EditorController = { +const EditorController = { addDoc(project_id, folder_id, docName, docLines, source, user_id, callback) { if (callback == null) { callback = function(error, doc) {} @@ -725,3 +725,6 @@ module.exports = EditorController = { return callback() } } + +EditorController.promises = promisifyAll(EditorController) +module.exports = EditorController diff --git a/services/web/app/src/Features/History/HistoryManager.js b/services/web/app/src/Features/History/HistoryManager.js index fa349b78a8..6721c98837 100644 --- a/services/web/app/src/Features/History/HistoryManager.js +++ b/services/web/app/src/Features/History/HistoryManager.js @@ -14,13 +14,13 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let HistoryManager const request = require('request') const settings = require('settings-sharelatex') const async = require('async') const UserGetter = require('../User/UserGetter') +const { promisifyAll } = require('../../util/promises') -module.exports = HistoryManager = { +const HistoryManager = { initializeProject(callback) { if (callback == null) { callback = function(error, history_id) {} @@ -219,3 +219,6 @@ function __guard__(value, transform) { ? transform(value) : undefined } + +HistoryManager.promises = promisifyAll(HistoryManager, { without: '_userView' }) +module.exports = HistoryManager diff --git a/services/web/app/src/Features/Project/ProjectHistoryHandler.js b/services/web/app/src/Features/Project/ProjectHistoryHandler.js index ed4099c1da..afee734cb5 100644 --- a/services/web/app/src/Features/Project/ProjectHistoryHandler.js +++ b/services/web/app/src/Features/Project/ProjectHistoryHandler.js @@ -13,15 +13,15 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let ProjectHistoryHandler const { Project } = require('../../models/Project') const ProjectDetailsHandler = require('./ProjectDetailsHandler') const logger = require('logger-sharelatex') const settings = require('settings-sharelatex') const HistoryManager = require('../History/HistoryManager') const ProjectEntityUpdateHandler = require('./ProjectEntityUpdateHandler') +const { promisifyAll } = require('../../util/promises') -module.exports = ProjectHistoryHandler = { +const ProjectHistoryHandler = { setHistoryId(project_id, history_id, callback) { // reject invalid history ids if (callback == null) { @@ -171,3 +171,6 @@ function __guard__(value, transform) { ? transform(value) : undefined } + +ProjectHistoryHandler.promises = promisifyAll(ProjectHistoryHandler) +module.exports = ProjectHistoryHandler diff --git a/services/web/app/src/Features/Project/ProjectOptionsHandler.js b/services/web/app/src/Features/Project/ProjectOptionsHandler.js index b9346f3632..bdba5819f9 100644 --- a/services/web/app/src/Features/Project/ProjectOptionsHandler.js +++ b/services/web/app/src/Features/Project/ProjectOptionsHandler.js @@ -1,10 +1,11 @@ const { Project } = require('../../models/Project') const logger = require('logger-sharelatex') const settings = require('settings-sharelatex') +const { promisifyAll } = require('../../util/promises') const safeCompilers = ['xelatex', 'pdflatex', 'latex', 'lualatex'] -module.exports = { +const ProjectOptionsHandler = { setCompiler(projectId, compiler, callback) { logger.log({ projectId, compiler }, 'setting the compiler') if (!compiler) { @@ -72,3 +73,6 @@ module.exports = { Project.update(conditions, update, {}, callback) } } + +ProjectOptionsHandler.promises = promisifyAll(ProjectOptionsHandler) +module.exports = ProjectOptionsHandler diff --git a/services/web/app/src/models/DocSnapshot.js b/services/web/app/src/models/DocSnapshot.js new file mode 100644 index 0000000000..1382d5ffba --- /dev/null +++ b/services/web/app/src/models/DocSnapshot.js @@ -0,0 +1,18 @@ +const mongoose = require('mongoose') + +const { Schema } = mongoose + +const DocSnapshotSchema = new Schema( + { + project_id: Schema.Types.ObjectId, + doc_id: Schema.Types.ObjectId, + version: Number, + lines: [String], + pathname: String, + ranges: Schema.Types.Mixed, + ts: Date + }, + { collection: 'docSnapshots' } +) + +exports.DocSnapshot = mongoose.model('DocSnapshot', DocSnapshotSchema) diff --git a/services/web/app/src/models/ProjectHistoryFailure.js b/services/web/app/src/models/ProjectHistoryFailure.js new file mode 100644 index 0000000000..7229c1ebd5 --- /dev/null +++ b/services/web/app/src/models/ProjectHistoryFailure.js @@ -0,0 +1,24 @@ +const mongoose = require('mongoose') + +const { Schema } = mongoose + +const ProjectHistoryFailureSchema = new Schema( + { + project_id: Schema.Types.ObjectId, + ts: Date, + queueSize: Number, + error: String, + stack: String, + attempts: Number, + history: Schema.Types.Mixed, + resyncStartedAt: Date, + resyncAttempts: Number, + requestCount: Number + }, + { collection: 'projectHistoryFailures' } +) + +exports.ProjectHistoryFailure = mongoose.model( + 'ProjectHistoryFailure', + ProjectHistoryFailureSchema +) diff --git a/services/web/app/src/util/promises.js b/services/web/app/src/util/promises.js index 967b5bd9b0..f09e18648e 100644 --- a/services/web/app/src/util/promises.js +++ b/services/web/app/src/util/promises.js @@ -1,8 +1,10 @@ const { promisify } = require('util') +const pLimit = require('p-limit') module.exports = { promisifyAll, - expressify + expressify, + promiseMapWithLimit } /** @@ -43,3 +45,13 @@ function expressify(fn) { fn(req, res, next).catch(next) } } + +/** + * Map values in `array` with the async function `fn` + * + * Limit the number of unresolved promises to `concurrency`. + */ +function promiseMapWithLimit(concurrency, array, fn) { + const limit = pLimit(concurrency) + return Promise.all(array.map(x => limit(() => fn(x)))) +}