Files
overleaf-cep/services/web/app/src/Features/ThirdPartyDataStore/TpdsController.js
Alf Eaton 1ebc8a79cb Merge pull request #3495 from overleaf/ae-prettier-2
Upgrade Prettier to v2

GitOrigin-RevId: 85aa3fa1acb6332c4f58c46165a43d1a51471f33
2021-04-15 02:05:22 +00:00

140 lines
4.4 KiB
JavaScript

let parseParams
const TpdsUpdateHandler = require('./TpdsUpdateHandler')
const UpdateMerger = require('./UpdateMerger')
const Errors = require('../Errors/Errors')
const logger = require('logger-sharelatex')
const Path = require('path')
const metrics = require('@overleaf/metrics')
const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
const AuthenticationController = require('../Authentication/AuthenticationController')
const TpdsQueueManager = require('./TpdsQueueManager').promises
module.exports = {
// mergeUpdate and deleteUpdate are used by Dropbox, where the project is only passed as the name, as the
// first part of the file path. They have to check the project exists, find it, and create it if not.
// They also ignore 'noisy' files like .DS_Store, .gitignore, etc.
mergeUpdate(req, res) {
metrics.inc('tpds.merge-update')
const { filePath, userId, projectName } = parseParams(req)
const source = req.headers['x-sl-update-source'] || 'unknown'
TpdsUpdateHandler.newUpdate(
userId,
projectName,
filePath,
req,
source,
err => {
if (err) {
if (err.name === 'TooManyRequestsError') {
logger.warn(
{ err, userId, filePath },
'tpds update failed to be processed, too many requests'
)
res.sendStatus(429)
} else if (err.message === 'project_has_too_many_files') {
logger.warn(
{ err, userId, filePath },
'tpds trying to append to project over file limit'
)
NotificationsBuilder.tpdsFileLimit(userId).create(projectName)
res.sendStatus(400)
} else {
logger.err(
{ err, userId, filePath },
'error receiving update from tpds'
)
res.sendStatus(500)
}
} else {
res.sendStatus(200)
}
}
)
},
deleteUpdate(req, res) {
metrics.inc('tpds.delete-update')
const { filePath, userId, projectName } = parseParams(req)
const source = req.headers['x-sl-update-source'] || 'unknown'
TpdsUpdateHandler.deleteUpdate(
userId,
projectName,
filePath,
source,
err => {
if (err) {
logger.err(
{ err, userId, filePath },
'error receiving update from tpds'
)
res.sendStatus(500)
} else {
res.sendStatus(200)
}
}
)
},
// updateProjectContents and deleteProjectContents are used by GitHub. The project_id is known so we
// can skip right ahead to creating/updating/deleting the file. These methods will not ignore noisy
// files like .DS_Store, .gitignore, etc because people are generally more explicit with the files they
// want in git.
updateProjectContents(req, res, next) {
const projectId = req.params.project_id
const path = `/${req.params[0]}` // UpdateMerger expects leading slash
const source = req.headers['x-sl-update-source'] || 'unknown'
UpdateMerger.mergeUpdate(null, projectId, path, req, source, error => {
if (error) {
if (error.constructor === Errors.InvalidNameError) {
return res.sendStatus(422)
} else {
return next(error)
}
}
res.sendStatus(200)
})
},
deleteProjectContents(req, res, next) {
const projectId = req.params.project_id
const path = `/${req.params[0]}` // UpdateMerger expects leading slash
const source = req.headers['x-sl-update-source'] || 'unknown'
UpdateMerger.deleteUpdate(null, projectId, path, source, error => {
if (error) {
return next(error)
}
res.sendStatus(200)
})
},
async getQueues(req, res, next) {
const userId = AuthenticationController.getLoggedInUserId(req)
try {
res.json(await TpdsQueueManager.getQueues(userId))
} catch (err) {
next(err)
}
},
parseParams: (parseParams = function (req) {
let filePath, projectName
let path = req.params[0]
const userId = req.params.user_id
path = Path.join('/', path)
if (path.substring(1).indexOf('/') === -1) {
filePath = '/'
projectName = path.substring(1)
} else {
filePath = path.substring(path.indexOf('/', 1))
projectName = path.substring(0, path.indexOf('/', 1))
projectName = projectName.replace('/', '')
}
return { filePath, userId, projectName }
})
}