mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #3014 from overleaf/ns-delete-project-history-cleanup
Decaf cleanup HistoryController GitOrigin-RevId: e5df4cde30d8b9e65062e1484699326e96c4eb92
This commit is contained in:
parent
1fe7eaab90
commit
3ce57ed442
2 changed files with 102 additions and 150 deletions
|
@ -1,22 +1,5 @@
|
||||||
/* eslint-disable
|
|
||||||
camelcase,
|
|
||||||
handle-callback-err,
|
|
||||||
max-len,
|
|
||||||
no-undef,
|
|
||||||
no-unused-vars,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
|
||||||
* DS103: Rewrite code to no longer use __guard__
|
|
||||||
* DS207: Consider shorter variations of null checks
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
let HistoryController
|
let HistoryController
|
||||||
const OError = require('@overleaf/o-error')
|
const OError = require('@overleaf/o-error')
|
||||||
const _ = require('lodash')
|
|
||||||
const async = require('async')
|
const async = require('async')
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
|
@ -32,45 +15,32 @@ const { pipeline } = require('stream')
|
||||||
|
|
||||||
module.exports = HistoryController = {
|
module.exports = HistoryController = {
|
||||||
selectHistoryApi(req, res, next) {
|
selectHistoryApi(req, res, next) {
|
||||||
if (next == null) {
|
const { Project_id: projectId } = req.params
|
||||||
next = function(error) {}
|
|
||||||
}
|
|
||||||
const project_id = req.params != null ? req.params.Project_id : undefined
|
|
||||||
// find out which type of history service this project uses
|
// find out which type of history service this project uses
|
||||||
return ProjectDetailsHandler.getDetails(project_id, function(err, project) {
|
ProjectDetailsHandler.getDetails(projectId, function(err, project) {
|
||||||
if (err != null) {
|
if (err) {
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
const history =
|
const history = project.overleaf && project.overleaf.history
|
||||||
project.overleaf != null ? project.overleaf.history : undefined
|
if (history && history.id && history.display) {
|
||||||
if (
|
|
||||||
(history != null ? history.id : undefined) != null &&
|
|
||||||
(history != null ? history.display : undefined)
|
|
||||||
) {
|
|
||||||
req.useProjectHistory = true
|
req.useProjectHistory = true
|
||||||
} else {
|
} else {
|
||||||
req.useProjectHistory = false
|
req.useProjectHistory = false
|
||||||
}
|
}
|
||||||
return next()
|
next()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
ensureProjectHistoryEnabled(req, res, next) {
|
ensureProjectHistoryEnabled(req, res, next) {
|
||||||
if (next == null) {
|
if (req.useProjectHistory) {
|
||||||
next = function(error) {}
|
next()
|
||||||
}
|
|
||||||
if (req.useProjectHistory != null) {
|
|
||||||
return next()
|
|
||||||
} else {
|
} else {
|
||||||
return res.sendStatus(404)
|
res.sendStatus(404)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
proxyToHistoryApi(req, res, next) {
|
proxyToHistoryApi(req, res, next) {
|
||||||
if (next == null) {
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
next = function(error) {}
|
|
||||||
}
|
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
|
||||||
const url =
|
const url =
|
||||||
HistoryController.buildHistoryServiceUrl(req.useProjectHistory) + req.url
|
HistoryController.buildHistoryServiceUrl(req.useProjectHistory) + req.url
|
||||||
|
|
||||||
|
@ -78,41 +48,38 @@ module.exports = HistoryController = {
|
||||||
url,
|
url,
|
||||||
method: req.method,
|
method: req.method,
|
||||||
headers: {
|
headers: {
|
||||||
'X-User-Id': user_id
|
'X-User-Id': userId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
getReq.pipe(res)
|
getReq.pipe(res)
|
||||||
return getReq.on('error', function(error) {
|
getReq.on('error', function(err) {
|
||||||
logger.warn({ url, err: error }, 'history API error')
|
logger.warn({ url, err }, 'history API error')
|
||||||
return next(error)
|
next(err)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
proxyToHistoryApiAndInjectUserDetails(req, res, next) {
|
proxyToHistoryApiAndInjectUserDetails(req, res, next) {
|
||||||
if (next == null) {
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
next = function(error) {}
|
|
||||||
}
|
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
|
||||||
const url =
|
const url =
|
||||||
HistoryController.buildHistoryServiceUrl(req.useProjectHistory) + req.url
|
HistoryController.buildHistoryServiceUrl(req.useProjectHistory) + req.url
|
||||||
return HistoryController._makeRequest(
|
HistoryController._makeRequest(
|
||||||
{
|
{
|
||||||
url,
|
url,
|
||||||
method: req.method,
|
method: req.method,
|
||||||
json: true,
|
json: true,
|
||||||
headers: {
|
headers: {
|
||||||
'X-User-Id': user_id
|
'X-User-Id': userId
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function(error, body) {
|
function(err, body) {
|
||||||
if (error != null) {
|
if (err) {
|
||||||
return next(error)
|
return next(err)
|
||||||
}
|
}
|
||||||
return HistoryManager.injectUserDetails(body, function(error, data) {
|
HistoryManager.injectUserDetails(body, function(err, data) {
|
||||||
if (error != null) {
|
if (err) {
|
||||||
return next(error)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.json(data)
|
res.json(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -129,37 +96,32 @@ module.exports = HistoryController = {
|
||||||
},
|
},
|
||||||
|
|
||||||
resyncProjectHistory(req, res, next) {
|
resyncProjectHistory(req, res, next) {
|
||||||
if (next == null) {
|
const projectId = req.params.Project_id
|
||||||
next = function(error) {}
|
ProjectEntityUpdateHandler.resyncProjectHistory(projectId, function(err) {
|
||||||
}
|
if (err instanceof Errors.ProjectHistoryDisabledError) {
|
||||||
const project_id = req.params.Project_id
|
|
||||||
return ProjectEntityUpdateHandler.resyncProjectHistory(project_id, function(
|
|
||||||
error
|
|
||||||
) {
|
|
||||||
if (error instanceof Errors.ProjectHistoryDisabledError) {
|
|
||||||
return res.sendStatus(404)
|
return res.sendStatus(404)
|
||||||
}
|
}
|
||||||
if (error != null) {
|
if (err) {
|
||||||
return next(error)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.sendStatus(204)
|
res.sendStatus(204)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
restoreFileFromV2(req, res, next) {
|
restoreFileFromV2(req, res, next) {
|
||||||
const { project_id } = req.params
|
const { project_id: projectId } = req.params
|
||||||
const { version, pathname } = req.body
|
const { version, pathname } = req.body
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
return RestoreManager.restoreFileFromV2(
|
RestoreManager.restoreFileFromV2(
|
||||||
user_id,
|
userId,
|
||||||
project_id,
|
projectId,
|
||||||
version,
|
version,
|
||||||
pathname,
|
pathname,
|
||||||
function(error, entity) {
|
function(err, entity) {
|
||||||
if (error != null) {
|
if (err) {
|
||||||
return next(error)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.json({
|
res.json({
|
||||||
type: entity.type,
|
type: entity.type,
|
||||||
id: entity._id
|
id: entity._id
|
||||||
})
|
})
|
||||||
|
@ -168,19 +130,19 @@ module.exports = HistoryController = {
|
||||||
},
|
},
|
||||||
|
|
||||||
restoreDocFromDeletedDoc(req, res, next) {
|
restoreDocFromDeletedDoc(req, res, next) {
|
||||||
const { project_id, doc_id } = req.params
|
const { project_id: projectId, doc_id: docId } = req.params
|
||||||
const { name } = req.body
|
const { name } = req.body
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
return res.sendStatus(400) // Malformed request
|
return res.sendStatus(400) // Malformed request
|
||||||
}
|
}
|
||||||
return RestoreManager.restoreDocFromDeletedDoc(
|
RestoreManager.restoreDocFromDeletedDoc(
|
||||||
user_id,
|
userId,
|
||||||
project_id,
|
projectId,
|
||||||
doc_id,
|
docId,
|
||||||
name,
|
name,
|
||||||
(error, doc) => {
|
(err, doc) => {
|
||||||
if (error != null) return next(error)
|
if (err) return next(err)
|
||||||
res.json({
|
res.json({
|
||||||
doc_id: doc._id
|
doc_id: doc._id
|
||||||
})
|
})
|
||||||
|
@ -189,51 +151,48 @@ module.exports = HistoryController = {
|
||||||
},
|
},
|
||||||
|
|
||||||
getLabels(req, res, next) {
|
getLabels(req, res, next) {
|
||||||
const project_id = req.params.Project_id
|
const projectId = req.params.Project_id
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
HistoryController._makeRequest(
|
||||||
return HistoryController._makeRequest(
|
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `${
|
url: `${settings.apis.project_history.url}/project/${projectId}/labels`,
|
||||||
settings.apis.project_history.url
|
|
||||||
}/project/${project_id}/labels`,
|
|
||||||
json: true
|
json: true
|
||||||
},
|
},
|
||||||
function(error, labels) {
|
function(err, labels) {
|
||||||
if (error != null) {
|
if (err) {
|
||||||
return next(error)
|
return next(err)
|
||||||
}
|
}
|
||||||
HistoryController._enrichLabels(labels, (err, labels) => {
|
HistoryController._enrichLabels(labels, (err, labels) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.json(labels)
|
res.json(labels)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
createLabel(req, res, next) {
|
createLabel(req, res, next) {
|
||||||
const project_id = req.params.Project_id
|
const projectId = req.params.Project_id
|
||||||
const { comment, version } = req.body
|
const { comment, version } = req.body
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
return HistoryController._makeRequest(
|
HistoryController._makeRequest(
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${
|
url: `${
|
||||||
settings.apis.project_history.url
|
settings.apis.project_history.url
|
||||||
}/project/${project_id}/user/${user_id}/labels`,
|
}/project/${projectId}/user/${userId}/labels`,
|
||||||
json: { comment, version }
|
json: { comment, version }
|
||||||
},
|
},
|
||||||
function(error, label) {
|
function(err, label) {
|
||||||
if (error != null) {
|
if (err) {
|
||||||
return next(error)
|
return next(err)
|
||||||
}
|
}
|
||||||
HistoryController._enrichLabel(label, (err, label) => {
|
HistoryController._enrichLabel(label, (err, label) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.json(label)
|
res.json(label)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -293,7 +252,7 @@ module.exports = HistoryController = {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return 'Anonymous'
|
return 'Anonymous'
|
||||||
}
|
}
|
||||||
if (user.name != null) {
|
if (user.name) {
|
||||||
return user.name
|
return user.name
|
||||||
}
|
}
|
||||||
let name = [user.first_name, user.last_name]
|
let name = [user.first_name, user.last_name]
|
||||||
|
@ -303,67 +262,66 @@ module.exports = HistoryController = {
|
||||||
if (name === '') {
|
if (name === '') {
|
||||||
name = user.email.split('@')[0]
|
name = user.email.split('@')[0]
|
||||||
}
|
}
|
||||||
if (name == null || name === '') {
|
if (!name) {
|
||||||
return '?'
|
return '?'
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteLabel(req, res, next) {
|
deleteLabel(req, res, next) {
|
||||||
const project_id = req.params.Project_id
|
const { Project_id: projectId, label_id: labelId } = req.params
|
||||||
const { label_id } = req.params
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
HistoryController._makeRequest(
|
||||||
return HistoryController._makeRequest(
|
|
||||||
{
|
{
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
url: `${
|
url: `${
|
||||||
settings.apis.project_history.url
|
settings.apis.project_history.url
|
||||||
}/project/${project_id}/user/${user_id}/labels/${label_id}`
|
}/project/${projectId}/user/${userId}/labels/${labelId}`
|
||||||
},
|
},
|
||||||
function(error) {
|
function(err) {
|
||||||
if (error != null) {
|
if (err) {
|
||||||
return next(error)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.sendStatus(204)
|
res.sendStatus(204)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
_makeRequest(options, callback) {
|
_makeRequest(options, callback) {
|
||||||
return request(options, function(error, response, body) {
|
return request(options, function(err, response, body) {
|
||||||
if (error != null) {
|
if (err) {
|
||||||
return callback(error)
|
return callback(err)
|
||||||
}
|
}
|
||||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
return callback(null, body)
|
callback(null, body)
|
||||||
} else {
|
} else {
|
||||||
error = new Error(
|
err = new Error(
|
||||||
`history api responded with non-success code: ${response.statusCode}`
|
`history api responded with non-success code: ${response.statusCode}`
|
||||||
)
|
)
|
||||||
return callback(error)
|
callback(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
downloadZipOfVersion(req, res, next) {
|
downloadZipOfVersion(req, res, next) {
|
||||||
const { project_id, version } = req.params
|
const { project_id: projectId, version } = req.params
|
||||||
return ProjectDetailsHandler.getDetails(project_id, function(err, project) {
|
ProjectDetailsHandler.getDetails(projectId, function(err, project) {
|
||||||
if (err != null) {
|
if (err) {
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
const v1_id = __guard__(
|
const v1Id =
|
||||||
project.overleaf != null ? project.overleaf.history : undefined,
|
project.overleaf &&
|
||||||
x => x.id
|
project.overleaf.history &&
|
||||||
)
|
project.overleaf.history.id
|
||||||
if (v1_id == null) {
|
if (v1Id == null) {
|
||||||
logger.err(
|
logger.error(
|
||||||
{ project_id, version },
|
{ projectId, version },
|
||||||
'got request for zip version of non-v1 history project'
|
'got request for zip version of non-v1 history project'
|
||||||
)
|
)
|
||||||
return res.sendStatus(402)
|
return res.sendStatus(402)
|
||||||
}
|
}
|
||||||
return HistoryController._pipeHistoryZipToResponse(
|
HistoryController._pipeHistoryZipToResponse(
|
||||||
v1_id,
|
v1Id,
|
||||||
version,
|
version,
|
||||||
`${project.name} (Version ${version})`,
|
`${project.name} (Version ${version})`,
|
||||||
req,
|
req,
|
||||||
|
@ -373,7 +331,7 @@ module.exports = HistoryController = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
_pipeHistoryZipToResponse(v1_project_id, version, name, req, res, next) {
|
_pipeHistoryZipToResponse(v1ProjectId, version, name, req, res, next) {
|
||||||
if (req.aborted) {
|
if (req.aborted) {
|
||||||
// client has disconnected -- skip project history api call and download
|
// client has disconnected -- skip project history api call and download
|
||||||
return
|
return
|
||||||
|
@ -382,7 +340,7 @@ module.exports = HistoryController = {
|
||||||
res.setTimeout(6 * 60 * 1000)
|
res.setTimeout(6 * 60 * 1000)
|
||||||
const url = `${
|
const url = `${
|
||||||
settings.apis.v1_history.url
|
settings.apis.v1_history.url
|
||||||
}/projects/${v1_project_id}/version/${version}/zip`
|
}/projects/${v1ProjectId}/version/${version}/zip`
|
||||||
const options = {
|
const options = {
|
||||||
auth: {
|
auth: {
|
||||||
user: settings.apis.v1_history.user,
|
user: settings.apis.v1_history.user,
|
||||||
|
@ -392,10 +350,10 @@ module.exports = HistoryController = {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
return request(options, function(err, response, body) {
|
request(options, function(err, response, body) {
|
||||||
if (err) {
|
if (err) {
|
||||||
OError.tag(err, 'history API error', {
|
OError.tag(err, 'history API error', {
|
||||||
v1_project_id,
|
v1ProjectId,
|
||||||
version
|
version
|
||||||
})
|
})
|
||||||
return next(err)
|
return next(err)
|
||||||
|
@ -407,7 +365,7 @@ module.exports = HistoryController = {
|
||||||
let retryAttempt = 0
|
let retryAttempt = 0
|
||||||
let retryDelay = 2000
|
let retryDelay = 2000
|
||||||
// retry for about 6 minutes starting with short delay
|
// retry for about 6 minutes starting with short delay
|
||||||
return async.retry(
|
async.retry(
|
||||||
40,
|
40,
|
||||||
callback =>
|
callback =>
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
@ -448,39 +406,33 @@ module.exports = HistoryController = {
|
||||||
pipeline(response, res, err => {
|
pipeline(response, res, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{ err, v1_project_id, version, retryAttempt },
|
{ err, v1ProjectId, version, retryAttempt },
|
||||||
'history s3 proxying error'
|
'history s3 proxying error'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
callback()
|
callback()
|
||||||
})
|
})
|
||||||
return getReq.on('error', function(err) {
|
getReq.on('error', function(err) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{ err, v1_project_id, version, retryAttempt },
|
{ err, v1ProjectId, version, retryAttempt },
|
||||||
'history s3 download error'
|
'history s3 download error'
|
||||||
)
|
)
|
||||||
cleanupAbortTrigger()
|
cleanupAbortTrigger()
|
||||||
return callback(err)
|
callback(err)
|
||||||
})
|
})
|
||||||
}, retryDelay),
|
}, retryDelay),
|
||||||
function(err) {
|
function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
OError.tag(err, 'history s3 download failed', {
|
OError.tag(err, 'history s3 download failed', {
|
||||||
v1_project_id,
|
v1ProjectId,
|
||||||
version,
|
version,
|
||||||
retryAttempt
|
retryAttempt
|
||||||
})
|
})
|
||||||
return next(err)
|
next(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function __guard__(value, transform) {
|
|
||||||
return typeof value !== 'undefined' && value !== null
|
|
||||||
? transform(value)
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ describe('HistoryController', function() {
|
||||||
|
|
||||||
describe('selectHistoryApi', function() {
|
describe('selectHistoryApi', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.req = { url: '/mock/url', method: 'POST' }
|
this.req = { url: '/mock/url', method: 'POST', params: {} }
|
||||||
this.res = 'mock-res'
|
this.res = 'mock-res'
|
||||||
return (this.next = sinon.stub())
|
return (this.next = sinon.stub())
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue