Merge pull request #3495 from overleaf/ae-prettier-2

Upgrade Prettier to v2

GitOrigin-RevId: 85aa3fa1acb6332c4f58c46165a43d1a51471f33
This commit is contained in:
Alf Eaton
2021-04-14 14:17:21 +01:00
committed by Copybot
parent 930d7ba028
commit 1ebc8a79cb
582 changed files with 20382 additions and 20374 deletions

View File

@@ -5,3 +5,4 @@ frontend/js/vendor
modules/**/frontend/js/vendor
public/js
public/minjs
frontend/stylesheets/components/nvd3.less

View File

@@ -45,7 +45,7 @@ if (!module.parent) {
}
Promise.all([mongodb.waitForDb(), mongoose.connectionPromise])
.then(() => {
Server.server.listen(port, host, function() {
Server.server.listen(port, host, function () {
logger.info(`web starting up, listening on ${host}:${port}`)
logger.info(`${require('http').globalAgent.maxSockets} sockets enabled`)
// wait until the process is ready before monitoring the event loop
@@ -59,7 +59,7 @@ if (!module.parent) {
}
// handle SIGTERM for graceful shutdown in kubernetes
process.on('SIGTERM', function(signal) {
process.on('SIGTERM', function (signal) {
logger.warn({ signal: signal }, 'received signal, shutting down')
Settings.shuttingDown = true
})

View File

@@ -15,7 +15,7 @@ module.exports = {
let countryCode = null
if (userId) {
GeoIpLookup.getDetails(req.ip, function(err, geoDetails) {
GeoIpLookup.getDetails(req.ip, function (err, geoDetails) {
if (err) {
metrics.inc('analytics_geo_ip_lookup_errors')
} else if (geoDetails && geoDetails.country_code) {
@@ -43,7 +43,7 @@ module.exports = {
req.query.start_date,
req.query.end_date,
req.query.lag,
function(error, licences) {
function (error, licences) {
if (error) {
return next(error)
}
@@ -58,7 +58,7 @@ module.exports = {
req.query.start_date,
req.query.end_date,
req.query.lag,
function(error, licences) {
function (error, licences) {
if (error) {
return next(error)
}

View File

@@ -58,7 +58,7 @@ const AuthenticationController = {
// This function is middleware which wraps the passport.authenticate middleware,
// so we can send back our custom `{message: {text: "", type: ""}}` responses on failure,
// and send a `{redir: ""}` response on success
passport.authenticate('local', function(err, user, info) {
passport.authenticate('local', function (err, user, info) {
if (err) {
return next(err)
}
@@ -81,86 +81,96 @@ const AuthenticationController = {
} // OAuth2 'state' mismatch
const Modules = require('../../infrastructure/Modules')
Modules.hooks.fire('preFinishLogin', req, res, user, function(
error,
results
) {
if (error) {
return next(error)
}
if (results.some(result => result && result.doNotFinish)) {
return
}
if (user.must_reconfirm) {
return AuthenticationController._redirectToReconfirmPage(req, res, user)
}
const redir =
AuthenticationController._getRedirectFromSession(req) || '/project'
_loginAsyncHandlers(req, user)
const userId = user._id
UserAuditLogHandler.addEntry(userId, 'login', userId, req.ip, err => {
if (err) {
return next(err)
Modules.hooks.fire(
'preFinishLogin',
req,
res,
user,
function (error, results) {
if (error) {
return next(error)
}
_afterLoginSessionSetup(req, user, function(err) {
if (results.some(result => result && result.doNotFinish)) {
return
}
if (user.must_reconfirm) {
return AuthenticationController._redirectToReconfirmPage(
req,
res,
user
)
}
const redir =
AuthenticationController._getRedirectFromSession(req) || '/project'
_loginAsyncHandlers(req, user)
const userId = user._id
UserAuditLogHandler.addEntry(userId, 'login', userId, req.ip, err => {
if (err) {
return next(err)
}
AuthenticationController._clearRedirectFromSession(req)
AsyncFormHelper.redirect(req, res, redir)
_afterLoginSessionSetup(req, user, function (err) {
if (err) {
return next(err)
}
AuthenticationController._clearRedirectFromSession(req)
AsyncFormHelper.redirect(req, res, redir)
})
})
})
})
}
)
},
doPassportLogin(req, username, password, done) {
const email = username.toLowerCase()
const Modules = require('../../infrastructure/Modules')
Modules.hooks.fire('preDoPassportLogin', req, email, function(
err,
infoList
) {
if (err) {
return done(err)
}
const info = infoList.find(i => i != null)
if (info != null) {
return done(null, false, info)
}
LoginRateLimiter.processLoginRequest(email, function(err, isAllowed) {
Modules.hooks.fire(
'preDoPassportLogin',
req,
email,
function (err, infoList) {
if (err) {
return done(err)
}
if (!isAllowed) {
logger.log({ email }, 'too many login requests')
return done(null, null, {
text: req.i18n.translate('to_many_login_requests_2_mins'),
type: 'error'
})
const info = infoList.find(i => i != null)
if (info != null) {
return done(null, false, info)
}
AuthenticationManager.authenticate({ email }, password, function(
error,
user
) {
if (error != null) {
return done(error)
LoginRateLimiter.processLoginRequest(email, function (err, isAllowed) {
if (err) {
return done(err)
}
if (user != null) {
// async actions
done(null, user)
} else {
AuthenticationController._recordFailedLogin()
logger.log({ email }, 'failed log in')
done(null, false, {
text: req.i18n.translate('email_or_password_wrong_try_again'),
if (!isAllowed) {
logger.log({ email }, 'too many login requests')
return done(null, null, {
text: req.i18n.translate('to_many_login_requests_2_mins'),
type: 'error'
})
}
AuthenticationManager.authenticate(
{ email },
password,
function (error, user) {
if (error != null) {
return done(error)
}
if (user != null) {
// async actions
done(null, user)
} else {
AuthenticationController._recordFailedLogin()
logger.log({ email }, 'failed log in')
done(null, false, {
text: req.i18n.translate('email_or_password_wrong_try_again'),
type: 'error'
})
}
}
)
})
})
})
}
)
},
ipMatchCheck(req, user) {
@@ -215,9 +225,9 @@ const AuthenticationController = {
},
requireLogin() {
const doRequest = function(req, res, next) {
const doRequest = function (req, res, next) {
if (next == null) {
next = function() {}
next = function () {}
}
if (!AuthenticationController.isUserLoggedIn(req)) {
if (acceptsJson(req)) return send401WithChallenge(res)
@@ -234,45 +244,47 @@ const AuthenticationController = {
requireOauth() {
// require this here because module may not be included in some versions
const Oauth2Server = require('../../../../modules/oauth2-server/app/src/Oauth2Server')
return function(req, res, next) {
return function (req, res, next) {
if (next == null) {
next = function() {}
next = function () {}
}
const request = new Oauth2Server.Request(req)
const response = new Oauth2Server.Response(res)
return Oauth2Server.server.authenticate(request, response, {}, function(
err,
token
) {
if (err) {
// use a 401 status code for malformed header for git-bridge
if (
err.code === 400 &&
err.message === 'Invalid request: malformed authorization header'
) {
err.code = 401
return Oauth2Server.server.authenticate(
request,
response,
{},
function (err, token) {
if (err) {
// use a 401 status code for malformed header for git-bridge
if (
err.code === 400 &&
err.message === 'Invalid request: malformed authorization header'
) {
err.code = 401
}
// send all other errors
return res
.status(err.code)
.json({ error: err.name, error_description: err.message })
}
// send all other errors
return res
.status(err.code)
.json({ error: err.name, error_description: err.message })
req.oauth = { access_token: token.accessToken }
req.oauth_token = token
req.oauth_user = token.user
return next()
}
req.oauth = { access_token: token.accessToken }
req.oauth_token = token
req.oauth_user = token.user
return next()
})
)
}
},
validateUserSession: function() {
validateUserSession: function () {
// Middleware to check that the user's session is still good on key actions,
// such as opening a a project. Could be used to check that session has not
// exceeded a maximum lifetime (req.session.session_created), or for session
// hijacking checks (e.g. change of ip address, req.session.ip_address). For
// now, just check that the session has been loaded from the session store
// correctly.
return function(req, res, next) {
return function (req, res, next) {
// check that the session store is returning valid results
if (req.session && !SessionStoreManager.hasValidationToken(req)) {
// force user to update session
@@ -349,7 +361,7 @@ const AuthenticationController = {
return next()
},
httpAuth: basicAuth(function(user, pass) {
httpAuth: basicAuth(function (user, pass) {
let expectedPassword = Settings.httpAuthUsers[user]
const isValid =
expectedPassword &&
@@ -424,7 +436,7 @@ const AuthenticationController = {
_recordSuccessfulLogin(userId, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
UserUpdater.updateUser(
userId.toString(),
@@ -432,7 +444,7 @@ const AuthenticationController = {
$set: { lastLoggedIn: new Date() },
$inc: { loginCount: 1 }
},
function(error) {
function (error) {
if (error != null) {
callback(error)
}
@@ -465,9 +477,9 @@ const AuthenticationController = {
function _afterLoginSessionSetup(req, user, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
req.login(user, function(err) {
req.login(user, function (err) {
if (err) {
OError.tag(err, 'error from req.login', {
user_id: user._id
@@ -477,7 +489,7 @@ function _afterLoginSessionSetup(req, user, callback) {
// Regenerate the session to get a new sessionID (cookie value) to
// protect against session fixation attacks
const oldSession = req.session
req.session.destroy(function(err) {
req.session.destroy(function (err) {
if (err) {
OError.tag(err, 'error when trying to destroy old session', {
user_id: user._id
@@ -493,14 +505,14 @@ function _afterLoginSessionSetup(req, user, callback) {
req.session[key] = value
}
}
req.session.save(function(err) {
req.session.save(function (err) {
if (err) {
OError.tag(err, 'error saving regenerated session after login', {
user_id: user._id
})
return callback(err)
}
UserSessionsManager.trackSession(user, req.sessionID, function() {})
UserSessionsManager.trackSession(user, req.sessionID, function () {})
callback(null)
})
})

View File

@@ -12,7 +12,7 @@ const util = require('util')
const BCRYPT_ROUNDS = Settings.security.bcryptRounds || 12
const BCRYPT_MINOR_VERSION = Settings.security.bcryptMinorVersion || 'a'
const _checkWriteResult = function(result, callback) {
const _checkWriteResult = function (result, callback) {
// for MongoDB
if (result && result.modifiedCount === 1) {
callback(null, true)
@@ -33,7 +33,7 @@ const AuthenticationManager = {
if (!user || !user.hashedPassword) {
return callback(null, null)
}
bcrypt.compare(password, user.hashedPassword, function(error, match) {
bcrypt.compare(password, user.hashedPassword, function (error, match) {
if (error) {
return callback(error)
}
@@ -44,7 +44,7 @@ const AuthenticationManager = {
user,
user.hashedPassword,
password,
function(err) {
function (err) {
if (err) {
return callback(err)
}
@@ -146,7 +146,7 @@ const AuthenticationManager = {
},
hashPassword(password, callback) {
bcrypt.genSalt(BCRYPT_ROUNDS, BCRYPT_MINOR_VERSION, function(error, salt) {
bcrypt.genSalt(BCRYPT_ROUNDS, BCRYPT_MINOR_VERSION, function (error, salt) {
if (error) {
return callback(error)
}
@@ -162,7 +162,7 @@ const AuthenticationManager = {
if (validationError) {
return callback(validationError)
}
this.hashPassword(password, function(error, hash) {
this.hashPassword(password, function (error, hash) {
if (error) {
return callback(error)
}
@@ -178,7 +178,7 @@ const AuthenticationManager = {
password: true
}
},
function(updateError, result) {
function (updateError, result) {
if (updateError) {
return callback(updateError)
}

View File

@@ -54,20 +54,21 @@ const AuthorizationManager = {
return callback(new Error('invalid project id'))
}
// Note, the Project property in the DB is `publicAccesLevel`, without the second `s`
ProjectGetter.getProject(projectId, { publicAccesLevel: 1 }, function(
error,
project
) {
if (error) {
return callback(error)
ProjectGetter.getProject(
projectId,
{ publicAccesLevel: 1 },
function (error, project) {
if (error) {
return callback(error)
}
if (!project) {
return callback(
new Errors.NotFoundError(`no project found with id ${projectId}`)
)
}
callback(null, project.publicAccesLevel)
}
if (!project) {
return callback(
new Errors.NotFoundError(`no project found with id ${projectId}`)
)
}
callback(null, project.publicAccesLevel)
})
)
},
// Get the privilege level that the user has for the project
@@ -95,72 +96,78 @@ const AuthorizationManager = {
// User is present, get their privilege level from database
getPrivilegeLevelForProjectWithUser(userId, projectId, token, callback) {
CollaboratorsGetter.getMemberIdPrivilegeLevel(userId, projectId, function(
error,
privilegeLevel
) {
if (error) {
return callback(error)
}
if (privilegeLevel && privilegeLevel !== PrivilegeLevels.NONE) {
// The user has direct access
return callback(null, privilegeLevel, false, false)
}
AuthorizationManager.isUserSiteAdmin(userId, function(error, isAdmin) {
CollaboratorsGetter.getMemberIdPrivilegeLevel(
userId,
projectId,
function (error, privilegeLevel) {
if (error) {
return callback(error)
}
if (isAdmin) {
return callback(null, PrivilegeLevels.OWNER, false, true)
if (privilegeLevel && privilegeLevel !== PrivilegeLevels.NONE) {
// The user has direct access
return callback(null, privilegeLevel, false, false)
}
// Legacy public-access system
// User is present (not anonymous), but does not have direct access
AuthorizationManager.getPublicAccessLevel(projectId, function(
err,
publicAccessLevel
) {
if (err) {
return callback(err)
AuthorizationManager.isUserSiteAdmin(userId, function (error, isAdmin) {
if (error) {
return callback(error)
}
if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
return callback(null, PrivilegeLevels.READ_ONLY, true, false)
if (isAdmin) {
return callback(null, PrivilegeLevels.OWNER, false, true)
}
if (publicAccessLevel === PublicAccessLevels.READ_AND_WRITE) {
return callback(null, PrivilegeLevels.READ_AND_WRITE, true, false)
}
callback(null, PrivilegeLevels.NONE, false, false)
// Legacy public-access system
// User is present (not anonymous), but does not have direct access
AuthorizationManager.getPublicAccessLevel(
projectId,
function (err, publicAccessLevel) {
if (err) {
return callback(err)
}
if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
return callback(null, PrivilegeLevels.READ_ONLY, true, false)
}
if (publicAccessLevel === PublicAccessLevels.READ_AND_WRITE) {
return callback(
null,
PrivilegeLevels.READ_AND_WRITE,
true,
false
)
}
callback(null, PrivilegeLevels.NONE, false, false)
}
)
})
})
})
}
)
},
// User is Anonymous, Try Token-based access
getPrivilegeLevelForProjectWithoutUser(projectId, token, callback) {
AuthorizationManager.getPublicAccessLevel(projectId, function(
err,
publicAccessLevel
) {
if (err) {
return callback(err)
AuthorizationManager.getPublicAccessLevel(
projectId,
function (err, publicAccessLevel) {
if (err) {
return callback(err)
}
if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
// Legacy public read-only access for anonymous user
return callback(null, PrivilegeLevels.READ_ONLY, true, false)
}
if (publicAccessLevel === PublicAccessLevels.READ_AND_WRITE) {
// Legacy public read-write access for anonymous user
return callback(null, PrivilegeLevels.READ_AND_WRITE, true, false)
}
if (publicAccessLevel === PublicAccessLevels.TOKEN_BASED) {
return AuthorizationManager.getPrivilegeLevelForProjectWithToken(
projectId,
token,
callback
)
}
// Deny anonymous user access
callback(null, PrivilegeLevels.NONE, false, false)
}
if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
// Legacy public read-only access for anonymous user
return callback(null, PrivilegeLevels.READ_ONLY, true, false)
}
if (publicAccessLevel === PublicAccessLevels.READ_AND_WRITE) {
// Legacy public read-write access for anonymous user
return callback(null, PrivilegeLevels.READ_AND_WRITE, true, false)
}
if (publicAccessLevel === PublicAccessLevels.TOKEN_BASED) {
return AuthorizationManager.getPrivilegeLevelForProjectWithToken(
projectId,
token,
callback
)
}
// Deny anonymous user access
callback(null, PrivilegeLevels.NONE, false, false)
})
)
},
getPrivilegeLevelForProjectWithToken(projectId, token, callback) {
@@ -170,7 +177,7 @@ const AuthorizationManager = {
TokenAccessHandler.validateTokenForAnonymousAccess(
projectId,
token,
function(err, isValidReadAndWrite, isValidReadOnly) {
function (err, isValidReadAndWrite, isValidReadOnly) {
if (err) {
return callback(err)
}
@@ -193,7 +200,7 @@ const AuthorizationManager = {
userId,
projectId,
token,
function(error, privilegeLevel) {
function (error, privilegeLevel) {
if (error) {
return callback(error)
}
@@ -214,7 +221,7 @@ const AuthorizationManager = {
userId,
projectId,
token,
function(error, privilegeLevel) {
function (error, privilegeLevel) {
if (error) {
return callback(error)
}
@@ -233,7 +240,7 @@ const AuthorizationManager = {
userId,
projectId,
token,
function(error, privilegeLevel, becausePublic) {
function (error, privilegeLevel, becausePublic) {
if (error) {
return callback(error)
}
@@ -256,7 +263,7 @@ const AuthorizationManager = {
userId,
projectId,
token,
function(error, privilegeLevel, becausePublic, becauseSiteAdmin) {
function (error, privilegeLevel, becausePublic, becauseSiteAdmin) {
if (error) {
return callback(error)
}
@@ -273,7 +280,7 @@ const AuthorizationManager = {
if (!userId) {
return callback(null, false)
}
User.findOne({ _id: userId }, { isAdmin: 1 }, function(error, user) {
User.findOne({ _id: userId }, { isAdmin: 1 }, function (error, user) {
if (error) {
return callback(error)
}

View File

@@ -11,7 +11,7 @@ const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
module.exports = AuthorizationMiddleware = {
ensureUserCanReadMultipleProjects(req, res, next) {
const projectIds = (req.query.project_ids || '').split(',')
AuthorizationMiddleware._getUserId(req, function(error, userId) {
AuthorizationMiddleware._getUserId(req, function (error, userId) {
if (error) {
return next(error)
}
@@ -19,13 +19,13 @@ module.exports = AuthorizationMiddleware = {
// errors in callbacks
async.rejectSeries(
projectIds,
function(projectId, cb) {
function (projectId, cb) {
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserReadProject(
userId,
projectId,
token,
function(error, canRead) {
function (error, canRead) {
if (error) {
return next(error)
}
@@ -33,7 +33,7 @@ module.exports = AuthorizationMiddleware = {
}
)
},
function(unauthorizedProjectIds) {
function (unauthorizedProjectIds) {
if (unauthorizedProjectIds.length > 0) {
return AuthorizationMiddleware.redirectToRestricted(req, res, next)
}
@@ -44,178 +44,173 @@ module.exports = AuthorizationMiddleware = {
},
blockRestrictedUserFromProject(req, res, next) {
AuthorizationMiddleware._getUserAndProjectId(req, function(
error,
userId,
projectId
) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.isRestrictedUserForProject(
userId,
projectId,
token,
(err, isRestrictedUser) => {
if (err) {
return next(err)
}
if (isRestrictedUser) {
return res.sendStatus(403)
}
next()
AuthorizationMiddleware._getUserAndProjectId(
req,
function (error, userId, projectId) {
if (error) {
return next(error)
}
)
})
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.isRestrictedUserForProject(
userId,
projectId,
token,
(err, isRestrictedUser) => {
if (err) {
return next(err)
}
if (isRestrictedUser) {
return res.sendStatus(403)
}
next()
}
)
}
)
},
ensureUserCanReadProject(req, res, next) {
AuthorizationMiddleware._getUserAndProjectId(req, function(
error,
userId,
projectId
) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserReadProject(
userId,
projectId,
token,
function(error, canRead) {
if (error) {
return next(error)
}
if (canRead) {
AuthorizationMiddleware._getUserAndProjectId(
req,
function (error, userId, projectId) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserReadProject(
userId,
projectId,
token,
function (error, canRead) {
if (error) {
return next(error)
}
if (canRead) {
logger.log(
{ userId, projectId },
'allowing user read access to project'
)
return next()
}
logger.log(
{ userId, projectId },
'allowing user read access to project'
'denying user read access to project'
)
return next()
HttpErrorHandler.forbidden(req, res)
}
logger.log(
{ userId, projectId },
'denying user read access to project'
)
HttpErrorHandler.forbidden(req, res)
}
)
})
)
}
)
},
ensureUserCanWriteProjectSettings(req, res, next) {
AuthorizationMiddleware._getUserAndProjectId(req, function(
error,
userId,
projectId
) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserWriteProjectSettings(
userId,
projectId,
token,
function(error, canWrite) {
if (error) {
return next(error)
}
if (canWrite) {
AuthorizationMiddleware._getUserAndProjectId(
req,
function (error, userId, projectId) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserWriteProjectSettings(
userId,
projectId,
token,
function (error, canWrite) {
if (error) {
return next(error)
}
if (canWrite) {
logger.log(
{ userId, projectId },
'allowing user write access to project settings'
)
return next()
}
logger.log(
{ userId, projectId },
'allowing user write access to project settings'
'denying user write access to project settings'
)
return next()
HttpErrorHandler.forbidden(req, res)
}
logger.log(
{ userId, projectId },
'denying user write access to project settings'
)
HttpErrorHandler.forbidden(req, res)
}
)
})
)
}
)
},
ensureUserCanWriteProjectContent(req, res, next) {
AuthorizationMiddleware._getUserAndProjectId(req, function(
error,
userId,
projectId
) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserWriteProjectContent(
userId,
projectId,
token,
function(error, canWrite) {
if (error) {
return next(error)
}
if (canWrite) {
AuthorizationMiddleware._getUserAndProjectId(
req,
function (error, userId, projectId) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserWriteProjectContent(
userId,
projectId,
token,
function (error, canWrite) {
if (error) {
return next(error)
}
if (canWrite) {
logger.log(
{ userId, projectId },
'allowing user write access to project content'
)
return next()
}
logger.log(
{ userId, projectId },
'allowing user write access to project content'
'denying user write access to project settings'
)
return next()
HttpErrorHandler.forbidden(req, res)
}
logger.log(
{ userId, projectId },
'denying user write access to project settings'
)
HttpErrorHandler.forbidden(req, res)
}
)
})
)
}
)
},
ensureUserCanAdminProject(req, res, next) {
AuthorizationMiddleware._getUserAndProjectId(req, function(
error,
userId,
projectId
) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserAdminProject(
userId,
projectId,
token,
function(error, canAdmin) {
if (error) {
return next(error)
}
if (canAdmin) {
AuthorizationMiddleware._getUserAndProjectId(
req,
function (error, userId, projectId) {
if (error) {
return next(error)
}
const token = TokenAccessHandler.getRequestToken(req, projectId)
AuthorizationManager.canUserAdminProject(
userId,
projectId,
token,
function (error, canAdmin) {
if (error) {
return next(error)
}
if (canAdmin) {
logger.log(
{ userId, projectId },
'allowing user admin access to project'
)
return next()
}
logger.log(
{ userId, projectId },
'allowing user admin access to project'
'denying user admin access to project'
)
return next()
HttpErrorHandler.forbidden(req, res)
}
logger.log(
{ userId, projectId },
'denying user admin access to project'
)
HttpErrorHandler.forbidden(req, res)
}
)
})
)
}
)
},
ensureUserIsSiteAdmin(req, res, next) {
AuthorizationMiddleware._getUserId(req, function(error, userId) {
AuthorizationMiddleware._getUserId(req, function (error, userId) {
if (error) {
return next(error)
}
AuthorizationManager.isUserSiteAdmin(userId, function(error, isAdmin) {
AuthorizationManager.isUserSiteAdmin(userId, function (error, isAdmin) {
if (error) {
return next(error)
}
@@ -239,7 +234,7 @@ module.exports = AuthorizationMiddleware = {
new Errors.NotFoundError(`invalid projectId: ${projectId}`)
)
}
AuthorizationMiddleware._getUserId(req, function(error, userId) {
AuthorizationMiddleware._getUserId(req, function (error, userId) {
if (error) {
return callback(error)
}

View File

@@ -12,7 +12,7 @@ const BetaProgramController = {
if (userId == null) {
return next(new Error('no user id in session'))
}
BetaProgramHandler.optIn(userId, function(err) {
BetaProgramHandler.optIn(userId, function (err) {
if (err) {
return next(err)
}
@@ -26,7 +26,7 @@ const BetaProgramController = {
if (userId == null) {
return next(new Error('no user id in session'))
}
BetaProgramHandler.optOut(userId, function(err) {
BetaProgramHandler.optOut(userId, function (err) {
if (err) {
return next(err)
}
@@ -37,7 +37,7 @@ const BetaProgramController = {
optInPage(req, res, next) {
const userId = AuthenticationController.getLoggedInUserId(req)
logger.log({ user_id: userId }, 'showing beta participation page for user')
UserGetter.getUser(userId, function(err, user) {
UserGetter.getUser(userId, function (err, user) {
if (err) {
OError.tag(err, 'error fetching user', {
userId

View File

@@ -22,7 +22,7 @@ const V1Api = require('../V1/V1Api')
module.exports = BrandVariationsHandler = {
getBrandVariationById(brandVariationId, callback) {
if (callback == null) {
callback = function(error, brandVariationDetails) {}
callback = function (error, brandVariationDetails) {}
}
if (brandVariationId == null || brandVariationId === '') {
return callback(new Error('Branding variation id not provided'))
@@ -32,7 +32,7 @@ module.exports = BrandVariationsHandler = {
{
uri: `/api/v2/brand_variations/${brandVariationId}`
},
function(error, response, brandVariationDetails) {
function (error, response, brandVariationDetails) {
if (error != null) {
OError.tag(error, 'error getting brand variation details', {
brandVariationId
@@ -46,7 +46,7 @@ module.exports = BrandVariationsHandler = {
}
}
var _formatBrandVariationDetails = function(details) {
var _formatBrandVariationDetails = function (details) {
if (details.export_url != null) {
details.export_url = _setV1AsHostIfRelativeURL(details.export_url)
}

View File

@@ -17,7 +17,7 @@ const Settings = require('settings-sharelatex')
module.exports = CaptchaMiddleware = {
validateCaptcha(action) {
return function(req, res, next) {
return function (req, res, next) {
if (
(Settings.recaptcha != null ? Settings.recaptcha.siteKey : undefined) ==
null
@@ -42,7 +42,7 @@ module.exports = CaptchaMiddleware = {
return request.post(
'https://www.google.com/recaptcha/api/siteverify',
options,
function(error, response, body) {
function (error, response, body) {
if (error != null) {
return next(error)
}

View File

@@ -19,9 +19,9 @@ const settings = require('settings-sharelatex')
module.exports = ChatApiHandler = {
_apiRequest(opts, callback) {
if (callback == null) {
callback = function(error, data) {}
callback = function (error, data) {}
}
return request(opts, function(error, response, data) {
return request(opts, function (error, response, data) {
if (error != null) {
return callback(error)
}
@@ -71,7 +71,7 @@ module.exports = ChatApiHandler = {
sendComment(project_id, thread_id, user_id, content, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ChatApiHandler._apiRequest(
{
@@ -85,7 +85,7 @@ module.exports = ChatApiHandler = {
getThreads(project_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ChatApiHandler._apiRequest(
{
@@ -99,7 +99,7 @@ module.exports = ChatApiHandler = {
resolveThread(project_id, thread_id, user_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ChatApiHandler._apiRequest(
{
@@ -113,7 +113,7 @@ module.exports = ChatApiHandler = {
reopenThread(project_id, thread_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ChatApiHandler._apiRequest(
{
@@ -126,7 +126,7 @@ module.exports = ChatApiHandler = {
deleteThread(project_id, thread_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ChatApiHandler._apiRequest(
{
@@ -139,7 +139,7 @@ module.exports = ChatApiHandler = {
editMessage(project_id, thread_id, message_id, content, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ChatApiHandler._apiRequest(
{
@@ -155,7 +155,7 @@ module.exports = ChatApiHandler = {
deleteMessage(project_id, thread_id, message_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ChatApiHandler._apiRequest(
{

View File

@@ -36,25 +36,25 @@ module.exports = ChatController = {
project_id,
user_id,
content,
function(err, message) {
function (err, message) {
if (err != null) {
return next(err)
}
return UserInfoManager.getPersonalInfo(message.user_id, function(
err,
user
) {
if (err != null) {
return next(err)
return UserInfoManager.getPersonalInfo(
message.user_id,
function (err, user) {
if (err != null) {
return next(err)
}
message.user = UserInfoController.formatPersonalInfo(user)
EditorRealTimeController.emitToRoom(
project_id,
'new-chat-message',
message
)
return res.sendStatus(204)
}
message.user = UserInfoController.formatPersonalInfo(user)
EditorRealTimeController.emitToRoom(
project_id,
'new-chat-message',
message
)
return res.sendStatus(204)
})
)
}
)
},
@@ -66,13 +66,13 @@ module.exports = ChatController = {
project_id,
query.limit,
query.before,
function(err, messages) {
function (err, messages) {
if (err != null) {
return next(err)
}
return ChatController._injectUserInfoIntoThreads(
{ global: { messages } },
function(err) {
function (err) {
if (err != null) {
return next(err)
}
@@ -89,7 +89,7 @@ module.exports = ChatController = {
// user fields
let message, thread, thread_id, user_id
if (callback == null) {
callback = function(error, threads) {}
callback = function (error, threads) {}
}
const user_ids = {}
for (thread_id in threads) {
@@ -108,7 +108,7 @@ module.exports = ChatController = {
const _ = user_ids[user_id]
;(user_id =>
jobs.push(cb =>
UserInfoManager.getPersonalInfo(user_id, function(error, user) {
UserInfoManager.getPersonalInfo(user_id, function (error, user) {
if (error != null) return cb(error)
user = UserInfoController.formatPersonalInfo(user)
users[user_id] = user
@@ -117,7 +117,7 @@ module.exports = ChatController = {
))(user_id)
}
return async.series(jobs, function(error) {
return async.series(jobs, function (error) {
if (error != null) {
return callback(error)
}

View File

@@ -30,7 +30,7 @@ module.exports = CollaboratorsEmailHandler = {
return Project.findOne({ _id: project_id })
.select('name owner_ref')
.populate('owner_ref')
.exec(function(err, project) {
.exec(function (err, project) {
const emailOptions = {
to: email,
replyTo: project.owner_ref.email,

View File

@@ -31,37 +31,38 @@ module.exports = CollaboratorsInviteController = {
getAllInvites(req, res, next) {
const projectId = req.params.Project_id
logger.log({ projectId }, 'getting all active invites for project')
return CollaboratorsInviteHandler.getAllInvites(projectId, function(
err,
invites
) {
if (err != null) {
OError.tag(err, 'error getting invites for project', {
projectId
})
return next(err)
return CollaboratorsInviteHandler.getAllInvites(
projectId,
function (err, invites) {
if (err != null) {
OError.tag(err, 'error getting invites for project', {
projectId
})
return next(err)
}
return res.json({ invites })
}
return res.json({ invites })
})
)
},
_checkShouldInviteEmail(email, callback) {
if (callback == null) {
callback = function(err, shouldAllowInvite) {}
callback = function (err, shouldAllowInvite) {}
}
if (Settings.restrictInvitesToExistingAccounts === true) {
logger.log({ email }, 'checking if user exists with this email')
return UserGetter.getUserByAnyEmail(email, { _id: 1 }, function(
err,
user
) {
if (err != null) {
return callback(err)
return UserGetter.getUserByAnyEmail(
email,
{ _id: 1 },
function (err, user) {
if (err != null) {
return callback(err)
}
const userExists =
user != null && (user != null ? user._id : undefined) != null
return callback(null, userExists)
}
const userExists =
user != null && (user != null ? user._id : undefined) != null
return callback(null, userExists)
})
)
} else {
return callback(null, true)
}
@@ -69,11 +70,11 @@ module.exports = CollaboratorsInviteController = {
_checkRateLimit(user_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return LimitationsManager.allowedNumberOfCollaboratorsForUser(
user_id,
function(err, collabLimit) {
function (err, collabLimit) {
if (collabLimit == null) {
collabLimit = 1
}
@@ -134,7 +135,7 @@ module.exports = CollaboratorsInviteController = {
}
return CollaboratorsInviteController._checkRateLimit(
sendingUserId,
function(error, underRateLimit) {
function (error, underRateLimit) {
if (error != null) {
return next(error)
}
@@ -143,7 +144,7 @@ module.exports = CollaboratorsInviteController = {
}
return CollaboratorsInviteController._checkShouldInviteEmail(
email,
function(err, shouldAllowInvite) {
function (err, shouldAllowInvite) {
if (err != null) {
OError.tag(
err,
@@ -171,7 +172,7 @@ module.exports = CollaboratorsInviteController = {
sendingUser,
email,
privileges,
function(err, invite) {
function (err, invite) {
if (err != null) {
OError.tag(err, 'error creating project invite', {
projectId,
@@ -207,7 +208,7 @@ module.exports = CollaboratorsInviteController = {
return CollaboratorsInviteHandler.revokeInvite(
projectId,
inviteId,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'error revoking invite', {
projectId,
@@ -232,7 +233,7 @@ module.exports = CollaboratorsInviteController = {
const sendingUser = AuthenticationController.getSessionUser(req)
return CollaboratorsInviteController._checkRateLimit(
sendingUser._id,
function(error, underRateLimit) {
function (error, underRateLimit) {
if (error != null) {
return next(error)
}
@@ -243,7 +244,7 @@ module.exports = CollaboratorsInviteController = {
projectId,
sendingUser,
inviteId,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'error resending invite', {
projectId,
@@ -261,7 +262,7 @@ module.exports = CollaboratorsInviteController = {
viewInvite(req, res, next) {
const projectId = req.params.Project_id
const { token } = req.params
const _renderInvalidPage = function() {
const _renderInvalidPage = function () {
logger.log(
{ projectId, token },
'invite not valid, rendering not-valid page'
@@ -273,7 +274,7 @@ module.exports = CollaboratorsInviteController = {
return CollaboratorsGetter.isUserInvitedMemberOfProject(
currentUser._id,
projectId,
function(err, isMember) {
function (err, isMember) {
if (err != null) {
OError.tag(err, 'error checking if user is member of project', {
projectId
@@ -291,7 +292,7 @@ module.exports = CollaboratorsInviteController = {
return CollaboratorsInviteHandler.getInviteByToken(
projectId,
token,
function(err, invite) {
function (err, invite) {
if (err != null) {
OError.tag(err, 'error getting invite by token', {
projectId,
@@ -308,7 +309,7 @@ module.exports = CollaboratorsInviteController = {
return UserGetter.getUser(
{ _id: invite.sendingUserId },
{ email: 1, first_name: 1, last_name: 1 },
function(err, owner) {
function (err, owner) {
if (err != null) {
OError.tag(err, 'error getting project owner', {
projectId
@@ -320,28 +321,29 @@ module.exports = CollaboratorsInviteController = {
return _renderInvalidPage()
}
// fetch the project name
return ProjectGetter.getProject(projectId, {}, function(
err,
project
) {
if (err != null) {
OError.tag(err, 'error getting project', {
projectId
return ProjectGetter.getProject(
projectId,
{},
function (err, project) {
if (err != null) {
OError.tag(err, 'error getting project', {
projectId
})
return next(err)
}
if (project == null) {
logger.log({ projectId }, 'no project found')
return _renderInvalidPage()
}
// finally render the invite
return res.render('project/invite/show', {
invite,
project,
owner,
title: 'Project Invite'
})
return next(err)
}
if (project == null) {
logger.log({ projectId }, 'no project found')
return _renderInvalidPage()
}
// finally render the invite
return res.render('project/invite/show', {
invite,
project,
owner,
title: 'Project Invite'
})
})
)
}
)
}
@@ -362,7 +364,7 @@ module.exports = CollaboratorsInviteController = {
projectId,
token,
currentUser,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'error accepting invite by token', {
projectId,

View File

@@ -26,10 +26,10 @@ const { promisifyAll } = require('../../util/promises')
const CollaboratorsInviteHandler = {
getAllInvites(projectId, callback) {
if (callback == null) {
callback = function(err, invites) {}
callback = function (err, invites) {}
}
logger.log({ projectId }, 'fetching invites for project')
return ProjectInvite.find({ projectId }, function(err, invites) {
return ProjectInvite.find({ projectId }, function (err, invites) {
if (err != null) {
OError.tag(err, 'error getting invites from mongo', {
projectId
@@ -46,10 +46,10 @@ const CollaboratorsInviteHandler = {
getInviteCount(projectId, callback) {
if (callback == null) {
callback = function(err, count) {}
callback = function (err, count) {}
}
logger.log({ projectId }, 'counting invites for project')
return ProjectInvite.countDocuments({ projectId }, function(err, count) {
return ProjectInvite.countDocuments({ projectId }, function (err, count) {
if (err != null) {
OError.tag(err, 'error getting invites from mongo', {
projectId
@@ -62,55 +62,57 @@ const CollaboratorsInviteHandler = {
_trySendInviteNotification(projectId, sendingUser, invite, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
const { email } = invite
return UserGetter.getUserByAnyEmail(email, { _id: 1 }, function(
err,
existingUser
) {
if (err != null) {
OError.tag(err, 'error checking if user exists', {
projectId,
email
})
return callback(err)
}
if (existingUser == null) {
logger.log({ projectId, email }, 'no existing user found, returning')
return callback(null)
}
return ProjectGetter.getProject(projectId, { _id: 1, name: 1 }, function(
err,
project
) {
return UserGetter.getUserByAnyEmail(
email,
{ _id: 1 },
function (err, existingUser) {
if (err != null) {
OError.tag(err, 'error getting project', {
OError.tag(err, 'error checking if user exists', {
projectId,
email
})
return callback(err)
}
if (project == null) {
logger.log(
{ projectId },
'no project found while sending notification, returning'
)
if (existingUser == null) {
logger.log({ projectId, email }, 'no existing user found, returning')
return callback(null)
}
return NotificationsBuilder.projectInvite(
invite,
project,
sendingUser,
existingUser
).create(callback)
})
})
return ProjectGetter.getProject(
projectId,
{ _id: 1, name: 1 },
function (err, project) {
if (err != null) {
OError.tag(err, 'error getting project', {
projectId,
email
})
return callback(err)
}
if (project == null) {
logger.log(
{ projectId },
'no project found while sending notification, returning'
)
return callback(null)
}
return NotificationsBuilder.projectInvite(
invite,
project,
sendingUser,
existingUser
).create(callback)
}
)
}
)
},
_tryCancelInviteNotification(inviteId, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
return NotificationsBuilder.projectInvite(
{ _id: inviteId },
@@ -122,7 +124,7 @@ const CollaboratorsInviteHandler = {
_sendMessages(projectId, sendingUser, invite, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
logger.log(
{ projectId, inviteId: invite._id },
@@ -133,7 +135,7 @@ const CollaboratorsInviteHandler = {
invite.email,
invite,
sendingUser,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -141,7 +143,7 @@ const CollaboratorsInviteHandler = {
projectId,
sendingUser,
invite,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -154,13 +156,13 @@ const CollaboratorsInviteHandler = {
inviteToProject(projectId, sendingUser, email, privileges, callback) {
if (callback == null) {
callback = function(err, invite) {}
callback = function (err, invite) {}
}
logger.log(
{ projectId, sendingUserId: sendingUser._id, email, privileges },
'adding invite'
)
return Crypto.randomBytes(24, function(err, buffer) {
return Crypto.randomBytes(24, function (err, buffer) {
if (err != null) {
OError.tag(err, 'error generating random token', {
projectId,
@@ -177,7 +179,7 @@ const CollaboratorsInviteHandler = {
projectId,
privileges
})
return invite.save(function(err, invite) {
return invite.save(function (err, invite) {
if (err != null) {
OError.tag(err, 'error saving token', {
projectId,
@@ -191,7 +193,7 @@ const CollaboratorsInviteHandler = {
projectId,
sendingUser,
invite,
function(err) {
function (err) {
if (err != null) {
return logger.err(
{ err, projectId, email },
@@ -207,98 +209,101 @@ const CollaboratorsInviteHandler = {
revokeInvite(projectId, inviteId, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
logger.log({ projectId, inviteId }, 'removing invite')
return ProjectInvite.deleteOne({ projectId, _id: inviteId }, function(err) {
if (err != null) {
OError.tag(err, 'error removing invite', {
projectId,
inviteId
})
return callback(err)
return ProjectInvite.deleteOne(
{ projectId, _id: inviteId },
function (err) {
if (err != null) {
OError.tag(err, 'error removing invite', {
projectId,
inviteId
})
return callback(err)
}
CollaboratorsInviteHandler._tryCancelInviteNotification(
inviteId,
function () {}
)
return callback(null)
}
CollaboratorsInviteHandler._tryCancelInviteNotification(
inviteId,
function() {}
)
return callback(null)
})
)
},
resendInvite(projectId, sendingUser, inviteId, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
logger.log({ projectId, inviteId }, 'resending invite email')
return ProjectInvite.findOne({ _id: inviteId, projectId }, function(
err,
invite
) {
if (err != null) {
OError.tag(err, 'error finding invite', {
projectId,
inviteId
})
return callback(err)
}
if (invite == null) {
logger.err(
{ err, projectId, inviteId },
'no invite found, nothing to resend'
)
return callback(null)
}
return CollaboratorsInviteHandler._sendMessages(
projectId,
sendingUser,
invite,
function(err) {
if (err != null) {
OError.tag(err, 'error resending invite messages', {
projectId,
inviteId
})
return callback(err)
}
return ProjectInvite.findOne(
{ _id: inviteId, projectId },
function (err, invite) {
if (err != null) {
OError.tag(err, 'error finding invite', {
projectId,
inviteId
})
return callback(err)
}
if (invite == null) {
logger.err(
{ err, projectId, inviteId },
'no invite found, nothing to resend'
)
return callback(null)
}
)
})
return CollaboratorsInviteHandler._sendMessages(
projectId,
sendingUser,
invite,
function (err) {
if (err != null) {
OError.tag(err, 'error resending invite messages', {
projectId,
inviteId
})
return callback(err)
}
return callback(null)
}
)
}
)
},
getInviteByToken(projectId, tokenString, callback) {
if (callback == null) {
callback = function(err, invite) {}
callback = function (err, invite) {}
}
logger.log({ projectId, tokenString }, 'fetching invite by token')
return ProjectInvite.findOne({ projectId, token: tokenString }, function(
err,
invite
) {
if (err != null) {
OError.tag(err, 'error fetching invite', {
projectId
})
return callback(err)
return ProjectInvite.findOne(
{ projectId, token: tokenString },
function (err, invite) {
if (err != null) {
OError.tag(err, 'error fetching invite', {
projectId
})
return callback(err)
}
if (invite == null) {
logger.err({ err, projectId, token: tokenString }, 'no invite found')
return callback(null, null)
}
return callback(null, invite)
}
if (invite == null) {
logger.err({ err, projectId, token: tokenString }, 'no invite found')
return callback(null, null)
}
return callback(null, invite)
})
)
},
acceptInvite(projectId, tokenString, user, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
logger.log({ projectId, userId: user._id, tokenString }, 'accepting invite')
return CollaboratorsInviteHandler.getInviteByToken(
projectId,
tokenString,
function(err, invite) {
function (err, invite) {
if (err != null) {
OError.tag(err, 'error finding invite', {
projectId,
@@ -320,7 +325,7 @@ const CollaboratorsInviteHandler = {
invite.sendingUserId,
user._id,
invite.privileges,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'error adding user to project', {
projectId,
@@ -331,7 +336,7 @@ const CollaboratorsInviteHandler = {
}
// Remove invite
logger.log({ projectId, inviteId }, 'removing invite')
return ProjectInvite.deleteOne({ _id: inviteId }, function(err) {
return ProjectInvite.deleteOne({ _id: inviteId }, function (err) {
if (err != null) {
OError.tag(err, 'error removing invite', {
projectId,
@@ -341,7 +346,7 @@ const CollaboratorsInviteHandler = {
}
CollaboratorsInviteHandler._tryCancelInviteNotification(
inviteId,
function() {}
function () {}
)
return callback()
})

View File

@@ -27,7 +27,7 @@ const clsiCookiesEnabled =
(Settings.clsiCookie != null ? Settings.clsiCookie.key : undefined) != null &&
Settings.clsiCookie.key.length !== 0
module.exports = function(backendGroup) {
module.exports = function (backendGroup) {
return {
buildKey(project_id) {
if (backendGroup != null) {
@@ -39,7 +39,7 @@ module.exports = function(backendGroup) {
_getServerId(project_id, callback) {
if (callback == null) {
callback = function(err, serverId) {}
callback = function (err, serverId) {}
}
return rclient.get(this.buildKey(project_id), (err, serverId) => {
if (err != null) {
@@ -55,7 +55,7 @@ module.exports = function(backendGroup) {
_populateServerIdViaRequest(project_id, callback) {
if (callback == null) {
callback = function(err, serverId) {}
callback = function (err, serverId) {}
}
const url = `${Settings.apis.clsi.url}/project/${project_id}/status`
return request.post(url, (err, res, body) => {
@@ -65,7 +65,7 @@ module.exports = function(backendGroup) {
})
return callback(err)
}
return this.setServerId(project_id, res, function(err, serverId) {
return this.setServerId(project_id, res, function (err, serverId) {
if (err != null) {
logger.warn(
{ err, project_id },
@@ -88,7 +88,7 @@ module.exports = function(backendGroup) {
setServerId(project_id, response, callback) {
if (callback == null) {
callback = function(err, serverId) {}
callback = function (err, serverId) {}
}
if (!clsiCookiesEnabled) {
return callback()
@@ -112,7 +112,7 @@ module.exports = function(backendGroup) {
_setServerIdInRedis(rclient, project_id, serverId, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
rclient.setex(
this.buildKey(project_id),
@@ -124,7 +124,7 @@ module.exports = function(backendGroup) {
clearServerId(project_id, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
if (!clsiCookiesEnabled) {
return callback()
@@ -134,7 +134,7 @@ module.exports = function(backendGroup) {
getCookieJar(project_id, callback) {
if (callback == null) {
callback = function(err, jar) {}
callback = function (err, jar) {}
}
if (!clsiCookiesEnabled) {
return callback(null, request.jar())

View File

@@ -26,7 +26,7 @@ module.exports = ClsiFormatChecker = {
}
}
return async.series(jobs, function(err, problems) {
return async.series(jobs, function (err, problems) {
if (err != null) {
return callback(err)
}
@@ -44,7 +44,7 @@ module.exports = ClsiFormatChecker = {
_checkForConflictingPaths(resources, callback) {
const paths = resources.map(resource => resource.path)
const conflicts = _.filter(paths, function(path) {
const conflicts = _.filter(paths, function (path) {
const matchingPaths = _.filter(
paths,
checkPath => checkPath.indexOf(path + '/') !== -1
@@ -63,7 +63,7 @@ module.exports = ClsiFormatChecker = {
let totalSize = 0
let sizedResources = resources.map(function(resource) {
let sizedResources = resources.map(function (resource) {
const result = { path: resource.path }
if (resource.content != null) {
result.size = resource.content.replace(/\n/g, '').length
@@ -79,9 +79,7 @@ module.exports = ClsiFormatChecker = {
if (!tooLarge) {
return callback()
} else {
sizedResources = _.sortBy(sizedResources, 'size')
.reverse()
.slice(0, 10)
sizedResources = _.sortBy(sizedResources, 'size').reverse().slice(0, 10)
return callback(null, { resources: sizedResources, totalSize })
}
}

View File

@@ -34,50 +34,48 @@ const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
// unsetting it if it removes any documents from the doc updater.
const buildState = s =>
crypto
.createHash('sha1')
.update(s, 'utf8')
.digest('hex')
crypto.createHash('sha1').update(s, 'utf8').digest('hex')
module.exports = ClsiStateManager = {
computeHash(project, options, callback) {
if (callback == null) {
callback = function(err, hash) {}
callback = function (err, hash) {}
}
return ProjectEntityHandler.getAllEntitiesFromProject(project, function(
err,
docs,
files
) {
const fileList = Array.from(files || []).map(
f => `${f.file._id}:${f.file.rev}:${f.file.created}:${f.path}`
)
const docList = Array.from(docs || []).map(d => `${d.doc._id}:${d.path}`)
const sortedEntityList = [
...Array.from(docList),
...Array.from(fileList)
].sort()
// ignore the isAutoCompile options as it doesn't affect the
// output, but include all other options e.g. draft
const optionsList = (() => {
const result = []
const object = options || {}
for (let key in object) {
const value = object[key]
if (!['isAutoCompile'].includes(key)) {
result.push(`option ${key}:${value}`)
return ProjectEntityHandler.getAllEntitiesFromProject(
project,
function (err, docs, files) {
const fileList = Array.from(files || []).map(
f => `${f.file._id}:${f.file.rev}:${f.file.created}:${f.path}`
)
const docList = Array.from(docs || []).map(
d => `${d.doc._id}:${d.path}`
)
const sortedEntityList = [
...Array.from(docList),
...Array.from(fileList)
].sort()
// ignore the isAutoCompile options as it doesn't affect the
// output, but include all other options e.g. draft
const optionsList = (() => {
const result = []
const object = options || {}
for (let key in object) {
const value = object[key]
if (!['isAutoCompile'].includes(key)) {
result.push(`option ${key}:${value}`)
}
}
}
return result
})()
const sortedOptionsList = optionsList.sort()
const hash = buildState(
[
...Array.from(sortedEntityList),
...Array.from(sortedOptionsList)
].join('\n')
)
return callback(null, hash)
})
return result
})()
const sortedOptionsList = optionsList.sort()
const hash = buildState(
[
...Array.from(sortedEntityList),
...Array.from(sortedOptionsList)
].join('\n')
)
return callback(null, hash)
}
)
}
}

View File

@@ -104,11 +104,11 @@ module.exports = CompileController = {
stopCompile(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
const project_id = req.params.Project_id
const user_id = AuthenticationController.getLoggedInUserId(req)
return CompileManager.stopCompile(project_id, user_id, function(error) {
return CompileManager.stopCompile(project_id, user_id, function (error) {
if (error != null) {
return next(error)
}
@@ -119,7 +119,7 @@ module.exports = CompileController = {
// Used for submissions through the public API
compileSubmission(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
res.setTimeout(COMPILE_TIMEOUT_MS)
const { submission_id } = req.params
@@ -150,7 +150,7 @@ module.exports = CompileController = {
submission_id,
req.body,
options,
function(error, status, outputFiles, clsiServerId, validationProblems) {
function (error, status, outputFiles, clsiServerId, validationProblems) {
if (error != null) {
return next(error)
}
@@ -189,13 +189,13 @@ module.exports = CompileController = {
downloadPdf(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
Metrics.inc('pdf-downloads')
const project_id = req.params.Project_id
const isPdfjsPartialDownload =
req.query != null ? req.query.pdfng : undefined
const rateLimit = function(callback) {
const rateLimit = function (callback) {
if (isPdfjsPartialDownload) {
return callback(null, true)
} else {
@@ -209,51 +209,52 @@ module.exports = CompileController = {
}
}
return ProjectGetter.getProject(project_id, { name: 1 }, function(
err,
project
) {
res.contentType('application/pdf')
const filename = `${CompileController._getSafeProjectName(project)}.pdf`
return ProjectGetter.getProject(
project_id,
{ name: 1 },
function (err, project) {
res.contentType('application/pdf')
const filename = `${CompileController._getSafeProjectName(project)}.pdf`
if (req.query.popupDownload) {
res.setContentDisposition('attachment', { filename })
} else {
res.setContentDisposition('', { filename })
}
return rateLimit(function(err, canContinue) {
if (err != null) {
logger.err({ err }, 'error checking rate limit for pdf download')
return res.sendStatus(500)
} else if (!canContinue) {
logger.log(
{ project_id, ip: req.ip },
'rate limit hit downloading pdf'
)
return res.sendStatus(500)
if (req.query.popupDownload) {
res.setContentDisposition('attachment', { filename })
} else {
return CompileController._downloadAsUser(req, function(
error,
user_id
) {
const url = CompileController._getFileUrl(
project_id,
user_id,
req.params.build_id,
'output.pdf'
)
return CompileController.proxyToClsi(
project_id,
url,
req,
res,
next
)
})
res.setContentDisposition('', { filename })
}
})
})
return rateLimit(function (err, canContinue) {
if (err != null) {
logger.err({ err }, 'error checking rate limit for pdf download')
return res.sendStatus(500)
} else if (!canContinue) {
logger.log(
{ project_id, ip: req.ip },
'rate limit hit downloading pdf'
)
return res.sendStatus(500)
} else {
return CompileController._downloadAsUser(
req,
function (error, user_id) {
const url = CompileController._getFileUrl(
project_id,
user_id,
req.params.build_id,
'output.pdf'
)
return CompileController.proxyToClsi(
project_id,
url,
req,
res,
next
)
}
)
}
})
}
)
},
_getSafeProjectName(project) {
@@ -264,18 +265,21 @@ module.exports = CompileController = {
deleteAuxFiles(req, res, next) {
const project_id = req.params.Project_id
const { clsiserverid } = req.query
return CompileController._compileAsUser(req, function(error, user_id) {
return CompileController._compileAsUser(req, function (error, user_id) {
if (error != null) {
return next(error)
}
CompileManager.deleteAuxFiles(project_id, user_id, clsiserverid, function(
error
) {
if (error != null) {
return next(error)
CompileManager.deleteAuxFiles(
project_id,
user_id,
clsiserverid,
function (error) {
if (error != null) {
return next(error)
}
return res.sendStatus(200)
}
return res.sendStatus(200)
})
)
})
},
@@ -283,7 +287,7 @@ module.exports = CompileController = {
compileAndDownloadPdf(req, res, next) {
const { project_id } = req.params
// pass user_id as null, since templates are an "anonymous" compile
return CompileManager.compile(project_id, null, {}, function(err) {
return CompileManager.compile(project_id, null, {}, function (err) {
if (err != null) {
logger.err(
{ err, project_id },
@@ -298,10 +302,10 @@ module.exports = CompileController = {
getFileFromClsi(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
const project_id = req.params.Project_id
return CompileController._downloadAsUser(req, function(error, user_id) {
return CompileController._downloadAsUser(req, function (error, user_id) {
if (error != null) {
return next(error)
}
@@ -317,7 +321,7 @@ module.exports = CompileController = {
getFileFromClsiWithoutUser(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
const { submission_id } = req.params
const url = CompileController._getFileUrl(
@@ -367,7 +371,7 @@ module.exports = CompileController = {
proxySyncPdf(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
const project_id = req.params.Project_id
const { page, h, v } = req.query
@@ -381,7 +385,7 @@ module.exports = CompileController = {
return next(new Error('invalid v parameter'))
}
// whether this request is going to a per-user container
return CompileController._compileAsUser(req, function(error, user_id) {
return CompileController._compileAsUser(req, function (error, user_id) {
if (error != null) {
return next(error)
}
@@ -403,7 +407,7 @@ module.exports = CompileController = {
proxySyncCode(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
const project_id = req.params.Project_id
const { file, line, column } = req.query
@@ -425,7 +429,7 @@ module.exports = CompileController = {
if (!(column != null ? column.match(/^\d+$/) : undefined)) {
return next(new Error('invalid column parameter'))
}
return CompileController._compileAsUser(req, function(error, user_id) {
return CompileController._compileAsUser(req, function (error, user_id) {
if (error != null) {
return next(error)
}
@@ -447,7 +451,7 @@ module.exports = CompileController = {
proxyToClsi(project_id, url, req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
if (req.query != null ? req.query.compileGroup : undefined) {
return CompileController.proxyToClsiWithLimits(
@@ -459,28 +463,28 @@ module.exports = CompileController = {
next
)
} else {
return CompileManager.getProjectCompileLimits(project_id, function(
error,
limits
) {
if (error != null) {
return next(error)
return CompileManager.getProjectCompileLimits(
project_id,
function (error, limits) {
if (error != null) {
return next(error)
}
return CompileController.proxyToClsiWithLimits(
project_id,
url,
limits,
req,
res,
next
)
}
return CompileController.proxyToClsiWithLimits(
project_id,
url,
limits,
req,
res,
next
)
})
)
}
},
proxyToClsiWithLimits(project_id, url, limits, req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
_getPersistenceOptions(req, project_id, (err, persistenceOptions) => {
let qs
@@ -541,7 +545,7 @@ module.exports = CompileController = {
const project_id = req.params.Project_id
const file = req.query.file || false
const { clsiserverid } = req.query
return CompileController._compileAsUser(req, function(error, user_id) {
return CompileController._compileAsUser(req, function (error, user_id) {
if (error != null) {
return next(error)
}
@@ -550,7 +554,7 @@ module.exports = CompileController = {
user_id,
file,
clsiserverid,
function(error, body) {
function (error, body) {
if (error != null) {
return next(error)
}

View File

@@ -30,10 +30,10 @@ module.exports = CompileManager = {
options = {}
}
if (_callback == null) {
_callback = function(error) {}
_callback = function (error) {}
}
const timer = new Metrics.Timer('editor.compile')
const callback = function(...args) {
const callback = function (...args) {
timer.done()
return _callback(...Array.from(args || []))
}
@@ -41,7 +41,7 @@ module.exports = CompileManager = {
return CompileManager._checkIfRecentlyCompiled(
project_id,
user_id,
function(error, recentlyCompiled) {
function (error, recentlyCompiled) {
if (error != null) {
return callback(error)
}
@@ -52,20 +52,20 @@ module.exports = CompileManager = {
return CompileManager._checkIfAutoCompileLimitHasBeenHit(
options.isAutoCompile,
'everyone',
function(err, canCompile) {
function (err, canCompile) {
if (!canCompile) {
return callback(null, 'autocompile-backoff', [])
}
return ProjectRootDocManager.ensureRootDocumentIsSet(
project_id,
function(error) {
function (error) {
if (error != null) {
return callback(error)
}
return CompileManager.getProjectCompileLimits(
project_id,
function(error, limits) {
function (error, limits) {
if (error != null) {
return callback(error)
}
@@ -77,7 +77,7 @@ module.exports = CompileManager = {
return CompileManager._checkCompileGroupAutoCompileLimit(
options.isAutoCompile,
limits.compileGroup,
function(err, canCompile) {
function (err, canCompile) {
if (!canCompile) {
return callback(null, 'autocompile-backoff', [])
}
@@ -89,7 +89,7 @@ module.exports = CompileManager = {
project_id,
compileAsUser,
options,
function(
function (
error,
status,
outputFiles,
@@ -123,100 +123,105 @@ module.exports = CompileManager = {
stopCompile(project_id, user_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return CompileManager.getProjectCompileLimits(project_id, function(
error,
limits
) {
if (error != null) {
return callback(error)
return CompileManager.getProjectCompileLimits(
project_id,
function (error, limits) {
if (error != null) {
return callback(error)
}
return ClsiManager.stopCompile(project_id, user_id, limits, callback)
}
return ClsiManager.stopCompile(project_id, user_id, limits, callback)
})
)
},
deleteAuxFiles(project_id, user_id, clsiserverid, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return CompileManager.getProjectCompileLimits(project_id, function(
error,
limits
) {
if (error != null) {
return callback(error)
return CompileManager.getProjectCompileLimits(
project_id,
function (error, limits) {
if (error != null) {
return callback(error)
}
ClsiManager.deleteAuxFiles(
project_id,
user_id,
limits,
clsiserverid,
callback
)
}
ClsiManager.deleteAuxFiles(
project_id,
user_id,
limits,
clsiserverid,
callback
)
})
)
},
getProjectCompileLimits(project_id, callback) {
if (callback == null) {
callback = function(error, limits) {}
callback = function (error, limits) {}
}
return ProjectGetter.getProject(project_id, { owner_ref: 1 }, function(
error,
project
) {
if (error != null) {
return callback(error)
}
return UserGetter.getUser(
project.owner_ref,
{ alphaProgram: 1, betaProgram: 1, features: 1 },
function(err, owner) {
if (error != null) {
return callback(error)
}
let ownerFeatures = (owner && owner.features) || {}
// put alpha users into their own compile group
if (owner && owner.alphaProgram) {
ownerFeatures.compileGroup = 'alpha'
}
return callback(null, {
timeout:
ownerFeatures.compileTimeout ||
Settings.defaultFeatures.compileTimeout,
compileGroup:
ownerFeatures.compileGroup ||
Settings.defaultFeatures.compileGroup
})
return ProjectGetter.getProject(
project_id,
{ owner_ref: 1 },
function (error, project) {
if (error != null) {
return callback(error)
}
)
})
return UserGetter.getUser(
project.owner_ref,
{ alphaProgram: 1, betaProgram: 1, features: 1 },
function (err, owner) {
if (error != null) {
return callback(error)
}
let ownerFeatures = (owner && owner.features) || {}
// put alpha users into their own compile group
if (owner && owner.alphaProgram) {
ownerFeatures.compileGroup = 'alpha'
}
return callback(null, {
timeout:
ownerFeatures.compileTimeout ||
Settings.defaultFeatures.compileTimeout,
compileGroup:
ownerFeatures.compileGroup ||
Settings.defaultFeatures.compileGroup
})
}
)
}
)
},
COMPILE_DELAY: 1, // seconds
_checkIfRecentlyCompiled(project_id, user_id, callback) {
if (callback == null) {
callback = function(error, recentlyCompiled) {}
callback = function (error, recentlyCompiled) {}
}
const key = `compile:${project_id}:${user_id}`
return rclient.set(key, true, 'EX', this.COMPILE_DELAY, 'NX', function(
error,
ok
) {
if (error != null) {
return callback(error)
return rclient.set(
key,
true,
'EX',
this.COMPILE_DELAY,
'NX',
function (error, ok) {
if (error != null) {
return callback(error)
}
if (ok === 'OK') {
return callback(null, false)
} else {
return callback(null, true)
}
}
if (ok === 'OK') {
return callback(null, false)
} else {
return callback(null, true)
}
})
)
},
_checkCompileGroupAutoCompileLimit(isAutoCompile, compileGroup, callback) {
if (callback == null) {
callback = function(err, canCompile) {}
callback = function (err, canCompile) {}
}
if (!isAutoCompile) {
return callback(null, true)
@@ -236,7 +241,7 @@ module.exports = CompileManager = {
_checkIfAutoCompileLimitHasBeenHit(isAutoCompile, compileGroup, callback) {
if (callback == null) {
callback = function(err, canCompile) {}
callback = function (err, canCompile) {}
}
if (!isAutoCompile) {
return callback(null, true)
@@ -248,7 +253,7 @@ module.exports = CompileManager = {
subjectName: compileGroup,
throttle: Settings.rateLimit.autoCompile[compileGroup] || 25
}
return rateLimiter.addCount(opts, function(err, canCompile) {
return rateLimiter.addCount(opts, function (err, canCompile) {
if (err != null) {
canCompile = false
}
@@ -261,23 +266,23 @@ module.exports = CompileManager = {
wordCount(project_id, user_id, file, clsiserverid, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return CompileManager.getProjectCompileLimits(project_id, function(
error,
limits
) {
if (error != null) {
return callback(error)
return CompileManager.getProjectCompileLimits(
project_id,
function (error, limits) {
if (error != null) {
return callback(error)
}
ClsiManager.wordCount(
project_id,
user_id,
file,
limits,
clsiserverid,
callback
)
}
ClsiManager.wordCount(
project_id,
user_id,
file,
limits,
clsiserverid,
callback
)
})
)
}
}

View File

@@ -22,58 +22,63 @@ const Modules = require('../../infrastructure/Modules')
module.exports = ContactsController = {
getContacts(req, res, next) {
const user_id = AuthenticationController.getLoggedInUserId(req)
return ContactManager.getContactIds(user_id, { limit: 50 }, function(
error,
contact_ids
) {
if (error != null) {
return next(error)
}
return UserGetter.getUsers(
contact_ids,
{
email: 1,
first_name: 1,
last_name: 1,
holdingAccount: 1
},
function(error, contacts) {
if (error != null) {
return next(error)
}
// UserGetter.getUsers may not preserve order so put them back in order
const positions = {}
for (let i = 0; i < contact_ids.length; i++) {
const contact_id = contact_ids[i]
positions[contact_id] = i
}
contacts.sort(
(a, b) =>
positions[a._id != null ? a._id.toString() : undefined] -
positions[b._id != null ? b._id.toString() : undefined]
)
// Don't count holding accounts to discourage users from repeating mistakes (mistyped or wrong emails, etc)
contacts = contacts.filter(c => !c.holdingAccount)
contacts = contacts.map(ContactsController._formatContact)
return Modules.hooks.fire('getContacts', user_id, contacts, function(
error,
additional_contacts
) {
return ContactManager.getContactIds(
user_id,
{ limit: 50 },
function (error, contact_ids) {
if (error != null) {
return next(error)
}
return UserGetter.getUsers(
contact_ids,
{
email: 1,
first_name: 1,
last_name: 1,
holdingAccount: 1
},
function (error, contacts) {
if (error != null) {
return next(error)
}
contacts = contacts.concat(...Array.from(additional_contacts || []))
return res.send({
contacts
})
})
}
)
})
// UserGetter.getUsers may not preserve order so put them back in order
const positions = {}
for (let i = 0; i < contact_ids.length; i++) {
const contact_id = contact_ids[i]
positions[contact_id] = i
}
contacts.sort(
(a, b) =>
positions[a._id != null ? a._id.toString() : undefined] -
positions[b._id != null ? b._id.toString() : undefined]
)
// Don't count holding accounts to discourage users from repeating mistakes (mistyped or wrong emails, etc)
contacts = contacts.filter(c => !c.holdingAccount)
contacts = contacts.map(ContactsController._formatContact)
return Modules.hooks.fire(
'getContacts',
user_id,
contacts,
function (error, additional_contacts) {
if (error != null) {
return next(error)
}
contacts = contacts.concat(
...Array.from(additional_contacts || [])
)
return res.send({
contacts
})
}
)
}
)
}
)
},
_formatContact(contact) {

View File

@@ -23,7 +23,7 @@ module.exports = ContactManager = {
options = { limits: 50 }
}
if (callback == null) {
callback = function(error, contacts) {}
callback = function (error, contacts) {}
}
const url = `${settings.apis.contacts.url}/user/${user_id}/contacts`
return request.get(
@@ -33,7 +33,7 @@ module.exports = ContactManager = {
json: true,
jar: false
},
function(error, res, data) {
function (error, res, data) {
if (error != null) {
return callback(error)
}
@@ -55,7 +55,7 @@ module.exports = ContactManager = {
addContact(user_id, contact_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
const url = `${settings.apis.contacts.url}/user/${user_id}/contacts`
return request.post(
@@ -66,7 +66,7 @@ module.exports = ContactManager = {
},
jar: false
},
function(error, res, data) {
function (error, res, data) {
if (error != null) {
return callback(error)
}

View File

@@ -24,7 +24,7 @@ module.exports = CooldownManager = {
putProjectOnCooldown(projectId, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
logger.log(
{ projectId },
@@ -41,16 +41,16 @@ module.exports = CooldownManager = {
isProjectOnCooldown(projectId, callback) {
if (callback == null) {
callback = function(err, isOnCooldown) {}
callback = function (err, isOnCooldown) {}
}
return rclient.get(CooldownManager._buildKey(projectId), function(
err,
result
) {
if (err != null) {
return callback(err)
return rclient.get(
CooldownManager._buildKey(projectId),
function (err, result) {
if (err != null) {
return callback(err)
}
return callback(null, result === '1')
}
return callback(null, result === '1')
})
)
}
}

View File

@@ -20,21 +20,21 @@ module.exports = CooldownMiddleware = {
if (projectId == null) {
return next(new Error('[Cooldown] No projectId parameter on route'))
}
return CooldownManager.isProjectOnCooldown(projectId, function(
err,
projectIsOnCooldown
) {
if (err != null) {
return next(err)
return CooldownManager.isProjectOnCooldown(
projectId,
function (err, projectIsOnCooldown) {
if (err != null) {
return next(err)
}
if (projectIsOnCooldown) {
logger.log(
{ projectId },
'[Cooldown] project is on cooldown, denying request'
)
return res.sendStatus(429)
}
return next()
}
if (projectIsOnCooldown) {
logger.log(
{ projectId },
'[Cooldown] project is on cooldown, denying request'
)
return res.sendStatus(429)
}
return next()
})
)
}
}

View File

@@ -24,12 +24,12 @@ const TIMEOUT = 30 * 1000 // request timeout
const DocstoreManager = {
deleteDoc(project_id, doc_id, name, deletedAt, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}`
const docMetaData = { deleted: true, deletedAt, name }
const options = { url, json: docMetaData, timeout: TIMEOUT }
request.patch(options, function(error, res) {
request.patch(options, function (error, res) {
if (error != null) {
return callback(error)
}
@@ -59,7 +59,7 @@ const DocstoreManager = {
getAllDocs(project_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
const url = `${settings.apis.docstore.url}/project/${project_id}/doc`
return request.get(
@@ -68,7 +68,7 @@ const DocstoreManager = {
timeout: TIMEOUT,
json: true
},
function(error, res, docs) {
function (error, res, docs) {
if (error != null) {
return callback(error)
}
@@ -87,29 +87,30 @@ const DocstoreManager = {
getAllDeletedDocs(project_id, callback) {
const url = `${settings.apis.docstore.url}/project/${project_id}/doc-deleted`
request.get({ url, timeout: TIMEOUT, json: true }, function(
error,
res,
docs
) {
if (error) {
callback(OError.tag(error, 'could not get deleted docs from docstore'))
} else if (res.statusCode === 200) {
callback(null, docs)
} else {
callback(
new OError(
`docstore api responded with non-success code: ${res.statusCode}`,
{ project_id }
request.get(
{ url, timeout: TIMEOUT, json: true },
function (error, res, docs) {
if (error) {
callback(
OError.tag(error, 'could not get deleted docs from docstore')
)
)
} else if (res.statusCode === 200) {
callback(null, docs)
} else {
callback(
new OError(
`docstore api responded with non-success code: ${res.statusCode}`,
{ project_id }
)
)
}
}
})
)
},
getAllRanges(project_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
const url = `${settings.apis.docstore.url}/project/${project_id}/ranges`
return request.get(
@@ -118,7 +119,7 @@ const DocstoreManager = {
timeout: TIMEOUT,
json: true
},
function(error, res, docs) {
function (error, res, docs) {
if (error != null) {
return callback(error)
}
@@ -140,7 +141,7 @@ const DocstoreManager = {
options = {}
}
if (callback == null) {
callback = function(error, lines, rev, version) {}
callback = function (error, lines, rev, version) {}
}
if (typeof options === 'function') {
callback = options
@@ -156,7 +157,7 @@ const DocstoreManager = {
timeout: TIMEOUT,
json: true
},
function(error, res, doc) {
function (error, res, doc) {
if (error != null) {
return callback(error)
}
@@ -191,36 +192,35 @@ const DocstoreManager = {
isDocDeleted(project_id, doc_id, callback) {
const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}/deleted`
request.get({ url, timeout: TIMEOUT, json: true }, function(
err,
res,
body
) {
if (err) {
callback(err)
} else if (res.statusCode === 200) {
callback(null, body.deleted)
} else if (res.statusCode === 404) {
callback(
new Errors.NotFoundError({
message: 'doc does not exist in project',
info: { project_id, doc_id }
})
)
} else {
callback(
new OError(
`docstore api responded with non-success code: ${res.statusCode}`,
{ project_id, doc_id }
request.get(
{ url, timeout: TIMEOUT, json: true },
function (err, res, body) {
if (err) {
callback(err)
} else if (res.statusCode === 200) {
callback(null, body.deleted)
} else if (res.statusCode === 404) {
callback(
new Errors.NotFoundError({
message: 'doc does not exist in project',
info: { project_id, doc_id }
})
)
)
} else {
callback(
new OError(
`docstore api responded with non-success code: ${res.statusCode}`,
{ project_id, doc_id }
)
)
}
}
})
)
},
updateDoc(project_id, doc_id, lines, version, ranges, callback) {
if (callback == null) {
callback = function(error, modified, rev) {}
callback = function (error, modified, rev) {}
}
const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}`
return request.post(
@@ -233,7 +233,7 @@ const DocstoreManager = {
ranges
}
},
function(error, res, result) {
function (error, res, result) {
if (error != null) {
return callback(error)
}
@@ -270,7 +270,7 @@ const DocstoreManager = {
const url = `${settings.apis.docstore.url}/project/${project_id}/${method}`
logger.log({ project_id }, `calling ${method} for project in docstore`)
// use default timeout for archiving/unarchiving/destroying
request.post(url, function(err, res, docs) {
request.post(url, function (err, res, docs) {
if (err != null) {
OError.tag(err, `error calling ${method} project in docstore`, {
project_id

View File

@@ -101,7 +101,7 @@ function getDocument(projectId, docId, fromVersion, callback) {
},
projectId,
'get-document',
function(error, doc) {
function (error, doc) {
if (error) {
return callback(error)
}
@@ -133,7 +133,7 @@ function getProjectDocsIfMatch(projectId, projectStateHash, callback) {
// fall back to getting them from mongo.
const timer = new metrics.Timer('get-project-docs')
const url = `${settings.apis.documentupdater.url}/project/${projectId}/get_and_flush_if_old?state=${projectStateHash}`
request.post(url, function(error, res, body) {
request.post(url, function (error, res, body) {
timer.done()
if (error) {
OError.tag(error, 'error getting project docs from doc updater', {
@@ -300,7 +300,7 @@ function _makeRequest(options, projectId, metricsKey, callback) {
json: options.json,
method: options.method || 'GET'
},
function(error, res, body) {
function (error, res, body) {
timer.done()
if (error) {
logger.warn(

View File

@@ -23,7 +23,7 @@ const _ = require('lodash')
module.exports = {
getDocument(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
const project_id = req.params.Project_id
const { doc_id } = req.params
@@ -32,7 +32,7 @@ module.exports = {
return ProjectGetter.getProject(
project_id,
{ rootFolder: true, overleaf: true },
function(error, project) {
function (error, project) {
if (error != null) {
return next(error)
}
@@ -41,7 +41,7 @@ module.exports = {
}
return ProjectLocator.findElement(
{ project, element_id: doc_id, type: 'doc' },
function(error, doc, path) {
function (error, doc, path) {
if (error != null) {
OError.tag(error, 'error finding element for getDocument', {
doc_id,
@@ -49,45 +49,43 @@ module.exports = {
})
return next(error)
}
return ProjectEntityHandler.getDoc(project_id, doc_id, function(
error,
lines,
rev,
version,
ranges
) {
if (error != null) {
OError.tag(
error,
'error finding doc contents for getDocument',
{
doc_id,
project_id
}
)
return next(error)
return ProjectEntityHandler.getDoc(
project_id,
doc_id,
function (error, lines, rev, version, ranges) {
if (error != null) {
OError.tag(
error,
'error finding doc contents for getDocument',
{
doc_id,
project_id
}
)
return next(error)
}
if (plain) {
res.type('text/plain')
return res.send(lines.join('\n'))
} else {
const projectHistoryId = _.get(project, 'overleaf.history.id')
const projectHistoryType = _.get(
project,
'overleaf.history.display'
)
? 'project-history'
: undefined // for backwards compatibility, don't send anything if the project is still on track-changes
return res.json({
lines,
version,
ranges,
pathname: path.fileSystem,
projectHistoryId,
projectHistoryType
})
}
}
if (plain) {
res.type('text/plain')
return res.send(lines.join('\n'))
} else {
const projectHistoryId = _.get(project, 'overleaf.history.id')
const projectHistoryType = _.get(
project,
'overleaf.history.display'
)
? 'project-history'
: undefined // for backwards compatibility, don't send anything if the project is still on track-changes
return res.json({
lines,
version,
ranges,
pathname: path.fileSystem,
projectHistoryId,
projectHistoryType
})
}
})
)
}
)
}
@@ -96,7 +94,7 @@ module.exports = {
setDocument(req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
const project_id = req.params.Project_id
const { doc_id } = req.params
@@ -109,7 +107,7 @@ module.exports = {
ranges,
lastUpdatedAt,
lastUpdatedBy,
function(error) {
function (error) {
if (error != null) {
OError.tag(error, 'error finding element for getDocument', {
doc_id,

View File

@@ -22,34 +22,36 @@ module.exports = ProjectDownloadsController = {
downloadProject(req, res, next) {
const project_id = req.params.Project_id
Metrics.inc('zip-downloads')
return DocumentUpdaterHandler.flushProjectToMongo(project_id, function(
error
) {
if (error != null) {
return next(error)
}
return ProjectGetter.getProject(project_id, { name: true }, function(
error,
project
) {
return DocumentUpdaterHandler.flushProjectToMongo(
project_id,
function (error) {
if (error != null) {
return next(error)
}
return ProjectZipStreamManager.createZipStreamForProject(
return ProjectGetter.getProject(
project_id,
function(error, stream) {
{ name: true },
function (error, project) {
if (error != null) {
return next(error)
}
res.setContentDisposition('attachment', {
filename: `${project.name}.zip`
})
res.contentType('application/zip')
return stream.pipe(res)
return ProjectZipStreamManager.createZipStreamForProject(
project_id,
function (error, stream) {
if (error != null) {
return next(error)
}
res.setContentDisposition('attachment', {
filename: `${project.name}.zip`
})
res.contentType('application/zip')
return stream.pipe(res)
}
)
}
)
})
})
}
)
},
downloadMultipleProjects(req, res, next) {
@@ -57,13 +59,13 @@ module.exports = ProjectDownloadsController = {
Metrics.inc('zip-downloads-multiple')
return DocumentUpdaterHandler.flushMultipleProjectsToMongo(
project_ids,
function(error) {
function (error) {
if (error != null) {
return next(error)
}
return ProjectZipStreamManager.createZipStreamForMultipleProjects(
project_ids,
function(error, stream) {
function (error, stream) {
if (error != null) {
return next(error)
}

View File

@@ -26,7 +26,7 @@ module.exports = ProjectZipStreamManager = {
// We'll build up a zip file that contains multiple zip files
if (callback == null) {
callback = function(error, stream) {}
callback = function (error, stream) {}
}
const archive = archiver('zip')
archive.on('error', err =>
@@ -41,38 +41,39 @@ module.exports = ProjectZipStreamManager = {
for (let project_id of Array.from(project_ids || [])) {
;(project_id =>
jobs.push(callback =>
ProjectGetter.getProject(project_id, { name: true }, function(
error,
project
) {
if (error != null) {
return callback(error)
}
logger.log(
{ project_id, name: project.name },
'appending project to zip stream'
)
return ProjectZipStreamManager.createZipStreamForProject(
project_id,
function(error, stream) {
if (error != null) {
return callback(error)
}
archive.append(stream, { name: `${project.name}.zip` })
return stream.on('end', function() {
logger.log(
{ project_id, name: project.name },
'zip stream ended'
)
return callback()
})
ProjectGetter.getProject(
project_id,
{ name: true },
function (error, project) {
if (error != null) {
return callback(error)
}
)
})
logger.log(
{ project_id, name: project.name },
'appending project to zip stream'
)
return ProjectZipStreamManager.createZipStreamForProject(
project_id,
function (error, stream) {
if (error != null) {
return callback(error)
}
archive.append(stream, { name: `${project.name}.zip` })
return stream.on('end', function () {
logger.log(
{ project_id, name: project.name },
'zip stream ended'
)
return callback()
})
}
)
}
)
))(project_id)
}
return async.series(jobs, function() {
return async.series(jobs, function () {
logger.log(
{ project_ids },
'finished creating zip stream of multiple projects'
@@ -83,7 +84,7 @@ module.exports = ProjectZipStreamManager = {
createZipStreamForProject(project_id, callback) {
if (callback == null) {
callback = function(error, stream) {}
callback = function (error, stream) {}
}
const archive = archiver('zip')
// return stream immediately before we start adding things to it
@@ -115,20 +116,20 @@ module.exports = ProjectZipStreamManager = {
addAllDocsToArchive(project_id, archive, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ProjectEntityHandler.getAllDocs(project_id, function(error, docs) {
return ProjectEntityHandler.getAllDocs(project_id, function (error, docs) {
if (error != null) {
return callback(error)
}
const jobs = []
for (let path in docs) {
const doc = docs[path]
;(function(path, doc) {
;(function (path, doc) {
if (path[0] === '/') {
path = path.slice(1)
}
return jobs.push(function(callback) {
return jobs.push(function (callback) {
logger.log({ project_id }, 'Adding doc')
archive.append(doc.lines.join('\n'), { name: path })
return callback()
@@ -141,37 +142,42 @@ module.exports = ProjectZipStreamManager = {
addAllFilesToArchive(project_id, archive, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ProjectEntityHandler.getAllFiles(project_id, function(error, files) {
if (error != null) {
return callback(error)
return ProjectEntityHandler.getAllFiles(
project_id,
function (error, files) {
if (error != null) {
return callback(error)
}
const jobs = []
for (let path in files) {
const file = files[path]
;((path, file) =>
jobs.push(callback =>
FileStoreHandler.getFileStream(
project_id,
file._id,
{},
function (error, stream) {
if (error != null) {
logger.warn(
{ err: error, project_id, file_id: file._id },
'something went wrong adding file to zip archive'
)
return callback(err)
}
if (path[0] === '/') {
path = path.slice(1)
}
archive.append(stream, { name: path })
return stream.on('end', () => callback())
}
)
))(path, file)
}
return async.parallelLimit(jobs, 5, callback)
}
const jobs = []
for (let path in files) {
const file = files[path]
;((path, file) =>
jobs.push(callback =>
FileStoreHandler.getFileStream(project_id, file._id, {}, function(
error,
stream
) {
if (error != null) {
logger.warn(
{ err: error, project_id, file_id: file._id },
'something went wrong adding file to zip archive'
)
return callback(err)
}
if (path[0] === '/') {
path = path.slice(1)
}
archive.append(stream, { name: path })
return stream.on('end', () => callback())
})
))(path, file)
}
return async.parallelLimit(jobs, 5, callback)
})
)
}
}

View File

@@ -31,7 +31,7 @@ const { promisifyAll } = require('../../util/promises')
const EditorController = {
addDoc(project_id, folder_id, docName, docLines, source, user_id, callback) {
if (callback == null) {
callback = function(error, doc) {}
callback = function (error, doc) {}
}
return EditorController.addDocWithRanges(
project_id,
@@ -56,7 +56,7 @@ const EditorController = {
callback
) {
if (callback == null) {
callback = function(error, doc) {}
callback = function (error, doc) {}
}
docName = docName.trim()
Metrics.inc('editor.add-doc')
@@ -99,7 +99,7 @@ const EditorController = {
callback
) {
if (callback == null) {
callback = function(error, file) {}
callback = function (error, file) {}
}
fileName = fileName.trim()
Metrics.inc('editor.add-file')
@@ -143,7 +143,7 @@ const EditorController = {
callback
) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectEntityUpdateHandler.upsertDoc(
project_id,
@@ -152,7 +152,7 @@ const EditorController = {
docLines,
source,
user_id,
function(err, doc, didAddNewDoc) {
function (err, doc, didAddNewDoc) {
if (didAddNewDoc) {
EditorRealTimeController.emitToRoom(
project_id,
@@ -179,7 +179,7 @@ const EditorController = {
callback
) {
if (callback == null) {
callback = function(err, file) {}
callback = function (err, file) {}
}
return ProjectEntityUpdateHandler.upsertFile(
project_id,
@@ -188,7 +188,7 @@ const EditorController = {
fsPath,
linkedFileData,
user_id,
function(err, newFile, didAddFile, existingFile) {
function (err, newFile, didAddFile, existingFile) {
if (err != null) {
return callback(err)
}
@@ -230,14 +230,14 @@ const EditorController = {
docLines,
source,
user_id,
function(err, doc, didAddNewDoc, newFolders, lastFolder) {
function (err, doc, didAddNewDoc, newFolders, lastFolder) {
if (err != null) {
return callback(err)
}
return EditorController._notifyProjectUsersOfNewFolders(
project_id,
newFolders,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -273,14 +273,21 @@ const EditorController = {
fsPath,
linkedFileData,
user_id,
function(err, newFile, didAddFile, existingFile, newFolders, lastFolder) {
function (
err,
newFile,
didAddFile,
existingFile,
newFolders,
lastFolder
) {
if (err != null) {
return callback(err)
}
return EditorController._notifyProjectUsersOfNewFolders(
project_id,
newFolders,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -312,7 +319,7 @@ const EditorController = {
addFolder(project_id, folder_id, folderName, source, userId, callback) {
if (callback == null) {
callback = function(error, folder) {}
callback = function (error, folder) {}
}
folderName = folderName.trim()
Metrics.inc('editor.add-folder')
@@ -335,7 +342,7 @@ const EditorController = {
folder_id,
folder,
userId,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -348,7 +355,7 @@ const EditorController = {
mkdirp(project_id, path, callback) {
if (callback == null) {
callback = function(error, newFolders, lastFolder) {}
callback = function (error, newFolders, lastFolder) {}
}
logger.log({ project_id, path }, "making directories if they don't exist")
return ProjectEntityUpdateHandler.mkdirp(
@@ -366,7 +373,7 @@ const EditorController = {
return EditorController._notifyProjectUsersOfNewFolders(
project_id,
newFolders,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -379,7 +386,7 @@ const EditorController = {
deleteEntity(project_id, entity_id, entityType, source, userId, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
Metrics.inc('editor.delete-entity')
return ProjectEntityUpdateHandler.deleteEntity(
@@ -387,7 +394,7 @@ const EditorController = {
entity_id,
entityType,
userId,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'could not delete entity', {
project_id,
@@ -416,7 +423,7 @@ const EditorController = {
project_id,
path,
user_id,
function(err, entity_id) {
function (err, entity_id) {
if (err != null) {
return callback(err)
}
@@ -433,13 +440,13 @@ const EditorController = {
updateProjectDescription(project_id, description, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
logger.log({ project_id, description }, 'updating project description')
return ProjectDetailsHandler.setProjectDescription(
project_id,
description,
function(err) {
function (err) {
if (err != null) {
OError.tag(
err,
@@ -468,7 +475,7 @@ const EditorController = {
renameEntity(project_id, entity_id, entityType, newName, userId, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
newName = sanitize.escape(newName)
Metrics.inc('editor.rename-entity')
@@ -478,7 +485,7 @@ const EditorController = {
entityType,
newName,
userId,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'error renaming entity', {
project_id,
@@ -503,7 +510,7 @@ const EditorController = {
moveEntity(project_id, entity_id, folder_id, entityType, userId, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
Metrics.inc('editor.move-entity')
return ProjectEntityUpdateHandler.moveEntity(
@@ -512,7 +519,7 @@ const EditorController = {
folder_id,
entityType,
userId,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'error moving entity', {
project_id,
@@ -534,73 +541,79 @@ const EditorController = {
renameProject(project_id, newName, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectDetailsHandler.renameProject(project_id, newName, function(
err
) {
if (err != null) {
OError.tag(err, 'error renaming project', {
return ProjectDetailsHandler.renameProject(
project_id,
newName,
function (err) {
if (err != null) {
OError.tag(err, 'error renaming project', {
project_id,
newName
})
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'projectNameUpdated',
newName
})
return callback(err)
)
return callback()
}
EditorRealTimeController.emitToRoom(
project_id,
'projectNameUpdated',
newName
)
return callback()
})
)
},
setCompiler(project_id, compiler, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectOptionsHandler.setCompiler(project_id, compiler, function(
err
) {
if (err != null) {
return callback(err)
return ProjectOptionsHandler.setCompiler(
project_id,
compiler,
function (err) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'compilerUpdated',
compiler
)
return callback()
}
EditorRealTimeController.emitToRoom(
project_id,
'compilerUpdated',
compiler
)
return callback()
})
)
},
setImageName(project_id, imageName, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectOptionsHandler.setImageName(project_id, imageName, function(
err
) {
if (err != null) {
return callback(err)
return ProjectOptionsHandler.setImageName(
project_id,
imageName,
function (err) {
if (err != null) {
return callback(err)
}
EditorRealTimeController.emitToRoom(
project_id,
'imageNameUpdated',
imageName
)
return callback()
}
EditorRealTimeController.emitToRoom(
project_id,
'imageNameUpdated',
imageName
)
return callback()
})
)
},
setSpellCheckLanguage(project_id, languageCode, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectOptionsHandler.setSpellCheckLanguage(
project_id,
languageCode,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -616,12 +629,12 @@ const EditorController = {
setPublicAccessLevel(project_id, newAccessLevel, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectDetailsHandler.setPublicAccessLevel(
project_id,
newAccessLevel,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -633,7 +646,7 @@ const EditorController = {
if (newAccessLevel === PublicAccessLevels.TOKEN_BASED) {
return ProjectDetailsHandler.ensureTokensArePresent(
project_id,
function(err, tokens) {
function (err, tokens) {
if (err != null) {
return callback(err)
}
@@ -654,12 +667,12 @@ const EditorController = {
setRootDoc(project_id, newRootDocID, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectEntityUpdateHandler.setRootDoc(
project_id,
newRootDocID,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -675,7 +688,7 @@ const EditorController = {
_notifyProjectUsersOfNewFolders(project_id, folders, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return async.eachSeries(
folders,
@@ -699,7 +712,7 @@ const EditorController = {
callback
) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
EditorRealTimeController.emitToRoom(
project_id,

View File

@@ -49,41 +49,41 @@ module.exports = {
}
}
return ExportsHandler.exportProject(export_params, function(
err,
export_data
) {
if (err != null) {
if (err.forwardResponse != null) {
logger.log(
{ responseError: err.forwardResponse },
'forwarding response'
)
const statusCode = err.forwardResponse.status || 500
return res.status(statusCode).json(err.forwardResponse)
} else {
return next(err)
return ExportsHandler.exportProject(
export_params,
function (err, export_data) {
if (err != null) {
if (err.forwardResponse != null) {
logger.log(
{ responseError: err.forwardResponse },
'forwarding response'
)
const statusCode = err.forwardResponse.status || 500
return res.status(statusCode).json(err.forwardResponse)
} else {
return next(err)
}
}
logger.log(
{
user_id,
project_id,
brand_variation_id,
export_v1_id: export_data.v1_id
},
'exported project'
)
return res.json({
export_v1_id: export_data.v1_id,
message: export_data.message
})
}
logger.log(
{
user_id,
project_id,
brand_variation_id,
export_v1_id: export_data.v1_id
},
'exported project'
)
return res.json({
export_v1_id: export_data.v1_id,
message: export_data.message
})
})
)
},
exportStatus(req, res) {
const { export_id } = req.params
return ExportsHandler.fetchExport(export_id, function(err, export_json) {
return ExportsHandler.fetchExport(export_id, function (err, export_json) {
let json
if (err != null) {
json = {
@@ -112,15 +112,16 @@ module.exports = {
const { type, export_id } = req.params
AuthenticationController.getLoggedInUserId(req)
return ExportsHandler.fetchDownload(export_id, type, function(
err,
export_file_url
) {
if (err != null) {
return next(err)
}
return ExportsHandler.fetchDownload(
export_id,
type,
function (err, export_file_url) {
if (err != null) {
return next(err)
}
return res.redirect(export_file_url)
})
return res.redirect(export_file_url)
}
)
}
}

View File

@@ -30,13 +30,13 @@ settings = require('settings-sharelatex')
module.exports = ExportsHandler = self = {
exportProject(export_params, callback) {
if (callback == null) {
callback = function(error, export_data) {}
callback = function (error, export_data) {}
}
return self._buildExport(export_params, function(err, export_data) {
return self._buildExport(export_params, function (err, export_data) {
if (err != null) {
return callback(err)
}
return self._requestExport(export_data, function(err, body) {
return self._requestExport(export_data, function (err, body) {
if (err != null) {
return callback(err)
}
@@ -50,7 +50,7 @@ module.exports = ExportsHandler = self = {
_buildExport(export_params, callback) {
if (callback == null) {
callback = function(err, export_data) {}
callback = function (err, export_data) {}
}
const {
project_id,
@@ -70,17 +70,18 @@ module.exports = ExportsHandler = self = {
rootDoc: [
'project',
(cb, results) =>
ProjectRootDocManager.ensureRootDocumentIsValid(project_id, function(
error
) {
if (error != null) {
return callback(error)
ProjectRootDocManager.ensureRootDocumentIsValid(
project_id,
function (error) {
if (error != null) {
return callback(error)
}
return ProjectLocator.findRootDoc(
{ project: results.project, project_id },
cb
)
}
return ProjectLocator.findRootDoc(
{ project: results.project, project_id },
cb
)
})
)
],
user(cb) {
return UserGetter.getUser(
@@ -92,7 +93,7 @@ module.exports = ExportsHandler = self = {
historyVersion(cb) {
return ProjectHistoryHandler.ensureHistoryExistsForProject(
project_id,
function(error) {
function (error) {
if (error != null) {
return callback(error)
}
@@ -102,7 +103,7 @@ module.exports = ExportsHandler = self = {
}
}
return async.auto(jobs, function(err, results) {
return async.auto(jobs, function (err, results) {
if (err != null) {
OError.tag(err, 'error building project export', {
project_id,
@@ -167,7 +168,7 @@ module.exports = ExportsHandler = self = {
_requestExport(export_data, callback) {
if (callback == null) {
callback = function(err, export_v1_id) {}
callback = function (err, export_v1_id) {}
}
return request.post(
{
@@ -175,7 +176,7 @@ module.exports = ExportsHandler = self = {
auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass },
json: export_data
},
function(err, res, body) {
function (err, res, body) {
if (err != null) {
OError.tag(err, 'error making request to v1 export', {
export: export_data
@@ -197,14 +198,14 @@ module.exports = ExportsHandler = self = {
_requestVersion(project_id, callback) {
if (callback == null) {
callback = function(err, export_v1_id) {}
callback = function (err, export_v1_id) {}
}
return request.get(
{
url: `${settings.apis.project_history.url}/project/${project_id}/version`,
json: true
},
function(err, res, body) {
function (err, res, body) {
if (err != null) {
OError.tag(err, 'error making request to project history', {
project_id
@@ -225,14 +226,14 @@ module.exports = ExportsHandler = self = {
fetchExport(export_id, callback) {
if (callback == null) {
callback = function(err, export_json) {}
callback = function (err, export_json) {}
}
return request.get(
{
url: `${settings.apis.v1.url}/api/v1/sharelatex/exports/${export_id}`,
auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass }
},
function(err, res, body) {
function (err, res, body) {
if (err != null) {
OError.tag(err, 'error making request to v1 export', {
export: export_id
@@ -253,14 +254,14 @@ module.exports = ExportsHandler = self = {
fetchDownload(export_id, type, callback) {
if (callback == null) {
callback = function(err, file_url) {}
callback = function (err, file_url) {}
}
return request.get(
{
url: `${settings.apis.v1.url}/api/v1/sharelatex/exports/${export_id}/${type}_url`,
auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass }
},
function(err, res, body) {
function (err, res, body) {
if (err != null) {
OError.tag(err, 'error making request to v1 export', {
export: export_id

View File

@@ -20,7 +20,7 @@ const _ = require('underscore')
module.exports = FileHashManager = {
computeHash(filePath, callback) {
if (callback == null) {
callback = function(error, hashValue) {}
callback = function (error, hashValue) {}
}
callback = _.once(callback) // avoid double callbacks
@@ -28,20 +28,20 @@ module.exports = FileHashManager = {
const getGitBlobHeader = byteLength => `blob ${byteLength}` + '\x00'
const getByteLengthOfFile = cb =>
fs.stat(filePath, function(err, stats) {
fs.stat(filePath, function (err, stats) {
if (err != null) {
return cb(err)
}
return cb(null, stats.size)
})
return getByteLengthOfFile(function(err, byteLength) {
return getByteLengthOfFile(function (err, byteLength) {
if (err != null) {
return callback(err)
}
const input = fs.createReadStream(filePath)
input.on('error', function(err) {
input.on('error', function (err) {
logger.warn({ filePath, err }, 'error opening file in computeHash')
return callback(err)
})
@@ -49,7 +49,7 @@ module.exports = FileHashManager = {
const hash = crypto.createHash('sha1')
hash.setEncoding('hex')
hash.update(getGitBlobHeader(byteLength))
hash.on('readable', function() {
hash.on('readable', function () {
const result = hash.read()
if (result != null) {
return callback(null, result.toString('hex'))

View File

@@ -12,7 +12,7 @@ module.exports = {
const userAgent = req.get('User-Agent')
ProjectLocator.findElement(
{ project_id: projectId, element_id: fileId, type: 'file' },
function(err, file) {
function (err, file) {
if (err) {
logger.err(
{ err, projectId, fileId, queryString },
@@ -20,24 +20,26 @@ module.exports = {
)
return res.sendStatus(500)
}
FileStoreHandler.getFileStream(projectId, fileId, queryString, function(
err,
stream
) {
if (err) {
logger.err(
{ err, projectId, fileId, queryString },
'error getting file stream for downloading file'
)
return res.sendStatus(500)
FileStoreHandler.getFileStream(
projectId,
fileId,
queryString,
function (err, stream) {
if (err) {
logger.err(
{ err, projectId, fileId, queryString },
'error getting file stream for downloading file'
)
return res.sendStatus(500)
}
// mobile safari will try to render html files, prevent this
if (isMobileSafari(userAgent) && isHtml(file)) {
res.setHeader('Content-Type', 'text/plain')
}
res.setContentDisposition('attachment', { filename: file.name })
stream.pipe(res)
}
// mobile safari will try to render html files, prevent this
if (isMobileSafari(userAgent) && isHtml(file)) {
res.setHeader('Content-Type', 'text/plain')
}
res.setContentDisposition('attachment', { filename: file.name })
stream.pipe(res)
})
)
}
)
},

View File

@@ -17,7 +17,7 @@ const FileStoreHandler = {
RETRY_ATTEMPTS: 3,
uploadFileFromDisk(projectId, fileArgs, fsPath, callback) {
fs.lstat(fsPath, function(err, stat) {
fs.lstat(fsPath, function (err, stat) {
if (err) {
logger.warn({ err, projectId, fileArgs, fsPath }, 'error stating file')
callback(err)
@@ -45,7 +45,7 @@ const FileStoreHandler = {
fsPath,
cb
),
function(err, result) {
function (err, result) {
if (err) {
OError.tag(err, 'Error uploading file, retries failed', {
projectId,
@@ -62,21 +62,21 @@ const FileStoreHandler = {
_doUploadFileFromDisk(projectId, fileArgs, fsPath, callback) {
const callbackOnce = _.once(callback)
FileHashManager.computeHash(fsPath, function(err, hashValue) {
FileHashManager.computeHash(fsPath, function (err, hashValue) {
if (err) {
return callbackOnce(err)
}
const fileRef = new File(Object.assign({}, fileArgs, { hash: hashValue }))
const fileId = fileRef._id
const readStream = fs.createReadStream(fsPath)
readStream.on('error', function(err) {
readStream.on('error', function (err) {
logger.warn(
{ err, projectId, fileId, fsPath },
'something went wrong on the read stream of uploadFileFromDisk'
)
callbackOnce(err)
})
readStream.on('open', function() {
readStream.on('open', function () {
const url = FileStoreHandler._buildUrl(projectId, fileId)
const opts = {
method: 'post',
@@ -87,14 +87,14 @@ const FileStoreHandler = {
} // send the hash to the filestore as a custom header so it can be checked
}
const writeStream = request(opts)
writeStream.on('error', function(err) {
writeStream.on('error', function (err) {
logger.warn(
{ err, projectId, fileId, fsPath },
'something went wrong on the write stream of uploadFileFromDisk'
)
callbackOnce(err)
})
writeStream.on('response', function(response) {
writeStream.on('response', function (response) {
if (![200, 201].includes(response.statusCode)) {
err = new OError(
`non-ok response from filestore for upload: ${response.statusCode}`,
@@ -168,7 +168,7 @@ const FileStoreHandler = {
uri: this._buildUrl(projectId, fileId),
timeout: FIVE_MINS_IN_MS
}
return request(opts, function(err, response) {
return request(opts, function (err, response) {
if (err) {
logger.warn(
{ err, projectId, fileId },
@@ -217,7 +217,7 @@ const FileStoreHandler = {
uri: this._buildUrl(newProjectId, newFileId),
timeout: FIVE_MINS_IN_MS
}
return request(opts, function(err, response) {
return request(opts, function (err, response) {
if (err) {
OError.tag(
err,

View File

@@ -61,7 +61,7 @@ module.exports = {
},
checkRedis(req, res, next) {
return rclient.healthCheck(function(error) {
return rclient.healthCheck(function (error) {
if (error != null) {
logger.err({ err: error }, 'failed redis health check')
return res.sendStatus(500)
@@ -72,23 +72,23 @@ module.exports = {
},
checkMongo(req, res, next) {
return UserGetter.getUserEmail(settings.smokeTest.userId, function(
err,
email
) {
if (err != null) {
logger.err({ err }, 'mongo health check failed, error present')
return res.sendStatus(500)
} else if (email == null) {
logger.err(
{ err },
'mongo health check failed, no emai present in find result'
)
return res.sendStatus(500)
} else {
return res.sendStatus(200)
return UserGetter.getUserEmail(
settings.smokeTest.userId,
function (err, email) {
if (err != null) {
logger.err({ err }, 'mongo health check failed, error present')
return res.sendStatus(500)
} else if (email == null) {
logger.err(
{ err },
'mongo health check failed, no emai present in find result'
)
return res.sendStatus(500)
} else {
return res.sendStatus(200)
}
}
})
)
}
}

View File

@@ -17,7 +17,7 @@ module.exports = HistoryController = {
selectHistoryApi(req, res, next) {
const { Project_id: projectId } = req.params
// find out which type of history service this project uses
ProjectDetailsHandler.getDetails(projectId, function(err, project) {
ProjectDetailsHandler.getDetails(projectId, function (err, project) {
if (err) {
return next(err)
}
@@ -52,7 +52,7 @@ module.exports = HistoryController = {
}
})
getReq.pipe(res)
getReq.on('error', function(err) {
getReq.on('error', function (err) {
logger.warn({ url, err }, 'history API error')
next(err)
})
@@ -71,11 +71,11 @@ module.exports = HistoryController = {
'X-User-Id': userId
}
},
function(err, body) {
function (err, body) {
if (err) {
return next(err)
}
HistoryManager.injectUserDetails(body, function(err, data) {
HistoryManager.injectUserDetails(body, function (err, data) {
if (err) {
return next(err)
}
@@ -97,7 +97,7 @@ module.exports = HistoryController = {
resyncProjectHistory(req, res, next) {
const projectId = req.params.Project_id
ProjectEntityUpdateHandler.resyncProjectHistory(projectId, function(err) {
ProjectEntityUpdateHandler.resyncProjectHistory(projectId, function (err) {
if (err instanceof Errors.ProjectHistoryDisabledError) {
return res.sendStatus(404)
}
@@ -117,7 +117,7 @@ module.exports = HistoryController = {
projectId,
version,
pathname,
function(err, entity) {
function (err, entity) {
if (err) {
return next(err)
}
@@ -158,7 +158,7 @@ module.exports = HistoryController = {
url: `${settings.apis.project_history.url}/project/${projectId}/labels`,
json: true
},
function(err, labels) {
function (err, labels) {
if (err) {
return next(err)
}
@@ -182,7 +182,7 @@ module.exports = HistoryController = {
url: `${settings.apis.project_history.url}/project/${projectId}/user/${userId}/labels`,
json: { comment, version }
},
function(err, label) {
function (err, label) {
if (err) {
return next(err)
}
@@ -230,7 +230,7 @@ module.exports = HistoryController = {
UserGetter.getUsers(
Array.from(uniqueUsers),
{ first_name: 1, last_name: 1, email: 1 },
function(err, rawUsers) {
function (err, rawUsers) {
if (err) {
return callback(err)
}
@@ -274,7 +274,7 @@ module.exports = HistoryController = {
method: 'DELETE',
url: `${settings.apis.project_history.url}/project/${projectId}/user/${userId}/labels/${labelId}`
},
function(err) {
function (err) {
if (err) {
return next(err)
}
@@ -284,7 +284,7 @@ module.exports = HistoryController = {
},
_makeRequest(options, callback) {
return request(options, function(err, response, body) {
return request(options, function (err, response, body) {
if (err) {
return callback(err)
}
@@ -301,7 +301,7 @@ module.exports = HistoryController = {
downloadZipOfVersion(req, res, next) {
const { project_id: projectId, version } = req.params
ProjectDetailsHandler.getDetails(projectId, function(err, project) {
ProjectDetailsHandler.getDetails(projectId, function (err, project) {
if (err) {
return next(err)
}
@@ -344,7 +344,7 @@ module.exports = HistoryController = {
method: 'post',
url
}
request(options, function(err, response, body) {
request(options, function (err, response, body) {
if (err) {
OError.tag(err, 'history API error', {
v1ProjectId,
@@ -362,7 +362,7 @@ module.exports = HistoryController = {
async.retry(
40,
callback =>
setTimeout(function() {
setTimeout(function () {
if (req.aborted) {
// client has disconnected -- skip s3 download
return callback() // stop async.retry loop
@@ -384,7 +384,7 @@ module.exports = HistoryController = {
req.off('aborted', abortS3Request)
res.off('timeout', abortS3Request)
}
getReq.on('response', function(response) {
getReq.on('response', function (response) {
if (response.statusCode !== 200) {
cleanupAbortTrigger()
return callback(new Error('invalid response'))
@@ -407,7 +407,7 @@ module.exports = HistoryController = {
})
callback()
})
getReq.on('error', function(err) {
getReq.on('error', function (err) {
logger.warn(
{ err, v1ProjectId, version, retryAttempt },
'history s3 download error'
@@ -416,7 +416,7 @@ module.exports = HistoryController = {
callback(err)
})
}, retryDelay),
function(err) {
function (err) {
if (err) {
OError.tag(err, 'history s3 download failed', {
v1ProjectId,

View File

@@ -28,13 +28,13 @@ module.exports = RestoreManager = {
// It looks up the deleted doc's contents, and then creates a new doc with the same content.
// We don't actually remove the deleted doc entry, just create a new one from its lines.
if (callback == null) {
callback = function(error, doc, folder_id) {}
callback = function (error, doc, folder_id) {}
}
return ProjectEntityHandler.getDoc(
project_id,
doc_id,
{ include_deleted: true },
function(error, lines) {
function (error, lines) {
if (error != null) {
return callback(error)
}
@@ -59,13 +59,13 @@ module.exports = RestoreManager = {
restoreFileFromV2(user_id, project_id, version, pathname, callback) {
if (callback == null) {
callback = function(error, entity) {}
callback = function (error, entity) {}
}
return RestoreManager._writeFileVersionToDisk(
project_id,
version,
pathname,
function(error, fsPath) {
function (error, fsPath) {
if (error != null) {
return callback(error)
}
@@ -75,54 +75,55 @@ module.exports = RestoreManager = {
// no directory
dirname = ''
}
return RestoreManager._findOrCreateFolder(project_id, dirname, function(
error,
parent_folder_id
) {
if (error != null) {
return callback(error)
}
const addEntityWithName = (name, callback) =>
FileSystemImportManager.addEntity(
user_id,
project_id,
parent_folder_id,
name,
fsPath,
false,
return RestoreManager._findOrCreateFolder(
project_id,
dirname,
function (error, parent_folder_id) {
if (error != null) {
return callback(error)
}
const addEntityWithName = (name, callback) =>
FileSystemImportManager.addEntity(
user_id,
project_id,
parent_folder_id,
name,
fsPath,
false,
callback
)
return RestoreManager._addEntityWithUniqueName(
addEntityWithName,
basename,
callback
)
return RestoreManager._addEntityWithUniqueName(
addEntityWithName,
basename,
callback
)
})
}
)
}
)
},
_findOrCreateFolder(project_id, dirname, callback) {
if (callback == null) {
callback = function(error, folder_id) {}
callback = function (error, folder_id) {}
}
return EditorController.mkdirp(project_id, dirname, function(
error,
newFolders,
lastFolder
) {
if (error != null) {
return callback(error)
return EditorController.mkdirp(
project_id,
dirname,
function (error, newFolders, lastFolder) {
if (error != null) {
return callback(error)
}
return callback(null, lastFolder != null ? lastFolder._id : undefined)
}
return callback(null, lastFolder != null ? lastFolder._id : undefined)
})
)
},
_addEntityWithUniqueName(addEntityWithName, basename, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return addEntityWithName(basename, function(error, entity) {
return addEntityWithName(basename, function (error, entity) {
if (error != null) {
if (error instanceof Errors.InvalidNameError) {
// likely a duplicate name, so try with a prefix
@@ -146,7 +147,7 @@ module.exports = RestoreManager = {
_writeFileVersionToDisk(project_id, version, pathname, callback) {
if (callback == null) {
callback = function(error, fsPath) {}
callback = function (error, fsPath) {}
}
const url = `${
Settings.apis.project_history.url

View File

@@ -22,7 +22,7 @@ module.exports = {
return InactiveProjectManager.deactivateOldProjects(
numberOfProjectsToArchive,
ageOfProjects,
function(err, projectsDeactivated) {
function (err, projectsDeactivated) {
if (err != null) {
return res.sendStatus(500)
} else {
@@ -34,7 +34,7 @@ module.exports = {
deactivateProject(req, res) {
const { project_id } = req.params
return InactiveProjectManager.deactivateProject(project_id, function(err) {
return InactiveProjectManager.deactivateProject(project_id, function (err) {
if (err != null) {
return res.sendStatus(500)
} else {

View File

@@ -24,35 +24,36 @@ const { ObjectId } = require('mongodb')
const MILISECONDS_IN_DAY = 86400000
module.exports = InactiveProjectManager = {
reactivateProjectIfRequired(project_id, callback) {
return ProjectGetter.getProject(project_id, { active: true }, function(
err,
project
) {
if (err != null) {
OError.tag(err, 'error getting project', {
project_id
})
return callback(err)
}
logger.log(
{ project_id, active: project.active },
'seeing if need to reactivate project'
)
if (project.active) {
return callback()
}
return DocstoreManager.unarchiveProject(project_id, function(err) {
return ProjectGetter.getProject(
project_id,
{ active: true },
function (err, project) {
if (err != null) {
OError.tag(err, 'error reactivating project in docstore', {
OError.tag(err, 'error getting project', {
project_id
})
return callback(err)
}
return ProjectUpdateHandler.markAsActive(project_id, callback)
})
})
logger.log(
{ project_id, active: project.active },
'seeing if need to reactivate project'
)
if (project.active) {
return callback()
}
return DocstoreManager.unarchiveProject(project_id, function (err) {
if (err != null) {
OError.tag(err, 'error reactivating project in docstore', {
project_id
})
return callback(err)
}
return ProjectUpdateHandler.markAsActive(project_id, callback)
})
}
)
},
deactivateOldProjects(limit, daysOld, callback) {
@@ -73,12 +74,12 @@ module.exports = InactiveProjectManager = {
.sort({ _id: 1 })
.limit(limit)
.read('secondary')
.exec(function(err, projects) {
.exec(function (err, projects) {
if (err != null) {
logger.err({ err }, 'could not get projects for deactivating')
}
const jobs = _.map(projects, project => cb =>
InactiveProjectManager.deactivateProject(project._id, function(err) {
InactiveProjectManager.deactivateProject(project._id, function (err) {
if (err) {
logger.err(
{ project_id: project._id, err: err },
@@ -92,7 +93,7 @@ module.exports = InactiveProjectManager = {
{ numberOfProjects: projects && projects.length },
'deactivating projects'
)
async.series(jobs, function(err) {
async.series(jobs, function (err) {
if (err != null) {
logger.warn({ err }, 'error deactivating projects')
}
@@ -107,7 +108,7 @@ module.exports = InactiveProjectManager = {
cb => DocstoreManager.archiveProject(project_id, cb),
cb => ProjectUpdateHandler.markAsInactive(project_id, cb)
]
return async.series(jobs, function(err) {
return async.series(jobs, function (err) {
if (err != null) {
logger.warn({ err, project_id }, 'error deactivating project')
}

View File

@@ -99,7 +99,7 @@ const InstitutionsAPI = {
},
defaultErrorMessage: "Couldn't create affiliation"
},
function(error, body) {
function (error, body) {
if (error) {
if (error.info && error.info.statusCode === 422) {
return callback(
@@ -115,7 +115,7 @@ const InstitutionsAPI = {
// have notifications delete any ip matcher notifications for this university
NotificationsBuilder.ipMatcherAffiliation(userId).read(
university.id,
function(err) {
function (err) {
if (err) {
// log and ignore error
logger.err(
@@ -191,7 +191,7 @@ const InstitutionsAPI = {
}
}
var makeAffiliationRequest = function(requestOptions, callback) {
var makeAffiliationRequest = function (requestOptions, callback) {
if (!settings.apis.v1.url) {
return callback(null)
} // service is not configured
@@ -207,7 +207,7 @@ var makeAffiliationRequest = function(requestOptions, callback) {
json: true,
timeout: 20 * 1000
},
function(error, response, body) {
function (error, response, body) {
if (error) {
return callback(
new V1ConnectionError('error getting affiliations from v1').withCause(

View File

@@ -8,7 +8,7 @@ const ASYNC_AFFILIATIONS_LIMIT = 10
module.exports = {
confirmDomain(req, res, next) {
const { hostname } = req.body
affiliateUsers(hostname, function(error) {
affiliateUsers(hostname, function (error) {
if (error) {
return next(error)
}
@@ -17,13 +17,9 @@ module.exports = {
}
}
var affiliateUsers = function(hostname, callback) {
const reversedHostname = hostname
.trim()
.split('')
.reverse()
.join('')
UserGetter.getUsersByHostname(hostname, { _id: 1 }, function(error, users) {
var affiliateUsers = function (hostname, callback) {
const reversedHostname = hostname.trim().split('').reverse().join('')
UserGetter.getUsersByHostname(hostname, { _id: 1 }, function (error, users) {
if (error) {
OError.tag(error, 'problem fetching users by hostname')
return callback(error)
@@ -44,7 +40,7 @@ var affiliateUsers = function(hostname, callback) {
})
}
var affiliateUserByReversedHostname = function(
var affiliateUserByReversedHostname = function (
user,
reversedHostname,
callback

View File

@@ -5,18 +5,21 @@ const Settings = require('settings-sharelatex')
module.exports = InstitutionsFeatures = {
getInstitutionsFeatures(userId, callback) {
InstitutionsFeatures.getInstitutionsPlan(userId, function(error, planCode) {
if (error) {
return callback(error)
InstitutionsFeatures.getInstitutionsPlan(
userId,
function (error, planCode) {
if (error) {
return callback(error)
}
const plan = planCode && PlansLocator.findLocalPlanInSettings(planCode)
const features = plan && plan.features
callback(null, features || {})
}
const plan = planCode && PlansLocator.findLocalPlanInSettings(planCode)
const features = plan && plan.features
callback(null, features || {})
})
)
},
getInstitutionsPlan(userId, callback) {
InstitutionsFeatures.hasLicence(userId, function(error, hasLicence) {
InstitutionsFeatures.hasLicence(userId, function (error, hasLicence) {
if (error) {
return callback(error)
}
@@ -28,7 +31,7 @@ module.exports = InstitutionsFeatures = {
},
hasLicence(userId, callback) {
UserGetter.getUserFullEmails(userId, function(error, emailsData) {
UserGetter.getUserFullEmails(userId, function (error, emailsData) {
if (error) {
return callback(error)
}

View File

@@ -5,7 +5,7 @@ const UserMembershipEntityConfigs = require('../UserMembership/UserMembershipEnt
module.exports = InstitutionsGetter = {
getConfirmedAffiliations(userId, callback) {
UserGetter.getUserFullEmails(userId, function(error, emailsData) {
UserGetter.getUserFullEmails(userId, function (error, emailsData) {
if (error) {
return callback(error)
}

View File

@@ -18,8 +18,8 @@ module.exports = {
async.waterfall(
[
cb => fetchInstitutionAndAffiliations(institutionId, cb),
function(institution, affiliations, cb) {
affiliations = _.map(affiliations, function(affiliation) {
function (institution, affiliations, cb) {
affiliations = _.map(affiliations, function (affiliation) {
affiliation.institutionName = institution.name
affiliation.institutionId = institutionId
return affiliation
@@ -50,7 +50,7 @@ module.exports = {
},
getInstitutionUsersSubscriptions(institutionId, callback) {
getInstitutionAffiliations(institutionId, function(error, affiliations) {
getInstitutionAffiliations(institutionId, function (error, affiliations) {
if (error) {
return callback(error)
}
@@ -84,12 +84,12 @@ var fetchInstitutionAndAffiliations = (institutionId, callback) =>
callback
)
var refreshFeatures = function(affiliation, callback) {
var refreshFeatures = function (affiliation, callback) {
const userId = ObjectId(affiliation.user_id)
FeaturesUpdater.refreshFeatures(userId, callback)
}
var refreshFeaturesAndNotify = function(affiliation, callback) {
var refreshFeaturesAndNotify = function (affiliation, callback) {
const userId = ObjectId(affiliation.user_id)
async.waterfall(
[
@@ -124,7 +124,7 @@ var getUserInfo = (userId, callback) =>
var notifyUser = (user, affiliation, subscription, featuresChanged, callback) =>
async.parallel(
[
function(cb) {
function (cb) {
if (featuresChanged) {
NotificationsBuilder.featuresUpgradedByAffiliation(
affiliation,
@@ -134,7 +134,7 @@ var notifyUser = (user, affiliation, subscription, featuresChanged, callback) =>
cb()
}
},
function(cb) {
function (cb) {
if (
subscription &&
!subscription.planCode.match(/(free|trial)/) &&
@@ -152,7 +152,7 @@ var notifyUser = (user, affiliation, subscription, featuresChanged, callback) =>
callback
)
var checkFeatures = function(institutionId, users) {
var checkFeatures = function (institutionId, users) {
const usersSummary = {
confirmedEmailUsers: {
total: users.length, // all users are confirmed email users
@@ -167,7 +167,7 @@ var checkFeatures = function(institutionId, users) {
nonProUsers: []
}
}
users.forEach(function(user) {
users.forEach(function (user) {
let isSSOEntitled = SAMLIdentityManager.userHasEntitlement(
user,
institutionId

View File

@@ -75,7 +75,7 @@ module.exports = LinkedFilesController = {
name,
parent_folder_id,
user_id,
function(err, newFileId) {
function (err, newFileId) {
if (err != null) {
return LinkedFilesController.handleError(err, req, res, next)
}
@@ -88,47 +88,46 @@ module.exports = LinkedFilesController = {
const { project_id, file_id } = req.params
const user_id = AuthenticationController.getLoggedInUserId(req)
return LinkedFilesHandler.getFileById(project_id, file_id, function(
err,
file,
path,
parentFolder
) {
if (err != null) {
return next(err)
}
if (file == null) {
return res.sendStatus(404)
}
const { name } = file
const { linkedFileData } = file
if (
linkedFileData == null ||
(linkedFileData != null ? linkedFileData.provider : undefined) == null
) {
return res.sendStatus(409)
}
const { provider } = linkedFileData
const parent_folder_id = parentFolder._id
const Agent = LinkedFilesController._getAgent(provider)
if (Agent == null) {
return res.sendStatus(400)
}
return Agent.refreshLinkedFile(
project_id,
linkedFileData,
name,
parent_folder_id,
user_id,
function(err, newFileId) {
if (err != null) {
return LinkedFilesController.handleError(err, req, res, next)
}
return res.json({ new_file_id: newFileId })
return LinkedFilesHandler.getFileById(
project_id,
file_id,
function (err, file, path, parentFolder) {
if (err != null) {
return next(err)
}
)
})
if (file == null) {
return res.sendStatus(404)
}
const { name } = file
const { linkedFileData } = file
if (
linkedFileData == null ||
(linkedFileData != null ? linkedFileData.provider : undefined) == null
) {
return res.sendStatus(409)
}
const { provider } = linkedFileData
const parent_folder_id = parentFolder._id
const Agent = LinkedFilesController._getAgent(provider)
if (Agent == null) {
return res.sendStatus(400)
}
return Agent.refreshLinkedFile(
project_id,
linkedFileData,
name,
parent_folder_id,
user_id,
function (err, newFileId) {
if (err != null) {
return LinkedFilesController.handleError(err, req, res, next)
}
return res.json({ new_file_id: newFileId })
}
)
}
)
},
handleError(error, req, res, next) {

View File

@@ -28,7 +28,7 @@ const {
module.exports = LinkedFilesHandler = {
getFileById(project_id, file_id, callback) {
if (callback == null) {
callback = function(err, file) {}
callback = function (err, file) {}
}
return ProjectLocator.findElement(
{
@@ -36,7 +36,7 @@ module.exports = LinkedFilesHandler = {
element_id: file_id,
type: 'file'
},
function(err, file, path, parentFolder) {
function (err, file, path, parentFolder) {
if (err != null) {
return callback(err)
}
@@ -47,14 +47,14 @@ module.exports = LinkedFilesHandler = {
getSourceProject(data, callback) {
if (callback == null) {
callback = function(err, project) {}
callback = function (err, project) {}
}
const projection = { _id: 1, name: 1 }
if (data.v1_source_doc_id != null) {
return Project.findOne(
{ 'overleaf.id': data.v1_source_doc_id },
projection,
function(err, project) {
function (err, project) {
if (err != null) {
return callback(err)
}
@@ -68,7 +68,7 @@ module.exports = LinkedFilesHandler = {
return ProjectGetter.getProject(
data.source_project_id,
projection,
function(err, project) {
function (err, project) {
if (err != null) {
return callback(err)
}
@@ -93,32 +93,33 @@ module.exports = LinkedFilesHandler = {
callback
) {
if (callback == null) {
callback = function(err, file) {}
callback = function (err, file) {}
}
callback = _.once(callback)
return FileWriter.writeStreamToDisk(project_id, readStream, function(
err,
fsPath
) {
if (err != null) {
return callback(err)
}
return EditorController.upsertFile(
project_id,
parent_folder_id,
name,
fsPath,
linkedFileData,
'upload',
user_id,
(err, file) => {
if (err != null) {
return callback(err)
}
return callback(null, file)
return FileWriter.writeStreamToDisk(
project_id,
readStream,
function (err, fsPath) {
if (err != null) {
return callback(err)
}
)
})
return EditorController.upsertFile(
project_id,
parent_folder_id,
name,
fsPath,
linkedFileData,
'upload',
user_id,
(err, file) => {
if (err != null) {
return callback(err)
}
return callback(null, file)
}
)
}
)
},
importContent(
@@ -131,31 +132,32 @@ module.exports = LinkedFilesHandler = {
callback
) {
if (callback == null) {
callback = function(err, file) {}
callback = function (err, file) {}
}
callback = _.once(callback)
return FileWriter.writeContentToDisk(project_id, content, function(
err,
fsPath
) {
if (err != null) {
return callback(err)
}
return EditorController.upsertFile(
project_id,
parent_folder_id,
name,
fsPath,
linkedFileData,
'upload',
user_id,
(err, file) => {
if (err != null) {
return callback(err)
}
return callback(null, file)
return FileWriter.writeContentToDisk(
project_id,
content,
function (err, fsPath) {
if (err != null) {
return callback(err)
}
)
})
return EditorController.upsertFile(
project_id,
parent_folder_id,
name,
fsPath,
linkedFileData,
'upload',
user_id,
(err, file) => {
if (err != null) {
return callback(err)
}
return callback(null, file)
}
)
}
)
}
}

View File

@@ -73,7 +73,7 @@ module.exports = ProjectFileAgent = {
_prepare(project_id, linkedFileData, user_id, callback) {
if (callback == null) {
callback = function(err, linkedFileData) {}
callback = function (err, linkedFileData) {}
}
return this._checkAuth(
project_id,
@@ -118,7 +118,7 @@ module.exports = ProjectFileAgent = {
return DocstoreManager.getDoc(
source_project._id,
entity._id,
function(err, lines) {
function (err, lines) {
if (err != null) {
return callback(err)
}
@@ -129,7 +129,7 @@ module.exports = ProjectFileAgent = {
name,
parent_folder_id,
user_id,
function(err, file) {
function (err, file) {
if (err != null) {
return callback(err)
}
@@ -143,7 +143,7 @@ module.exports = ProjectFileAgent = {
source_project._id,
entity._id,
null,
function(err, fileStream) {
function (err, fileStream) {
if (err != null) {
return callback(err)
}
@@ -154,7 +154,7 @@ module.exports = ProjectFileAgent = {
name,
parent_folder_id,
user_id,
function(err, file) {
function (err, file) {
if (err != null) {
return callback(err)
}
@@ -174,18 +174,18 @@ module.exports = ProjectFileAgent = {
_getEntity(linkedFileData, current_user_id, callback) {
if (callback == null) {
callback = function(err, entity, type) {}
callback = function (err, entity, type) {}
}
callback = _.once(callback)
const { source_entity_path } = linkedFileData
return this._getSourceProject(linkedFileData, function(err, project) {
return this._getSourceProject(linkedFileData, function (err, project) {
if (err != null) {
return callback(err)
}
const source_project_id = project._id
return DocumentUpdaterHandler.flushProjectToMongo(
source_project_id,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -195,7 +195,7 @@ module.exports = ProjectFileAgent = {
path: source_entity_path,
exactCaseMatch: true
},
function(err, entity, type) {
function (err, entity, type) {
if (err != null) {
if (/^not found.*/.test(err.toString())) {
err = new SourceFileNotFoundError()
@@ -236,13 +236,13 @@ module.exports = ProjectFileAgent = {
_checkAuth(project_id, data, current_user_id, callback) {
if (callback == null) {
callback = function(error, allowed) {}
callback = function (error, allowed) {}
}
callback = _.once(callback)
if (!ProjectFileAgent._validate(data)) {
return callback(new BadDataError())
}
return this._getSourceProject(data, function(err, project) {
return this._getSourceProject(data, function (err, project) {
if (err != null) {
return callback(err)
}
@@ -250,7 +250,7 @@ module.exports = ProjectFileAgent = {
current_user_id,
project._id,
null,
function(err, canRead) {
function (err, canRead) {
if (err != null) {
return callback(err)
}

View File

@@ -32,7 +32,7 @@ const logger = require('logger-sharelatex')
module.exports = ProjectOutputFileAgent = {
_prepare(project_id, linkedFileData, user_id, callback) {
if (callback == null) {
callback = function(err, linkedFileData) {}
callback = function (err, linkedFileData) {}
}
return this._checkAuth(
project_id,
@@ -91,7 +91,7 @@ module.exports = ProjectOutputFileAgent = {
name,
parent_folder_id,
user_id,
function(err, file) {
function (err, file) {
if (err != null) {
return callback(err)
}
@@ -147,7 +147,7 @@ module.exports = ProjectOutputFileAgent = {
name,
parent_folder_id,
user_id,
function(err, file) {
function (err, file) {
if (err != null) {
return callback(err)
}
@@ -197,13 +197,13 @@ module.exports = ProjectOutputFileAgent = {
_checkAuth(project_id, data, current_user_id, callback) {
if (callback == null) {
callback = function(err, allowed) {}
callback = function (err, allowed) {}
}
callback = _.once(callback)
if (!this._validate(data)) {
return callback(new BadDataError())
}
return this._getSourceProject(data, function(err, project) {
return this._getSourceProject(data, function (err, project) {
if (err != null) {
return callback(err)
}
@@ -211,7 +211,7 @@ module.exports = ProjectOutputFileAgent = {
current_user_id,
project._id,
null,
function(err, canRead) {
function (err, canRead) {
if (err != null) {
return callback(err)
}
@@ -223,11 +223,11 @@ module.exports = ProjectOutputFileAgent = {
_getFileStream(linkedFileData, user_id, callback) {
if (callback == null) {
callback = function(err, fileStream) {}
callback = function (err, fileStream) {}
}
callback = _.once(callback)
const { source_output_file_path, build_id } = linkedFileData
return this._getSourceProject(linkedFileData, function(err, project) {
return this._getSourceProject(linkedFileData, function (err, project) {
if (err != null) {
return callback(err)
}
@@ -237,7 +237,7 @@ module.exports = ProjectOutputFileAgent = {
user_id,
build_id,
source_output_file_path,
function(err, readStream) {
function (err, readStream) {
if (err != null) {
return callback(err)
}
@@ -250,48 +250,49 @@ module.exports = ProjectOutputFileAgent = {
_compileAndGetFileStream(linkedFileData, user_id, callback) {
if (callback == null) {
callback = function(err, stream, build_id) {}
callback = function (err, stream, build_id) {}
}
callback = _.once(callback)
const { source_output_file_path } = linkedFileData
return this._getSourceProject(linkedFileData, function(err, project) {
return this._getSourceProject(linkedFileData, function (err, project) {
if (err != null) {
return callback(err)
}
const source_project_id = project._id
return CompileManager.compile(source_project_id, user_id, {}, function(
err,
status,
outputFiles
) {
if (err != null) {
return callback(err)
}
if (status !== 'success') {
return callback(new OutputFileFetchFailedError())
}
const outputFile = _.find(
outputFiles,
o => o.path === source_output_file_path
)
if (outputFile == null) {
return callback(new OutputFileFetchFailedError())
}
const build_id = outputFile.build
return ClsiManager.getOutputFileStream(
source_project_id,
user_id,
build_id,
source_output_file_path,
function(err, readStream) {
if (err != null) {
return callback(err)
}
readStream.pause()
return callback(null, readStream, build_id)
return CompileManager.compile(
source_project_id,
user_id,
{},
function (err, status, outputFiles) {
if (err != null) {
return callback(err)
}
)
})
if (status !== 'success') {
return callback(new OutputFileFetchFailedError())
}
const outputFile = _.find(
outputFiles,
o => o.path === source_output_file_path
)
if (outputFile == null) {
return callback(new OutputFileFetchFailedError())
}
const build_id = outputFile.build
return ClsiManager.getOutputFileStream(
source_project_id,
user_id,
build_id,
source_output_file_path,
function (err, readStream) {
if (err != null) {
return callback(err)
}
readStream.pause()
return callback(null, readStream, build_id)
}
)
}
)
})
}
}

View File

@@ -30,40 +30,42 @@ module.exports = UrlAgent = {
callback
) {
linkedFileData = this._sanitizeData(linkedFileData)
return this._getUrlStream(project_id, linkedFileData, user_id, function(
err,
readStream
) {
if (err != null) {
return callback(err)
}
readStream.on('error', callback)
return readStream.on('response', function(response) {
if (response.statusCode >= 200 && response.statusCode < 300) {
readStream.resume()
return LinkedFilesHandler.importFromStream(
project_id,
readStream,
linkedFileData,
name,
parent_folder_id,
user_id,
function(err, file) {
if (err != null) {
return callback(err)
}
return callback(null, file._id)
}
) // Created
} else {
const error = new UrlFetchFailedError(
`url fetch failed: ${linkedFileData.url}`
)
error.statusCode = response.statusCode
return callback(error)
return this._getUrlStream(
project_id,
linkedFileData,
user_id,
function (err, readStream) {
if (err != null) {
return callback(err)
}
})
})
readStream.on('error', callback)
return readStream.on('response', function (response) {
if (response.statusCode >= 200 && response.statusCode < 300) {
readStream.resume()
return LinkedFilesHandler.importFromStream(
project_id,
readStream,
linkedFileData,
name,
parent_folder_id,
user_id,
function (err, file) {
if (err != null) {
return callback(err)
}
return callback(null, file._id)
}
) // Created
} else {
const error = new UrlFetchFailedError(
`url fetch failed: ${linkedFileData.url}`
)
error.statusCode = response.statusCode
return callback(error)
}
})
}
)
},
refreshLinkedFile(
@@ -93,7 +95,7 @@ module.exports = UrlAgent = {
_getUrlStream(project_id, data, current_user_id, callback) {
if (callback == null) {
callback = function(error, fsPath) {}
callback = function (error, fsPath) {}
}
callback = _.once(callback)
let { url } = data

View File

@@ -21,22 +21,22 @@ module.exports = MetaController = {
getMetadata(req, res, next) {
const { project_id } = req.params
logger.log({ project_id }, 'getting all labels for project')
return MetaHandler.getAllMetaForProject(project_id, function(
err,
projectMeta
) {
if (err != null) {
OError.tag(
err,
'[MetaController] error getting all labels from project',
{
project_id
}
)
return next(err)
return MetaHandler.getAllMetaForProject(
project_id,
function (err, projectMeta) {
if (err != null) {
OError.tag(
err,
'[MetaController] error getting all labels from project',
{
project_id
}
)
return next(err)
}
return res.json({ projectId: project_id, projectMeta })
}
return res.json({ projectId: project_id, projectMeta })
})
)
},
broadcastMetadataForDoc(req, res, next) {
@@ -44,27 +44,28 @@ module.exports = MetaController = {
const { doc_id } = req.params
const { broadcast } = req.body
logger.log({ project_id, doc_id, broadcast }, 'getting labels for doc')
return MetaHandler.getMetaForDoc(project_id, doc_id, function(
err,
docMeta
) {
if (err != null) {
OError.tag(err, '[MetaController] error getting labels from doc', {
project_id,
doc_id
})
return next(err)
return MetaHandler.getMetaForDoc(
project_id,
doc_id,
function (err, docMeta) {
if (err != null) {
OError.tag(err, '[MetaController] error getting labels from doc', {
project_id,
doc_id
})
return next(err)
}
// default to broadcasting, unless explicitly disabled (for backwards compatibility)
if (broadcast !== false) {
EditorRealTimeController.emitToRoom(project_id, 'broadcastDocMeta', {
docId: doc_id,
meta: docMeta
})
return res.sendStatus(200)
} else {
return res.json({ docId: doc_id, meta: docMeta })
}
}
// default to broadcasting, unless explicitly disabled (for backwards compatibility)
if (broadcast !== false) {
EditorRealTimeController.emitToRoom(project_id, 'broadcastDocMeta', {
docId: doc_id,
meta: docMeta
})
return res.sendStatus(200)
} else {
return res.json({ docId: doc_id, meta: docMeta })
}
})
)
}
}

View File

@@ -33,43 +33,49 @@ module.exports = MetaHandler = {
getAllMetaForProject(projectId, callback) {
if (callback == null) {
callback = function(err, projectMeta) {}
callback = function (err, projectMeta) {}
}
return DocumentUpdaterHandler.flushProjectToMongo(projectId, function(err) {
if (err != null) {
return callback(err)
}
return ProjectEntityHandler.getAllDocs(projectId, function(err, docs) {
return DocumentUpdaterHandler.flushProjectToMongo(
projectId,
function (err) {
if (err != null) {
return callback(err)
}
const projectMeta = MetaHandler.extractMetaFromProjectDocs(docs)
return callback(null, projectMeta)
})
})
return ProjectEntityHandler.getAllDocs(projectId, function (err, docs) {
if (err != null) {
return callback(err)
}
const projectMeta = MetaHandler.extractMetaFromProjectDocs(docs)
return callback(null, projectMeta)
})
}
)
},
getMetaForDoc(projectId, docId, callback) {
if (callback == null) {
callback = function(err, docMeta) {}
callback = function (err, docMeta) {}
}
return DocumentUpdaterHandler.flushDocToMongo(projectId, docId, function(
err
) {
if (err != null) {
return callback(err)
}
return ProjectEntityHandler.getDoc(projectId, docId, function(
err,
lines
) {
return DocumentUpdaterHandler.flushDocToMongo(
projectId,
docId,
function (err) {
if (err != null) {
return callback(err)
}
const docMeta = MetaHandler.extractMetaFromDoc(lines)
return callback(null, docMeta)
})
})
return ProjectEntityHandler.getDoc(
projectId,
docId,
function (err, lines) {
if (err != null) {
return callback(err)
}
const docMeta = MetaHandler.extractMetaFromDoc(lines)
return callback(null, docMeta)
}
)
}
)
},
extractMetaFromDoc(lines) {

View File

@@ -180,10 +180,7 @@ function makeMailchimpProvider() {
}
function hashEmail(email) {
return crypto
.createHash('md5')
.update(email.toLowerCase())
.digest('hex')
return crypto.createHash('md5').update(email.toLowerCase()).digest('hex')
}
function getMergeFields(user) {

View File

@@ -8,7 +8,7 @@ function dropboxDuplicateProjectNames(userId) {
key: `dropboxDuplicateProjectNames-${userId}`,
create(projectName, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
NotificationsHandler.createNotification(
userId,
@@ -22,7 +22,7 @@ function dropboxDuplicateProjectNames(userId) {
},
read(callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
NotificationsHandler.markAsReadWithKey(userId, this.key, callback)
}
@@ -34,7 +34,7 @@ function featuresUpgradedByAffiliation(affiliation, user) {
key: `features-updated-by=${affiliation.institutionId}`,
create(callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
const messageOpts = { institutionName: affiliation.institutionName }
NotificationsHandler.createNotification(
@@ -49,7 +49,7 @@ function featuresUpgradedByAffiliation(affiliation, user) {
},
read(callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
}
@@ -61,7 +61,7 @@ function redundantPersonalSubscription(affiliation, user) {
key: `redundant-personal-subscription-${affiliation.institutionId}`,
create(callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
const messageOpts = { institutionName: affiliation.institutionName }
NotificationsHandler.createNotification(
@@ -76,7 +76,7 @@ function redundantPersonalSubscription(affiliation, user) {
},
read(callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
}
@@ -88,7 +88,7 @@ function projectInvite(invite, project, sendingUser, user) {
key: `project-invite-${invite._id}`,
create(callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
const messageOpts = {
userName: sendingUser.first_name,
@@ -107,7 +107,7 @@ function projectInvite(invite, project, sendingUser, user) {
},
read(callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
}
@@ -118,7 +118,7 @@ function ipMatcherAffiliation(userId) {
return {
create(ip, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
if (!settings.apis.v1.url) {
// service is not configured
@@ -133,7 +133,7 @@ function ipMatcherAffiliation(userId) {
json: true,
timeout: 20 * 1000
},
function(error, response, body) {
function (error, response, body) {
if (error != null) {
return callback(error)
}
@@ -167,7 +167,7 @@ function ipMatcherAffiliation(userId) {
read(universityId, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
const key = `ip-matched-affiliation-${universityId}`
NotificationsHandler.markAsReadWithKey(userId, key, callback)
@@ -180,7 +180,7 @@ function tpdsFileLimit(userId) {
key: `tpdsFileLimit-${userId}`,
create(projectName, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
const messageOpts = {
projectName: projectName
@@ -197,7 +197,7 @@ function tpdsFileLimit(userId) {
},
read(callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
}
@@ -215,7 +215,7 @@ const NotificationsBuilder = {
}
NotificationsBuilder.promises = {
redundantPersonalSubscription: function(affiliation, user) {
redundantPersonalSubscription: function (affiliation, user) {
return promisifyAll(redundantPersonalSubscription(affiliation, user))
}
}

View File

@@ -17,19 +17,22 @@ const _ = require('underscore')
module.exports = {
getAllUnreadNotifications(req, res) {
const user_id = AuthenticationController.getLoggedInUserId(req)
return NotificationsHandler.getUserNotifications(user_id, function(
err,
unreadNotifications
) {
unreadNotifications = _.map(unreadNotifications, function(notification) {
notification.html = req.i18n.translate(
notification.templateKey,
notification.messageOpts
return NotificationsHandler.getUserNotifications(
user_id,
function (err, unreadNotifications) {
unreadNotifications = _.map(
unreadNotifications,
function (notification) {
notification.html = req.i18n.translate(
notification.templateKey,
notification.messageOpts
)
return notification
}
)
return notification
})
return res.send(unreadNotifications)
})
return res.send(unreadNotifications)
}
)
},
markNotificationAsRead(req, res) {

View File

@@ -17,7 +17,7 @@ const logger = require('logger-sharelatex')
const oneSecond = 1000
const makeRequest = function(opts, callback) {
const makeRequest = function (opts, callback) {
if (
(settings.apis.notifications != null
? settings.apis.notifications.url
@@ -41,7 +41,7 @@ module.exports = {
timeout: oneSecond,
method: 'GET'
}
return makeRequest(opts, function(err, res, unreadNotifications) {
return makeRequest(opts, function (err, res, unreadNotifications) {
const statusCode = res != null ? res.statusCode : 500
if (err != null || statusCode !== 200) {
const e = new Error(

View File

@@ -17,14 +17,14 @@ const logger = require('logger-sharelatex')
module.exports = {
getProjectDetails(req, res, next) {
const { project_id } = req.params
return ProjectDetailsHandler.getDetails(project_id, function(
err,
projDetails
) {
if (err != null) {
return next(err)
return ProjectDetailsHandler.getDetails(
project_id,
function (err, projDetails) {
if (err != null) {
return next(err)
}
return res.json(projDetails)
}
return res.json(projDetails)
})
)
}
}

View File

@@ -25,7 +25,7 @@ module.exports = ProjectCollabratecDetailsHandler = {
callback
) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectCollabratecDetailsHandler.setCollabratecUsers(
project_id,
@@ -36,7 +36,7 @@ module.exports = ProjectCollabratecDetailsHandler = {
isLinkedCollabratecUserProject(project_id, user_id, callback) {
if (callback == null) {
callback = function(err, isLinked) {}
callback = function (err, isLinked) {}
}
try {
project_id = ObjectId(project_id)
@@ -53,7 +53,7 @@ module.exports = ProjectCollabratecDetailsHandler = {
}
}
}
return Project.findOne(query, { _id: 1 }, function(err, project) {
return Project.findOne(query, { _id: 1 }, function (err, project) {
if (err != null) {
callback(err)
}
@@ -68,7 +68,7 @@ module.exports = ProjectCollabratecDetailsHandler = {
callback
) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
try {
project_id = ObjectId(project_id)
@@ -102,7 +102,7 @@ module.exports = ProjectCollabratecDetailsHandler = {
setCollabratecUsers(project_id, collabratec_users, callback) {
let err
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
try {
project_id = ObjectId(project_id)
@@ -127,7 +127,7 @@ module.exports = ProjectCollabratecDetailsHandler = {
unlinkCollabratecUserProject(project_id, user_id, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
try {
project_id = ObjectId(project_id)
@@ -149,7 +149,7 @@ module.exports = ProjectCollabratecDetailsHandler = {
updateCollabratecUserIds(old_user_id, new_user_id, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
try {
old_user_id = ObjectId(old_user_id)

View File

@@ -64,10 +64,7 @@ const ProjectController = {
return true
}
const data = `${rolloutName}:${objectId.toString()}`
const md5hash = crypto
.createHash('md5')
.update(data)
.digest('hex')
const md5hash = crypto.createHash('md5').update(data).digest('hex')
const counter = parseInt(md5hash.slice(26, 32), 16)
return counter % 100 < percentage
},
@@ -162,7 +159,7 @@ const ProjectController = {
const projectId = req.params.Project_id
const userId = AuthenticationController.getLoggedInUserId(req)
ProjectDeleter.archiveProject(projectId, userId, function(err) {
ProjectDeleter.archiveProject(projectId, userId, function (err) {
if (err != null) {
return next(err)
} else {
@@ -175,7 +172,7 @@ const ProjectController = {
const projectId = req.params.Project_id
const userId = AuthenticationController.getLoggedInUserId(req)
ProjectDeleter.unarchiveProject(projectId, userId, function(err) {
ProjectDeleter.unarchiveProject(projectId, userId, function (err) {
if (err != null) {
return next(err)
} else {
@@ -188,7 +185,7 @@ const ProjectController = {
const projectId = req.params.project_id
const userId = AuthenticationController.getLoggedInUserId(req)
ProjectDeleter.trashProject(projectId, userId, function(err) {
ProjectDeleter.trashProject(projectId, userId, function (err) {
if (err != null) {
return next(err)
} else {
@@ -201,7 +198,7 @@ const ProjectController = {
const projectId = req.params.project_id
const userId = AuthenticationController.getLoggedInUserId(req)
ProjectDeleter.untrashProject(projectId, userId, function(err) {
ProjectDeleter.untrashProject(projectId, userId, function (err) {
if (err != null) {
return next(err)
} else {

View File

@@ -33,7 +33,7 @@ const AnalyticsManager = require('../Analytics/AnalyticsManager')
const ProjectCreationHandler = {
createBlankProject(owner_id, projectName, attributes, callback) {
if (callback == null) {
callback = function(error, project) {}
callback = function (error, project) {}
}
metrics.inc('project-creation')
if (arguments.length === 3) {
@@ -41,59 +41,60 @@ const ProjectCreationHandler = {
attributes = {}
}
return ProjectDetailsHandler.validateProjectName(projectName, function(
error
) {
if (error != null) {
return callback(error)
}
if (attributes.overleaf !== undefined && attributes.overleaf != null) {
return ProjectCreationHandler._createBlankProject(
owner_id,
projectName,
attributes,
function(error, project) {
if (error != null) {
return callback(error)
}
AnalyticsManager.recordEvent(owner_id, 'project-imported', {
projectId: project._id,
attributes
})
return callback(error, project)
}
)
} else {
return HistoryManager.initializeProject(function(error, history) {
if (error != null) {
return callback(error)
}
attributes.overleaf = {
history: { id: history != null ? history.overleaf_id : undefined }
}
return ProjectDetailsHandler.validateProjectName(
projectName,
function (error) {
if (error != null) {
return callback(error)
}
if (attributes.overleaf !== undefined && attributes.overleaf != null) {
return ProjectCreationHandler._createBlankProject(
owner_id,
projectName,
attributes,
function(error, project) {
function (error, project) {
if (error != null) {
return callback(error)
}
AnalyticsManager.recordEvent(owner_id, 'project-created', {
AnalyticsManager.recordEvent(owner_id, 'project-imported', {
projectId: project._id,
attributes
})
return callback(error, project)
}
)
})
} else {
return HistoryManager.initializeProject(function (error, history) {
if (error != null) {
return callback(error)
}
attributes.overleaf = {
history: { id: history != null ? history.overleaf_id : undefined }
}
return ProjectCreationHandler._createBlankProject(
owner_id,
projectName,
attributes,
function (error, project) {
if (error != null) {
return callback(error)
}
AnalyticsManager.recordEvent(owner_id, 'project-created', {
projectId: project._id,
attributes
})
return callback(error, project)
}
)
})
}
}
})
)
},
_createBlankProject(owner_id, projectName, attributes, callback) {
if (callback == null) {
callback = function(error, project) {}
callback = function (error, project) {}
}
const rootFolder = new Folder({ name: 'rootFolder' })
@@ -113,28 +114,29 @@ const ProjectCreationHandler = {
}
}
project.rootFolder[0] = rootFolder
return User.findById(owner_id, 'ace.spellCheckLanguage', function(
err,
user
) {
project.spellCheckLanguage = user.ace.spellCheckLanguage
return project.save(function(err) {
if (err != null) {
return callback(err)
}
return callback(err, project)
})
})
return User.findById(
owner_id,
'ace.spellCheckLanguage',
function (err, user) {
project.spellCheckLanguage = user.ace.spellCheckLanguage
return project.save(function (err) {
if (err != null) {
return callback(err)
}
return callback(err, project)
})
}
)
},
createProjectFromSnippet(owner_id, projectName, docLines, callback) {
if (callback == null) {
callback = function(error, project) {}
callback = function (error, project) {}
}
return ProjectCreationHandler.createBlankProject(
owner_id,
projectName,
function(error, project) {
function (error, project) {
if (error != null) {
return callback(error)
}
@@ -150,12 +152,12 @@ const ProjectCreationHandler = {
createBasicProject(owner_id, projectName, callback) {
if (callback == null) {
callback = function(error, project) {}
callback = function (error, project) {}
}
return ProjectCreationHandler.createBlankProject(
owner_id,
projectName,
function(error, project) {
function (error, project) {
if (error != null) {
return callback(error)
}
@@ -163,7 +165,7 @@ const ProjectCreationHandler = {
'mainbasic.tex',
owner_id,
projectName,
function(error, docLines) {
function (error, docLines) {
if (error != null) {
return callback(error)
}
@@ -181,12 +183,12 @@ const ProjectCreationHandler = {
createExampleProject(owner_id, projectName, callback) {
if (callback == null) {
callback = function(error, project) {}
callback = function (error, project) {}
}
return ProjectCreationHandler.createBlankProject(
owner_id,
projectName,
function(error, project) {
function (error, project) {
if (error != null) {
return callback(error)
}
@@ -197,7 +199,7 @@ const ProjectCreationHandler = {
'main.tex',
owner_id,
projectName,
function(error, docLines) {
function (error, docLines) {
if (error != null) {
return callback(error)
}
@@ -214,7 +216,7 @@ const ProjectCreationHandler = {
'references.bib',
owner_id,
projectName,
function(error, docLines) {
function (error, docLines) {
if (error != null) {
return callback(error)
}
@@ -228,7 +230,7 @@ const ProjectCreationHandler = {
)
}
),
function(callback) {
function (callback) {
const universePath = Path.resolve(
__dirname + '/../../../templates/project_files/universe.jpg'
)
@@ -251,7 +253,7 @@ const ProjectCreationHandler = {
_createRootDoc(project, owner_id, docLines, callback) {
if (callback == null) {
callback = function(error, project) {}
callback = function (error, project) {}
}
return ProjectEntityUpdateHandler.addDoc(
project._id,
@@ -259,7 +261,7 @@ const ProjectCreationHandler = {
'main.tex',
docLines,
owner_id,
function(error, doc) {
function (error, doc) {
if (error != null) {
OError.tag(error, 'error adding root doc when creating project')
return callback(error)
@@ -275,47 +277,48 @@ const ProjectCreationHandler = {
_buildTemplate(template_name, user_id, project_name, callback) {
if (callback == null) {
callback = function(error, output) {}
callback = function (error, output) {}
}
return User.findById(user_id, 'first_name last_name', function(
error,
user
) {
if (error != null) {
return callback(error)
}
const monthNames = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
]
const templatePath = Path.resolve(
__dirname + `/../../../templates/project_files/${template_name}`
)
return fs.readFile(templatePath, function(error, template) {
return User.findById(
user_id,
'first_name last_name',
function (error, user) {
if (error != null) {
return callback(error)
}
const data = {
project_name,
user,
year: new Date().getUTCFullYear(),
month: monthNames[new Date().getUTCMonth()]
}
const output = _.template(template.toString(), data)
return callback(null, output.split('\n'))
})
})
const monthNames = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
]
const templatePath = Path.resolve(
__dirname + `/../../../templates/project_files/${template_name}`
)
return fs.readFile(templatePath, function (error, template) {
if (error != null) {
return callback(error)
}
const data = {
project_name,
user,
year: new Date().getUTCFullYear(),
month: monthNames[new Date().getUTCMonth()]
}
const output = _.template(template.toString(), data)
return callback(null, output.split('\n'))
})
}
)
}
}

View File

@@ -308,7 +308,7 @@ const ProjectEntityUpdateHandler = {
addDocWithRanges: wrapWithLock({
beforeLock(next) {
return function(
return function (
projectId,
folderId,
docName,
@@ -457,7 +457,7 @@ const ProjectEntityUpdateHandler = {
addFile: wrapWithLock({
beforeLock(next) {
return function(
return function (
projectId,
folderId,
fileName,
@@ -544,7 +544,7 @@ const ProjectEntityUpdateHandler = {
replaceFile: wrapWithLock({
beforeLock(next) {
return function(
return function (
projectId,
fileId,
fsPath,
@@ -648,7 +648,7 @@ const ProjectEntityUpdateHandler = {
}
}),
upsertDoc: wrapWithLock(function(
upsertDoc: wrapWithLock(function (
projectId,
folderId,
docName,
@@ -796,7 +796,7 @@ const ProjectEntityUpdateHandler = {
upsertFile: wrapWithLock({
beforeLock(next) {
return function(
return function (
projectId,
folderId,
fileName,
@@ -974,7 +974,7 @@ const ProjectEntityUpdateHandler = {
}
}),
upsertDocWithPath: wrapWithLock(function(
upsertDocWithPath: wrapWithLock(function (
projectId,
elementPath,
docLines,
@@ -1014,7 +1014,7 @@ const ProjectEntityUpdateHandler = {
upsertFileWithPath: wrapWithLock({
beforeLock(next) {
return function(
return function (
projectId,
elementPath,
fsPath,
@@ -1102,7 +1102,7 @@ const ProjectEntityUpdateHandler = {
}
}),
deleteEntity: wrapWithLock(function(
deleteEntity: wrapWithLock(function (
projectId,
entityId,
entityType,
@@ -1174,7 +1174,7 @@ const ProjectEntityUpdateHandler = {
)
),
mkdirp: wrapWithLock(function(projectId, path, callback) {
mkdirp: wrapWithLock(function (projectId, path, callback) {
for (let folder of path.split('/')) {
if (folder.length > 0 && !SafePath.isCleanFilename(folder)) {
return callback(new Errors.InvalidNameError('invalid element name'))
@@ -1188,7 +1188,7 @@ const ProjectEntityUpdateHandler = {
)
}),
mkdirpWithExactCase: wrapWithLock(function(projectId, path, callback) {
mkdirpWithExactCase: wrapWithLock(function (projectId, path, callback) {
for (let folder of path.split('/')) {
if (folder.length > 0 && !SafePath.isCleanFilename(folder)) {
return callback(new Errors.InvalidNameError('invalid element name'))
@@ -1202,7 +1202,7 @@ const ProjectEntityUpdateHandler = {
)
}),
addFolder: wrapWithLock(function(
addFolder: wrapWithLock(function (
projectId,
parentFolderId,
folderName,
@@ -1219,7 +1219,7 @@ const ProjectEntityUpdateHandler = {
)
}),
moveEntity: wrapWithLock(function(
moveEntity: wrapWithLock(function (
projectId,
entityId,
destFolderId,
@@ -1272,7 +1272,7 @@ const ProjectEntityUpdateHandler = {
)
}),
renameEntity: wrapWithLock(function(
renameEntity: wrapWithLock(function (
projectId,
entityId,
entityType,
@@ -1572,7 +1572,7 @@ const ProjectEntityUpdateHandler = {
convertDocToFile: wrapWithLock({
beforeLock(next) {
return function(projectId, docId, userId, callback) {
return function (projectId, docId, userId, callback) {
DocumentUpdaterHandler.flushDocToMongo(projectId, docId, err => {
if (err) {
return callback(err)

View File

@@ -72,7 +72,7 @@ const ProjectGetter = {
return callback(err)
}
db.projects.findOne(query, { projection }, function(err, project) {
db.projects.findOne(query, { projection }, function (err, project) {
if (err) {
OError.tag(err, 'error getting project', {
query,
@@ -85,43 +85,49 @@ const ProjectGetter = {
},
getProjectIdByReadAndWriteToken(token, callback) {
Project.findOne({ 'tokens.readAndWrite': token }, { _id: 1 }, function(
err,
project
) {
if (err) {
return callback(err)
Project.findOne(
{ 'tokens.readAndWrite': token },
{ _id: 1 },
function (err, project) {
if (err) {
return callback(err)
}
if (project == null) {
return callback()
}
callback(null, project._id)
}
if (project == null) {
return callback()
}
callback(null, project._id)
})
)
},
findAllUsersProjects(userId, fields, callback) {
const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
Project.find({ owner_ref: userId }, fields, function(error, ownedProjects) {
if (error) {
return callback(error)
}
CollaboratorsGetter.getProjectsUserIsMemberOf(userId, fields, function(
error,
projects
) {
Project.find(
{ owner_ref: userId },
fields,
function (error, ownedProjects) {
if (error) {
return callback(error)
}
const result = {
owned: ownedProjects || [],
readAndWrite: projects.readAndWrite || [],
readOnly: projects.readOnly || [],
tokenReadAndWrite: projects.tokenReadAndWrite || [],
tokenReadOnly: projects.tokenReadOnly || []
}
callback(null, result)
})
})
CollaboratorsGetter.getProjectsUserIsMemberOf(
userId,
fields,
function (error, projects) {
if (error) {
return callback(error)
}
const result = {
owned: ownedProjects || [],
readAndWrite: projects.readAndWrite || [],
readOnly: projects.readOnly || [],
tokenReadAndWrite: projects.tokenReadAndWrite || [],
tokenReadOnly: projects.tokenReadOnly || []
}
callback(null, result)
}
)
}
)
},
/**

View File

@@ -126,7 +126,7 @@ function _addSuffixToProjectName(name, suffix, maxLength) {
function _addNumericSuffixToProjectName(name, allProjectNames, maxLength) {
const NUMERIC_SUFFIX_MATCH = / \((\d+)\)$/
const suffixedName = function(basename, number) {
const suffixedName = function (basename, number) {
const suffix = ` (${number})`
return basename.substr(0, maxLength - suffix.length) + suffix
}

View File

@@ -25,7 +25,7 @@ const ProjectHistoryHandler = {
setHistoryId(project_id, history_id, callback) {
// reject invalid history ids
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
if (!history_id || typeof history_id !== 'number') {
return callback(new Error('invalid history id'))
@@ -34,7 +34,7 @@ const ProjectHistoryHandler = {
return Project.updateOne(
{ _id: project_id, 'overleaf.history.id': { $exists: false } },
{ 'overleaf.history.id': history_id },
function(err, result) {
function (err, result) {
if (err != null) {
return callback(err)
}
@@ -48,29 +48,32 @@ const ProjectHistoryHandler = {
getHistoryId(project_id, callback) {
if (callback == null) {
callback = function(err, result) {}
callback = function (err, result) {}
}
return ProjectDetailsHandler.getDetails(project_id, function(err, project) {
if (err != null) {
return callback(err)
} // n.b. getDetails returns an error if the project doesn't exist
return callback(
null,
__guard__(
return ProjectDetailsHandler.getDetails(
project_id,
function (err, project) {
if (err != null) {
return callback(err)
} // n.b. getDetails returns an error if the project doesn't exist
return callback(
null,
__guard__(
project != null ? project.overleaf : undefined,
x1 => x1.history
),
x => x.id
__guard__(
project != null ? project.overleaf : undefined,
x1 => x1.history
),
x => x.id
)
)
)
})
}
)
},
upgradeHistory(project_id, callback) {
// project must have an overleaf.history.id before allowing display of new history
if (callback == null) {
callback = function(err, result) {}
callback = function (err, result) {}
}
return Project.updateOne(
{ _id: project_id, 'overleaf.history.id': { $exists: true } },
@@ -78,7 +81,7 @@ const ProjectHistoryHandler = {
'overleaf.history.display': true,
'overleaf.history.upgradedAt': new Date()
},
function(err, result) {
function (err, result) {
if (err != null) {
return callback(err)
}
@@ -93,7 +96,7 @@ const ProjectHistoryHandler = {
downgradeHistory(project_id, callback) {
if (callback == null) {
callback = function(err, result) {}
callback = function (err, result) {}
}
return Project.updateOne(
{ _id: project_id, 'overleaf.history.upgradedAt': { $exists: true } },
@@ -101,7 +104,7 @@ const ProjectHistoryHandler = {
'overleaf.history.display': false,
$unset: { 'overleaf.history.upgradedAt': 1 }
},
function(err, result) {
function (err, result) {
if (err != null) {
return callback(err)
}
@@ -120,45 +123,45 @@ const ProjectHistoryHandler = {
// state. Setting a history id when one wasn't present before is ok,
// because undefined history ids aren't cached.
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return ProjectHistoryHandler.getHistoryId(project_id, function(
err,
history_id
) {
if (err != null) {
return callback(err)
}
if (history_id != null) {
return callback()
} // history already exists, success
return HistoryManager.initializeProject(function(err, history) {
return ProjectHistoryHandler.getHistoryId(
project_id,
function (err, history_id) {
if (err != null) {
return callback(err)
}
if (!(history != null ? history.overleaf_id : undefined)) {
return callback(new Error('failed to initialize history id'))
}
return ProjectHistoryHandler.setHistoryId(
project_id,
history.overleaf_id,
function(err) {
if (err != null) {
return callback(err)
}
return ProjectEntityUpdateHandler.resyncProjectHistory(
project_id,
function(err) {
if (err != null) {
return callback(err)
}
return HistoryManager.flushProject(project_id, callback)
}
)
if (history_id != null) {
return callback()
} // history already exists, success
return HistoryManager.initializeProject(function (err, history) {
if (err != null) {
return callback(err)
}
)
})
})
if (!(history != null ? history.overleaf_id : undefined)) {
return callback(new Error('failed to initialize history id'))
}
return ProjectHistoryHandler.setHistoryId(
project_id,
history.overleaf_id,
function (err) {
if (err != null) {
return callback(err)
}
return ProjectEntityUpdateHandler.resyncProjectHistory(
project_id,
function (err) {
if (err != null) {
return callback(err)
}
return HistoryManager.flushProject(project_id, callback)
}
)
}
)
})
}
)
}
}

View File

@@ -19,11 +19,12 @@ function findElement(options, _callback) {
const elementType = sanitizeTypeOfElement(type)
let count = 0
const endOfBranch = function() {
const endOfBranch = function () {
if (--count === 0) {
logger.warn(
`element ${elementId} could not be found for project ${projectId ||
project._id}`
`element ${elementId} could not be found for project ${
projectId || project._id
}`
)
callback(new Errors.NotFoundError('entity not found'))
}

View File

@@ -28,9 +28,9 @@ const _ = require('underscore')
module.exports = ProjectRootDocManager = {
setRootDocAutomatically(project_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ProjectEntityHandler.getAllDocs(project_id, function(error, docs) {
return ProjectEntityHandler.getAllDocs(project_id, function (error, docs) {
if (error != null) {
return callback(error)
}
@@ -38,23 +38,23 @@ module.exports = ProjectRootDocManager = {
const jobs = _.map(
docs,
(doc, path) =>
function(cb) {
function (cb) {
if (
ProjectEntityUpdateHandler.isPathValidForRootDoc(path) &&
DocumentHelper.contentHasDocumentclass(doc.lines)
) {
async.setImmediate(function() {
async.setImmediate(function () {
cb(doc._id)
})
} else {
async.setImmediate(function() {
async.setImmediate(function () {
cb(null)
})
}
}
)
return async.series(jobs, function(root_doc_id) {
return async.series(jobs, function (root_doc_id) {
if (root_doc_id != null) {
return ProjectEntityUpdateHandler.setRootDoc(
project_id,
@@ -70,7 +70,7 @@ module.exports = ProjectRootDocManager = {
findRootDocFileFromDirectory(directoryPath, callback) {
if (callback == null) {
callback = function(error, path, content) {}
callback = function (error, path, content) {}
}
const filePathsPromise = globby(['**/*.{tex,Rtex}'], {
cwd: directoryPath,
@@ -88,7 +88,7 @@ module.exports = ProjectRootDocManager = {
ProjectRootDocManager._sortFileList(
unsortedFiles,
directoryPath,
function(err, files) {
function (err, files) {
if (err != null) {
return callback(err)
}
@@ -96,12 +96,12 @@ module.exports = ProjectRootDocManager = {
return async.until(
() => doc != null || files.length === 0,
function(cb) {
function (cb) {
const file = files.shift()
return fs.readFile(
Path.join(directoryPath, file),
'utf8',
function(error, content) {
function (error, content) {
if (error != null) {
return cb(error)
}
@@ -131,11 +131,11 @@ module.exports = ProjectRootDocManager = {
setRootDocFromName(project_id, rootDocName, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ProjectEntityHandler.getAllDocPathsFromProjectById(
project_id,
function(error, docPaths) {
function (error, docPaths) {
let doc_id, path
if (error != null) {
return callback(error)
@@ -180,89 +180,91 @@ module.exports = ProjectRootDocManager = {
ensureRootDocumentIsSet(project_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ProjectGetter.getProject(project_id, { rootDoc_id: 1 }, function(
error,
project
) {
if (error != null) {
return callback(error)
}
if (project == null) {
return callback(new Error('project not found'))
}
return ProjectGetter.getProject(
project_id,
{ rootDoc_id: 1 },
function (error, project) {
if (error != null) {
return callback(error)
}
if (project == null) {
return callback(new Error('project not found'))
}
if (project.rootDoc_id != null) {
return callback()
} else {
return ProjectRootDocManager.setRootDocAutomatically(
project_id,
callback
)
if (project.rootDoc_id != null) {
return callback()
} else {
return ProjectRootDocManager.setRootDocAutomatically(
project_id,
callback
)
}
}
})
)
},
ensureRootDocumentIsValid(project_id, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return ProjectGetter.getProject(project_id, { rootDoc_id: 1 }, function(
error,
project
) {
if (error != null) {
return callback(error)
}
if (project == null) {
return callback(new Error('project not found'))
}
return ProjectGetter.getProject(
project_id,
{ rootDoc_id: 1 },
function (error, project) {
if (error != null) {
return callback(error)
}
if (project == null) {
return callback(new Error('project not found'))
}
if (project.rootDoc_id != null) {
return ProjectEntityHandler.getAllDocPathsFromProjectById(
project_id,
function(error, docPaths) {
if (error != null) {
return callback(error)
}
let rootDocValid = false
for (let doc_id in docPaths) {
const _path = docPaths[doc_id]
if (doc_id === project.rootDoc_id) {
rootDocValid = true
if (project.rootDoc_id != null) {
return ProjectEntityHandler.getAllDocPathsFromProjectById(
project_id,
function (error, docPaths) {
if (error != null) {
return callback(error)
}
let rootDocValid = false
for (let doc_id in docPaths) {
const _path = docPaths[doc_id]
if (doc_id === project.rootDoc_id) {
rootDocValid = true
}
}
if (rootDocValid) {
return callback()
} else {
return ProjectEntityUpdateHandler.unsetRootDoc(project_id, () =>
ProjectRootDocManager.setRootDocAutomatically(
project_id,
callback
)
)
}
}
if (rootDocValid) {
return callback()
} else {
return ProjectEntityUpdateHandler.unsetRootDoc(project_id, () =>
ProjectRootDocManager.setRootDocAutomatically(
project_id,
callback
)
)
}
}
)
} else {
return ProjectRootDocManager.setRootDocAutomatically(
project_id,
callback
)
)
} else {
return ProjectRootDocManager.setRootDocAutomatically(
project_id,
callback
)
}
}
})
)
},
_sortFileList(listToSort, rootDirectory, callback) {
if (callback == null) {
callback = function(error, result) {}
callback = function (error, result) {}
}
return async.mapLimit(
listToSort,
5,
(filePath, cb) =>
fs.stat(Path.join(rootDirectory, filePath), function(err, stat) {
fs.stat(Path.join(rootDirectory, filePath), function (err, stat) {
if (err != null) {
return cb(err)
}
@@ -273,7 +275,7 @@ module.exports = ProjectRootDocManager = {
name: Path.basename(filePath)
})
}),
function(err, files) {
function (err, files) {
if (err != null) {
return callback(err)
}

View File

@@ -17,7 +17,7 @@ const logger = require('logger-sharelatex')
module.exports = {
markAsUpdated(projectId, lastUpdatedAt, lastUpdatedBy, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
if (lastUpdatedAt == null) {
lastUpdatedAt = new Date()
@@ -38,7 +38,7 @@ module.exports = {
markAsOpened(project_id, callback) {
const conditions = { _id: project_id }
const update = { lastOpened: Date.now() }
return Project.updateOne(conditions, update, {}, function(err) {
return Project.updateOne(conditions, update, {}, function (err) {
if (callback != null) {
return callback()
}
@@ -48,7 +48,7 @@ module.exports = {
markAsInactive(project_id, callback) {
const conditions = { _id: project_id }
const update = { active: false }
return Project.updateOne(conditions, update, {}, function(err) {
return Project.updateOne(conditions, update, {}, function (err) {
if (callback != null) {
return callback()
}
@@ -58,7 +58,7 @@ module.exports = {
markAsActive(project_id, callback) {
const conditions = { _id: project_id }
const update = { active: true }
return Project.updateOne(conditions, update, {}, function(err) {
return Project.updateOne(conditions, update, {}, function (err) {
if (callback != null) {
return callback()
}

View File

@@ -18,7 +18,7 @@
// frontend/js/ide/directives/SafePath.js
// frontend/js/features/file-tree/util/safe-path.js
const load = function() {
const load = function () {
let SafePath
const BADCHAR_RX = new RegExp(
`\

View File

@@ -21,7 +21,7 @@ const _ = require('underscore')
module.exports = PublishersGetter = {
getManagedPublishers(user_id, callback) {
if (callback == null) {
callback = function(error, managedPublishers) {}
callback = function (error, managedPublishers) {}
}
return UserMembershipsHandler.getEntitiesByUser(
UserMembershipEntityConfigs.publisher,

View File

@@ -5,14 +5,14 @@ const FeaturesUpdater = require('../Subscription/FeaturesUpdater')
module.exports = {
allocate(referalId, newUserId, referalSource, referalMedium, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
if (referalId == null) {
return callback(null)
}
const query = { referal_id: referalId }
return User.findOne(query, { _id: 1 }, function(error, user) {
return User.findOne(query, { _id: 1 }, function (error, user) {
if (error != null) {
return callback(error)
}
@@ -32,7 +32,7 @@ module.exports = {
}
},
{},
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'something went wrong allocating referal', {
referalId,

View File

@@ -7,10 +7,10 @@ let ReferalFeatures
module.exports = ReferalFeatures = {
getBonusFeatures(userId, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
const query = { _id: userId }
User.findOne(query, { refered_user_count: 1 }, function(error, user) {
User.findOne(query, { refered_user_count: 1 }, function (error, user) {
if (error) {
return callback(error)
}
@@ -37,7 +37,7 @@ module.exports = ReferalFeatures = {
_getBonusLevel(user) {
let highestBonusLevel = 0
_.each(_.keys(Settings.bonus_features), function(level) {
_.each(_.keys(Settings.bonus_features), function (level) {
const levelIsLessThanUser = level <= user.refered_user_count
const levelIsMoreThanCurrentHighest = level >= highestBonusLevel
if (levelIsLessThanUser && levelIsMoreThanCurrentHighest) {

View File

@@ -3,7 +3,7 @@ const { User } = require('../../models/User')
module.exports = {
getReferedUsers(userId, callback) {
const projection = { refered_users: 1, refered_user_count: 1 }
User.findById(userId, projection, function(err, user) {
User.findById(userId, projection, function (err, user) {
if (err) {
return callback(err)
}

View File

@@ -28,7 +28,7 @@ module.exports = ReferencesController = {
)
return res.sendStatus(400)
}
return ReferencesHandler.index(projectId, docIds, function(err, data) {
return ReferencesHandler.index(projectId, docIds, function (err, data) {
if (err != null) {
logger.err({ err, projectId }, 'error indexing all references')
return res.sendStatus(500)
@@ -46,7 +46,7 @@ module.exports = ReferencesController = {
indexAll(req, res) {
const projectId = req.params.Project_id
const { shouldBroadcast } = req.body
return ReferencesHandler.indexAll(projectId, function(err, data) {
return ReferencesHandler.indexAll(projectId, function (err, data) {
if (err != null) {
logger.err({ err, projectId }, 'error indexing all references')
return res.sendStatus(500)

View File

@@ -42,8 +42,8 @@ module.exports = ReferencesHandler = {
_findBibFileIds(project) {
const ids = []
var _process = function(folder) {
_.each(folder.fileRefs || [], function(file) {
var _process = function (folder) {
_.each(folder.fileRefs || [], function (file) {
if (
__guard__(file != null ? file.name : undefined, x1 =>
x1.match(/^.*\.bib$/)
@@ -60,8 +60,8 @@ module.exports = ReferencesHandler = {
_findBibDocIds(project) {
const ids = []
var _process = function(folder) {
_.each(folder.docs || [], function(doc) {
var _process = function (folder) {
_.each(folder.docs || [], function (doc) {
if (
__guard__(doc != null ? doc.name : undefined, x1 =>
x1.match(/^.*\.bib$/)
@@ -78,32 +78,33 @@ module.exports = ReferencesHandler = {
_isFullIndex(project, callback) {
if (callback == null) {
callback = function(err, result) {}
callback = function (err, result) {}
}
return UserGetter.getUser(project.owner_ref, { features: true }, function(
err,
owner
) {
if (err != null) {
return callback(err)
return UserGetter.getUser(
project.owner_ref,
{ features: true },
function (err, owner) {
if (err != null) {
return callback(err)
}
const features = owner != null ? owner.features : undefined
return callback(
null,
(features != null ? features.references : undefined) === true ||
(features != null ? features.referencesSearch : undefined) === true
)
}
const features = owner != null ? owner.features : undefined
return callback(
null,
(features != null ? features.references : undefined) === true ||
(features != null ? features.referencesSearch : undefined) === true
)
})
)
},
indexAll(projectId, callback) {
if (callback == null) {
callback = function(err, data) {}
callback = function (err, data) {}
}
return ProjectGetter.getProject(
projectId,
{ rootFolder: true, owner_ref: 1 },
function(err, project) {
function (err, project) {
if (err) {
OError.tag(err, 'error finding project', {
projectId
@@ -126,12 +127,12 @@ module.exports = ReferencesHandler = {
index(projectId, docIds, callback) {
if (callback == null) {
callback = function(err, data) {}
callback = function (err, data) {}
}
return ProjectGetter.getProject(
projectId,
{ rootFolder: true, owner_ref: 1 },
function(err, project) {
function (err, project) {
if (err) {
OError.tag(err, 'error finding project', {
projectId
@@ -153,7 +154,7 @@ module.exports = ReferencesHandler = {
if (!Features.hasFeature('references')) {
return callback()
}
return ReferencesHandler._isFullIndex(project, function(err, isFullIndex) {
return ReferencesHandler._isFullIndex(project, function (err, isFullIndex) {
if (err) {
OError.tag(err, 'error checking whether to do full index', {
projectId
@@ -168,7 +169,7 @@ module.exports = ReferencesHandler = {
docIds.map(docId => cb =>
DocumentUpdaterHandler.flushDocToMongo(projectId, docId, cb)
),
function(err) {
function (err) {
// continue
if (err) {
OError.tag(err, 'error flushing docs to mongo', {
@@ -192,7 +193,7 @@ module.exports = ReferencesHandler = {
fullIndex: isFullIndex
}
},
function(err, res, data) {
function (err, res, data) {
if (err) {
OError.tag(err, 'error communicating with references api', {
projectId

View File

@@ -16,7 +16,7 @@ function processLoginRequest(email, callback) {
function recordSuccessfulLogin(email, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
RateLimiter.clearRateLimit('login', email, callback)
}

View File

@@ -26,7 +26,7 @@ module.exports = {
options = {}
}
if (callback == null) {
callback = function(error, data) {}
callback = function (error, data) {}
}
if (typeof options === 'function') {
callback = options
@@ -44,7 +44,7 @@ module.exports = {
createdAt,
expiresAt
},
function(error) {
function (error) {
if (error != null) {
return callback(error)
}
@@ -55,7 +55,7 @@ module.exports = {
getValueFromTokenAndExpire(use, token, callback) {
if (callback == null) {
callback = function(error, data) {}
callback = function (error, data) {}
}
const now = new Date()
return db.tokens.findOneAndUpdate(
@@ -70,7 +70,7 @@ module.exports = {
usedAt: now
}
},
function(error, result) {
function (error, result) {
if (error != null) {
return callback(error)
}

View File

@@ -16,7 +16,7 @@ const settings = require('settings-sharelatex')
Unique clients are identified by user_id if logged in, and IP address if not.
*/
function rateLimit(opts) {
return function(req, res, next) {
return function (req, res, next) {
const userId = AuthenticationController.getLoggedInUserId(req) || req.ip
if (
settings.smokeTest &&
@@ -41,7 +41,7 @@ function rateLimit(opts) {
subjectName,
throttle: opts.maxRequests || 6
}
return RateLimiter.addCount(options, function(error, canContinue) {
return RateLimiter.addCount(options, function (error, canContinue) {
if (error != null) {
return next(error)
}
@@ -62,7 +62,7 @@ function loginRateLimit(req, res, next) {
if (!email) {
return next()
}
LoginRateLimiter.processLoginRequest(email, function(err, isAllowed) {
LoginRateLimiter.processLoginRequest(email, function (err, isAllowed) {
if (err) {
return next(err)
}

View File

@@ -27,7 +27,7 @@ const SystemMessageManager = require('../SystemMessages/SystemMessageManager')
const oneMinInMs = 60 * 1000
var updateOpenConnetionsMetrics = function() {
var updateOpenConnetionsMetrics = function () {
metrics.gauge(
'open_connections.socketio',
__guard__(
@@ -79,7 +79,7 @@ const AdminController = {
})()
}
return SystemMessageManager.getMessagesFromDB(function(
return SystemMessageManager.getMessagesFromDB(function (
error,
systemMessages
) {
@@ -124,7 +124,7 @@ const AdminController = {
writeAllToMongo(req, res) {
logger.log('writing all docs to mongo')
Settings.mongo.writeAll = true
return DocumentUpdaterHandler.flushAllDocsToMongo(function() {
return DocumentUpdaterHandler.flushAllDocsToMongo(function () {
logger.log('all docs have been saved to mongo')
return res.sendStatus(200)
})
@@ -144,18 +144,19 @@ const AdminController = {
},
createMessage(req, res, next) {
return SystemMessageManager.createMessage(req.body.content, function(
error
) {
if (error != null) {
return next(error)
return SystemMessageManager.createMessage(
req.body.content,
function (error) {
if (error != null) {
return next(error)
}
return res.sendStatus(200)
}
return res.sendStatus(200)
})
)
},
clearMessages(req, res, next) {
return SystemMessageManager.clearMessages(function(error) {
return SystemMessageManager.clearMessages(function (error) {
if (error != null) {
return next(error)
}

View File

@@ -38,7 +38,7 @@ module.exports = {
json: req.body,
timeout: TEN_SECONDS
})
.on('error', function(error) {
.on('error', function (error) {
logger.error({ err: error }, 'Spelling API error')
return res.status(500).end()
})

View File

@@ -48,14 +48,14 @@ module.exports = HomeController = {
},
externalPage(page, title) {
return function(req, res, next) {
return function (req, res, next) {
if (next == null) {
next = function(error) {}
next = function (error) {}
}
const path = Path.resolve(
__dirname + `/../../../views/external/${page}.pug`
)
return fs.exists(path, function(exists) {
return fs.exists(path, function (exists) {
// No error in this callback - old method in Node.js!
if (exists) {
return res.render(`external/${page}.pug`, { title })

View File

@@ -67,7 +67,7 @@ const FeaturesUpdater = {
FeaturesUpdater._getFeaturesOverrides(userId, cb)
}
}
async.series(jobs, function(err, results) {
async.series(jobs, function (err, results) {
if (err) {
OError.tag(
err,
@@ -158,26 +158,25 @@ const FeaturesUpdater = {
},
_getV1Features(userId, callback) {
V1SubscriptionManager.getPlanCodeFromV1(userId, function(
err,
planCode,
v1Id
) {
if (err) {
if ((err ? err.name : undefined) === 'NotFoundError') {
return callback(null, [])
V1SubscriptionManager.getPlanCodeFromV1(
userId,
function (err, planCode, v1Id) {
if (err) {
if ((err ? err.name : undefined) === 'NotFoundError') {
return callback(null, [])
}
return callback(err)
}
return callback(err)
}
callback(
err,
FeaturesUpdater._mergeFeatures(
V1SubscriptionManager.getGrandfatheredFeaturesForV1User(v1Id) || {},
FeaturesUpdater._planCodeToFeatures(planCode)
callback(
err,
FeaturesUpdater._mergeFeatures(
V1SubscriptionManager.getGrandfatheredFeaturesForV1User(v1Id) || {},
FeaturesUpdater._planCodeToFeatures(planCode)
)
)
)
})
}
)
},
_mergeFeatures(featuresA, featuresB) {
@@ -277,31 +276,32 @@ const FeaturesUpdater = {
doSyncFromV1(v1UserId, callback) {
logger.log({ v1UserId }, '[AccountSync] starting account sync')
return UserGetter.getUser({ 'overleaf.id': v1UserId }, { _id: 1 }, function(
err,
user
) {
if (err != null) {
OError.tag(err, '[AccountSync] error getting user', {
v1UserId
})
return callback(err)
return UserGetter.getUser(
{ 'overleaf.id': v1UserId },
{ _id: 1 },
function (err, user) {
if (err != null) {
OError.tag(err, '[AccountSync] error getting user', {
v1UserId
})
return callback(err)
}
if ((user != null ? user._id : undefined) == null) {
logger.warn({ v1UserId }, '[AccountSync] no user found for v1 id')
return callback(null)
}
logger.log(
{ v1UserId, userId: user._id },
'[AccountSync] updating user subscription and features'
)
return FeaturesUpdater.refreshFeatures(user._id, callback)
}
if ((user != null ? user._id : undefined) == null) {
logger.warn({ v1UserId }, '[AccountSync] no user found for v1 id')
return callback(null)
}
logger.log(
{ v1UserId, userId: user._id },
'[AccountSync] updating user subscription and features'
)
return FeaturesUpdater.refreshFeatures(user._id, callback)
})
)
}
}
const refreshFeaturesPromise = userId =>
new Promise(function(resolve, reject) {
new Promise(function (resolve, reject) {
FeaturesUpdater.refreshFeatures(
userId,
(error, features, featuresChanged) => {

View File

@@ -41,7 +41,7 @@ module.exports = LimitationsManager = {
},
allowedNumberOfCollaboratorsForUser(user_id, callback) {
return UserGetter.getUser(user_id, { features: 1 }, function(error, user) {
return UserGetter.getUser(user_id, { features: 1 }, function (error, user) {
if (error != null) {
return callback(error)
}
@@ -55,7 +55,7 @@ module.exports = LimitationsManager = {
canAddXCollaborators(project_id, x_collaborators, callback) {
if (callback == null) {
callback = function(error, allowed) {}
callback = function (error, allowed) {}
}
return this.allowedNumberOfCollaboratorsInProject(
project_id,
@@ -94,7 +94,7 @@ module.exports = LimitationsManager = {
hasPaidSubscription(user, callback) {
if (callback == null) {
callback = function(err, hasSubscriptionOrIsMember) {}
callback = function (err, hasSubscriptionOrIsMember) {}
}
return this.userHasV2Subscription(
user,
@@ -132,27 +132,27 @@ module.exports = LimitationsManager = {
userHasV2Subscription(user, callback) {
if (callback == null) {
callback = function(err, hasSubscription, subscription) {}
callback = function (err, hasSubscription, subscription) {}
}
return SubscriptionLocator.getUsersSubscription(user._id, function(
err,
subscription
) {
if (err != null) {
return callback(err)
return SubscriptionLocator.getUsersSubscription(
user._id,
function (err, subscription) {
if (err != null) {
return callback(err)
}
const hasValidSubscription =
subscription != null &&
(subscription.recurlySubscription_id != null ||
(subscription != null ? subscription.customAccount : undefined) ===
true)
return callback(err, hasValidSubscription, subscription)
}
const hasValidSubscription =
subscription != null &&
(subscription.recurlySubscription_id != null ||
(subscription != null ? subscription.customAccount : undefined) ===
true)
return callback(err, hasValidSubscription, subscription)
})
)
},
userHasV1OrV2Subscription(user, callback) {
if (callback == null) {
callback = function(err, hasSubscription) {}
callback = function (err, hasSubscription) {}
}
return this.userHasV2Subscription(user, (err, hasV2Subscription) => {
if (err != null) {
@@ -175,35 +175,37 @@ module.exports = LimitationsManager = {
userIsMemberOfGroupSubscription(user, callback) {
if (callback == null) {
callback = function(error, isMember, subscriptions) {}
callback = function (error, isMember, subscriptions) {}
}
return SubscriptionLocator.getMemberSubscriptions(user._id, function(
err,
subscriptions
) {
if (subscriptions == null) {
subscriptions = []
return SubscriptionLocator.getMemberSubscriptions(
user._id,
function (err, subscriptions) {
if (subscriptions == null) {
subscriptions = []
}
if (err != null) {
return callback(err)
}
return callback(err, subscriptions.length > 0, subscriptions)
}
if (err != null) {
return callback(err)
}
return callback(err, subscriptions.length > 0, subscriptions)
})
)
},
userHasV1Subscription(user, callback) {
if (callback == null) {
callback = function(error, hasV1Subscription) {}
callback = function (error, hasV1Subscription) {}
}
return V1SubscriptionManager.getSubscriptionsFromV1(user._id, function(
err,
v1Subscription
) {
return callback(
err,
!!(v1Subscription != null ? v1Subscription.has_subscription : undefined)
)
})
return V1SubscriptionManager.getSubscriptionsFromV1(
user._id,
function (err, v1Subscription) {
return callback(
err,
!!(v1Subscription != null
? v1Subscription.has_subscription
: undefined)
)
}
)
},
teamHasReachedMemberLimit(subscription) {
@@ -217,27 +219,27 @@ module.exports = LimitationsManager = {
hasGroupMembersLimitReached(subscriptionId, callback) {
if (callback == null) {
callback = function(err, limitReached, subscription) {}
callback = function (err, limitReached, subscription) {}
}
return SubscriptionLocator.getSubscription(subscriptionId, function(
err,
subscription
) {
if (err != null) {
OError.tag(err, 'error getting subscription', {
subscriptionId
})
return callback(err)
}
if (subscription == null) {
logger.warn({ subscriptionId }, 'no subscription found')
return callback(new Error('no subscription found'))
}
return SubscriptionLocator.getSubscription(
subscriptionId,
function (err, subscription) {
if (err != null) {
OError.tag(err, 'error getting subscription', {
subscriptionId
})
return callback(err)
}
if (subscription == null) {
logger.warn({ subscriptionId }, 'no subscription found')
return callback(new Error('no subscription found'))
}
const limitReached = LimitationsManager.teamHasReachedMemberLimit(
subscription
)
return callback(err, limitReached, subscription)
})
const limitReached = LimitationsManager.teamHasReachedMemberLimit(
subscription
)
return callback(err, limitReached, subscription)
}
)
}
}

View File

@@ -65,7 +65,7 @@ const RecurlyWrapper = {
method: 'GET',
expect404: true
},
function(error, response, responseBody) {
function (error, response, responseBody) {
if (error) {
OError.tag(
error,
@@ -86,20 +86,20 @@ const RecurlyWrapper = {
return next(null, cache)
}
logger.log({ user_id: user._id }, 'user appears to exist in recurly')
return RecurlyWrapper._parseAccountXml(responseBody, function(
err,
account
) {
if (err) {
OError.tag(err, 'error parsing account', {
user_id: user._id
})
return next(err)
return RecurlyWrapper._parseAccountXml(
responseBody,
function (err, account) {
if (err) {
OError.tag(err, 'error parsing account', {
user_id: user._id
})
return next(err)
}
cache.userExists = true
cache.account = account
return next(null, cache)
}
cache.userExists = true
cache.account = account
return next(null, cache)
})
)
}
)
},
@@ -142,19 +142,19 @@ const RecurlyWrapper = {
)
return next(error)
}
return RecurlyWrapper._parseAccountXml(responseBody, function(
err,
account
) {
if (err) {
OError.tag(err, 'error creating account', {
user_id: user._id
})
return next(err)
return RecurlyWrapper._parseAccountXml(
responseBody,
function (err, account) {
if (err) {
OError.tag(err, 'error creating account', {
user_id: user._id
})
return next(err)
}
cache.account = account
return next(null, cache)
}
cache.account = account
return next(null, cache)
})
)
}
)
},
@@ -189,20 +189,20 @@ const RecurlyWrapper = {
)
return next(error)
}
return RecurlyWrapper._parseBillingInfoXml(responseBody, function(
err,
billingInfo
) {
if (err) {
OError.tag(err, 'error creating billing info', {
user_id: user._id,
accountCode
})
return next(err)
return RecurlyWrapper._parseBillingInfoXml(
responseBody,
function (err, billingInfo) {
if (err) {
OError.tag(err, 'error creating billing info', {
user_id: user._id,
accountCode
})
return next(err)
}
cache.billingInfo = billingInfo
return next(null, cache)
}
cache.billingInfo = billingInfo
return next(null, cache)
})
)
}
)
},
@@ -255,19 +255,19 @@ const RecurlyWrapper = {
)
return next(error)
}
return RecurlyWrapper._parseBillingInfoXml(responseBody, function(
err,
billingInfo
) {
if (err) {
OError.tag(err, 'error updating billing info', {
user_id: user._id
})
return next(err)
return RecurlyWrapper._parseBillingInfoXml(
responseBody,
function (err, billingInfo) {
if (err) {
OError.tag(err, 'error updating billing info', {
user_id: user._id
})
return next(err)
}
cache.billingInfo = billingInfo
return next(null, cache)
}
cache.billingInfo = billingInfo
return next(null, cache)
})
)
}
)
},
@@ -308,19 +308,19 @@ const RecurlyWrapper = {
)
return next(error)
}
return RecurlyWrapper._parseSubscriptionXml(responseBody, function(
err,
subscription
) {
if (err) {
OError.tag(err, 'error creating subscription', {
user_id: user._id
})
return next(err)
return RecurlyWrapper._parseSubscriptionXml(
responseBody,
function (err, subscription) {
if (err) {
OError.tag(err, 'error creating subscription', {
user_id: user._id
})
return next(err)
}
cache.subscription = subscription
return next(null, cache)
}
cache.subscription = subscription
return next(null, cache)
})
)
}
)
}
@@ -348,7 +348,7 @@ const RecurlyWrapper = {
RecurlyWrapper._paypal.setAddressAndCompanyBillingInfo,
RecurlyWrapper._paypal.createSubscription
],
function(err, result) {
function (err, result) {
if (err) {
OError.tag(err, 'error in paypal subscription creation process', {
user_id: user._id
@@ -449,7 +449,7 @@ const RecurlyWrapper = {
const { expect404, expect422 } = options
delete options.expect404
delete options.expect422
return request(options, function(error, response, body) {
return request(options, function (error, response, body) {
if (
error == null &&
response.statusCode !== 200 &&
@@ -532,16 +532,16 @@ const RecurlyWrapper = {
)
}
return RecurlyWrapper.getAccount(accountId, function(
error,
account
) {
if (error != null) {
return callback(error)
return RecurlyWrapper.getAccount(
accountId,
function (error, account) {
if (error != null) {
return callback(error)
}
recurlySubscription.account = account
return callback(null, recurlySubscription)
}
recurlySubscription.account = account
return callback(null, recurlySubscription)
})
)
} else {
return callback(null, recurlySubscription)
}
@@ -566,7 +566,7 @@ const RecurlyWrapper = {
if (error != null) {
return callback(error)
}
return RecurlyWrapper._parseXml(body, function(err, data) {
return RecurlyWrapper._parseXml(body, function (err, data) {
if (err != null) {
logger.warn({ err }, 'could not get accoutns')
callback(err)
@@ -620,29 +620,30 @@ const RecurlyWrapper = {
if (error != null) {
return callback(error)
}
return RecurlyWrapper._parseRedemptionsXml(body, function(
error,
redemptions
) {
if (error != null) {
return callback(error)
}
const activeRedemptions = redemptions.filter(
redemption => redemption.state === 'active'
)
const couponCodes = activeRedemptions.map(
redemption => redemption.coupon_code
)
return Async.map(couponCodes, RecurlyWrapper.getCoupon, function(
error,
coupons
) {
return RecurlyWrapper._parseRedemptionsXml(
body,
function (error, redemptions) {
if (error != null) {
return callback(error)
}
return callback(null, coupons)
})
})
const activeRedemptions = redemptions.filter(
redemption => redemption.state === 'active'
)
const couponCodes = activeRedemptions.map(
redemption => redemption.coupon_code
)
return Async.map(
couponCodes,
RecurlyWrapper.getCoupon,
function (error, coupons) {
if (error != null) {
return callback(error)
}
return callback(null, coupons)
}
)
}
)
}
)
},
@@ -776,9 +777,9 @@ const RecurlyWrapper = {
url: `subscriptions/${subscriptionId}/cancel`,
method: 'put'
},
function(error, response, body) {
function (error, response, body) {
if (error != null) {
return RecurlyWrapper._parseXml(body, function(_err, parsed) {
return RecurlyWrapper._parseXml(body, function (_err, parsed) {
if (
__guard__(
parsed != null ? parsed.error : undefined,
@@ -870,7 +871,7 @@ const RecurlyWrapper = {
listAccountActiveSubscriptions(account_id, callback) {
if (callback == null) {
callback = function(error, subscriptions) {}
callback = function (error, subscriptions) {}
}
return RecurlyWrapper.apiRequest(
{
@@ -880,7 +881,7 @@ const RecurlyWrapper = {
},
expect404: true
},
function(error, response, body) {
function (error, response, body) {
if (error != null) {
return callback(error)
}
@@ -975,7 +976,7 @@ const RecurlyWrapper = {
},
_parseXmlAndGetAttribute(xml, attribute, callback) {
return RecurlyWrapper._parseXml(xml, function(error, data) {
return RecurlyWrapper._parseXml(xml, function (error, data) {
if (error != null) {
return callback(error)
}
@@ -990,7 +991,7 @@ const RecurlyWrapper = {
},
_parseXml(xml, callback) {
var convertDataTypes = function(data) {
var convertDataTypes = function (data) {
let key, value
if (data != null && data.$ != null) {
if (data.$.nil === 'nil') {
@@ -1033,7 +1034,7 @@ const RecurlyWrapper = {
explicitArray: false,
emptyTag: ''
})
return parser.parseString(xml, function(error, data) {
return parser.parseString(xml, function (error, data) {
if (error != null) {
return callback(error)
}

View File

@@ -41,7 +41,7 @@ module.exports = SubscriptionController = {
return GeoIpLookup.getCurrencyCode(
(req.query != null ? req.query.ip : undefined) || req.ip,
function(err, recomendedCurrency) {
function (err, recomendedCurrency) {
if (err != null) {
return next(err)
}
@@ -57,16 +57,17 @@ module.exports = SubscriptionController = {
})
const user_id = AuthenticationController.getLoggedInUserId(req)
if (user_id != null) {
return UserGetter.getUser(user_id, { signUpDate: 1 }, function(
err,
user
) {
if (err != null) {
return next(err)
return UserGetter.getUser(
user_id,
{ signUpDate: 1 },
function (err, user) {
if (err != null) {
return next(err)
}
currentUser = user
return render()
}
currentUser = user
return render()
})
)
} else {
return render()
}
@@ -81,68 +82,68 @@ module.exports = SubscriptionController = {
if (!plan) {
return HttpErrorHandler.unprocessableEntity(req, res, 'Plan not found')
}
return LimitationsManager.userHasV1OrV2Subscription(user, function(
err,
hasSubscription
) {
if (err != null) {
return next(err)
}
if (hasSubscription) {
return res.redirect('/user/subscription?hasSubscription=true')
} else {
// LimitationsManager.userHasV2Subscription only checks Mongo. Double check with
// Recurly as well at this point (we don't do this most places for speed).
return SubscriptionHandler.validateNoSubscriptionInRecurly(
user._id,
function(error, valid) {
if (error != null) {
return next(error)
}
if (!valid) {
res.redirect('/user/subscription?hasSubscription=true')
} else {
let currency =
req.query.currency != null
? req.query.currency.toUpperCase()
: undefined
return GeoIpLookup.getCurrencyCode(
(req.query != null ? req.query.ip : undefined) || req.ip,
function(err, recomendedCurrency, countryCode) {
if (err != null) {
return next(err)
}
if (recomendedCurrency != null && currency == null) {
currency = recomendedCurrency
}
return res.render('subscriptions/new', {
title: 'subscribe',
currency,
countryCode,
plan,
showStudentPlan: req.query.ssp === 'true',
recurlyConfig: JSON.stringify({
return LimitationsManager.userHasV1OrV2Subscription(
user,
function (err, hasSubscription) {
if (err != null) {
return next(err)
}
if (hasSubscription) {
return res.redirect('/user/subscription?hasSubscription=true')
} else {
// LimitationsManager.userHasV2Subscription only checks Mongo. Double check with
// Recurly as well at this point (we don't do this most places for speed).
return SubscriptionHandler.validateNoSubscriptionInRecurly(
user._id,
function (error, valid) {
if (error != null) {
return next(error)
}
if (!valid) {
res.redirect('/user/subscription?hasSubscription=true')
} else {
let currency =
req.query.currency != null
? req.query.currency.toUpperCase()
: undefined
return GeoIpLookup.getCurrencyCode(
(req.query != null ? req.query.ip : undefined) || req.ip,
function (err, recomendedCurrency, countryCode) {
if (err != null) {
return next(err)
}
if (recomendedCurrency != null && currency == null) {
currency = recomendedCurrency
}
return res.render('subscriptions/new', {
title: 'subscribe',
currency,
subdomain: Settings.apis.recurly.subdomain
}),
showCouponField: !!req.query.scf,
showVatField: !!req.query.svf,
gaOptimize: true
})
}
)
countryCode,
plan,
showStudentPlan: req.query.ssp === 'true',
recurlyConfig: JSON.stringify({
currency,
subdomain: Settings.apis.recurly.subdomain
}),
showCouponField: !!req.query.scf,
showVatField: !!req.query.svf,
gaOptimize: true
})
}
)
}
}
}
)
)
}
}
})
)
},
userSubscriptionPage(req, res, next) {
const user = AuthenticationController.getSessionUser(req)
return SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel(
user,
function(error, results) {
function (error, results) {
if (error != null) {
return next(error)
}
@@ -155,31 +156,31 @@ module.exports = SubscriptionController = {
managedPublishers,
v1SubscriptionStatus
} = results
return LimitationsManager.userHasV1OrV2Subscription(user, function(
err,
hasSubscription
) {
if (error != null) {
return next(error)
return LimitationsManager.userHasV1OrV2Subscription(
user,
function (err, hasSubscription) {
if (error != null) {
return next(error)
}
const fromPlansPage = req.query.hasSubscription
const plans = SubscriptionViewModelBuilder.buildPlansList()
const data = {
title: 'your_subscription',
plans,
user,
hasSubscription,
fromPlansPage,
personalSubscription,
memberGroupSubscriptions,
managedGroupSubscriptions,
confirmedMemberAffiliations,
managedInstitutions,
managedPublishers,
v1SubscriptionStatus
}
return res.render('subscriptions/dashboard', data)
}
const fromPlansPage = req.query.hasSubscription
const plans = SubscriptionViewModelBuilder.buildPlansList()
const data = {
title: 'your_subscription',
plans,
user,
hasSubscription,
fromPlansPage,
personalSubscription,
memberGroupSubscriptions,
managedGroupSubscriptions,
confirmedMemberAffiliations,
managedInstitutions,
managedPublishers,
v1SubscriptionStatus
}
return res.render('subscriptions/dashboard', data)
})
)
}
)
},
@@ -193,54 +194,54 @@ module.exports = SubscriptionController = {
}
const { subscriptionDetails } = req.body
return LimitationsManager.userHasV1OrV2Subscription(user, function(
err,
hasSubscription
) {
if (err != null) {
return next(err)
}
if (hasSubscription) {
logger.warn({ user_id: user._id }, 'user already has subscription')
return res.sendStatus(409) // conflict
}
return SubscriptionHandler.createSubscription(
user,
subscriptionDetails,
recurlyTokenIds,
function(err) {
if (!err) {
return res.sendStatus(201)
}
if (
err instanceof SubscriptionErrors.RecurlyTransactionError ||
err instanceof Errors.InvalidError
) {
logger.error({ err }, 'recurly transaction error, potential 422')
return HttpErrorHandler.unprocessableEntity(
req,
res,
err.message,
OError.getFullInfo(err).public
)
}
logger.warn(
{ err, user_id: user._id },
'something went wrong creating subscription'
)
next(err)
return LimitationsManager.userHasV1OrV2Subscription(
user,
function (err, hasSubscription) {
if (err != null) {
return next(err)
}
)
})
if (hasSubscription) {
logger.warn({ user_id: user._id }, 'user already has subscription')
return res.sendStatus(409) // conflict
}
return SubscriptionHandler.createSubscription(
user,
subscriptionDetails,
recurlyTokenIds,
function (err) {
if (!err) {
return res.sendStatus(201)
}
if (
err instanceof SubscriptionErrors.RecurlyTransactionError ||
err instanceof Errors.InvalidError
) {
logger.error({ err }, 'recurly transaction error, potential 422')
return HttpErrorHandler.unprocessableEntity(
req,
res,
err.message,
OError.getFullInfo(err).public
)
}
logger.warn(
{ err, user_id: user._id },
'something went wrong creating subscription'
)
next(err)
}
)
}
)
},
successful_subscription(req, res, next) {
const user = AuthenticationController.getSessionUser(req)
return SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel(
user,
function(error, { personalSubscription }) {
function (error, { personalSubscription }) {
if (error != null) {
return next(error)
}
@@ -258,7 +259,7 @@ module.exports = SubscriptionController = {
cancelSubscription(req, res, next) {
const user = AuthenticationController.getSessionUser(req)
logger.log({ user_id: user._id }, 'canceling subscription')
return SubscriptionHandler.cancelSubscription(user, function(err) {
return SubscriptionHandler.cancelSubscription(user, function (err) {
if (err != null) {
OError.tag(err, 'something went wrong canceling subscription', {
user_id: user._id
@@ -281,7 +282,7 @@ module.exports = SubscriptionController = {
cancelV1Subscription(req, res, next) {
const user_id = AuthenticationController.getLoggedInUserId(req)
logger.log({ user_id }, 'canceling v1 subscription')
return V1SubscriptionManager.cancelV1Subscription(user_id, function(err) {
return V1SubscriptionManager.cancelV1Subscription(user_id, function (err) {
if (err != null) {
OError.tag(err, 'something went wrong canceling v1 subscription', {
user_id
@@ -310,7 +311,7 @@ module.exports = SubscriptionController = {
user,
planCode,
null,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'something went wrong updating subscription', {
user_id: user._id
@@ -324,20 +325,22 @@ module.exports = SubscriptionController = {
updateAccountEmailAddress(req, res, next) {
const user = AuthenticationController.getSessionUser(req)
RecurlyWrapper.updateAccountEmailAddress(user._id, user.email, function(
error
) {
if (error) {
return next(error)
RecurlyWrapper.updateAccountEmailAddress(
user._id,
user.email,
function (error) {
if (error) {
return next(error)
}
res.sendStatus(200)
}
res.sendStatus(200)
})
)
},
reactivateSubscription(req, res, next) {
const user = AuthenticationController.getSessionUser(req)
logger.log({ user_id: user._id }, 'reactivating subscription')
return SubscriptionHandler.reactivateSubscription(user, function(err) {
return SubscriptionHandler.reactivateSubscription(user, function (err) {
if (err != null) {
OError.tag(err, 'something went wrong reactivating subscription', {
user_id: user._id
@@ -363,7 +366,7 @@ module.exports = SubscriptionController = {
return SubscriptionHandler.syncSubscription(
recurlySubscription,
{ ip: req.ip },
function(err) {
function (err) {
if (err != null) {
return next(err)
}
@@ -374,7 +377,7 @@ module.exports = SubscriptionController = {
const recurlyAccountCode = eventData.account.account_code
return SubscriptionHandler.attemptPaypalInvoiceCollection(
recurlyAccountCode,
function(err) {
function (err) {
if (err) {
return next(err)
}
@@ -388,36 +391,38 @@ module.exports = SubscriptionController = {
renderUpgradeToAnnualPlanPage(req, res, next) {
const user = AuthenticationController.getSessionUser(req)
return LimitationsManager.userHasV2Subscription(user, function(
err,
hasSubscription,
subscription
) {
let planName
if (err != null) {
return next(err)
return LimitationsManager.userHasV2Subscription(
user,
function (err, hasSubscription, subscription) {
let planName
if (err != null) {
return next(err)
}
const planCode =
subscription != null ? subscription.planCode.toLowerCase() : undefined
if (
(planCode != null ? planCode.indexOf('annual') : undefined) !== -1
) {
planName = 'annual'
} else if (
(planCode != null ? planCode.indexOf('student') : undefined) !== -1
) {
planName = 'student'
} else if (
(planCode != null ? planCode.indexOf('collaborator') : undefined) !==
-1
) {
planName = 'collaborator'
}
if (!hasSubscription) {
return res.redirect('/user/subscription/plans')
}
return res.render('subscriptions/upgradeToAnnual', {
title: 'Upgrade to annual',
planName
})
}
const planCode =
subscription != null ? subscription.planCode.toLowerCase() : undefined
if ((planCode != null ? planCode.indexOf('annual') : undefined) !== -1) {
planName = 'annual'
} else if (
(planCode != null ? planCode.indexOf('student') : undefined) !== -1
) {
planName = 'student'
} else if (
(planCode != null ? planCode.indexOf('collaborator') : undefined) !== -1
) {
planName = 'collaborator'
}
if (!hasSubscription) {
return res.redirect('/user/subscription/plans')
}
return res.render('subscriptions/upgradeToAnnual', {
title: 'Upgrade to annual',
planName
})
})
)
},
processUpgradeToAnnualPlan(req, res, next) {
@@ -433,7 +438,7 @@ module.exports = SubscriptionController = {
user,
annualPlanName,
coupon_code,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'error updating subscription', {
user_id: user._id
@@ -447,29 +452,32 @@ module.exports = SubscriptionController = {
extendTrial(req, res, next) {
const user = AuthenticationController.getSessionUser(req)
return LimitationsManager.userHasV2Subscription(user, function(
err,
hasSubscription,
subscription
) {
if (err != null) {
return next(err)
}
return SubscriptionHandler.extendTrial(subscription, 14, function(err) {
return LimitationsManager.userHasV2Subscription(
user,
function (err, hasSubscription, subscription) {
if (err != null) {
return res.sendStatus(500)
} else {
return res.sendStatus(200)
return next(err)
}
})
})
return SubscriptionHandler.extendTrial(
subscription,
14,
function (err) {
if (err != null) {
return res.sendStatus(500)
} else {
return res.sendStatus(200)
}
}
)
}
)
},
recurlyNotificationParser(req, res, next) {
let xml = ''
req.on('data', chunk => (xml += chunk))
return req.on('end', () =>
RecurlyWrapper._parseXml(xml, function(error, body) {
RecurlyWrapper._parseXml(xml, function (error, body) {
if (error != null) {
return next(error)
}
@@ -481,7 +489,7 @@ module.exports = SubscriptionController = {
refreshUserFeatures(req, res, next) {
const { user_id } = req.params
return FeaturesUpdater.refreshFeatures(user_id, function(error) {
return FeaturesUpdater.refreshFeatures(user_id, function (error) {
if (error != null) {
return next(error)
}

View File

@@ -30,7 +30,7 @@ module.exports = {
return SubscriptionGroupHandler.removeUserFromGroup(
subscription._id,
userToRemove_id,
function(err) {
function (err) {
if (err != null) {
OError.tag(err, 'error removing user from group', {
subscriptionId: subscription._id,
@@ -46,28 +46,28 @@ module.exports = {
removeSelfFromGroup(req, res, next) {
const subscriptionId = req.query.subscriptionId
const userToRemove_id = AuthenticationController.getLoggedInUserId(req)
return SubscriptionLocator.getSubscription(subscriptionId, function(
error,
subscription
) {
if (error != null) {
return next(error)
}
return SubscriptionGroupHandler.removeUserFromGroup(
subscription._id,
userToRemove_id,
function(err) {
if (err != null) {
logger.err(
{ err, userToRemove_id, subscriptionId },
'error removing self from group'
)
return res.sendStatus(500)
}
return res.sendStatus(200)
return SubscriptionLocator.getSubscription(
subscriptionId,
function (error, subscription) {
if (error != null) {
return next(error)
}
)
})
return SubscriptionGroupHandler.removeUserFromGroup(
subscription._id,
userToRemove_id,
function (err) {
if (err != null) {
logger.err(
{ err, userToRemove_id, subscriptionId },
'error removing self from group'
)
return res.sendStatus(500)
}
return res.sendStatus(200)
}
)
}
)
}
}

View File

@@ -41,7 +41,7 @@ const SubscriptionGroupHandler = {
return Subscription.updateOne(
{ admin_id: oldId },
{ admin_id: newId },
function(error) {
function (error) {
if (error != null) {
return callback(error)
}
@@ -51,7 +51,7 @@ const SubscriptionGroupHandler = {
'manager_ids',
oldId,
newId,
function(error) {
function (error) {
if (error != null) {
return callback(error)
}
@@ -71,12 +71,12 @@ const SubscriptionGroupHandler = {
isUserPartOfGroup(user_id, subscription_id, callback) {
if (callback == null) {
callback = function(err, partOfGroup) {}
callback = function (err, partOfGroup) {}
}
return SubscriptionLocator.getSubscriptionByMemberIdAndId(
user_id,
subscription_id,
function(err, subscription) {
function (err, subscription) {
let partOfGroup
if (subscription != null) {
partOfGroup = true
@@ -90,7 +90,7 @@ const SubscriptionGroupHandler = {
getTotalConfirmedUsersInGroup(subscription_id, callback) {
if (callback == null) {
callback = function(err, totalUsers) {}
callback = function (err, totalUsers) {}
}
return SubscriptionLocator.getSubscription(
subscription_id,
@@ -106,7 +106,7 @@ const SubscriptionGroupHandler = {
}
}
var replaceInArray = function(model, property, oldValue, newValue, callback) {
var replaceInArray = function (model, property, oldValue, newValue, callback) {
// Mongo won't let us pull and addToSet in the same query, so do it in
// two. Note we need to add first, since the query is based on the old user.
const query = {}
@@ -118,7 +118,7 @@ var replaceInArray = function(model, property, oldValue, newValue, callback) {
const setOldValue = {}
setOldValue[property] = oldValue
model.updateMany(query, { $addToSet: setNewValue }, function(error) {
model.updateMany(query, { $addToSet: setNewValue }, function (error) {
if (error) {
return callback(error)
}

View File

@@ -11,228 +11,227 @@ const Analytics = require('../Analytics/AnalyticsManager')
const SubscriptionHandler = {
validateNoSubscriptionInRecurly(userId, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
RecurlyWrapper.listAccountActiveSubscriptions(userId, function(
error,
subscriptions
) {
if (subscriptions == null) {
subscriptions = []
}
if (error != null) {
return callback(error)
}
if (subscriptions.length > 0) {
SubscriptionUpdater.syncSubscription(subscriptions[0], userId, function(
error
) {
if (error != null) {
return callback(error)
}
callback(null, false)
})
} else {
callback(null, true)
}
})
},
createSubscription(user, subscriptionDetails, recurlyTokenIds, callback) {
SubscriptionHandler.validateNoSubscriptionInRecurly(user._id, function(
error,
valid
) {
if (error != null) {
return callback(error)
}
if (!valid) {
return callback(new Error('user already has subscription in recurly'))
}
RecurlyWrapper.createSubscription(
user,
subscriptionDetails,
recurlyTokenIds,
function(error, recurlySubscription) {
if (error != null) {
return callback(error)
}
return SubscriptionUpdater.syncSubscription(
recurlySubscription,
user._id,
function(error) {
RecurlyWrapper.listAccountActiveSubscriptions(
userId,
function (error, subscriptions) {
if (subscriptions == null) {
subscriptions = []
}
if (error != null) {
return callback(error)
}
if (subscriptions.length > 0) {
SubscriptionUpdater.syncSubscription(
subscriptions[0],
userId,
function (error) {
if (error != null) {
return callback(error)
}
return callback()
callback(null, false)
}
)
} else {
callback(null, true)
}
)
})
}
)
},
createSubscription(user, subscriptionDetails, recurlyTokenIds, callback) {
SubscriptionHandler.validateNoSubscriptionInRecurly(
user._id,
function (error, valid) {
if (error != null) {
return callback(error)
}
if (!valid) {
return callback(new Error('user already has subscription in recurly'))
}
RecurlyWrapper.createSubscription(
user,
subscriptionDetails,
recurlyTokenIds,
function (error, recurlySubscription) {
if (error != null) {
return callback(error)
}
return SubscriptionUpdater.syncSubscription(
recurlySubscription,
user._id,
function (error) {
if (error != null) {
return callback(error)
}
return callback()
}
)
}
)
}
)
},
updateSubscription(user, planCode, couponCode, callback) {
LimitationsManager.userHasV2Subscription(user, function(
err,
hasSubscription,
subscription
) {
if (err) {
logger.warn(
{ err, user_id: user._id, hasSubscription },
'there was an error checking user v2 subscription'
)
}
if (!hasSubscription) {
return callback()
} else {
return async.series(
[
function(cb) {
if (couponCode == null) {
return cb()
}
RecurlyWrapper.getSubscription(
subscription.recurlySubscription_id,
{ includeAccount: true },
function(err, usersSubscription) {
if (err != null) {
return callback(err)
}
RecurlyWrapper.redeemCoupon(
usersSubscription.account.account_code,
couponCode,
cb
)
LimitationsManager.userHasV2Subscription(
user,
function (err, hasSubscription, subscription) {
if (err) {
logger.warn(
{ err, user_id: user._id, hasSubscription },
'there was an error checking user v2 subscription'
)
}
if (!hasSubscription) {
return callback()
} else {
return async.series(
[
function (cb) {
if (couponCode == null) {
return cb()
}
)
},
cb =>
RecurlyWrapper.updateSubscription(
subscription.recurlySubscription_id,
{ plan_code: planCode, timeframe: 'now' },
function(error, recurlySubscription) {
if (error != null) {
return callback(error)
RecurlyWrapper.getSubscription(
subscription.recurlySubscription_id,
{ includeAccount: true },
function (err, usersSubscription) {
if (err != null) {
return callback(err)
}
RecurlyWrapper.redeemCoupon(
usersSubscription.account.account_code,
couponCode,
cb
)
}
SubscriptionUpdater.syncSubscription(
recurlySubscription,
user._id,
cb
)
}
)
],
callback
)
)
},
cb =>
RecurlyWrapper.updateSubscription(
subscription.recurlySubscription_id,
{ plan_code: planCode, timeframe: 'now' },
function (error, recurlySubscription) {
if (error != null) {
return callback(error)
}
SubscriptionUpdater.syncSubscription(
recurlySubscription,
user._id,
cb
)
}
)
],
callback
)
}
}
})
)
},
cancelSubscription(user, callback) {
LimitationsManager.userHasV2Subscription(user, function(
err,
hasSubscription,
subscription
) {
if (err) {
logger.warn(
{ err, user_id: user._id, hasSubscription },
'there was an error checking user v2 subscription'
)
}
if (hasSubscription) {
RecurlyWrapper.cancelSubscription(
subscription.recurlySubscription_id,
function(error) {
if (error != null) {
return callback(error)
}
const emailOpts = {
to: user.email,
first_name: user.first_name
}
const ONE_HOUR_IN_MS = 1000 * 60 * 60
setTimeout(
() =>
EmailHandler.sendEmail(
'canceledSubscription',
emailOpts,
err => {
if (err != null) {
logger.warn(
{ err },
'failed to send confirmation email for subscription cancellation'
)
LimitationsManager.userHasV2Subscription(
user,
function (err, hasSubscription, subscription) {
if (err) {
logger.warn(
{ err, user_id: user._id, hasSubscription },
'there was an error checking user v2 subscription'
)
}
if (hasSubscription) {
RecurlyWrapper.cancelSubscription(
subscription.recurlySubscription_id,
function (error) {
if (error != null) {
return callback(error)
}
const emailOpts = {
to: user.email,
first_name: user.first_name
}
const ONE_HOUR_IN_MS = 1000 * 60 * 60
setTimeout(
() =>
EmailHandler.sendEmail(
'canceledSubscription',
emailOpts,
err => {
if (err != null) {
logger.warn(
{ err },
'failed to send confirmation email for subscription cancellation'
)
}
}
}
),
ONE_HOUR_IN_MS
)
Analytics.recordEvent(user._id, 'subscription-canceled')
callback()
}
)
} else {
callback()
),
ONE_HOUR_IN_MS
)
Analytics.recordEvent(user._id, 'subscription-canceled')
callback()
}
)
} else {
callback()
}
}
})
)
},
reactivateSubscription(user, callback) {
LimitationsManager.userHasV2Subscription(user, function(
err,
hasSubscription,
subscription
) {
if (err) {
logger.warn(
{ err, user_id: user._id, hasSubscription },
'there was an error checking user v2 subscription'
)
}
if (hasSubscription) {
RecurlyWrapper.reactivateSubscription(
subscription.recurlySubscription_id,
function(error) {
if (error != null) {
return callback(error)
}
EmailHandler.sendEmail(
'reactivatedSubscription',
{ to: user.email },
err => {
if (err != null) {
logger.warn(
{ err },
'failed to send reactivation confirmation email'
)
}
LimitationsManager.userHasV2Subscription(
user,
function (err, hasSubscription, subscription) {
if (err) {
logger.warn(
{ err, user_id: user._id, hasSubscription },
'there was an error checking user v2 subscription'
)
}
if (hasSubscription) {
RecurlyWrapper.reactivateSubscription(
subscription.recurlySubscription_id,
function (error) {
if (error != null) {
return callback(error)
}
)
Analytics.recordEvent(user._id, 'subscription-reactivated')
callback()
}
)
} else {
callback()
EmailHandler.sendEmail(
'reactivatedSubscription',
{ to: user.email },
err => {
if (err != null) {
logger.warn(
{ err },
'failed to send reactivation confirmation email'
)
}
}
)
Analytics.recordEvent(user._id, 'subscription-reactivated')
callback()
}
)
} else {
callback()
}
}
})
)
},
syncSubscription(recurlySubscription, requesterData, callback) {
RecurlyWrapper.getSubscription(
recurlySubscription.uuid,
{ includeAccount: true },
function(error, recurlySubscription) {
function (error, recurlySubscription) {
if (error != null) {
return callback(error)
}
User.findById(
recurlySubscription.account.account_code,
{ _id: 1 },
function(error, user) {
function (error, user) {
if (error != null) {
return callback(error)
}

View File

@@ -21,20 +21,20 @@ require('./GroupPlansData') // make sure dynamic group plans are loaded
const SubscriptionLocator = {
getUsersSubscription(user_or_id, callback) {
const user_id = SubscriptionLocator._getUserId(user_or_id)
return Subscription.findOne({ admin_id: user_id }, function(
err,
subscription
) {
logger.log({ user_id }, 'got users subscription')
return callback(err, subscription)
})
return Subscription.findOne(
{ admin_id: user_id },
function (err, subscription) {
logger.log({ user_id }, 'got users subscription')
return callback(err, subscription)
}
)
},
getUserIndividualSubscription(user_or_id, callback) {
const user_id = SubscriptionLocator._getUserId(user_or_id)
return Subscription.findOne(
{ admin_id: user_id, groupPlan: false },
function(err, subscription) {
function (err, subscription) {
logger.log({ user_id }, 'got users individual subscription')
return callback(err, subscription)
}
@@ -43,7 +43,7 @@ const SubscriptionLocator = {
getManagedGroupSubscriptions(user_or_id, callback) {
if (callback == null) {
callback = function(error, managedSubscriptions) {}
callback = function (error, managedSubscriptions) {}
}
const user_id = SubscriptionLocator._getUserId(user_or_id)
return Subscription.find({

View File

@@ -45,37 +45,37 @@ const SubscriptionUpdater = {
callback = requesterData
requesterData = {}
}
SubscriptionLocator.getUsersSubscription(adminUserId, function(
err,
subscription
) {
if (err != null) {
return callback(err)
}
if (subscription != null) {
SubscriptionUpdater._updateSubscriptionFromRecurly(
recurlySubscription,
subscription,
requesterData,
callback
)
} else {
SubscriptionUpdater._createNewSubscription(adminUserId, function(
err,
subscription
) {
if (err != null) {
return callback(err)
}
SubscriptionLocator.getUsersSubscription(
adminUserId,
function (err, subscription) {
if (err != null) {
return callback(err)
}
if (subscription != null) {
SubscriptionUpdater._updateSubscriptionFromRecurly(
recurlySubscription,
subscription,
requesterData,
callback
)
})
} else {
SubscriptionUpdater._createNewSubscription(
adminUserId,
function (err, subscription) {
if (err != null) {
return callback(err)
}
SubscriptionUpdater._updateSubscriptionFromRecurly(
recurlySubscription,
subscription,
requesterData,
callback
)
}
)
}
}
})
)
},
addUserToGroup(subscriptionId, userId, callback) {
@@ -86,7 +86,7 @@ const SubscriptionUpdater = {
SubscriptionUpdater.addUsersToGroupWithoutFeaturesRefresh(
subscriptionId,
memberIds,
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
@@ -104,7 +104,7 @@ const SubscriptionUpdater = {
removeUserFromGroups(filter, userId, callback) {
const removeOperation = { $pull: { member_ids: userId } }
Subscription.updateMany(filter, removeOperation, function(err) {
Subscription.updateMany(filter, removeOperation, function (err) {
if (err != null) {
OError.tag(err, 'error removing user from groups', {
filter,
@@ -112,7 +112,7 @@ const SubscriptionUpdater = {
})
return callback(err)
}
UserGetter.getUser(userId, function(error, user) {
UserGetter.getUser(userId, function (error, user) {
if (error) {
return callback(error)
}
@@ -130,23 +130,23 @@ const SubscriptionUpdater = {
},
removeUserFromAllGroups(userId, callback) {
SubscriptionLocator.getMemberSubscriptions(userId, function(
error,
subscriptions
) {
if (error) {
return callback(error)
SubscriptionLocator.getMemberSubscriptions(
userId,
function (error, subscriptions) {
if (error) {
return callback(error)
}
if (!subscriptions) {
return callback()
}
const subscriptionIds = subscriptions.map(sub => sub._id)
SubscriptionUpdater.removeUserFromGroups(
{ _id: subscriptionIds },
userId,
callback
)
}
if (!subscriptions) {
return callback()
}
const subscriptionIds = subscriptions.map(sub => sub._id)
SubscriptionUpdater.removeUserFromGroups(
{ _id: subscriptionIds },
userId,
callback
)
})
)
},
deleteWithV1Id(v1TeamId, callback) {
@@ -155,7 +155,7 @@ const SubscriptionUpdater = {
deleteSubscription(subscription, deleterData, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
async.series(
[
@@ -178,38 +178,38 @@ const SubscriptionUpdater = {
},
restoreSubscription(subscriptionId, callback) {
SubscriptionLocator.getDeletedSubscription(subscriptionId, function(
err,
deletedSubscription
) {
if (err) {
return callback(err)
SubscriptionLocator.getDeletedSubscription(
subscriptionId,
function (err, deletedSubscription) {
if (err) {
return callback(err)
}
let subscription = deletedSubscription.subscription
async.series(
[
cb =>
// 1. upsert subscription
db.subscriptions.updateOne(
{ _id: subscription._id },
subscription,
{ upsert: true },
cb
),
cb =>
// 2. refresh users features. Do this before removing the
// subscription so the restore can be retried if this fails
SubscriptionUpdater._refreshUsersFeatures(subscription, cb),
cb =>
// 3. remove deleted subscription
DeletedSubscription.deleteOne(
{ 'subscription._id': subscription._id },
callback
)
],
callback
)
}
let subscription = deletedSubscription.subscription
async.series(
[
cb =>
// 1. upsert subscription
db.subscriptions.updateOne(
{ _id: subscription._id },
subscription,
{ upsert: true },
cb
),
cb =>
// 2. refresh users features. Do this before removing the
// subscription so the restore can be retried if this fails
SubscriptionUpdater._refreshUsersFeatures(subscription, cb),
cb =>
// 3. remove deleted subscription
DeletedSubscription.deleteOne(
{ 'subscription._id': subscription._id },
callback
)
],
callback
)
})
)
},
_refreshUsersFeatures(subscription, callback) {
@@ -284,7 +284,7 @@ const SubscriptionUpdater = {
})
}
}
subscription.save(function(error) {
subscription.save(function (error) {
if (error) {
return callback(error)
}

View File

@@ -37,7 +37,7 @@ module.exports = {
teamManagerId,
subscription,
email,
function(err, inviteUserData) {
function (err, inviteUserData) {
if (err != null) {
if (err.alreadyInTeam) {
return res.status(400).json({
@@ -66,58 +66,58 @@ module.exports = {
const { token } = req.params
const userId = AuthenticationController.getLoggedInUserId(req)
return TeamInvitesHandler.getInvite(token, function(
err,
invite,
teamSubscription
) {
if (err != null) {
return next(err)
}
if (!invite) {
return ErrorController.notFound(req, res, next)
}
return SubscriptionLocator.getUsersSubscription(userId, function(
err,
personalSubscription
) {
return TeamInvitesHandler.getInvite(
token,
function (err, invite, teamSubscription) {
if (err != null) {
return next(err)
}
const hasIndividualRecurlySubscription =
personalSubscription != null &&
personalSubscription.planCode.match(/(free|trial)/) == null &&
personalSubscription.groupPlan === false &&
personalSubscription.recurlySubscription_id != null &&
personalSubscription.recurlySubscription_id !== ''
if (!invite) {
return ErrorController.notFound(req, res, next)
}
return res.render('subscriptions/team/invite', {
inviterName: invite.inviterName,
inviteToken: invite.token,
hasIndividualRecurlySubscription,
appName: settings.appName,
expired: req.query.expired
})
})
})
return SubscriptionLocator.getUsersSubscription(
userId,
function (err, personalSubscription) {
if (err != null) {
return next(err)
}
const hasIndividualRecurlySubscription =
personalSubscription != null &&
personalSubscription.planCode.match(/(free|trial)/) == null &&
personalSubscription.groupPlan === false &&
personalSubscription.recurlySubscription_id != null &&
personalSubscription.recurlySubscription_id !== ''
return res.render('subscriptions/team/invite', {
inviterName: invite.inviterName,
inviteToken: invite.token,
hasIndividualRecurlySubscription,
appName: settings.appName,
expired: req.query.expired
})
}
)
}
)
},
acceptInvite(req, res, next) {
const { token } = req.params
const userId = AuthenticationController.getLoggedInUserId(req)
return TeamInvitesHandler.acceptInvite(token, userId, function(
err,
results
) {
if (err != null) {
return next(err)
return TeamInvitesHandler.acceptInvite(
token,
userId,
function (err, results) {
if (err != null) {
return next(err)
}
return res.sendStatus(204)
}
return res.sendStatus(204)
})
)
},
revokeInvite(req, res) {
@@ -132,7 +132,7 @@ module.exports = {
teamManagerId,
subscription,
email,
function(err, results) {
function (err, results) {
if (err != null) {
return next(err)
}

View File

@@ -20,20 +20,20 @@ const Errors = require('../Errors/Errors')
module.exports = TeamInvitesHandler = {
getInvite(token, callback) {
return Subscription.findOne({ 'teamInvites.token': token }, function(
err,
subscription
) {
if (err) {
return callback(err)
}
if (!subscription) {
return callback(new Errors.NotFoundError('team not found'))
}
return Subscription.findOne(
{ 'teamInvites.token': token },
function (err, subscription) {
if (err) {
return callback(err)
}
if (!subscription) {
return callback(new Errors.NotFoundError('team not found'))
}
const invite = subscription.teamInvites.find(i => i.token === token)
callback(null, invite, subscription)
})
const invite = subscription.teamInvites.find(i => i.token === token)
callback(null, invite, subscription)
}
)
},
createInvite(teamManagerId, subscription, email, callback) {
@@ -41,12 +41,12 @@ module.exports = TeamInvitesHandler = {
if (!email) {
return callback(new Error('invalid email'))
}
return UserGetter.getUser(teamManagerId, function(error, teamManager) {
return UserGetter.getUser(teamManagerId, function (error, teamManager) {
if (error) {
return callback(error)
}
removeLegacyInvite(subscription.id, email, function(error) {
removeLegacyInvite(subscription.id, email, function (error) {
if (error) {
return callback(error)
}
@@ -56,31 +56,31 @@ module.exports = TeamInvitesHandler = {
},
importInvite(subscription, inviterName, email, token, sentAt, callback) {
checkIfInviteIsPossible(subscription, email, function(
error,
possible,
reason
) {
if (error) {
return callback(error)
}
if (!possible) {
return callback(reason)
}
checkIfInviteIsPossible(
subscription,
email,
function (error, possible, reason) {
if (error) {
return callback(error)
}
if (!possible) {
return callback(reason)
}
subscription.teamInvites.push({
email,
inviterName,
token,
sentAt
})
subscription.teamInvites.push({
email,
inviterName,
token,
sentAt
})
subscription.save(callback)
})
subscription.save(callback)
}
)
},
acceptInvite(token, userId, callback) {
TeamInvitesHandler.getInvite(token, function(err, invite, subscription) {
TeamInvitesHandler.getInvite(token, function (err, invite, subscription) {
if (err) {
return callback(err)
}
@@ -88,15 +88,17 @@ module.exports = TeamInvitesHandler = {
return callback(new Errors.NotFoundError('invite not found'))
}
SubscriptionUpdater.addUserToGroup(subscription._id, userId, function(
err
) {
if (err) {
return callback(err)
}
SubscriptionUpdater.addUserToGroup(
subscription._id,
userId,
function (err) {
if (err) {
return callback(err)
}
removeInviteFromTeam(subscription.id, invite.email, callback)
})
removeInviteFromTeam(subscription.id, invite.email, callback)
}
)
})
},
@@ -112,7 +114,7 @@ module.exports = TeamInvitesHandler = {
// email is in Subscription.invited_emails when they join. We'll remove this
// after a short while.
createTeamInvitesForLegacyInvitedEmail(email, callback) {
SubscriptionLocator.getGroupsWithEmailInvite(email, function(err, teams) {
SubscriptionLocator.getGroupsWithEmailInvite(email, function (err, teams) {
if (err) {
return callback(err)
}
@@ -127,81 +129,83 @@ module.exports = TeamInvitesHandler = {
}
}
var createInvite = function(subscription, email, inviter, callback) {
checkIfInviteIsPossible(subscription, email, function(
error,
possible,
reason
) {
if (error) {
return callback(error)
}
if (!possible) {
return callback(reason)
}
// don't send invites when inviting self; add user directly to the group
const isInvitingSelf = inviter.emails.some(
emailData => emailData.email === email
)
if (isInvitingSelf) {
return SubscriptionUpdater.addUserToGroup(
subscription._id,
inviter._id,
err => {
if (err) {
return callback(err)
}
// legacy: remove any invite that might have been created in the past
removeInviteFromTeam(subscription._id, email, error => {
const inviteUserData = {
email: inviter.email,
first_name: inviter.first_name,
last_name: inviter.last_name,
invite: false
}
callback(error, inviteUserData)
})
}
)
}
const inviterName = getInviterName(inviter)
let invite = subscription.teamInvites.find(invite => invite.email === email)
if (invite) {
invite.sentAt = new Date()
} else {
invite = {
email,
inviterName,
token: crypto.randomBytes(32).toString('hex'),
sentAt: new Date()
}
subscription.teamInvites.push(invite)
}
subscription.save(function(error) {
var createInvite = function (subscription, email, inviter, callback) {
checkIfInviteIsPossible(
subscription,
email,
function (error, possible, reason) {
if (error) {
return callback(error)
}
const opts = {
to: email,
inviter,
acceptInviteUrl: `${settings.siteUrl}/subscription/invites/${invite.token}/`,
appName: settings.appName
if (!possible) {
return callback(reason)
}
EmailHandler.sendEmail('verifyEmailToJoinTeam', opts, error => {
Object.assign(invite, { invite: true })
callback(error, invite)
// don't send invites when inviting self; add user directly to the group
const isInvitingSelf = inviter.emails.some(
emailData => emailData.email === email
)
if (isInvitingSelf) {
return SubscriptionUpdater.addUserToGroup(
subscription._id,
inviter._id,
err => {
if (err) {
return callback(err)
}
// legacy: remove any invite that might have been created in the past
removeInviteFromTeam(subscription._id, email, error => {
const inviteUserData = {
email: inviter.email,
first_name: inviter.first_name,
last_name: inviter.last_name,
invite: false
}
callback(error, inviteUserData)
})
}
)
}
const inviterName = getInviterName(inviter)
let invite = subscription.teamInvites.find(
invite => invite.email === email
)
if (invite) {
invite.sentAt = new Date()
} else {
invite = {
email,
inviterName,
token: crypto.randomBytes(32).toString('hex'),
sentAt: new Date()
}
subscription.teamInvites.push(invite)
}
subscription.save(function (error) {
if (error) {
return callback(error)
}
const opts = {
to: email,
inviter,
acceptInviteUrl: `${settings.siteUrl}/subscription/invites/${invite.token}/`,
appName: settings.appName
}
EmailHandler.sendEmail('verifyEmailToJoinTeam', opts, error => {
Object.assign(invite, { invite: true })
callback(error, invite)
})
})
})
})
}
)
}
var removeInviteFromTeam = function(subscriptionId, email, callback) {
var removeInviteFromTeam = function (subscriptionId, email, callback) {
const searchConditions = { _id: new ObjectId(subscriptionId.toString()) }
const removeInvite = { $pull: { teamInvites: { email } } }
@@ -227,7 +231,7 @@ var removeLegacyInvite = (subscriptionId, email, callback) =>
callback
)
var checkIfInviteIsPossible = function(subscription, email, callback) {
var checkIfInviteIsPossible = function (subscription, email, callback) {
if (!subscription.groupPlan) {
logger.log(
{ subscriptionId: subscription.id },
@@ -244,7 +248,7 @@ var checkIfInviteIsPossible = function(subscription, email, callback) {
return callback(null, false, { limitReached: true })
}
UserGetter.getUserByAnyEmail(email, function(error, existingUser) {
UserGetter.getUserByAnyEmail(email, function (error, existingUser) {
if (error) {
return callback(error)
}
@@ -268,7 +272,7 @@ var checkIfInviteIsPossible = function(subscription, email, callback) {
})
}
var getInviterName = function(inviter) {
var getInviterName = function (inviter) {
let inviterName
if (inviter.first_name && inviter.last_name) {
inviterName = `${inviter.first_name} ${inviter.last_name} (${inviter.email})`

View File

@@ -26,7 +26,7 @@ module.exports = V1SubscriptionManager = {
// - 'v1_free'
getPlanCodeFromV1(userId, callback) {
if (callback == null) {
callback = function(err, planCode, v1Id) {}
callback = function (err, planCode, v1Id) {}
}
return V1SubscriptionManager._v1Request(
userId,
@@ -36,7 +36,7 @@ module.exports = V1SubscriptionManager = {
return `/api/v1/sharelatex/users/${v1Id}/plan_code`
}
},
function(error, body, v1Id) {
function (error, body, v1Id) {
if (error != null) {
return callback(error)
}
@@ -54,7 +54,7 @@ module.exports = V1SubscriptionManager = {
getSubscriptionsFromV1(userId, callback) {
if (callback == null) {
callback = function(err, subscriptions, v1Id) {}
callback = function (err, subscriptions, v1Id) {}
}
return V1SubscriptionManager._v1Request(
userId,
@@ -70,7 +70,7 @@ module.exports = V1SubscriptionManager = {
getSubscriptionStatusFromV1(userId, callback) {
if (callback == null) {
callback = function(err, status) {}
callback = function (err, status) {}
}
return V1SubscriptionManager._v1Request(
userId,
@@ -86,7 +86,7 @@ module.exports = V1SubscriptionManager = {
cancelV1Subscription(userId, callback) {
if (callback == null) {
callback = function(err) {}
callback = function (err) {}
}
return V1SubscriptionManager._v1Request(
userId,
@@ -102,22 +102,23 @@ module.exports = V1SubscriptionManager = {
v1IdForUser(userId, callback) {
if (callback == null) {
callback = function(err, v1Id) {}
callback = function (err, v1Id) {}
}
return UserGetter.getUser(userId, { 'overleaf.id': 1 }, function(
err,
user
) {
if (err != null) {
return callback(err)
}
const v1Id = __guard__(
user != null ? user.overleaf : undefined,
x => x.id
)
return UserGetter.getUser(
userId,
{ 'overleaf.id': 1 },
function (err, user) {
if (err != null) {
return callback(err)
}
const v1Id = __guard__(
user != null ? user.overleaf : undefined,
x => x.id
)
return callback(null, v1Id)
})
return callback(null, v1Id)
}
)
},
// v1 accounts created before migration to v2 had github and mendeley for free
@@ -140,13 +141,13 @@ module.exports = V1SubscriptionManager = {
_v1Request(userId, options, callback) {
if (callback == null) {
callback = function(err, body, v1Id) {}
callback = function (err, body, v1Id) {}
}
if (!settings.apis.v1.url) {
return callback(null, null)
}
return V1SubscriptionManager.v1IdForUser(userId, function(err, v1Id) {
return V1SubscriptionManager.v1IdForUser(userId, function (err, v1Id) {
if (err != null) {
return callback(err)
}
@@ -167,7 +168,7 @@ module.exports = V1SubscriptionManager = {
json: true,
timeout: 15 * 1000
},
function(error, response, body) {
function (error, response, body) {
if (error != null) {
return callback(
new V1ConnectionError({

View File

@@ -15,28 +15,28 @@ const { SystemMessage } = require('../../models/SystemMessage')
module.exports = SystemMessageManager = {
getMessages(callback) {
if (callback == null) {
callback = function(error, messages) {}
callback = function (error, messages) {}
}
callback(null, this._cachedMessages)
},
getMessagesFromDB(callback) {
if (callback == null) {
callback = function(error, messages) {}
callback = function (error, messages) {}
}
return SystemMessage.find({}, callback)
},
clearMessages(callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return SystemMessage.deleteMany({}, callback)
},
createMessage(content, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
const message = new SystemMessage({ content })
return message.save(callback)

View File

@@ -7,7 +7,7 @@ const TagsController = {
if (!userId) {
return next(new Errors.NotFoundError())
}
TagsHandler.getAllTags(userId, function(error, allTags) {
TagsHandler.getAllTags(userId, function (error, allTags) {
if (error != null) {
return next(error)
}
@@ -28,7 +28,7 @@ const TagsController = {
createTag(req, res, next) {
const userId = AuthenticationController.getLoggedInUserId(req)
const { name } = req.body
TagsHandler.createTag(userId, name, function(error, tag) {
TagsHandler.createTag(userId, name, function (error, tag) {
if (error != null) {
return next(error)
}
@@ -39,7 +39,7 @@ const TagsController = {
addProjectToTag(req, res, next) {
const userId = AuthenticationController.getLoggedInUserId(req)
const { tagId, projectId } = req.params
TagsHandler.addProjectToTag(userId, tagId, projectId, function(error) {
TagsHandler.addProjectToTag(userId, tagId, projectId, function (error) {
if (error) {
return next(error)
}
@@ -50,18 +50,23 @@ const TagsController = {
removeProjectFromTag(req, res, next) {
const userId = AuthenticationController.getLoggedInUserId(req)
const { tagId, projectId } = req.params
TagsHandler.removeProjectFromTag(userId, tagId, projectId, function(error) {
if (error) {
return next(error)
TagsHandler.removeProjectFromTag(
userId,
tagId,
projectId,
function (error) {
if (error) {
return next(error)
}
res.status(204).end()
}
res.status(204).end()
})
)
},
deleteTag(req, res, next) {
const userId = AuthenticationController.getLoggedInUserId(req)
const { tagId } = req.params
TagsHandler.deleteTag(userId, tagId, function(error) {
TagsHandler.deleteTag(userId, tagId, function (error) {
if (error) {
return next(error)
}
@@ -76,7 +81,7 @@ const TagsController = {
if (!name) {
return res.status(400).end()
}
TagsHandler.renameTag(userId, tagId, name, function(error) {
TagsHandler.renameTag(userId, tagId, name, function (error) {
if (error) {
return next(error)
}

View File

@@ -7,9 +7,9 @@ function getAllTags(userId, callback) {
function createTag(userId, name, callback) {
if (!callback) {
callback = function() {}
callback = function () {}
}
Tag.create({ user_id: userId, name }, function(err, tag) {
Tag.create({ user_id: userId, name }, function (err, tag) {
// on duplicate key error return existing tag
if (err && err.code === 11000) {
return Tag.findOne({ user_id: userId, name }, callback)
@@ -20,7 +20,7 @@ function createTag(userId, name, callback) {
function renameTag(userId, tagId, name, callback) {
if (!callback) {
callback = function() {}
callback = function () {}
}
Tag.updateOne(
{
@@ -38,7 +38,7 @@ function renameTag(userId, tagId, name, callback) {
function deleteTag(userId, tagId, callback) {
if (!callback) {
callback = function() {}
callback = function () {}
}
Tag.deleteOne(
{
@@ -52,7 +52,7 @@ function deleteTag(userId, tagId, callback) {
// TODO: unused?
function updateTagUserIds(oldUserId, newUserId, callback) {
if (!callback) {
callback = function() {}
callback = function () {}
}
const searchOps = { user_id: oldUserId }
const updateOperation = { $set: { user_id: newUserId } }
@@ -61,7 +61,7 @@ function updateTagUserIds(oldUserId, newUserId, callback) {
function removeProjectFromTag(userId, tagId, projectId, callback) {
if (!callback) {
callback = function() {}
callback = function () {}
}
const searchOps = {
_id: tagId,
@@ -73,7 +73,7 @@ function removeProjectFromTag(userId, tagId, projectId, callback) {
function addProjectToTag(userId, tagId, projectId, callback) {
if (!callback) {
callback = function() {}
callback = function () {}
}
const searchOps = {
_id: tagId,
@@ -85,7 +85,7 @@ function addProjectToTag(userId, tagId, projectId, callback) {
function addProjectToTagName(userId, name, projectId, callback) {
if (!callback) {
callback = function() {}
callback = function () {}
}
const searchOps = {
name,

View File

@@ -57,7 +57,7 @@ module.exports = TemplatesController = {
req.body.templateVersionId,
user_id,
req.body.imageName,
function(err, project) {
function (err, project) {
if (err != null) {
return next(err)
}

View File

@@ -49,11 +49,11 @@ const TemplatesManager = {
},
timeout: 60 * 1000
})
zipReq.on('error', function(err) {
zipReq.on('error', function (err) {
logger.warn({ err }, 'error getting zip from template API')
return callback(err)
})
return FileWriter.ensureDumpFolderExists(function(err) {
return FileWriter.ensureDumpFolderExists(function (err) {
if (err != null) {
return callback(err)
}
@@ -65,7 +65,7 @@ const TemplatesManager = {
fromV1TemplateId: templateId,
fromV1TemplateVersionId: templateVersionId
}
writeStream.on('close', function() {
writeStream.on('close', function () {
if (zipReq.response.statusCode !== 200) {
logger.warn(
{ uri: zipUrl, statusCode: zipReq.response.statusCode },
@@ -78,7 +78,7 @@ const TemplatesManager = {
projectName,
dumpPath,
attributes,
function(err, project) {
function (err, project) {
if (err != null) {
OError.tag(err, 'problem building project from zip', {
zipReq
@@ -97,11 +97,11 @@ const TemplatesManager = {
cb
)
],
function(err) {
function (err) {
if (err != null) {
return callback(err)
}
fs.unlink(dumpPath, function(err) {
fs.unlink(dumpPath, function (err) {
if (err != null) {
return logger.err({ err }, 'error unlinking template zip')
}
@@ -114,7 +114,7 @@ const TemplatesManager = {
{ _id: project._id },
update,
{},
function(err) {
function (err) {
if (err != null) {
return callback(err)
}

View File

@@ -119,7 +119,7 @@ module.exports = {
}
},
parseParams: (parseParams = function(req) {
parseParams: (parseParams = function (req) {
let filePath, projectName
let path = req.params[0]
const userId = req.params.user_id

View File

@@ -25,166 +25,173 @@ const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
module.exports = UpdateMerger = {
mergeUpdate(user_id, project_id, path, updateRequest, source, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return FileWriter.writeStreamToDisk(project_id, updateRequest, function(
err,
fsPath
) {
if (err != null) {
return callback(err)
return FileWriter.writeStreamToDisk(
project_id,
updateRequest,
function (err, fsPath) {
if (err != null) {
return callback(err)
}
return UpdateMerger._mergeUpdate(
user_id,
project_id,
path,
fsPath,
source,
mergeErr =>
fs.unlink(fsPath, function (deleteErr) {
if (deleteErr != null) {
logger.err({ project_id, fsPath }, 'error deleting file')
}
return callback(mergeErr)
})
)
}
return UpdateMerger._mergeUpdate(
user_id,
project_id,
path,
fsPath,
source,
mergeErr =>
fs.unlink(fsPath, function(deleteErr) {
if (deleteErr != null) {
logger.err({ project_id, fsPath }, 'error deleting file')
}
return callback(mergeErr)
})
)
})
)
},
_findExistingFileType(project_id, path, callback) {
ProjectEntityHandler.getAllEntities(project_id, function(err, docs, files) {
if (err != null) {
return callback(err)
ProjectEntityHandler.getAllEntities(
project_id,
function (err, docs, files) {
if (err != null) {
return callback(err)
}
var existingFileType = null
if (_.some(files, f => f.path === path)) {
existingFileType = 'file'
}
if (_.some(docs, d => d.path === path)) {
existingFileType = 'doc'
}
callback(null, existingFileType)
}
var existingFileType = null
if (_.some(files, f => f.path === path)) {
existingFileType = 'file'
}
if (_.some(docs, d => d.path === path)) {
existingFileType = 'doc'
}
callback(null, existingFileType)
})
)
},
_determineFileType(project_id, path, fsPath, callback) {
if (callback == null) {
callback = function(err, fileType) {}
callback = function (err, fileType) {}
}
// check if there is an existing file with the same path (we either need
// to overwrite it or delete it)
UpdateMerger._findExistingFileType(project_id, path, function(
err,
existingFileType
) {
if (err) {
return callback(err)
}
// determine whether the update should create a doc or binary file
FileTypeManager.getType(path, fsPath, function(
err,
{ binary, encoding }
) {
if (err != null) {
UpdateMerger._findExistingFileType(
project_id,
path,
function (err, existingFileType) {
if (err) {
return callback(err)
}
// determine whether the update should create a doc or binary file
FileTypeManager.getType(
path,
fsPath,
function (err, { binary, encoding }) {
if (err != null) {
return callback(err)
}
// If we receive a non-utf8 encoding, we won't be able to keep things in
// sync, so we'll treat non-utf8 files as binary
const isBinary = binary || encoding !== 'utf-8'
// If we receive a non-utf8 encoding, we won't be able to keep things in
// sync, so we'll treat non-utf8 files as binary
const isBinary = binary || encoding !== 'utf-8'
// Existing | Update | Action
// ---------|-----------|-------
// file | isBinary | existing-file
// file | !isBinary | existing-file
// doc | isBinary | new-file, delete-existing-doc
// doc | !isBinary | existing-doc
// null | isBinary | new-file
// null | !isBinary | new-doc
// Existing | Update | Action
// ---------|-----------|-------
// file | isBinary | existing-file
// file | !isBinary | existing-file
// doc | isBinary | new-file, delete-existing-doc
// doc | !isBinary | existing-doc
// null | isBinary | new-file
// null | !isBinary | new-doc
// if a binary file already exists, always keep it as a binary file
// even if the update looks like a text file
if (existingFileType === 'file') {
return callback(null, 'existing-file')
}
// if a binary file already exists, always keep it as a binary file
// even if the update looks like a text file
if (existingFileType === 'file') {
return callback(null, 'existing-file')
}
// if there is an existing doc, keep it as a doc except when the
// incoming update is binary. In that case delete the doc and replace
// it with a new file.
if (existingFileType === 'doc') {
if (isBinary) {
return callback(null, 'new-file', 'delete-existing-doc')
} else {
return callback(null, 'existing-doc')
// if there is an existing doc, keep it as a doc except when the
// incoming update is binary. In that case delete the doc and replace
// it with a new file.
if (existingFileType === 'doc') {
if (isBinary) {
return callback(null, 'new-file', 'delete-existing-doc')
} else {
return callback(null, 'existing-doc')
}
}
// if there no existing file, create a file or doc as needed
return callback(null, isBinary ? 'new-file' : 'new-doc')
}
}
// if there no existing file, create a file or doc as needed
return callback(null, isBinary ? 'new-file' : 'new-doc')
})
})
)
}
)
},
_mergeUpdate(user_id, project_id, path, fsPath, source, callback) {
if (callback == null) {
callback = function(error) {}
callback = function (error) {}
}
return UpdateMerger._determineFileType(project_id, path, fsPath, function(
err,
fileType,
deleteOriginalEntity
) {
if (err != null) {
return callback(err)
return UpdateMerger._determineFileType(
project_id,
path,
fsPath,
function (err, fileType, deleteOriginalEntity) {
if (err != null) {
return callback(err)
}
async.series(
[
function (cb) {
if (deleteOriginalEntity) {
// currently we only delete docs
UpdateMerger.deleteUpdate(user_id, project_id, path, source, cb)
} else {
cb()
}
},
function (cb) {
if (['existing-file', 'new-file'].includes(fileType)) {
return UpdateMerger.p.processFile(
project_id,
fsPath,
path,
source,
user_id,
cb
)
} else if (['existing-doc', 'new-doc'].includes(fileType)) {
return UpdateMerger.p.processDoc(
project_id,
user_id,
fsPath,
path,
source,
cb
)
} else {
return cb(new Error('unrecognized file'))
}
}
],
callback
)
}
async.series(
[
function(cb) {
if (deleteOriginalEntity) {
// currently we only delete docs
UpdateMerger.deleteUpdate(user_id, project_id, path, source, cb)
} else {
cb()
}
},
function(cb) {
if (['existing-file', 'new-file'].includes(fileType)) {
return UpdateMerger.p.processFile(
project_id,
fsPath,
path,
source,
user_id,
cb
)
} else if (['existing-doc', 'new-doc'].includes(fileType)) {
return UpdateMerger.p.processDoc(
project_id,
user_id,
fsPath,
path,
source,
cb
)
} else {
return cb(new Error('unrecognized file'))
}
}
],
callback
)
})
)
},
deleteUpdate(user_id, project_id, path, source, callback) {
if (callback == null) {
callback = function() {}
callback = function () {}
}
return EditorController.deleteEntityWithPath(
project_id,
path,
source,
user_id,
function() {
function () {
return callback()
}
)
@@ -192,32 +199,32 @@ module.exports = UpdateMerger = {
p: {
processDoc(project_id, user_id, fsPath, path, source, callback) {
return UpdateMerger.p.readFileIntoTextArray(fsPath, function(
err,
docLines
) {
if (err != null) {
OError.tag(
err,
'error reading file into text array for process doc update',
{
project_id
}
)
return callback(err)
}
logger.log({ docLines }, 'processing doc update from tpds')
return EditorController.upsertDocWithPath(
project_id,
path,
docLines,
source,
user_id,
function(err) {
return UpdateMerger.p.readFileIntoTextArray(
fsPath,
function (err, docLines) {
if (err != null) {
OError.tag(
err,
'error reading file into text array for process doc update',
{
project_id
}
)
return callback(err)
}
)
})
logger.log({ docLines }, 'processing doc update from tpds')
return EditorController.upsertDocWithPath(
project_id,
path,
docLines,
source,
user_id,
function (err) {
return callback(err)
}
)
}
)
},
processFile(project_id, fsPath, path, source, user_id, callback) {
@@ -228,14 +235,14 @@ module.exports = UpdateMerger = {
null,
source,
user_id,
function(err) {
function (err) {
return callback(err)
}
)
},
readFileIntoTextArray(path, callback) {
return fs.readFile(path, 'utf8', function(error, content) {
return fs.readFile(path, 'utf8', function (error, content) {
if (content == null) {
content = ''
}

View File

@@ -121,7 +121,7 @@ const TokenAccessHandler = {
{
'tokens.readAndWritePrefix': numerics
},
function(err, project) {
function (err, project) {
if (err != null) {
return callback(err)
}
@@ -263,7 +263,7 @@ const TokenAccessHandler = {
}
V1Api.request(
{ url: `/api/v1/sharelatex/docs/${token}/is_published` },
function(err, response, body) {
function (err, response, body) {
if (err != null) {
return callback(err)
}
@@ -279,7 +279,7 @@ const TokenAccessHandler = {
exported: false
})
}
UserGetter.getUser(v2UserId, { overleaf: 1 }, function(err, user) {
UserGetter.getUser(v2UserId, { overleaf: 1 }, function (err, user) {
if (err != null) {
return callback(err)
}
@@ -289,7 +289,7 @@ const TokenAccessHandler = {
}
V1Api.request(
{ url: `/api/v1/sharelatex/users/${v1UserId}/docs/${token}/info` },
function(err, response, body) {
function (err, response, body) {
if (err != null) {
return callback(err)
}

Some files were not shown because too many files have changed in this diff Show More