mirror of
https://github.com/overleaf/overleaf.git
synced 2024-09-16 02:52:31 -04:00
Merge pull request #3942 from overleaf/prettier-trailing-comma
Set Prettier's "trailingComma" setting to "es5" GitOrigin-RevId: 9f14150511929a855b27467ad17be6ab262fe5d5
This commit is contained in:
parent
15011a9982
commit
1be43911b4
877 changed files with 20093 additions and 20064 deletions
|
@ -3,7 +3,7 @@
|
|||
"jsxSingleQuote": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ const customConfig = require('../webpack.config.dev')
|
|||
module.exports = {
|
||||
stories: [
|
||||
'../frontend/stories/**/*.stories.js',
|
||||
'../modules/**/stories/**/*.stories.js'
|
||||
'../modules/**/stories/**/*.stories.js',
|
||||
],
|
||||
addons: ['@storybook/addon-essentials', '@storybook/addon-a11y'],
|
||||
webpackFinal: storybookConfig => {
|
||||
|
@ -31,8 +31,8 @@ module.exports = {
|
|||
),
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: ['to-string-loader', 'css-loader', 'less-loader']
|
||||
}
|
||||
use: ['to-string-loader', 'css-loader', 'less-loader'],
|
||||
},
|
||||
]
|
||||
|
||||
// Combine Storybook's webpack plugins with our webpack plugins
|
||||
|
@ -42,9 +42,9 @@ module.exports = {
|
|||
...storybookConfig,
|
||||
module: {
|
||||
...storybookConfig.module,
|
||||
rules
|
||||
rules,
|
||||
},
|
||||
plugins
|
||||
plugins,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ const theme = create({
|
|||
base: 'light',
|
||||
brandTitle: 'Overleaf',
|
||||
brandUrl: 'https://www.overleaf.com',
|
||||
brandImage
|
||||
brandImage,
|
||||
})
|
||||
|
||||
addons.setConfig({ theme })
|
||||
|
|
|
@ -14,11 +14,11 @@ i18n.use(initReactI18next).init({
|
|||
lng: 'en',
|
||||
|
||||
resources: {
|
||||
en: { translation: en }
|
||||
en: { translation: en },
|
||||
},
|
||||
|
||||
react: {
|
||||
useSuspense: false
|
||||
useSuspense: false,
|
||||
},
|
||||
|
||||
interpolation: {
|
||||
|
@ -27,9 +27,9 @@ i18n.use(initReactI18next).init({
|
|||
unescapeSuffix: 'HTML',
|
||||
skipOnVariables: true,
|
||||
defaultVariables: {
|
||||
appName: 'Overleaf'
|
||||
}
|
||||
}
|
||||
appName: 'Overleaf',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const parameters = {
|
||||
|
@ -39,8 +39,8 @@ export const parameters = {
|
|||
actions: { argTypesRegex: '^on.*' },
|
||||
docs: {
|
||||
// render stories in iframes, to isolate modals
|
||||
inlineStories: false
|
||||
}
|
||||
inlineStories: false,
|
||||
},
|
||||
}
|
||||
|
||||
export const globalTypes = {
|
||||
|
@ -53,10 +53,10 @@ export const globalTypes = {
|
|||
items: [
|
||||
{ value: 'default-', title: 'Default' },
|
||||
{ value: 'light-', title: 'Light' },
|
||||
{ value: 'ieee-', title: 'IEEE' }
|
||||
]
|
||||
}
|
||||
}
|
||||
{ value: 'ieee-', title: 'IEEE' },
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const loaders = [
|
||||
|
@ -68,9 +68,9 @@ export const loaders = [
|
|||
// so that webpack only bundles files ending with "style.less"
|
||||
activeStyle: await import(
|
||||
`../frontend/stylesheets/${theme === 'default-' ? '' : theme}style.less`
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
const withTheme = (Story, context) => {
|
||||
|
@ -88,5 +88,5 @@ export const decorators = [withTheme]
|
|||
|
||||
window.ExposedSettings = {
|
||||
maxEntitiesPerProject: 10,
|
||||
maxUploadSize: 5 * 1024 * 1024
|
||||
maxUploadSize: 5 * 1024 * 1024,
|
||||
}
|
||||
|
|
|
@ -34,5 +34,5 @@ module.exports = {
|
|||
AuthenticationController.getLoggedInUserId(req) || req.sessionID
|
||||
AnalyticsManager.recordEvent(userId, req.params.event, req.body)
|
||||
res.sendStatus(202)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -41,20 +41,20 @@ function updateEditingSession(userId, projectId, countryCode) {
|
|||
}
|
||||
Metrics.analyticsQueue.inc({
|
||||
status: 'adding',
|
||||
event_type: 'editing-session'
|
||||
event_type: 'editing-session',
|
||||
})
|
||||
analyticsEditingSessionsQueue
|
||||
.add({ userId, projectId, countryCode })
|
||||
.then(() => {
|
||||
Metrics.analyticsQueue.inc({
|
||||
status: 'added',
|
||||
event_type: 'editing-session'
|
||||
event_type: 'editing-session',
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
Metrics.analyticsQueue.inc({
|
||||
status: 'error',
|
||||
event_type: 'editing-session'
|
||||
event_type: 'editing-session',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -71,5 +71,5 @@ function isAnalyticsDisabled() {
|
|||
module.exports = {
|
||||
identifyUser,
|
||||
recordEvent,
|
||||
updateEditingSession
|
||||
updateEditingSession,
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ module.exports = {
|
|||
proxyReqOptDecorator(proxyReqOpts, srcReq) {
|
||||
proxyReqOpts.headers = {} // unset all headers
|
||||
return proxyReqOpts
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -19,5 +19,5 @@ module.exports = {
|
|||
AuthenticationController.httpAuth,
|
||||
AnalyticsProxy.call('/uniExternalCollaboration')
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ const AsyncFormHelper = require('../Helpers/AsyncFormHelper')
|
|||
const _ = require('lodash')
|
||||
const UserAuditLogHandler = require('../User/UserAuditLogHandler')
|
||||
const {
|
||||
acceptsJson
|
||||
acceptsJson,
|
||||
} = require('../../infrastructure/RequestContentTypeDetection')
|
||||
|
||||
function send401WithChallenge(res) {
|
||||
|
@ -45,7 +45,7 @@ const AuthenticationController = {
|
|||
session_created: new Date().toISOString(),
|
||||
ip_address: user._login_req_ip,
|
||||
must_reconfirm: user.must_reconfirm,
|
||||
v1_id: user.overleaf != null ? user.overleaf.id : undefined
|
||||
v1_id: user.overleaf != null ? user.overleaf.id : undefined,
|
||||
}
|
||||
callback(null, lightUser)
|
||||
},
|
||||
|
@ -145,7 +145,7 @@ const AuthenticationController = {
|
|||
logger.log({ email }, 'too many login requests')
|
||||
return done(null, null, {
|
||||
text: req.i18n.translate('to_many_login_requests_2_mins'),
|
||||
type: 'error'
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
AuthenticationManager.authenticate(
|
||||
|
@ -163,7 +163,7 @@ const AuthenticationController = {
|
|||
logger.log({ email }, 'failed log in')
|
||||
done(null, false, {
|
||||
text: req.i18n.translate('email_or_password_wrong_try_again'),
|
||||
type: 'error'
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ const AuthenticationController = {
|
|||
NotificationsBuilder.ipMatcherAffiliation(user._id).create(req.ip)
|
||||
}
|
||||
return UserUpdater.updateUser(user._id.toString(), {
|
||||
$set: { lastLoginIp: req.ip }
|
||||
$set: { lastLoginIp: req.ip },
|
||||
})
|
||||
},
|
||||
|
||||
|
@ -346,7 +346,7 @@ const AuthenticationController = {
|
|||
if (email == null) {
|
||||
return next(
|
||||
new OError('[ValidateAdmin] Admin user without email address', {
|
||||
userId: user._id
|
||||
userId: user._id,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ const AuthenticationController = {
|
|||
return next(
|
||||
new OError('[ValidateAdmin] Admin user with invalid email domain', {
|
||||
email: email,
|
||||
userId: user._id
|
||||
userId: user._id,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ const AuthenticationController = {
|
|||
userId.toString(),
|
||||
{
|
||||
$set: { lastLoggedIn: new Date() },
|
||||
$inc: { loginCount: 1 }
|
||||
$inc: { loginCount: 1 },
|
||||
},
|
||||
function (error) {
|
||||
if (error != null) {
|
||||
|
@ -472,7 +472,7 @@ const AuthenticationController = {
|
|||
if (req.session != null) {
|
||||
delete req.session.postLoginRedirect
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function _afterLoginSessionSetup(req, user, callback) {
|
||||
|
@ -482,7 +482,7 @@ function _afterLoginSessionSetup(req, user, callback) {
|
|||
req.login(user, function (err) {
|
||||
if (err) {
|
||||
OError.tag(err, 'error from req.login', {
|
||||
user_id: user._id
|
||||
user_id: user._id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ function _afterLoginSessionSetup(req, user, callback) {
|
|||
req.session.destroy(function (err) {
|
||||
if (err) {
|
||||
OError.tag(err, 'error when trying to destroy old session', {
|
||||
user_id: user._id
|
||||
user_id: user._id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -508,7 +508,7 @@ function _afterLoginSessionSetup(req, user, callback) {
|
|||
req.session.save(function (err) {
|
||||
if (err) {
|
||||
OError.tag(err, 'error saving regenerated session after login', {
|
||||
user_id: user._id
|
||||
user_id: user._id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
|
|
@ -5,5 +5,5 @@ class InvalidPasswordError extends Errors.BackwardCompatibleError {}
|
|||
|
||||
module.exports = {
|
||||
InvalidEmailError,
|
||||
InvalidPasswordError
|
||||
InvalidPasswordError,
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ const bcrypt = require('bcrypt')
|
|||
const EmailHelper = require('../Helpers/EmailHelper')
|
||||
const {
|
||||
InvalidEmailError,
|
||||
InvalidPasswordError
|
||||
InvalidPasswordError,
|
||||
} = require('./AuthenticationErrors')
|
||||
const util = require('util')
|
||||
|
||||
|
@ -70,7 +70,7 @@ const AuthenticationManager = {
|
|||
if (password == null) {
|
||||
return new InvalidPasswordError({
|
||||
message: 'password not set',
|
||||
info: { code: 'not_set' }
|
||||
info: { code: 'not_set' },
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -94,13 +94,13 @@ const AuthenticationManager = {
|
|||
if (password.length < min) {
|
||||
return new InvalidPasswordError({
|
||||
message: 'password is too short',
|
||||
info: { code: 'too_short' }
|
||||
info: { code: 'too_short' },
|
||||
})
|
||||
}
|
||||
if (password.length > max) {
|
||||
return new InvalidPasswordError({
|
||||
message: 'password is too long',
|
||||
info: { code: 'too_long' }
|
||||
info: { code: 'too_long' },
|
||||
})
|
||||
}
|
||||
if (
|
||||
|
@ -109,7 +109,7 @@ const AuthenticationManager = {
|
|||
) {
|
||||
return new InvalidPasswordError({
|
||||
message: 'password contains an invalid character',
|
||||
info: { code: 'invalid_character' }
|
||||
info: { code: 'invalid_character' },
|
||||
})
|
||||
}
|
||||
if (typeof email === 'string' && email !== '') {
|
||||
|
@ -120,7 +120,7 @@ const AuthenticationManager = {
|
|||
) {
|
||||
return new InvalidPasswordError({
|
||||
message: 'password contains part of email address',
|
||||
info: { code: 'contains_email' }
|
||||
info: { code: 'contains_email' },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -168,15 +168,15 @@ const AuthenticationManager = {
|
|||
}
|
||||
db.users.updateOne(
|
||||
{
|
||||
_id: ObjectId(user._id.toString())
|
||||
_id: ObjectId(user._id.toString()),
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
hashedPassword: hash
|
||||
hashedPassword: hash,
|
||||
},
|
||||
$unset: {
|
||||
password: true
|
||||
}
|
||||
password: true,
|
||||
},
|
||||
},
|
||||
function (updateError, result) {
|
||||
if (updateError) {
|
||||
|
@ -215,13 +215,13 @@ const AuthenticationManager = {
|
|||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
AuthenticationManager.promises = {
|
||||
authenticate: util.promisify(AuthenticationManager.authenticate),
|
||||
hashPassword: util.promisify(AuthenticationManager.hashPassword),
|
||||
setUserPassword: util.promisify(AuthenticationManager.setUserPassword)
|
||||
setUserPassword: util.promisify(AuthenticationManager.setUserPassword),
|
||||
}
|
||||
|
||||
module.exports = AuthenticationManager
|
||||
|
|
|
@ -209,7 +209,7 @@ const AuthorizationManager = {
|
|||
[
|
||||
PrivilegeLevels.OWNER,
|
||||
PrivilegeLevels.READ_AND_WRITE,
|
||||
PrivilegeLevels.READ_ONLY
|
||||
PrivilegeLevels.READ_ONLY,
|
||||
].includes(privilegeLevel)
|
||||
)
|
||||
}
|
||||
|
@ -286,10 +286,10 @@ const AuthorizationManager = {
|
|||
}
|
||||
callback(null, (user && user.isAdmin) === true)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = AuthorizationManager
|
||||
module.exports.promises = promisifyAll(AuthorizationManager, {
|
||||
without: 'isRestrictedUser'
|
||||
without: 'isRestrictedUser',
|
||||
})
|
||||
|
|
|
@ -267,5 +267,5 @@ module.exports = AuthorizationMiddleware = {
|
|||
AuthenticationController.setRedirectInSession(req, from)
|
||||
}
|
||||
res.redirect('/login')
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ const PrivilegeLevels = {
|
|||
NONE: false,
|
||||
READ_ONLY: 'readOnly',
|
||||
READ_AND_WRITE: 'readAndWrite',
|
||||
OWNER: 'owner'
|
||||
OWNER: 'owner',
|
||||
}
|
||||
|
||||
module.exports = PrivilegeLevels
|
||||
|
|
|
@ -2,5 +2,5 @@ module.exports = {
|
|||
READ_ONLY: 'readOnly', // LEGACY
|
||||
READ_AND_WRITE: 'readAndWrite', // LEGACY
|
||||
PRIVATE: 'private',
|
||||
TOKEN_BASED: 'tokenBased'
|
||||
TOKEN_BASED: 'tokenBased',
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module.exports = {
|
||||
INVITE: 'invite',
|
||||
TOKEN: 'token',
|
||||
OWNER: 'owner'
|
||||
OWNER: 'owner',
|
||||
}
|
||||
|
|
|
@ -40,17 +40,17 @@ const BetaProgramController = {
|
|||
UserGetter.getUser(userId, function (err, user) {
|
||||
if (err) {
|
||||
OError.tag(err, 'error fetching user', {
|
||||
userId
|
||||
userId,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
res.render('beta_program/opt_in', {
|
||||
title: 'sharelatex_beta_program',
|
||||
user,
|
||||
languages: Settings.languages
|
||||
languages: Settings.languages,
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = BetaProgramController
|
||||
|
|
|
@ -9,7 +9,7 @@ async function optIn(userId) {
|
|||
|
||||
async function optOut(userId) {
|
||||
await UserUpdater.promises.updateUser(userId, {
|
||||
$set: { betaProgram: false }
|
||||
$set: { betaProgram: false },
|
||||
})
|
||||
metrics.inc('beta-program.opt-out')
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ async function optOut(userId) {
|
|||
const BetaProgramHandler = {
|
||||
optIn: callbackify(optIn),
|
||||
|
||||
optOut: callbackify(optOut)
|
||||
optOut: callbackify(optOut),
|
||||
}
|
||||
|
||||
BetaProgramHandler.promises = {
|
||||
optIn,
|
||||
optOut
|
||||
optOut,
|
||||
}
|
||||
|
||||
module.exports = BetaProgramHandler
|
||||
|
|
|
@ -6,7 +6,7 @@ const V1Api = require('../V1/V1Api')
|
|||
const sanitizeHtml = require('sanitize-html')
|
||||
|
||||
module.exports = {
|
||||
getBrandVariationById
|
||||
getBrandVariationById,
|
||||
}
|
||||
|
||||
function getBrandVariationById(brandVariationId, callback) {
|
||||
|
@ -16,12 +16,12 @@ function getBrandVariationById(brandVariationId, callback) {
|
|||
logger.log({ brandVariationId }, 'fetching brand variation details from v1')
|
||||
V1Api.request(
|
||||
{
|
||||
uri: `/api/v2/brand_variations/${brandVariationId}`
|
||||
uri: `/api/v2/brand_variations/${brandVariationId}`,
|
||||
},
|
||||
function (error, response, brandVariationDetails) {
|
||||
if (error != null) {
|
||||
OError.tag(error, 'error getting brand variation details', {
|
||||
brandVariationId
|
||||
brandVariationId,
|
||||
})
|
||||
return callback(error)
|
||||
}
|
||||
|
|
|
@ -35,9 +35,9 @@ module.exports = CaptchaMiddleware = {
|
|||
const options = {
|
||||
form: {
|
||||
secret: Settings.recaptcha.secretKey,
|
||||
response
|
||||
response,
|
||||
},
|
||||
json: true
|
||||
json: true,
|
||||
}
|
||||
return request.post(
|
||||
'https://www.google.com/recaptcha/api/siteverify',
|
||||
|
@ -55,8 +55,8 @@ module.exports = CaptchaMiddleware = {
|
|||
errorReason: 'cannot_verify_user_not_robot',
|
||||
message: {
|
||||
text:
|
||||
'Sorry, we could not verify that you are not a robot. Please check that Google reCAPTCHA is not being blocked by an ad blocker or firewall.'
|
||||
}
|
||||
'Sorry, we could not verify that you are not a robot. Please check that Google reCAPTCHA is not being blocked by an ad blocker or firewall.',
|
||||
},
|
||||
})
|
||||
} else {
|
||||
return next()
|
||||
|
@ -64,5 +64,5 @@ module.exports = CaptchaMiddleware = {
|
|||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ module.exports = ChatApiHandler = {
|
|||
{
|
||||
url: `${settings.apis.chat.internal_url}/project/${project_id}/messages`,
|
||||
method: 'POST',
|
||||
json: { user_id, content }
|
||||
json: { user_id, content },
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -63,7 +63,7 @@ module.exports = ChatApiHandler = {
|
|||
url: `${settings.apis.chat.internal_url}/project/${project_id}/messages`,
|
||||
method: 'GET',
|
||||
qs,
|
||||
json: true
|
||||
json: true,
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -77,7 +77,7 @@ module.exports = ChatApiHandler = {
|
|||
{
|
||||
url: `${settings.apis.chat.internal_url}/project/${project_id}/thread/${thread_id}/messages`,
|
||||
method: 'POST',
|
||||
json: { user_id, content }
|
||||
json: { user_id, content },
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -91,7 +91,7 @@ module.exports = ChatApiHandler = {
|
|||
{
|
||||
url: `${settings.apis.chat.internal_url}/project/${project_id}/threads`,
|
||||
method: 'GET',
|
||||
json: true
|
||||
json: true,
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -105,7 +105,7 @@ module.exports = ChatApiHandler = {
|
|||
{
|
||||
url: `${settings.apis.chat.internal_url}/project/${project_id}/thread/${thread_id}/resolve`,
|
||||
method: 'POST',
|
||||
json: { user_id }
|
||||
json: { user_id },
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -118,7 +118,7 @@ module.exports = ChatApiHandler = {
|
|||
return ChatApiHandler._apiRequest(
|
||||
{
|
||||
url: `${settings.apis.chat.internal_url}/project/${project_id}/thread/${thread_id}/reopen`,
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -131,7 +131,7 @@ module.exports = ChatApiHandler = {
|
|||
return ChatApiHandler._apiRequest(
|
||||
{
|
||||
url: `${settings.apis.chat.internal_url}/project/${project_id}/thread/${thread_id}`,
|
||||
method: 'DELETE'
|
||||
method: 'DELETE',
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -146,8 +146,8 @@ module.exports = ChatApiHandler = {
|
|||
url: `${settings.apis.chat.internal_url}/project/${project_id}/thread/${thread_id}/messages/${message_id}/edit`,
|
||||
method: 'POST',
|
||||
json: {
|
||||
content
|
||||
}
|
||||
content,
|
||||
},
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -160,9 +160,9 @@ module.exports = ChatApiHandler = {
|
|||
return ChatApiHandler._apiRequest(
|
||||
{
|
||||
url: `${settings.apis.chat.internal_url}/project/${project_id}/thread/${thread_id}/messages/${message_id}`,
|
||||
method: 'DELETE'
|
||||
method: 'DELETE',
|
||||
},
|
||||
callback
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -132,5 +132,5 @@ module.exports = ChatController = {
|
|||
}
|
||||
return callback(null, threads)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ module.exports = {
|
|||
removeSelfFromProject: expressify(removeSelfFromProject),
|
||||
getAllMembers: expressify(getAllMembers),
|
||||
setCollaboratorInfo: expressify(setCollaboratorInfo),
|
||||
transferOwnership: expressify(transferOwnership)
|
||||
transferOwnership: expressify(transferOwnership),
|
||||
}
|
||||
|
||||
async function removeUserFromProject(req, res, next) {
|
||||
|
@ -24,7 +24,7 @@ async function removeUserFromProject(req, res, next) {
|
|||
const userId = req.params.user_id
|
||||
await _removeUserIdFromProject(projectId, userId)
|
||||
EditorRealTimeController.emitToRoom(projectId, 'project:membership:changed', {
|
||||
members: true
|
||||
members: true,
|
||||
})
|
||||
res.sendStatus(204)
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ async function transferOwnership(req, res, next) {
|
|||
toUserId,
|
||||
{
|
||||
allowTransferToNonCollaborators: sessionUser.isAdmin,
|
||||
sessionUserId: ObjectId(sessionUser._id)
|
||||
sessionUserId: ObjectId(sessionUser._id),
|
||||
}
|
||||
)
|
||||
res.sendStatus(204)
|
||||
|
|
|
@ -21,7 +21,7 @@ module.exports = CollaboratorsEmailHandler = {
|
|||
`${Settings.siteUrl}/project/${project._id}/invite/token/${invite.token}?` +
|
||||
[
|
||||
`project_name=${encodeURIComponent(project.name)}`,
|
||||
`user_first_name=${encodeURIComponent(project.owner_ref.first_name)}`
|
||||
`user_first_name=${encodeURIComponent(project.owner_ref.first_name)}`,
|
||||
].join('&')
|
||||
)
|
||||
},
|
||||
|
@ -35,13 +35,13 @@ module.exports = CollaboratorsEmailHandler = {
|
|||
to: email,
|
||||
replyTo: project.owner_ref.email,
|
||||
project: {
|
||||
name: project.name
|
||||
name: project.name,
|
||||
},
|
||||
inviteUrl: CollaboratorsEmailHandler._buildInviteUrl(project, invite),
|
||||
owner: project.owner_ref,
|
||||
sendingUser_id: sendingUser._id
|
||||
sendingUser_id: sendingUser._id,
|
||||
}
|
||||
return EmailHandler.sendEmail('projectInvite', emailOptions, callback)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ module.exports = {
|
|||
getProjectsUserIsMemberOf,
|
||||
isUserInvitedMemberOfProject,
|
||||
userIsTokenMember,
|
||||
getAllInvitedMembers
|
||||
}
|
||||
getAllInvitedMembers,
|
||||
},
|
||||
}
|
||||
|
||||
async function getMemberIdsWithPrivilegeLevels(projectId) {
|
||||
|
@ -49,7 +49,7 @@ async function getMemberIdsWithPrivilegeLevels(projectId) {
|
|||
readOnly_refs: 1,
|
||||
tokenAccessReadOnly_refs: 1,
|
||||
tokenAccessReadAndWrite_refs: 1,
|
||||
publicAccesLevel: 1
|
||||
publicAccesLevel: 1,
|
||||
})
|
||||
if (!project) {
|
||||
throw new Errors.NotFoundError(`no project found with id ${projectId}`)
|
||||
|
@ -136,7 +136,7 @@ async function getProjectsUserIsMemberOf(userId, fields) {
|
|||
readAndWrite,
|
||||
readOnly,
|
||||
tokenReadAndWrite,
|
||||
tokenReadOnly
|
||||
tokenReadOnly,
|
||||
] = await Promise.all([
|
||||
limit(() => Project.find({ collaberator_refs: userId }, fields).exec()),
|
||||
limit(() => Project.find({ readOnly_refs: userId }, fields).exec()),
|
||||
|
@ -144,7 +144,7 @@ async function getProjectsUserIsMemberOf(userId, fields) {
|
|||
Project.find(
|
||||
{
|
||||
tokenAccessReadAndWrite_refs: userId,
|
||||
publicAccesLevel: PublicAccessLevels.TOKEN_BASED
|
||||
publicAccesLevel: PublicAccessLevels.TOKEN_BASED,
|
||||
},
|
||||
fields
|
||||
).exec()
|
||||
|
@ -153,11 +153,11 @@ async function getProjectsUserIsMemberOf(userId, fields) {
|
|||
Project.find(
|
||||
{
|
||||
tokenAccessReadOnly_refs: userId,
|
||||
publicAccesLevel: PublicAccessLevels.TOKEN_BASED
|
||||
publicAccesLevel: PublicAccessLevels.TOKEN_BASED,
|
||||
},
|
||||
fields
|
||||
).exec()
|
||||
)
|
||||
),
|
||||
])
|
||||
return { readAndWrite, readOnly, tokenReadAndWrite, tokenReadOnly }
|
||||
}
|
||||
|
@ -182,11 +182,11 @@ async function userIsTokenMember(userId, projectId) {
|
|||
_id: projectId,
|
||||
$or: [
|
||||
{ tokenAccessReadOnly_refs: userId },
|
||||
{ tokenAccessReadAndWrite_refs: userId }
|
||||
]
|
||||
{ tokenAccessReadAndWrite_refs: userId },
|
||||
],
|
||||
},
|
||||
{
|
||||
_id: 1
|
||||
_id: 1,
|
||||
}
|
||||
).exec()
|
||||
return project != null
|
||||
|
@ -209,20 +209,20 @@ function _getMemberIdsWithPrivilegeLevelsFromFields(
|
|||
members.push({
|
||||
id: ownerId.toString(),
|
||||
privilegeLevel: PrivilegeLevels.OWNER,
|
||||
source: Sources.OWNER
|
||||
source: Sources.OWNER,
|
||||
})
|
||||
for (const memberId of collaboratorIds || []) {
|
||||
members.push({
|
||||
id: memberId.toString(),
|
||||
privilegeLevel: PrivilegeLevels.READ_AND_WRITE,
|
||||
source: Sources.INVITE
|
||||
source: Sources.INVITE,
|
||||
})
|
||||
}
|
||||
for (const memberId of readOnlyIds || []) {
|
||||
members.push({
|
||||
id: memberId.toString(),
|
||||
privilegeLevel: PrivilegeLevels.READ_ONLY,
|
||||
source: Sources.INVITE
|
||||
source: Sources.INVITE,
|
||||
})
|
||||
}
|
||||
if (publicAccessLevel === PublicAccessLevels.TOKEN_BASED) {
|
||||
|
@ -230,14 +230,14 @@ function _getMemberIdsWithPrivilegeLevelsFromFields(
|
|||
members.push({
|
||||
id: memberId.toString(),
|
||||
privilegeLevel: PrivilegeLevels.READ_AND_WRITE,
|
||||
source: Sources.TOKEN
|
||||
source: Sources.TOKEN,
|
||||
})
|
||||
}
|
||||
for (const memberId of tokenAccessReadOnlyIds || []) {
|
||||
members.push({
|
||||
id: memberId.toString(),
|
||||
privilegeLevel: PrivilegeLevels.READ_ONLY,
|
||||
source: Sources.TOKEN
|
||||
source: Sources.TOKEN,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ async function _loadMembers(members) {
|
|||
features: 1,
|
||||
first_name: 1,
|
||||
last_name: 1,
|
||||
signUpDate: 1
|
||||
signUpDate: 1,
|
||||
})
|
||||
if (user != null) {
|
||||
return { user, privilegeLevel: member.privilegeLevel }
|
||||
|
|
|
@ -22,8 +22,8 @@ module.exports = {
|
|||
removeUserFromAllProjects,
|
||||
addUserIdToProject,
|
||||
transferProjects,
|
||||
setCollaboratorPrivilegeLevel
|
||||
}
|
||||
setCollaboratorPrivilegeLevel,
|
||||
},
|
||||
}
|
||||
|
||||
async function removeUserFromProject(projectId, userId) {
|
||||
|
@ -50,8 +50,8 @@ async function removeUserFromProject(projectId, userId) {
|
|||
readOnly_refs: userId,
|
||||
tokenAccessReadOnly_refs: userId,
|
||||
tokenAccessReadAndWrite_refs: userId,
|
||||
trashed: userId
|
||||
}
|
||||
trashed: userId,
|
||||
},
|
||||
}
|
||||
)
|
||||
} else {
|
||||
|
@ -64,15 +64,15 @@ async function removeUserFromProject(projectId, userId) {
|
|||
tokenAccessReadOnly_refs: userId,
|
||||
tokenAccessReadAndWrite_refs: userId,
|
||||
archived: userId,
|
||||
trashed: userId
|
||||
}
|
||||
trashed: userId,
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
} catch (err) {
|
||||
throw OError.tag(err, 'problem removing user from project collaborators', {
|
||||
projectId,
|
||||
userId
|
||||
userId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -82,9 +82,9 @@ async function removeUserFromAllProjects(userId) {
|
|||
readAndWrite,
|
||||
readOnly,
|
||||
tokenReadAndWrite,
|
||||
tokenReadOnly
|
||||
tokenReadOnly,
|
||||
} = await CollaboratorsGetter.promises.getProjectsUserIsMemberOf(userId, {
|
||||
_id: 1
|
||||
_id: 1,
|
||||
})
|
||||
const allProjects = readAndWrite
|
||||
.concat(readOnly)
|
||||
|
@ -103,7 +103,7 @@ async function addUserIdToProject(
|
|||
) {
|
||||
const project = await ProjectGetter.promises.getProject(projectId, {
|
||||
collaberator_refs: 1,
|
||||
readOnly_refs: 1
|
||||
readOnly_refs: 1,
|
||||
})
|
||||
let level
|
||||
let existingUsers = project.collaberator_refs || []
|
||||
|
@ -144,8 +144,8 @@ async function transferProjects(fromUserId, toUserId) {
|
|||
$or: [
|
||||
{ owner_ref: fromUserId },
|
||||
{ collaberator_refs: fromUserId },
|
||||
{ readOnly_refs: fromUserId }
|
||||
]
|
||||
{ readOnly_refs: fromUserId },
|
||||
],
|
||||
},
|
||||
{ _id: 1 }
|
||||
).exec()
|
||||
|
@ -160,26 +160,26 @@ async function transferProjects(fromUserId, toUserId) {
|
|||
await Project.updateMany(
|
||||
{ collaberator_refs: fromUserId },
|
||||
{
|
||||
$addToSet: { collaberator_refs: toUserId }
|
||||
$addToSet: { collaberator_refs: toUserId },
|
||||
}
|
||||
).exec()
|
||||
await Project.updateMany(
|
||||
{ collaberator_refs: fromUserId },
|
||||
{
|
||||
$pull: { collaberator_refs: fromUserId }
|
||||
$pull: { collaberator_refs: fromUserId },
|
||||
}
|
||||
).exec()
|
||||
|
||||
await Project.updateMany(
|
||||
{ readOnly_refs: fromUserId },
|
||||
{
|
||||
$addToSet: { readOnly_refs: toUserId }
|
||||
$addToSet: { readOnly_refs: toUserId },
|
||||
}
|
||||
).exec()
|
||||
await Project.updateMany(
|
||||
{ readOnly_refs: fromUserId },
|
||||
{
|
||||
$pull: { readOnly_refs: fromUserId }
|
||||
$pull: { readOnly_refs: fromUserId },
|
||||
}
|
||||
).exec()
|
||||
|
||||
|
@ -201,21 +201,21 @@ async function setCollaboratorPrivilegeLevel(
|
|||
// collaborator
|
||||
const query = {
|
||||
_id: projectId,
|
||||
$or: [{ collaberator_refs: userId }, { readOnly_refs: userId }]
|
||||
$or: [{ collaberator_refs: userId }, { readOnly_refs: userId }],
|
||||
}
|
||||
let update
|
||||
switch (privilegeLevel) {
|
||||
case PrivilegeLevels.READ_AND_WRITE: {
|
||||
update = {
|
||||
$pull: { readOnly_refs: userId },
|
||||
$addToSet: { collaberator_refs: userId }
|
||||
$addToSet: { collaberator_refs: userId },
|
||||
}
|
||||
break
|
||||
}
|
||||
case PrivilegeLevels.READ_ONLY: {
|
||||
update = {
|
||||
$pull: { collaberator_refs: userId },
|
||||
$addToSet: { readOnly_refs: userId }
|
||||
$addToSet: { readOnly_refs: userId },
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -239,18 +239,18 @@ async function userIsTokenMember(userId, projectId) {
|
|||
_id: projectId,
|
||||
$or: [
|
||||
{ tokenAccessReadOnly_refs: userId },
|
||||
{ tokenAccessReadAndWrite_refs: userId }
|
||||
]
|
||||
{ tokenAccessReadAndWrite_refs: userId },
|
||||
],
|
||||
},
|
||||
{
|
||||
_id: 1
|
||||
_id: 1,
|
||||
}
|
||||
)
|
||||
return project != null
|
||||
} catch (err) {
|
||||
throw OError.tag(err, 'problem while checking if user is token member', {
|
||||
userId,
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
function (err, invites) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error getting invites for project', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
endpointName: 'invite-to-project-by-user-id',
|
||||
timeInterval: 60 * 30,
|
||||
subjectName: user_id,
|
||||
throttle: collabLimit
|
||||
throttle: collabLimit,
|
||||
}
|
||||
return rateLimiter.addCount(opts, callback)
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
{
|
||||
email,
|
||||
projectId,
|
||||
sendingUserId
|
||||
sendingUserId,
|
||||
}
|
||||
)
|
||||
return next(err)
|
||||
|
@ -164,7 +164,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
)
|
||||
return res.json({
|
||||
invite: null,
|
||||
error: 'cannot_invite_non_user'
|
||||
error: 'cannot_invite_non_user',
|
||||
})
|
||||
}
|
||||
return CollaboratorsInviteHandler.inviteToProject(
|
||||
|
@ -177,7 +177,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
OError.tag(err, 'error creating project invite', {
|
||||
projectId,
|
||||
email,
|
||||
sendingUserId
|
||||
sendingUserId,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error revoking invite', {
|
||||
projectId,
|
||||
inviteId
|
||||
inviteId,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error resending invite', {
|
||||
projectId,
|
||||
inviteId
|
||||
inviteId,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
function (err, isMember) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error checking if user is member of project', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error getting invite by token', {
|
||||
projectId,
|
||||
token
|
||||
token,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
function (err, owner) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error getting project owner', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
function (err, project) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error getting project', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
invite,
|
||||
project,
|
||||
owner,
|
||||
title: 'Project Invite'
|
||||
title: 'Project Invite',
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -368,7 +368,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error accepting invite by token', {
|
||||
projectId,
|
||||
token
|
||||
token,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ module.exports = CollaboratorsInviteController = {
|
|||
)
|
||||
AnalyticsManager.recordEvent(currentUser._id, 'project-invite-accept', {
|
||||
projectId,
|
||||
userId: currentUser._id
|
||||
userId: currentUser._id,
|
||||
})
|
||||
if (req.xhr) {
|
||||
return res.sendStatus(204) // Done async via project page notification
|
||||
|
@ -388,5 +388,5 @@ module.exports = CollaboratorsInviteController = {
|
|||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ const CollaboratorsInviteHandler = {
|
|||
return ProjectInvite.find({ projectId }, function (err, invites) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error getting invites from mongo', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ const CollaboratorsInviteHandler = {
|
|||
return ProjectInvite.countDocuments({ projectId }, function (err, count) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error getting invites from mongo', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ const CollaboratorsInviteHandler = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error checking if user exists', {
|
||||
projectId,
|
||||
email
|
||||
email,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ const CollaboratorsInviteHandler = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error getting project', {
|
||||
projectId,
|
||||
email
|
||||
email,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ const CollaboratorsInviteHandler = {
|
|||
OError.tag(err, 'error generating random token', {
|
||||
projectId,
|
||||
sendingUserId: sendingUser._id,
|
||||
email
|
||||
email,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -177,14 +177,14 @@ const CollaboratorsInviteHandler = {
|
|||
token,
|
||||
sendingUserId: sendingUser._id,
|
||||
projectId,
|
||||
privileges
|
||||
privileges,
|
||||
})
|
||||
return invite.save(function (err, invite) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error saving token', {
|
||||
projectId,
|
||||
sendingUserId: sendingUser._id,
|
||||
email
|
||||
email,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ const CollaboratorsInviteHandler = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error removing invite', {
|
||||
projectId,
|
||||
inviteId
|
||||
inviteId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ const CollaboratorsInviteHandler = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error finding invite', {
|
||||
projectId,
|
||||
inviteId
|
||||
inviteId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ const CollaboratorsInviteHandler = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error resending invite messages', {
|
||||
projectId,
|
||||
inviteId
|
||||
inviteId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ const CollaboratorsInviteHandler = {
|
|||
function (err, invite) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error fetching invite', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ const CollaboratorsInviteHandler = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error finding invite', {
|
||||
projectId,
|
||||
tokenString
|
||||
tokenString,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ const CollaboratorsInviteHandler = {
|
|||
OError.tag(err, 'error adding user to project', {
|
||||
projectId,
|
||||
inviteId,
|
||||
userId: user._id
|
||||
userId: user._id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ const CollaboratorsInviteHandler = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error removing invite', {
|
||||
projectId,
|
||||
inviteId
|
||||
inviteId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ const CollaboratorsInviteHandler = {
|
|||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = CollaboratorsInviteHandler
|
||||
|
|
|
@ -21,13 +21,13 @@ module.exports = {
|
|||
validate({
|
||||
params: Joi.object({
|
||||
Project_id: Joi.objectId(),
|
||||
user_id: Joi.objectId()
|
||||
user_id: Joi.objectId(),
|
||||
}),
|
||||
body: Joi.object({
|
||||
privilegeLevel: Joi.string()
|
||||
.valid(PrivilegeLevels.READ_ONLY, PrivilegeLevels.READ_AND_WRITE)
|
||||
.required()
|
||||
})
|
||||
.required(),
|
||||
}),
|
||||
}),
|
||||
AuthorizationMiddleware.ensureUserCanAdminProject,
|
||||
CollaboratorsController.setCollaboratorInfo
|
||||
|
@ -52,11 +52,11 @@ module.exports = {
|
|||
AuthenticationController.requireLogin(),
|
||||
validate({
|
||||
params: Joi.object({
|
||||
Project_id: Joi.objectId()
|
||||
Project_id: Joi.objectId(),
|
||||
}),
|
||||
body: Joi.object({
|
||||
user_id: Joi.objectId()
|
||||
})
|
||||
user_id: Joi.objectId(),
|
||||
}),
|
||||
}),
|
||||
AuthorizationMiddleware.ensureUserCanAdminProject,
|
||||
CollaboratorsController.transferOwnership
|
||||
|
@ -69,13 +69,13 @@ module.exports = {
|
|||
endpointName: 'invite-to-project-by-project-id',
|
||||
params: ['Project_id'],
|
||||
maxRequests: 100,
|
||||
timeInterval: 60 * 10
|
||||
timeInterval: 60 * 10,
|
||||
}),
|
||||
RateLimiterMiddleware.rateLimit({
|
||||
endpointName: 'invite-to-project-by-ip',
|
||||
ipOnly: true,
|
||||
maxRequests: 100,
|
||||
timeInterval: 60 * 10
|
||||
timeInterval: 60 * 10,
|
||||
}),
|
||||
CaptchaMiddleware.validateCaptcha('invite'),
|
||||
AuthenticationController.requireLogin(),
|
||||
|
@ -103,7 +103,7 @@ module.exports = {
|
|||
endpointName: 'resend-invite',
|
||||
params: ['Project_id'],
|
||||
maxRequests: 200,
|
||||
timeInterval: 60 * 10
|
||||
timeInterval: 60 * 10,
|
||||
}),
|
||||
AuthenticationController.requireLogin(),
|
||||
AuthorizationMiddleware.ensureUserCanAdminProject,
|
||||
|
@ -121,5 +121,5 @@ module.exports = {
|
|||
AuthenticationController.requireLogin(),
|
||||
CollaboratorsInviteController.acceptInvite
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ const TpdsProjectFlusher = require('../ThirdPartyDataStore/TpdsProjectFlusher')
|
|||
const ProjectAuditLogHandler = require('../Project/ProjectAuditLogHandler')
|
||||
|
||||
module.exports = {
|
||||
promises: { transferOwnership }
|
||||
promises: { transferOwnership },
|
||||
}
|
||||
|
||||
async function transferOwnership(projectId, newOwnerId, options = {}) {
|
||||
|
@ -19,7 +19,7 @@ async function transferOwnership(projectId, newOwnerId, options = {}) {
|
|||
// Fetch project and user
|
||||
const [project, newOwner] = await Promise.all([
|
||||
_getProject(projectId),
|
||||
_getUser(newOwnerId)
|
||||
_getUser(newOwnerId),
|
||||
])
|
||||
|
||||
// Exit early if the transferee is already the project owner
|
||||
|
@ -57,7 +57,7 @@ async function _getProject(projectId) {
|
|||
const project = await ProjectGetter.promises.getProject(projectId, {
|
||||
owner_ref: 1,
|
||||
collaberator_refs: 1,
|
||||
name: 1
|
||||
name: 1,
|
||||
})
|
||||
if (project == null) {
|
||||
throw new Errors.ProjectNotFoundError({ info: { projectId } })
|
||||
|
@ -111,14 +111,14 @@ async function _sendEmails(project, previousOwner, newOwner) {
|
|||
{
|
||||
to: previousOwner.email,
|
||||
project,
|
||||
newOwner
|
||||
newOwner,
|
||||
}
|
||||
),
|
||||
EmailHandler.promises.sendEmail('ownershipTransferConfirmationNewOwner', {
|
||||
to: newOwner.email,
|
||||
project,
|
||||
previousOwner
|
||||
})
|
||||
previousOwner,
|
||||
}),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ module.exports = function (backendGroup) {
|
|||
return request.post(url, (err, res, body) => {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error getting initial server id for project', {
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ module.exports = function (backendGroup) {
|
|||
return this._getServerId(project_id, (err, serverId) => {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error getting server id', {
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -153,6 +153,6 @@ module.exports = function (backendGroup) {
|
|||
jar.setCookie(serverCookie, Settings.apis.clsi.url)
|
||||
return callback(null, jar)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ module.exports = ClsiFormatChecker = {
|
|||
|
||||
sizeCheck(cb) {
|
||||
return ClsiFormatChecker._checkDocsAreUnderSizeLimit(resources, cb)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return async.series(jobs, function (err, problems) {
|
||||
|
@ -82,5 +82,5 @@ module.exports = ClsiFormatChecker = {
|
|||
sizedResources = _.sortBy(sizedResources, 'size').reverse().slice(0, 10)
|
||||
return callback(null, { resources: sizedResources, totalSize })
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -66,13 +66,13 @@ const ClsiManager = {
|
|||
if (err != null) {
|
||||
if (err.message === 'no main file specified') {
|
||||
return callback(null, 'validation-problems', null, null, {
|
||||
mainFile: err.message
|
||||
mainFile: err.message,
|
||||
})
|
||||
} else {
|
||||
return callback(
|
||||
OError.tag(err, 'Could not build request to CLSI', {
|
||||
projectId,
|
||||
options
|
||||
options,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ const ClsiManager = {
|
|||
OError.tag(err, 'CLSI compile failed', {
|
||||
submissionId,
|
||||
clsiRequest,
|
||||
options
|
||||
options,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ const ClsiManager = {
|
|||
)
|
||||
const opts = {
|
||||
url: compilerUrl,
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
}
|
||||
ClsiManager._makeRequest(projectId, opts, callback)
|
||||
},
|
||||
|
@ -147,7 +147,7 @@ const ClsiManager = {
|
|||
)
|
||||
const opts = {
|
||||
url: compilerUrl,
|
||||
method: 'DELETE'
|
||||
method: 'DELETE',
|
||||
}
|
||||
ClsiManager._makeRequestWithClsiServerId(
|
||||
projectId,
|
||||
|
@ -243,7 +243,7 @@ const ClsiManager = {
|
|||
return callback(
|
||||
OError.tag(err, 'error sending request to clsi', {
|
||||
projectId,
|
||||
userId
|
||||
userId,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ const ClsiManager = {
|
|||
if (err != null) {
|
||||
return callback(
|
||||
OError.tag(err, 'error getting cookie jar for CLSI request', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ const ClsiManager = {
|
|||
cb(err, {
|
||||
response,
|
||||
body,
|
||||
finishTime: new Date() - startTime
|
||||
finishTime: new Date() - startTime,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -347,11 +347,11 @@ const ClsiManager = {
|
|||
cb(err, {
|
||||
response,
|
||||
body,
|
||||
finishTime: new Date() - startTime
|
||||
finishTime: new Date() - startTime,
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
},
|
||||
(err, results) => {
|
||||
if (err != null) {
|
||||
|
@ -371,7 +371,7 @@ const ClsiManager = {
|
|||
timeDifference,
|
||||
currentCompileTime,
|
||||
newBackendCompileTime,
|
||||
projectId
|
||||
projectId,
|
||||
},
|
||||
'both clsi requests returned'
|
||||
)
|
||||
|
@ -389,13 +389,13 @@ const ClsiManager = {
|
|||
url: baseOpts.url.replace(
|
||||
Settings.apis.clsi.url,
|
||||
Settings.apis.clsi_new.url
|
||||
)
|
||||
),
|
||||
}
|
||||
NewBackendCloudClsiCookieManager.getCookieJar(projectId, (err, jar) => {
|
||||
if (err != null) {
|
||||
return callback(
|
||||
OError.tag(err, 'error getting cookie jar for CLSI request', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ const ClsiManager = {
|
|||
return callback(
|
||||
OError.tag(err, 'error making request to new CLSI', {
|
||||
projectId,
|
||||
opts
|
||||
opts,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -418,7 +418,7 @@ const ClsiManager = {
|
|||
if (err != null) {
|
||||
return callback(
|
||||
OError.tag(err, 'error setting server id on new backend', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ const ClsiManager = {
|
|||
const opts = {
|
||||
url: compileUrl,
|
||||
json: req,
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
}
|
||||
ClsiManager._makeRequest(projectId, opts, (err, response, body) => {
|
||||
if (err != null) {
|
||||
|
@ -460,7 +460,7 @@ const ClsiManager = {
|
|||
projectId,
|
||||
userId,
|
||||
compileOptions: req.compile.options,
|
||||
rootResourcePath: req.compile.rootResourcePath
|
||||
rootResourcePath: req.compile.rootResourcePath,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ const ClsiManager = {
|
|||
compileOptions: req.compile.options,
|
||||
rootResourcePath: req.compile.rootResourcePath,
|
||||
clsiResponse: body,
|
||||
statusCode: response.statusCode
|
||||
statusCode: response.statusCode,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ const ClsiManager = {
|
|||
path: file.path, // the clsi is now sending this to web
|
||||
url: Url.parse(file.url).path, // the location of the file on the clsi, excluding the host part
|
||||
type: file.type,
|
||||
build: file.build
|
||||
build: file.build,
|
||||
})
|
||||
}
|
||||
return outputFiles
|
||||
|
@ -574,7 +574,7 @@ const ClsiManager = {
|
|||
if (err != null) {
|
||||
return callback(
|
||||
OError.tag(err, 'failed to get contents from Mongo', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -607,7 +607,7 @@ const ClsiManager = {
|
|||
return callback(
|
||||
OError.tag(err, 'Failed to get project documents', {
|
||||
projectId,
|
||||
projectStateHash
|
||||
projectStateHash,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ const ClsiManager = {
|
|||
projectId,
|
||||
userId,
|
||||
buildId,
|
||||
outputFilePath
|
||||
outputFilePath,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -693,14 +693,14 @@ const ClsiManager = {
|
|||
if (err != null) {
|
||||
return callback(
|
||||
OError.tag(err, 'failed to get project contents from Mongo', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
)
|
||||
}
|
||||
options = {
|
||||
...options,
|
||||
syncType: 'full',
|
||||
syncState: projectStateHash
|
||||
syncState: projectStateHash,
|
||||
}
|
||||
ClsiManager._finaliseRequest(
|
||||
projectId,
|
||||
|
@ -756,7 +756,7 @@ const ClsiManager = {
|
|||
// add doc to resources unless it is just a stub entry
|
||||
resources.push({
|
||||
path,
|
||||
content: doc.lines.join('\n')
|
||||
content: doc.lines.join('\n'),
|
||||
})
|
||||
}
|
||||
if (
|
||||
|
@ -799,7 +799,7 @@ const ClsiManager = {
|
|||
resources.push({
|
||||
path,
|
||||
url: `${Settings.apis.filestore.url}/project/${project._id}/file/${file._id}`,
|
||||
modified: file.created != null ? file.created.getTime() : undefined
|
||||
modified: file.created != null ? file.created.getTime() : undefined,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -813,11 +813,11 @@ const ClsiManager = {
|
|||
check: options.check,
|
||||
syncType: options.syncType,
|
||||
syncState: options.syncState,
|
||||
compileGroup: options.compileGroup
|
||||
compileGroup: options.compileGroup,
|
||||
},
|
||||
rootResourcePath,
|
||||
resources
|
||||
}
|
||||
resources,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
|
@ -827,7 +827,7 @@ const ClsiManager = {
|
|||
return callback(
|
||||
OError.tag(err, 'Failed to build CLSI request', {
|
||||
projectId,
|
||||
options
|
||||
options,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -842,9 +842,9 @@ const ClsiManager = {
|
|||
url: wordCountUrl,
|
||||
qs: {
|
||||
file: filename,
|
||||
image: req.compile.options.imageName
|
||||
image: req.compile.options.imageName,
|
||||
},
|
||||
method: 'GET'
|
||||
method: 'GET',
|
||||
}
|
||||
ClsiManager._makeRequestWithClsiServerId(
|
||||
projectId,
|
||||
|
@ -865,7 +865,7 @@ const ClsiManager = {
|
|||
{
|
||||
projectId,
|
||||
clsiResponse: body,
|
||||
statusCode: response.statusCode
|
||||
statusCode: response.statusCode,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -873,7 +873,7 @@ const ClsiManager = {
|
|||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = ClsiManager
|
||||
|
|
|
@ -52,7 +52,7 @@ module.exports = ClsiStateManager = {
|
|||
)
|
||||
const sortedEntityList = [
|
||||
...Array.from(docList),
|
||||
...Array.from(fileList)
|
||||
...Array.from(fileList),
|
||||
].sort()
|
||||
// ignore the isAutoCompile options as it doesn't affect the
|
||||
// output, but include all other options e.g. draft
|
||||
|
@ -71,11 +71,11 @@ module.exports = ClsiStateManager = {
|
|||
const hash = buildState(
|
||||
[
|
||||
...Array.from(sortedEntityList),
|
||||
...Array.from(sortedOptionsList)
|
||||
...Array.from(sortedOptionsList),
|
||||
].join('\n')
|
||||
)
|
||||
return callback(null, hash)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ module.exports = CompileController = {
|
|||
const isAutoCompile = !!req.query.auto_compile
|
||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
||||
const options = {
|
||||
isAutoCompile
|
||||
isAutoCompile,
|
||||
}
|
||||
|
||||
if (req.body.rootDoc_id) {
|
||||
|
@ -96,7 +96,7 @@ module.exports = CompileController = {
|
|||
compileGroup: limits != null ? limits.compileGroup : undefined,
|
||||
clsiServerId,
|
||||
validationProblems,
|
||||
pdfDownloadDomain: Settings.pdfDownloadDomain
|
||||
pdfDownloadDomain: Settings.pdfDownloadDomain,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -160,7 +160,7 @@ module.exports = CompileController = {
|
|||
status,
|
||||
outputFiles,
|
||||
clsiServerId,
|
||||
validationProblems
|
||||
validationProblems,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ module.exports = CompileController = {
|
|||
endpointName: 'full-pdf-download',
|
||||
throttle: 1000,
|
||||
subjectName: req.ip,
|
||||
timeInterval: 60 * 60
|
||||
timeInterval: 60 * 60,
|
||||
}
|
||||
return RateLimiter.addCount(rateLimitOpts, callback)
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ module.exports = CompileController = {
|
|||
const limits = {
|
||||
compileGroup:
|
||||
(req.body != null ? req.body.compileGroup : undefined) ||
|
||||
Settings.defaultFeatures.compileGroup
|
||||
Settings.defaultFeatures.compileGroup,
|
||||
}
|
||||
return CompileController.proxyToClsiWithLimits(
|
||||
submission_id,
|
||||
|
@ -504,7 +504,7 @@ module.exports = CompileController = {
|
|||
url,
|
||||
method: req.method,
|
||||
timeout: oneMinute,
|
||||
...persistenceOptions
|
||||
...persistenceOptions,
|
||||
}
|
||||
// add any provided query string
|
||||
if (qs != null) {
|
||||
|
@ -563,7 +563,7 @@ module.exports = CompileController = {
|
|||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function _getPersistenceOptions(req, projectId, callback) {
|
||||
|
|
|
@ -186,7 +186,7 @@ module.exports = CompileManager = {
|
|||
Settings.defaultFeatures.compileTimeout,
|
||||
compileGroup:
|
||||
ownerFeatures.compileGroup ||
|
||||
Settings.defaultFeatures.compileGroup
|
||||
Settings.defaultFeatures.compileGroup,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -251,7 +251,7 @@ module.exports = CompileManager = {
|
|||
endpointName: 'auto_compile',
|
||||
timeInterval: 20,
|
||||
subjectName: compileGroup,
|
||||
throttle: Settings.rateLimit.autoCompile[compileGroup] || 25
|
||||
throttle: Settings.rateLimit.autoCompile[compileGroup] || 25,
|
||||
}
|
||||
return rateLimiter.addCount(opts, function (err, canCompile) {
|
||||
if (err != null) {
|
||||
|
@ -284,5 +284,5 @@ module.exports = CompileManager = {
|
|||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ module.exports = ContactsController = {
|
|||
email: 1,
|
||||
first_name: 1,
|
||||
last_name: 1,
|
||||
holdingAccount: 1
|
||||
holdingAccount: 1,
|
||||
},
|
||||
function (error, contacts) {
|
||||
if (error != null) {
|
||||
|
@ -71,7 +71,7 @@ module.exports = ContactsController = {
|
|||
...Array.from(additional_contacts || [])
|
||||
)
|
||||
return res.send({
|
||||
contacts
|
||||
contacts,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -87,7 +87,7 @@ module.exports = ContactsController = {
|
|||
email: contact.email || '',
|
||||
first_name: contact.first_name || '',
|
||||
last_name: contact.last_name || '',
|
||||
type: 'user'
|
||||
type: 'user',
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ module.exports = ContactManager = {
|
|||
url,
|
||||
qs: options,
|
||||
json: true,
|
||||
jar: false
|
||||
jar: false,
|
||||
},
|
||||
function (error, res, data) {
|
||||
if (error != null) {
|
||||
|
@ -62,9 +62,9 @@ module.exports = ContactManager = {
|
|||
{
|
||||
url,
|
||||
json: {
|
||||
contact_id
|
||||
contact_id,
|
||||
},
|
||||
jar: false
|
||||
jar: false,
|
||||
},
|
||||
function (error, res, data) {
|
||||
if (error != null) {
|
||||
|
@ -80,12 +80,12 @@ module.exports = ContactManager = {
|
|||
`contacts api responded with non-success code: ${res.statusCode}`,
|
||||
{
|
||||
user_id,
|
||||
contact_id
|
||||
contact_id,
|
||||
}
|
||||
)
|
||||
return callback(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -23,5 +23,5 @@ module.exports = {
|
|||
contactsAuthenticationMiddleware(),
|
||||
ContactController.getContacts
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -52,5 +52,5 @@ module.exports = CooldownManager = {
|
|||
return callback(null, result === '1')
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -36,5 +36,5 @@ module.exports = CooldownMiddleware = {
|
|||
return next()
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ const DocstoreManager = {
|
|||
message: 'tried to delete doc not in docstore',
|
||||
info: {
|
||||
project_id,
|
||||
doc_id
|
||||
}
|
||||
doc_id,
|
||||
},
|
||||
})
|
||||
return callback(error) // maybe suppress the error when delete doc which is not present?
|
||||
} else {
|
||||
|
@ -49,7 +49,7 @@ const DocstoreManager = {
|
|||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{
|
||||
project_id,
|
||||
doc_id
|
||||
doc_id,
|
||||
}
|
||||
)
|
||||
return callback(error)
|
||||
|
@ -66,7 +66,7 @@ const DocstoreManager = {
|
|||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: true
|
||||
json: true,
|
||||
},
|
||||
function (error, res, docs) {
|
||||
if (error != null) {
|
||||
|
@ -117,7 +117,7 @@ const DocstoreManager = {
|
|||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: true
|
||||
json: true,
|
||||
},
|
||||
function (error, res, docs) {
|
||||
if (error != null) {
|
||||
|
@ -155,7 +155,7 @@ const DocstoreManager = {
|
|||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: true
|
||||
json: true,
|
||||
},
|
||||
function (error, res, doc) {
|
||||
if (error != null) {
|
||||
|
@ -172,8 +172,8 @@ const DocstoreManager = {
|
|||
message: 'doc not found in docstore',
|
||||
info: {
|
||||
project_id,
|
||||
doc_id
|
||||
}
|
||||
doc_id,
|
||||
},
|
||||
})
|
||||
return callback(error)
|
||||
} else {
|
||||
|
@ -181,7 +181,7 @@ const DocstoreManager = {
|
|||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{
|
||||
project_id,
|
||||
doc_id
|
||||
doc_id,
|
||||
}
|
||||
)
|
||||
return callback(error)
|
||||
|
@ -203,7 +203,7 @@ const DocstoreManager = {
|
|||
callback(
|
||||
new Errors.NotFoundError({
|
||||
message: 'doc does not exist in project',
|
||||
info: { project_id, doc_id }
|
||||
info: { project_id, doc_id },
|
||||
})
|
||||
)
|
||||
} else {
|
||||
|
@ -230,8 +230,8 @@ const DocstoreManager = {
|
|||
json: {
|
||||
lines,
|
||||
version,
|
||||
ranges
|
||||
}
|
||||
ranges,
|
||||
},
|
||||
},
|
||||
function (error, res, result) {
|
||||
if (error != null) {
|
||||
|
@ -273,7 +273,7 @@ const DocstoreManager = {
|
|||
request.post(url, function (err, res, docs) {
|
||||
if (err != null) {
|
||||
OError.tag(err, `error calling ${method} project in docstore`, {
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -291,13 +291,13 @@ const DocstoreManager = {
|
|||
callback(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = DocstoreManager
|
||||
module.exports.promises = promisifyAll(DocstoreManager, {
|
||||
multiResult: {
|
||||
getDoc: ['lines', 'rev', 'version', 'ranges'],
|
||||
updateDoc: ['modified', 'rev']
|
||||
}
|
||||
updateDoc: ['modified', 'rev'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -34,15 +34,15 @@ module.exports = {
|
|||
acceptChanges: promisify(acceptChanges),
|
||||
deleteThread: promisify(deleteThread),
|
||||
resyncProjectHistory: promisify(resyncProjectHistory),
|
||||
updateProjectStructure: promisify(updateProjectStructure)
|
||||
}
|
||||
updateProjectStructure: promisify(updateProjectStructure),
|
||||
},
|
||||
}
|
||||
|
||||
function flushProjectToMongo(projectId, callback) {
|
||||
_makeRequest(
|
||||
{
|
||||
path: `/project/${projectId}/flush`,
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
},
|
||||
projectId,
|
||||
'flushing.mongo.project',
|
||||
|
@ -61,7 +61,7 @@ function flushProjectToMongoAndDelete(projectId, callback) {
|
|||
_makeRequest(
|
||||
{
|
||||
path: `/project/${projectId}`,
|
||||
method: 'DELETE'
|
||||
method: 'DELETE',
|
||||
},
|
||||
projectId,
|
||||
'flushing.mongo.project',
|
||||
|
@ -73,7 +73,7 @@ function flushDocToMongo(projectId, docId, callback) {
|
|||
_makeRequest(
|
||||
{
|
||||
path: `/project/${projectId}/doc/${docId}/flush`,
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
},
|
||||
projectId,
|
||||
'flushing.mongo.doc',
|
||||
|
@ -85,7 +85,7 @@ function deleteDoc(projectId, docId, callback) {
|
|||
_makeRequest(
|
||||
{
|
||||
path: `/project/${projectId}/doc/${docId}`,
|
||||
method: 'DELETE'
|
||||
method: 'DELETE',
|
||||
},
|
||||
projectId,
|
||||
'delete.mongo.doc',
|
||||
|
@ -97,7 +97,7 @@ function getDocument(projectId, docId, fromVersion, callback) {
|
|||
_makeRequest(
|
||||
{
|
||||
path: `/project/${projectId}/doc/${docId}?fromVersion=${fromVersion}`,
|
||||
json: true
|
||||
json: true,
|
||||
},
|
||||
projectId,
|
||||
'get-document',
|
||||
|
@ -118,8 +118,8 @@ function setDocument(projectId, docId, userId, docLines, source, callback) {
|
|||
json: {
|
||||
lines: docLines,
|
||||
source,
|
||||
user_id: userId
|
||||
}
|
||||
user_id: userId,
|
||||
},
|
||||
},
|
||||
projectId,
|
||||
'set-document',
|
||||
|
@ -138,7 +138,7 @@ function getProjectDocsIfMatch(projectId, projectStateHash, callback) {
|
|||
if (error) {
|
||||
OError.tag(error, 'error getting project docs from doc updater', {
|
||||
url,
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
return callback(error)
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ function getProjectDocsIfMatch(projectId, projectStateHash, callback) {
|
|||
`doc updater returned a non-success status code: ${res.statusCode}`,
|
||||
{
|
||||
projectId,
|
||||
url
|
||||
url,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -176,7 +176,7 @@ function clearProjectState(projectId, callback) {
|
|||
_makeRequest(
|
||||
{
|
||||
path: `/project/${projectId}/clearState`,
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
},
|
||||
projectId,
|
||||
'clear-project-state',
|
||||
|
@ -189,7 +189,7 @@ function acceptChanges(projectId, docId, changeIds, callback) {
|
|||
{
|
||||
path: `/project/${projectId}/doc/${docId}/change/accept`,
|
||||
json: { change_ids: changeIds },
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
},
|
||||
projectId,
|
||||
'accept-changes',
|
||||
|
@ -201,7 +201,7 @@ function deleteThread(projectId, docId, threadId, callback) {
|
|||
_makeRequest(
|
||||
{
|
||||
path: `/project/${projectId}/doc/${docId}/comment/${threadId}`,
|
||||
method: 'DELETE'
|
||||
method: 'DELETE',
|
||||
},
|
||||
projectId,
|
||||
'delete-thread',
|
||||
|
@ -220,7 +220,7 @@ function resyncProjectHistory(
|
|||
{
|
||||
path: `/project/${projectId}/history/resync`,
|
||||
json: { docs, files, projectHistoryId },
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
},
|
||||
projectId,
|
||||
'resync-project-history',
|
||||
|
@ -245,12 +245,12 @@ function updateProjectStructure(
|
|||
const {
|
||||
deletes: docDeletes,
|
||||
adds: docAdds,
|
||||
renames: docRenames
|
||||
renames: docRenames,
|
||||
} = _getUpdates('doc', changes.oldDocs, changes.newDocs)
|
||||
const {
|
||||
deletes: fileDeletes,
|
||||
adds: fileAdds,
|
||||
renames: fileRenames
|
||||
renames: fileRenames,
|
||||
} = _getUpdates('file', changes.oldFiles, changes.newFiles)
|
||||
const updates = [].concat(
|
||||
docDeletes,
|
||||
|
@ -282,9 +282,9 @@ function updateProjectStructure(
|
|||
updates,
|
||||
userId,
|
||||
version: projectVersion,
|
||||
projectHistoryId
|
||||
projectHistoryId,
|
||||
},
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
},
|
||||
projectId,
|
||||
'update-project-structure',
|
||||
|
@ -298,7 +298,7 @@ function _makeRequest(options, projectId, metricsKey, callback) {
|
|||
{
|
||||
url: `${settings.apis.documentupdater.url}${options.path}`,
|
||||
json: options.json,
|
||||
method: options.method || 'GET'
|
||||
method: options.method || 'GET',
|
||||
},
|
||||
function (error, res, body) {
|
||||
timer.done()
|
||||
|
@ -359,7 +359,7 @@ function _getUpdates(entityType, oldEntities, newEntities) {
|
|||
type: `rename-${entityType}`,
|
||||
id,
|
||||
pathname: oldEntity.path,
|
||||
newPathname: ''
|
||||
newPathname: '',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ function _getUpdates(entityType, oldEntities, newEntities) {
|
|||
pathname: newEntity.path,
|
||||
docLines: newEntity.docLines,
|
||||
url: newEntity.url,
|
||||
hash: newEntity.file != null ? newEntity.file.hash : undefined
|
||||
hash: newEntity.file != null ? newEntity.file.hash : undefined,
|
||||
})
|
||||
} else if (newEntity.path !== oldEntity.path) {
|
||||
// entity renamed
|
||||
|
@ -384,7 +384,7 @@ function _getUpdates(entityType, oldEntities, newEntities) {
|
|||
type: `rename-${entityType}`,
|
||||
id,
|
||||
pathname: oldEntity.path,
|
||||
newPathname: newEntity.path
|
||||
newPathname: newEntity.path,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ module.exports = {
|
|||
if (error != null) {
|
||||
OError.tag(error, 'error finding element for getDocument', {
|
||||
doc_id,
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return next(error)
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ module.exports = {
|
|||
'error finding doc contents for getDocument',
|
||||
{
|
||||
doc_id,
|
||||
project_id
|
||||
project_id,
|
||||
}
|
||||
)
|
||||
return next(error)
|
||||
|
@ -81,7 +81,7 @@ module.exports = {
|
|||
ranges,
|
||||
pathname: path.fileSystem,
|
||||
projectHistoryId,
|
||||
projectHistoryType
|
||||
projectHistoryType,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ module.exports = {
|
|||
if (error != null) {
|
||||
OError.tag(error, 'error finding element for getDocument', {
|
||||
doc_id,
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return next(error)
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ module.exports = {
|
|||
return res.sendStatus(200)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function __guard__(value, transform) {
|
||||
|
|
|
@ -74,5 +74,5 @@ module.exports = DocumentHelper = {
|
|||
} else {
|
||||
return content
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ module.exports = ProjectDownloadsController = {
|
|||
return next(error)
|
||||
}
|
||||
res.setContentDisposition('attachment', {
|
||||
filename: `${project.name}.zip`
|
||||
filename: `${project.name}.zip`,
|
||||
})
|
||||
res.contentType('application/zip')
|
||||
return stream.pipe(res)
|
||||
|
@ -70,7 +70,7 @@ module.exports = ProjectDownloadsController = {
|
|||
return next(error)
|
||||
}
|
||||
res.setContentDisposition('attachment', {
|
||||
filename: `Overleaf Projects (${project_ids.length} items).zip`
|
||||
filename: `Overleaf Projects (${project_ids.length} items).zip`,
|
||||
})
|
||||
res.contentType('application/zip')
|
||||
return stream.pipe(res)
|
||||
|
@ -78,5 +78,5 @@ module.exports = ProjectDownloadsController = {
|
|||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -179,5 +179,5 @@ module.exports = ProjectZipStreamManager = {
|
|||
return async.parallelLimit(jobs, 5, callback)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ const EditorController = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error adding doc without lock', {
|
||||
project_id,
|
||||
docName
|
||||
docName,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ const EditorController = {
|
|||
OError.tag(err, 'error adding file without lock', {
|
||||
project_id,
|
||||
folder_id,
|
||||
fileName
|
||||
fileName,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ const EditorController = {
|
|||
project_id,
|
||||
folder_id,
|
||||
folderName,
|
||||
source
|
||||
source,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ const EditorController = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'could not mkdirp', {
|
||||
project_id,
|
||||
path
|
||||
path,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ const EditorController = {
|
|||
OError.tag(err, 'could not delete entity', {
|
||||
project_id,
|
||||
entity_id,
|
||||
entityType
|
||||
entityType,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -453,7 +453,7 @@ const EditorController = {
|
|||
'something went wrong setting the project description',
|
||||
{
|
||||
project_id,
|
||||
description
|
||||
description,
|
||||
}
|
||||
)
|
||||
return callback(err)
|
||||
|
@ -491,7 +491,7 @@ const EditorController = {
|
|||
project_id,
|
||||
entity_id,
|
||||
entityType,
|
||||
newName
|
||||
newName,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -524,7 +524,7 @@ const EditorController = {
|
|||
OError.tag(err, 'error moving entity', {
|
||||
project_id,
|
||||
entity_id,
|
||||
folder_id
|
||||
folder_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ const EditorController = {
|
|||
if (err != null) {
|
||||
OError.tag(err, 'error renaming project', {
|
||||
project_id,
|
||||
newName
|
||||
newName,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -722,7 +722,7 @@ const EditorController = {
|
|||
userId
|
||||
)
|
||||
return callback()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
EditorController.promises = promisifyAll(EditorController)
|
||||
|
|
|
@ -28,7 +28,7 @@ module.exports = {
|
|||
deleteFolder: expressify(deleteFolder),
|
||||
deleteEntity: expressify(deleteEntity),
|
||||
convertDocToFile: expressify(convertDocToFile),
|
||||
_nameIsAcceptableLength
|
||||
_nameIsAcceptableLength,
|
||||
}
|
||||
|
||||
const unsupportedSpellcheckLanguages = [
|
||||
|
@ -50,7 +50,7 @@ const unsupportedSpellcheckLanguages = [
|
|||
'uk',
|
||||
'uz',
|
||||
'zu',
|
||||
'fi'
|
||||
'fi',
|
||||
]
|
||||
|
||||
async function joinProject(req, res, next) {
|
||||
|
@ -63,7 +63,7 @@ async function joinProject(req, res, next) {
|
|||
const {
|
||||
project,
|
||||
privilegeLevel,
|
||||
isRestrictedUser
|
||||
isRestrictedUser,
|
||||
} = await _buildJoinProjectView(req, projectId, userId)
|
||||
if (!project) {
|
||||
return res.sendStatus(403)
|
||||
|
@ -90,7 +90,7 @@ async function joinProject(req, res, next) {
|
|||
res.json({
|
||||
project,
|
||||
privilegeLevel,
|
||||
isRestrictedUser
|
||||
isRestrictedUser,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ async function _buildJoinProjectView(req, projectId, userId) {
|
|||
deletedDocsFromDocstore
|
||||
),
|
||||
privilegeLevel,
|
||||
isRestrictedUser
|
||||
isRestrictedUser,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,15 +37,15 @@ module.exports = EditorRealTimeController = {
|
|||
room_id,
|
||||
message,
|
||||
payload,
|
||||
_id: message_id
|
||||
_id: message_id,
|
||||
})
|
||||
Metrics.summary('redis.publish.editor-events', blob.length, {
|
||||
status: message
|
||||
status: message,
|
||||
})
|
||||
return rclient.publish(channel, blob)
|
||||
},
|
||||
|
||||
emitToAll(message, ...payload) {
|
||||
return this.emitToRoom('all', message, ...Array.from(payload))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ module.exports = {
|
|||
endpointName: 'add-doc-to-project',
|
||||
params: ['Project_id'],
|
||||
maxRequests: 30,
|
||||
timeInterval: 60
|
||||
timeInterval: 60,
|
||||
}),
|
||||
EditorHttpController.addDoc
|
||||
)
|
||||
|
@ -24,7 +24,7 @@ module.exports = {
|
|||
endpointName: 'add-folder-to-project',
|
||||
params: ['Project_id'],
|
||||
maxRequests: 60,
|
||||
timeInterval: 60
|
||||
timeInterval: 60,
|
||||
}),
|
||||
EditorHttpController.addFolder
|
||||
)
|
||||
|
@ -60,8 +60,8 @@ module.exports = {
|
|||
AuthenticationController.httpAuth,
|
||||
validate({
|
||||
body: Joi.object({
|
||||
userId: Joi.objectId().required()
|
||||
})
|
||||
userId: Joi.objectId().required(),
|
||||
}),
|
||||
}),
|
||||
EditorHttpController.convertDocToFile
|
||||
)
|
||||
|
@ -76,9 +76,9 @@ module.exports = {
|
|||
endpointName: 'join-project',
|
||||
params: ['Project_id'],
|
||||
maxRequests: 45,
|
||||
timeInterval: 60
|
||||
timeInterval: 60,
|
||||
}),
|
||||
EditorHttpController.joinProject
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -79,9 +79,9 @@ function ctaTemplate(content) {
|
|||
ctaText: content.ctaText(opts),
|
||||
ctaURL: content.ctaURL(opts),
|
||||
gmailGoToAction: content.gmailGoToAction(opts),
|
||||
StringHelper
|
||||
StringHelper,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,9 +113,9 @@ The ${settings.appName} Team - ${settings.siteUrl}\
|
|||
typeof content.title === 'function' ? content.title(opts) : undefined,
|
||||
greeting: content.greeting(opts),
|
||||
message: content.message(opts),
|
||||
StringHelper
|
||||
StringHelper,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ function buildEmail(templateName, opts) {
|
|||
return {
|
||||
subject: template.subject(opts),
|
||||
html: template.layout(opts),
|
||||
text: template.plainTextTemplate && template.plainTextTemplate(opts)
|
||||
text: template.plainTextTemplate && template.plainTextTemplate(opts),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,12 +141,12 @@ templates.registered = ctaTemplate({
|
|||
`Congratulations, you've just had an account created for you on ${
|
||||
settings.appName
|
||||
} with the email address '${_.escape(opts.to)}'.`,
|
||||
'Click here to set your password and log in:'
|
||||
'Click here to set your password and log in:',
|
||||
]
|
||||
},
|
||||
secondaryMessage() {
|
||||
return [
|
||||
`If you have any questions or problems, please contact ${settings.adminEmail}`
|
||||
`If you have any questions or problems, please contact ${settings.adminEmail}`,
|
||||
]
|
||||
},
|
||||
ctaText() {
|
||||
|
@ -154,7 +154,7 @@ templates.registered = ctaTemplate({
|
|||
},
|
||||
ctaURL(opts) {
|
||||
return opts.setNewPasswordUrl
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.canceledSubscription = ctaTemplate({
|
||||
|
@ -163,7 +163,7 @@ templates.canceledSubscription = ctaTemplate({
|
|||
},
|
||||
message() {
|
||||
return [
|
||||
`We are sorry to see you cancelled your ${settings.appName} premium subscription. Would you mind giving us some feedback on what the site is lacking at the moment via this quick survey?`
|
||||
`We are sorry to see you cancelled your ${settings.appName} premium subscription. Would you mind giving us some feedback on what the site is lacking at the moment via this quick survey?`,
|
||||
]
|
||||
},
|
||||
secondaryMessage() {
|
||||
|
@ -174,7 +174,7 @@ templates.canceledSubscription = ctaTemplate({
|
|||
},
|
||||
ctaURL(opts) {
|
||||
return 'https://docs.google.com/forms/d/e/1FAIpQLSfa7z_s-cucRRXm70N4jEcSbFsZeb0yuKThHGQL8ySEaQzF0Q/viewform?usp=sf_link'
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.reactivatedSubscription = ctaTemplate({
|
||||
|
@ -189,7 +189,7 @@ templates.reactivatedSubscription = ctaTemplate({
|
|||
},
|
||||
ctaURL(opts) {
|
||||
return `${settings.siteUrl}/user/subscription`
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.passwordResetRequested = ctaTemplate({
|
||||
|
@ -205,7 +205,7 @@ templates.passwordResetRequested = ctaTemplate({
|
|||
secondaryMessage() {
|
||||
return [
|
||||
"If you ignore this message, your password won't be changed.",
|
||||
"If you didn't request a password reset, let us know."
|
||||
"If you didn't request a password reset, let us know.",
|
||||
]
|
||||
},
|
||||
ctaText() {
|
||||
|
@ -213,7 +213,7 @@ templates.passwordResetRequested = ctaTemplate({
|
|||
},
|
||||
ctaURL(opts) {
|
||||
return opts.setNewPasswordUrl
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.confirmEmail = ctaTemplate({
|
||||
|
@ -225,13 +225,13 @@ templates.confirmEmail = ctaTemplate({
|
|||
},
|
||||
message(opts) {
|
||||
return [
|
||||
`Please confirm that you have added a new email, ${opts.to}, to your ${settings.appName} account.`
|
||||
`Please confirm that you have added a new email, ${opts.to}, to your ${settings.appName} account.`,
|
||||
]
|
||||
},
|
||||
secondaryMessage() {
|
||||
return [
|
||||
'If you did not request this, you can simply ignore this message.',
|
||||
`If you have any questions or trouble confirming your email address, please get in touch with our support team at ${settings.adminEmail}.`
|
||||
`If you have any questions or trouble confirming your email address, please get in touch with our support team at ${settings.adminEmail}.`,
|
||||
]
|
||||
},
|
||||
ctaText() {
|
||||
|
@ -239,7 +239,7 @@ templates.confirmEmail = ctaTemplate({
|
|||
},
|
||||
ctaURL(opts) {
|
||||
return opts.confirmEmailUrl
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.projectInvite = ctaTemplate({
|
||||
|
@ -263,7 +263,7 @@ templates.projectInvite = ctaTemplate({
|
|||
SpamSafe.safeEmail(opts.owner.email, 'a collaborator')
|
||||
)} wants to share ${_.escape(
|
||||
SpamSafe.safeProjectName(opts.project.name, 'a new project')
|
||||
)} with you.`
|
||||
)} with you.`,
|
||||
]
|
||||
},
|
||||
ctaText() {
|
||||
|
@ -278,9 +278,9 @@ templates.projectInvite = ctaTemplate({
|
|||
name: 'View project',
|
||||
description: `Join ${_.escape(
|
||||
SpamSafe.safeProjectName(opts.project.name, 'project')
|
||||
)} at ${settings.appName}`
|
||||
)} at ${settings.appName}`,
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.reconfirmEmail = ctaTemplate({
|
||||
|
@ -292,13 +292,13 @@ templates.reconfirmEmail = ctaTemplate({
|
|||
},
|
||||
message(opts) {
|
||||
return [
|
||||
`Please reconfirm your email address, ${opts.to}, on your ${settings.appName} account.`
|
||||
`Please reconfirm your email address, ${opts.to}, on your ${settings.appName} account.`,
|
||||
]
|
||||
},
|
||||
secondaryMessage() {
|
||||
return [
|
||||
'If you did not request this, you can simply ignore this message.',
|
||||
`If you have any questions or trouble confirming your email address, please get in touch with our support team at ${settings.adminEmail}.`
|
||||
`If you have any questions or trouble confirming your email address, please get in touch with our support team at ${settings.adminEmail}.`,
|
||||
]
|
||||
},
|
||||
ctaText() {
|
||||
|
@ -306,7 +306,7 @@ templates.reconfirmEmail = ctaTemplate({
|
|||
},
|
||||
ctaURL(opts) {
|
||||
return opts.confirmEmailUrl
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.verifyEmailToJoinTeam = ctaTemplate({
|
||||
|
@ -322,7 +322,7 @@ templates.verifyEmailToJoinTeam = ctaTemplate({
|
|||
},
|
||||
message(opts) {
|
||||
return [
|
||||
`Please click the button below to join the team and enjoy the benefits of an upgraded ${settings.appName} account.`
|
||||
`Please click the button below to join the team and enjoy the benefits of an upgraded ${settings.appName} account.`,
|
||||
]
|
||||
},
|
||||
ctaText(opts) {
|
||||
|
@ -330,7 +330,7 @@ templates.verifyEmailToJoinTeam = ctaTemplate({
|
|||
},
|
||||
ctaURL(opts) {
|
||||
return opts.acceptInviteUrl
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.testEmail = ctaTemplate({
|
||||
|
@ -351,7 +351,7 @@ templates.testEmail = ctaTemplate({
|
|||
},
|
||||
ctaURL() {
|
||||
return settings.siteUrl
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.ownershipTransferConfirmationPreviousOwner = NoCTAEmailTemplate({
|
||||
|
@ -376,9 +376,9 @@ templates.ownershipTransferConfirmationPreviousOwner = NoCTAEmailTemplate({
|
|||
: `<b>${projectName}</b>`
|
||||
return [
|
||||
`As per your request, we have made ${nameAndEmail} the owner of ${projectNameDisplay}.`,
|
||||
`If you haven't asked to change the owner of ${projectNameDisplay}, please get in touch with us via ${settings.adminEmail}.`
|
||||
`If you haven't asked to change the owner of ${projectNameDisplay}, please get in touch with us via ${settings.adminEmail}.`,
|
||||
]
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.ownershipTransferConfirmationNewOwner = ctaTemplate({
|
||||
|
@ -402,7 +402,7 @@ templates.ownershipTransferConfirmationNewOwner = ctaTemplate({
|
|||
? projectName
|
||||
: `<b>${projectName}</b>`
|
||||
return [
|
||||
`${nameAndEmail} has made you the owner of ${projectNameEmphasized}. You can now manage ${projectName} sharing settings.`
|
||||
`${nameAndEmail} has made you the owner of ${projectNameEmphasized}. You can now manage ${projectName} sharing settings.`,
|
||||
]
|
||||
},
|
||||
ctaText(opts) {
|
||||
|
@ -413,7 +413,7 @@ templates.ownershipTransferConfirmationNewOwner = ctaTemplate({
|
|||
settings.siteUrl
|
||||
}/project/${opts.project._id.toString()}`
|
||||
return projectUrl
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.userOnboardingEmail = NoCTAEmailTemplate({
|
||||
|
@ -466,9 +466,9 @@ templates.userOnboardingEmail = NoCTAEmailTemplate({
|
|||
'Thanks again for using Overleaf :)',
|
||||
`John`,
|
||||
`Dr John Hammersley <br />Co-founder & CEO <br />${siteLink}<hr>`,
|
||||
`Don't want onboarding emails like this from us? Don't worry, this is the only one. If you've previously subscribed to emails about product offers and company news and events, you can unsubscribe ${userSettingsLink}.`
|
||||
`Don't want onboarding emails like this from us? Don't worry, this is the only one. If you've previously subscribed to emails about product offers and company news and events, you can unsubscribe ${userSettingsLink}.`,
|
||||
]
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
templates.securityAlert = NoCTAEmailTemplate({
|
||||
|
@ -504,9 +504,9 @@ templates.securityAlert = NoCTAEmailTemplate({
|
|||
...message,
|
||||
`If this was you, you can ignore this email.`,
|
||||
`If this was not you, we recommend getting in touch with our support team at ${settings.adminEmail} to report this as potentially suspicious activity on your account.`,
|
||||
`We also encourage you to read our ${helpLink} to keeping your ${settings.appName} account safe.`
|
||||
`We also encourage you to read our ${helpLink} to keeping your ${settings.appName} account safe.`,
|
||||
]
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
function _formatUserNameAndEmail(user, placeholder) {
|
||||
|
@ -527,5 +527,5 @@ module.exports = {
|
|||
templates,
|
||||
ctaTemplate,
|
||||
NoCTAEmailTemplate,
|
||||
buildEmail
|
||||
buildEmail,
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ const EMAIL_SETTINGS = Settings.email || {}
|
|||
module.exports = {
|
||||
sendEmail: callbackify(sendEmail),
|
||||
promises: {
|
||||
sendEmail
|
||||
}
|
||||
sendEmail,
|
||||
},
|
||||
}
|
||||
|
||||
async function sendEmail(emailType, opts) {
|
||||
|
|
|
@ -3,13 +3,13 @@ const sanitizeOptions = {
|
|||
html: {
|
||||
allowedTags: ['span', 'b', 'br', 'i'],
|
||||
allowedAttributes: {
|
||||
span: ['style', 'class']
|
||||
}
|
||||
span: ['style', 'class'],
|
||||
},
|
||||
},
|
||||
plainText: {
|
||||
allowedTags: [],
|
||||
allowedAttributes: {}
|
||||
}
|
||||
allowedAttributes: {},
|
||||
},
|
||||
}
|
||||
|
||||
function cleanHTML(text, isPlainText) {
|
||||
|
@ -23,5 +23,5 @@ function displayLink(text, url, isPlainText) {
|
|||
|
||||
module.exports = {
|
||||
cleanHTML,
|
||||
displayLink
|
||||
displayLink,
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ function linkOrUnlink(accountLinked, providerName, email) {
|
|||
return {
|
||||
to: email,
|
||||
action: `${providerName} account ${action}`,
|
||||
actionDescribed: `${indefiniteArticle} ${providerName} account ${actionDescribed} your account ${email}`
|
||||
actionDescribed: `${indefiniteArticle} ${providerName} account ${actionDescribed} your account ${email}`,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
linkOrUnlink
|
||||
linkOrUnlink,
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ const EMAIL_SETTINGS = Settings.email || {}
|
|||
module.exports = {
|
||||
sendEmail: callbackify(sendEmail),
|
||||
promises: {
|
||||
sendEmail
|
||||
}
|
||||
sendEmail,
|
||||
},
|
||||
}
|
||||
|
||||
const client = getClient()
|
||||
|
@ -36,8 +36,8 @@ function getClient() {
|
|||
client = nodemailer.createTransport(
|
||||
mandrillTransport({
|
||||
auth: {
|
||||
apiKey: emailParameters.MandrillApiKey
|
||||
}
|
||||
apiKey: emailParameters.MandrillApiKey,
|
||||
},
|
||||
})
|
||||
)
|
||||
} else {
|
||||
|
@ -61,7 +61,7 @@ function getClient() {
|
|||
client = {
|
||||
async sendMail(options) {
|
||||
logger.log({ options }, 'Would send email if enabled.')
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
return client
|
||||
|
@ -76,7 +76,7 @@ async function sendEmail(options) {
|
|||
sendingUser_id: options.sendingUser_id,
|
||||
to: options.to,
|
||||
subject: options.subject,
|
||||
canContinue
|
||||
canContinue,
|
||||
},
|
||||
'rate limit hit for sending email, not sending'
|
||||
)
|
||||
|
@ -90,7 +90,7 @@ async function sendEmail(options) {
|
|||
html: options.html,
|
||||
text: options.text,
|
||||
replyTo: options.replyTo || EMAIL_SETTINGS.replyToAddress,
|
||||
socketTimeout: 30 * 1000
|
||||
socketTimeout: 30 * 1000,
|
||||
}
|
||||
if (EMAIL_SETTINGS.textEncoding != null) {
|
||||
sendMailOptions.textEncoding = EMAIL_SETTINGS.textEncoding
|
||||
|
@ -110,7 +110,7 @@ async function checkCanSendEmail(options) {
|
|||
endpointName: 'send_email',
|
||||
timeInterval: 60 * 60 * 3,
|
||||
subjectName: options.sendingUser_id,
|
||||
throttle: 100
|
||||
throttle: 100,
|
||||
}
|
||||
const allowed = await RateLimiter.promises.addCount(opts)
|
||||
return allowed
|
||||
|
|
|
@ -50,7 +50,7 @@ const SpamSafe = {
|
|||
return email
|
||||
}
|
||||
return alternative
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = SpamSafe
|
||||
|
|
|
@ -28,13 +28,13 @@ module.exports = ErrorController = {
|
|||
SamlLogHandler.log(req.session.saml.universityId, req.sessionID, {
|
||||
error: {
|
||||
message: error && error.message,
|
||||
stack: error && error.stack
|
||||
stack: error && error.stack,
|
||||
},
|
||||
body: req.body,
|
||||
path: req.path,
|
||||
query: req.query,
|
||||
saml: req.session.saml,
|
||||
user_id: user && user._id
|
||||
user_id: user && user._id,
|
||||
})
|
||||
}
|
||||
if (error.code === 'EBADCSRFTOKEN') {
|
||||
|
@ -99,5 +99,5 @@ module.exports = ErrorController = {
|
|||
)
|
||||
res.sendStatus(500)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ class SAMLSessionDataMissing extends BackwardCompatibleError {
|
|||
universityId,
|
||||
universityName,
|
||||
externalUserId,
|
||||
institutionEmail
|
||||
institutionEmail,
|
||||
} = samlSession
|
||||
|
||||
if (
|
||||
|
@ -223,5 +223,5 @@ module.exports = {
|
|||
DocHasRangesError,
|
||||
InvalidQueryError,
|
||||
AffiliationError,
|
||||
InvalidInstitutionalEmailError
|
||||
InvalidInstitutionalEmailError,
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ function handleGeneric400Error(req, res, statusCode, message, info = {}) {
|
|||
case 'html':
|
||||
return res.render('general/400', {
|
||||
title: 'Client Error',
|
||||
message: message
|
||||
message: message,
|
||||
})
|
||||
case 'json':
|
||||
return renderJSONError(res, message, info)
|
||||
|
@ -85,7 +85,7 @@ module.exports = HttpErrorHandler = {
|
|||
case 'html':
|
||||
return res.render('general/400', {
|
||||
title: 'Client Error',
|
||||
message: message
|
||||
message: message,
|
||||
})
|
||||
case 'json':
|
||||
return renderJSONError(res, message, info)
|
||||
|
@ -124,7 +124,7 @@ module.exports = HttpErrorHandler = {
|
|||
case 'html':
|
||||
return res.render('general/400', {
|
||||
title: 'Client Error',
|
||||
message: message
|
||||
message: message,
|
||||
})
|
||||
case 'json':
|
||||
return renderJSONError(res, message, info)
|
||||
|
@ -157,5 +157,5 @@ module.exports = HttpErrorHandler = {
|
|||
default:
|
||||
return res.send(message)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ module.exports = {
|
|||
const export_params = {
|
||||
project_id,
|
||||
brand_variation_id,
|
||||
user_id
|
||||
user_id,
|
||||
}
|
||||
|
||||
if (req.body) {
|
||||
|
@ -69,13 +69,13 @@ module.exports = {
|
|||
user_id,
|
||||
project_id,
|
||||
brand_variation_id,
|
||||
export_v1_id: export_data.v1_id
|
||||
export_v1_id: export_data.v1_id,
|
||||
},
|
||||
'exported project'
|
||||
)
|
||||
return res.json({
|
||||
export_v1_id: export_data.v1_id,
|
||||
message: export_data.message
|
||||
message: export_data.message,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -88,7 +88,7 @@ module.exports = {
|
|||
if (err != null) {
|
||||
json = {
|
||||
status_summary: 'failed',
|
||||
status_detail: err.toString
|
||||
status_detail: err.toString,
|
||||
}
|
||||
res.json({ export_json: json })
|
||||
return err
|
||||
|
@ -102,7 +102,7 @@ module.exports = {
|
|||
v2_user_first_name: parsed_export.v2_user_first_name,
|
||||
v2_user_last_name: parsed_export.v2_user_last_name,
|
||||
title: parsed_export.title,
|
||||
token: parsed_export.token
|
||||
token: parsed_export.token,
|
||||
}
|
||||
return res.json({ export_json: json })
|
||||
})
|
||||
|
@ -123,5 +123,5 @@ module.exports = {
|
|||
return res.redirect(export_file_url)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ module.exports = ExportsHandler = self = {
|
|||
description,
|
||||
author,
|
||||
license,
|
||||
show_source
|
||||
show_source,
|
||||
} = export_params
|
||||
const jobs = {
|
||||
project(cb) {
|
||||
|
@ -81,7 +81,7 @@ module.exports = ExportsHandler = self = {
|
|||
cb
|
||||
)
|
||||
}
|
||||
)
|
||||
),
|
||||
],
|
||||
user(cb) {
|
||||
return UserGetter.getUser(
|
||||
|
@ -100,7 +100,7 @@ module.exports = ExportsHandler = self = {
|
|||
return self._requestVersion(project_id, cb)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return async.auto(jobs, function (err, results) {
|
||||
|
@ -108,7 +108,7 @@ module.exports = ExportsHandler = self = {
|
|||
OError.tag(err, 'error building project export', {
|
||||
project_id,
|
||||
user_id,
|
||||
brand_variation_id
|
||||
brand_variation_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ module.exports = ExportsHandler = self = {
|
|||
const { project, rootDoc, user, historyVersion } = results
|
||||
if (!rootDoc || rootDoc[1] == null) {
|
||||
err = new OError('cannot export project without root doc', {
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -144,8 +144,8 @@ module.exports = ExportsHandler = self = {
|
|||
description,
|
||||
author,
|
||||
license,
|
||||
showSource: show_source
|
||||
}
|
||||
showSource: show_source,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
id: user_id,
|
||||
|
@ -153,14 +153,14 @@ module.exports = ExportsHandler = self = {
|
|||
lastName: user.last_name,
|
||||
email: user.email,
|
||||
orcidId: null, // until v2 gets ORCID
|
||||
v1UserId: user.overleaf != null ? user.overleaf.id : undefined
|
||||
v1UserId: user.overleaf != null ? user.overleaf.id : undefined,
|
||||
},
|
||||
destination: {
|
||||
brandVariationId: brand_variation_id
|
||||
brandVariationId: brand_variation_id,
|
||||
},
|
||||
options: {
|
||||
callbackUrl: null
|
||||
} // for now, until we want v1 to call us back
|
||||
callbackUrl: null,
|
||||
}, // for now, until we want v1 to call us back
|
||||
}
|
||||
return callback(null, export_data)
|
||||
})
|
||||
|
@ -174,12 +174,12 @@ module.exports = ExportsHandler = self = {
|
|||
{
|
||||
url: `${settings.apis.v1.url}/api/v1/sharelatex/exports`,
|
||||
auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass },
|
||||
json: export_data
|
||||
json: export_data,
|
||||
},
|
||||
function (err, res, body) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error making request to v1 export', {
|
||||
export: export_data
|
||||
export: export_data,
|
||||
})
|
||||
return callback(err)
|
||||
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
|
@ -203,12 +203,12 @@ module.exports = ExportsHandler = self = {
|
|||
return request.get(
|
||||
{
|
||||
url: `${settings.apis.project_history.url}/project/${project_id}/version`,
|
||||
json: true
|
||||
json: true,
|
||||
},
|
||||
function (err, res, body) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error making request to project history', {
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return callback(err)
|
||||
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
|
@ -231,12 +231,12 @@ module.exports = ExportsHandler = self = {
|
|||
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 }
|
||||
auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass },
|
||||
},
|
||||
function (err, res, body) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error making request to v1 export', {
|
||||
export: export_id
|
||||
export: export_id,
|
||||
})
|
||||
return callback(err)
|
||||
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
|
@ -259,12 +259,12 @@ module.exports = ExportsHandler = self = {
|
|||
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 }
|
||||
auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass },
|
||||
},
|
||||
function (err, res, body) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error making request to v1 export', {
|
||||
export: export_id
|
||||
export: export_id,
|
||||
})
|
||||
return callback(err)
|
||||
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
|
@ -278,7 +278,7 @@ module.exports = ExportsHandler = self = {
|
|||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function __guard__(value, transform) {
|
||||
|
|
|
@ -57,5 +57,5 @@ module.exports = FileHashManager = {
|
|||
})
|
||||
return input.pipe(hash)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ module.exports = {
|
|||
res.set('Content-Length', fileSize)
|
||||
res.status(200).end()
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function isHtml(file) {
|
||||
|
|
|
@ -49,7 +49,7 @@ const FileStoreHandler = {
|
|||
if (err) {
|
||||
OError.tag(err, 'Error uploading file, retries failed', {
|
||||
projectId,
|
||||
fileArgs
|
||||
fileArgs,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -83,8 +83,8 @@ const FileStoreHandler = {
|
|||
uri: url,
|
||||
timeout: FIVE_MINS_IN_MS,
|
||||
headers: {
|
||||
'X-File-Hash-From-Web': hashValue
|
||||
} // send the hash to the filestore as a custom header so it can be checked
|
||||
'X-File-Hash-From-Web': hashValue,
|
||||
}, // send the hash to the filestore as a custom header so it can be checked
|
||||
}
|
||||
const writeStream = request(opts)
|
||||
writeStream.on('error', function (err) {
|
||||
|
@ -118,7 +118,7 @@ const FileStoreHandler = {
|
|||
method: 'get',
|
||||
uri: `${this._buildUrl(projectId, fileId)}${queryString}`,
|
||||
timeout: FIVE_MINS_IN_MS,
|
||||
headers: {}
|
||||
headers: {},
|
||||
}
|
||||
if (query != null && query.range != null) {
|
||||
const rangeText = query.range
|
||||
|
@ -142,7 +142,7 @@ const FileStoreHandler = {
|
|||
if (err) {
|
||||
OError.tag(err, 'failed to get file size from filestore', {
|
||||
projectId,
|
||||
fileId
|
||||
fileId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ const FileStoreHandler = {
|
|||
const opts = {
|
||||
method: 'delete',
|
||||
uri: this._buildUrl(projectId, fileId),
|
||||
timeout: FIVE_MINS_IN_MS
|
||||
timeout: FIVE_MINS_IN_MS,
|
||||
}
|
||||
return request(opts, function (err, response) {
|
||||
if (err) {
|
||||
|
@ -184,7 +184,7 @@ const FileStoreHandler = {
|
|||
{
|
||||
method: 'delete',
|
||||
uri: this._buildUrl(projectId),
|
||||
timeout: FIVE_MINS_IN_MS
|
||||
timeout: FIVE_MINS_IN_MS,
|
||||
},
|
||||
err => {
|
||||
if (err) {
|
||||
|
@ -211,11 +211,11 @@ const FileStoreHandler = {
|
|||
json: {
|
||||
source: {
|
||||
project_id: oldProjectId,
|
||||
file_id: oldFileId
|
||||
}
|
||||
file_id: oldFileId,
|
||||
},
|
||||
},
|
||||
uri: this._buildUrl(newProjectId, newFileId),
|
||||
timeout: FIVE_MINS_IN_MS
|
||||
timeout: FIVE_MINS_IN_MS,
|
||||
}
|
||||
return request(opts, function (err, response) {
|
||||
if (err) {
|
||||
|
@ -226,7 +226,7 @@ const FileStoreHandler = {
|
|||
oldProjectId,
|
||||
oldFileId,
|
||||
newProjectId,
|
||||
newFileId
|
||||
newFileId,
|
||||
}
|
||||
)
|
||||
return callback(err)
|
||||
|
@ -238,7 +238,7 @@ const FileStoreHandler = {
|
|||
`non-ok response from filestore for copyFile: ${response.statusCode}`,
|
||||
{
|
||||
uri: opts.uri,
|
||||
statusCode: response.statusCode
|
||||
statusCode: response.statusCode,
|
||||
}
|
||||
)
|
||||
return callback(err)
|
||||
|
@ -251,12 +251,12 @@ const FileStoreHandler = {
|
|||
`${settings.apis.filestore.url}/project/${projectId}` +
|
||||
(fileId ? `/file/${fileId}` : '')
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = FileStoreHandler
|
||||
module.exports.promises = promisifyAll(FileStoreHandler, {
|
||||
multiResult: {
|
||||
uploadFileFromDisk: ['url', 'fileRef']
|
||||
}
|
||||
uploadFileFromDisk: ['url', 'fileRef'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -5,7 +5,7 @@ const logger = require('logger-sharelatex')
|
|||
const UserGetter = require('../User/UserGetter')
|
||||
const {
|
||||
SmokeTestFailure,
|
||||
runSmokeTests
|
||||
runSmokeTests,
|
||||
} = require('./../../../../test/smoke/src/SmokeTests')
|
||||
|
||||
module.exports = {
|
||||
|
@ -89,7 +89,7 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function prettyJSON(blob) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const {
|
||||
acceptsJson
|
||||
acceptsJson,
|
||||
} = require('../../infrastructure/RequestContentTypeDetection')
|
||||
|
||||
module.exports = {
|
||||
redirect
|
||||
redirect,
|
||||
}
|
||||
|
||||
// redirect the request via headers or JSON response depending on the request
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const { UserSchema } = require('../../models/User')
|
||||
|
||||
module.exports = {
|
||||
hasAnyStaffAccess
|
||||
hasAnyStaffAccess,
|
||||
}
|
||||
|
||||
function hasAnyStaffAccess(user) {
|
||||
|
|
|
@ -25,5 +25,5 @@ function parseEmail(email) {
|
|||
|
||||
module.exports = {
|
||||
getDomain,
|
||||
parseEmail
|
||||
parseEmail,
|
||||
}
|
||||
|
|
|
@ -47,5 +47,5 @@ function isObjectIdInstance(id) {
|
|||
module.exports = {
|
||||
isObjectIdInstance,
|
||||
normalizeQuery,
|
||||
normalizeMultiQuery
|
||||
normalizeMultiQuery,
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ const Settings = require('settings-sharelatex')
|
|||
const EXISTING_UI = { newLogsUI: false, subvariant: null }
|
||||
const NEW_UI_WITH_POPUP = {
|
||||
newLogsUI: true,
|
||||
subvariant: 'new-logs-ui-with-popup'
|
||||
subvariant: 'new-logs-ui-with-popup',
|
||||
}
|
||||
const NEW_UI_WITHOUT_POPUP = {
|
||||
newLogsUI: true,
|
||||
subvariant: 'new-logs-ui-without-popup'
|
||||
subvariant: 'new-logs-ui-without-popup',
|
||||
}
|
||||
|
||||
function _getVariantForPercentile(
|
||||
|
@ -41,7 +41,7 @@ function getNewLogsUIVariantForUser(user) {
|
|||
const {
|
||||
_id: userId,
|
||||
alphaProgram: isAlphaUser,
|
||||
betaProgram: isBetaUser
|
||||
betaProgram: isBetaUser,
|
||||
} = user
|
||||
if (!userId) {
|
||||
return EXISTING_UI
|
||||
|
@ -67,5 +67,5 @@ function getNewLogsUIVariantForUser(user) {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
getNewLogsUIVariantForUser
|
||||
getNewLogsUIVariantForUser,
|
||||
}
|
||||
|
|
|
@ -42,5 +42,5 @@ function render(locale, components) {
|
|||
|
||||
module.exports = {
|
||||
SPLIT_REGEX,
|
||||
render
|
||||
render,
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ const JSON_ESCAPE = {
|
|||
'>': '\\u003e',
|
||||
'<': '\\u003c',
|
||||
'\u2028': '\\u2028',
|
||||
'\u2029': '\\u2029'
|
||||
'\u2029': '\\u2029',
|
||||
}
|
||||
|
||||
module.exports = StringHelper = {
|
||||
|
@ -26,5 +26,5 @@ module.exports = StringHelper = {
|
|||
JSON_ESCAPE_REGEXP,
|
||||
match => JSON_ESCAPE[match]
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ const UrlHelper = {
|
|||
url = `http://${url}`
|
||||
}
|
||||
return url
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = UrlHelper
|
||||
|
|
|
@ -48,8 +48,8 @@ module.exports = HistoryController = {
|
|||
url,
|
||||
method: req.method,
|
||||
headers: {
|
||||
'X-User-Id': userId
|
||||
}
|
||||
'X-User-Id': userId,
|
||||
},
|
||||
})
|
||||
getReq.pipe(res)
|
||||
getReq.on('error', function (err) {
|
||||
|
@ -68,8 +68,8 @@ module.exports = HistoryController = {
|
|||
method: req.method,
|
||||
json: true,
|
||||
headers: {
|
||||
'X-User-Id': userId
|
||||
}
|
||||
'X-User-Id': userId,
|
||||
},
|
||||
},
|
||||
function (err, body) {
|
||||
if (err) {
|
||||
|
@ -123,7 +123,7 @@ module.exports = HistoryController = {
|
|||
}
|
||||
res.json({
|
||||
type: entity.type,
|
||||
id: entity._id
|
||||
id: entity._id,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -144,7 +144,7 @@ module.exports = HistoryController = {
|
|||
(err, doc) => {
|
||||
if (err) return next(err)
|
||||
res.json({
|
||||
doc_id: doc._id
|
||||
doc_id: doc._id,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -156,7 +156,7 @@ module.exports = HistoryController = {
|
|||
{
|
||||
method: 'GET',
|
||||
url: `${settings.apis.project_history.url}/project/${projectId}/labels`,
|
||||
json: true
|
||||
json: true,
|
||||
},
|
||||
function (err, labels) {
|
||||
if (err) {
|
||||
|
@ -180,7 +180,7 @@ module.exports = HistoryController = {
|
|||
{
|
||||
method: 'POST',
|
||||
url: `${settings.apis.project_history.url}/project/${projectId}/user/${userId}/labels`,
|
||||
json: { comment, version }
|
||||
json: { comment, version },
|
||||
},
|
||||
function (err, label) {
|
||||
if (err) {
|
||||
|
@ -272,7 +272,7 @@ module.exports = HistoryController = {
|
|||
HistoryController._makeRequest(
|
||||
{
|
||||
method: 'DELETE',
|
||||
url: `${settings.apis.project_history.url}/project/${projectId}/user/${userId}/labels/${labelId}`
|
||||
url: `${settings.apis.project_history.url}/project/${projectId}/user/${userId}/labels/${labelId}`,
|
||||
},
|
||||
function (err) {
|
||||
if (err) {
|
||||
|
@ -338,17 +338,17 @@ module.exports = HistoryController = {
|
|||
const options = {
|
||||
auth: {
|
||||
user: settings.apis.v1_history.user,
|
||||
pass: settings.apis.v1_history.pass
|
||||
pass: settings.apis.v1_history.pass,
|
||||
},
|
||||
json: true,
|
||||
method: 'post',
|
||||
url
|
||||
url,
|
||||
}
|
||||
request(options, function (err, response, body) {
|
||||
if (err) {
|
||||
OError.tag(err, 'history API error', {
|
||||
v1ProjectId,
|
||||
version
|
||||
version,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ module.exports = HistoryController = {
|
|||
retryAttempt++
|
||||
const getReq = request({
|
||||
url: body.zipUrl,
|
||||
sendImmediately: true
|
||||
sendImmediately: true,
|
||||
})
|
||||
const abortS3Request = () => getReq.abort()
|
||||
req.on('aborted', abortS3Request)
|
||||
|
@ -394,7 +394,7 @@ module.exports = HistoryController = {
|
|||
delete response.headers['content-type']
|
||||
res.status(response.statusCode)
|
||||
res.setContentDisposition('attachment', {
|
||||
filename: `${name}.zip`
|
||||
filename: `${name}.zip`,
|
||||
})
|
||||
res.contentType('application/zip')
|
||||
pipeline(response, res, err => {
|
||||
|
@ -421,12 +421,12 @@ module.exports = HistoryController = {
|
|||
OError.tag(err, 'history s3 download failed', {
|
||||
v1ProjectId,
|
||||
version,
|
||||
retryAttempt
|
||||
retryAttempt,
|
||||
})
|
||||
next(err)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ module.exports = {
|
|||
flushProject,
|
||||
resyncProject,
|
||||
deleteProject,
|
||||
injectUserDetails
|
||||
}
|
||||
injectUserDetails,
|
||||
},
|
||||
}
|
||||
|
||||
async function initializeProject() {
|
||||
|
@ -30,7 +30,7 @@ async function initializeProject() {
|
|||
}
|
||||
try {
|
||||
const body = await request.post({
|
||||
url: `${settings.apis.project_history.url}/project`
|
||||
url: `${settings.apis.project_history.url}/project`,
|
||||
})
|
||||
const project = JSON.parse(body)
|
||||
const overleafId = project && project.project && project.project.id
|
||||
|
@ -46,11 +46,11 @@ async function initializeProject() {
|
|||
async function flushProject(projectId) {
|
||||
try {
|
||||
await request.post({
|
||||
url: `${settings.apis.project_history.url}/project/${projectId}/flush`
|
||||
url: `${settings.apis.project_history.url}/project/${projectId}/flush`,
|
||||
})
|
||||
} catch (err) {
|
||||
throw OError.tag(err, 'failed to flush project to project history', {
|
||||
projectId
|
||||
projectId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ async function flushProject(projectId) {
|
|||
async function resyncProject(projectId) {
|
||||
try {
|
||||
await request.post({
|
||||
url: `${settings.apis.project_history.url}/project/${projectId}/resync`
|
||||
url: `${settings.apis.project_history.url}/project/${projectId}/resync`,
|
||||
})
|
||||
} catch (err) {
|
||||
throw OError.tag(err, 'failed to resync project history', { projectId })
|
||||
|
@ -70,7 +70,7 @@ async function deleteProject(projectId, historyId) {
|
|||
const tasks = [
|
||||
request.delete(
|
||||
`${settings.apis.project_history.url}/project/${projectId}`
|
||||
)
|
||||
),
|
||||
]
|
||||
if (historyId != null) {
|
||||
tasks.push(
|
||||
|
@ -78,8 +78,8 @@ async function deleteProject(projectId, historyId) {
|
|||
url: `${settings.apis.v1_history.url}/projects/${historyId}`,
|
||||
auth: {
|
||||
user: settings.apis.v1_history.user,
|
||||
pass: settings.apis.v1_history.pass
|
||||
}
|
||||
pass: settings.apis.v1_history.pass,
|
||||
},
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ async function deleteProject(projectId, historyId) {
|
|||
} catch (err) {
|
||||
throw OError.tag(err, 'failed to clear project history', {
|
||||
projectId,
|
||||
historyId
|
||||
historyId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,5 +153,5 @@ module.exports = RestoreManager = {
|
|||
Settings.apis.project_history.url
|
||||
}/project/${project_id}/version/${version}/${encodeURIComponent(pathname)}`
|
||||
return FileWriter.writeUrlToDisk(project_id, url, callback)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -41,5 +41,5 @@ module.exports = {
|
|||
return res.sendStatus(200)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ module.exports = InactiveProjectManager = {
|
|||
function (err, project) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error getting project', {
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ module.exports = InactiveProjectManager = {
|
|||
return DocstoreManager.unarchiveProject(project_id, function (err) {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'error reactivating project in docstore', {
|
||||
project_id
|
||||
project_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ module.exports = InactiveProjectManager = {
|
|||
logger.log({ project_id }, 'deactivating inactive project')
|
||||
const jobs = [
|
||||
cb => DocstoreManager.archiveProject(project_id, cb),
|
||||
cb => ProjectUpdateHandler.markAsInactive(project_id, cb)
|
||||
cb => ProjectUpdateHandler.markAsInactive(project_id, cb),
|
||||
]
|
||||
return async.series(jobs, function (err) {
|
||||
if (err != null) {
|
||||
|
@ -114,5 +114,5 @@ module.exports = InactiveProjectManager = {
|
|||
}
|
||||
return callback(err)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ const { promisifyAll } = require('../../util/promises')
|
|||
const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
|
||||
const {
|
||||
V1ConnectionError,
|
||||
InvalidInstitutionalEmailError
|
||||
InvalidInstitutionalEmailError,
|
||||
} = require('../Errors/Errors')
|
||||
|
||||
const InstitutionsAPI = {
|
||||
|
@ -16,7 +16,7 @@ const InstitutionsAPI = {
|
|||
{
|
||||
method: 'GET',
|
||||
path: `/api/v2/institutions/${institutionId.toString()}/affiliations`,
|
||||
defaultErrorMessage: "Couldn't get institution affiliations"
|
||||
defaultErrorMessage: "Couldn't get institution affiliations",
|
||||
},
|
||||
(error, body) => callback(error, body || [])
|
||||
)
|
||||
|
@ -28,7 +28,7 @@ const InstitutionsAPI = {
|
|||
method: 'GET',
|
||||
path: `/api/v2/institutions/institutions_licences`,
|
||||
body: { query_date: queryDate, lag },
|
||||
defaultErrorMessage: 'Could not get institutions licences'
|
||||
defaultErrorMessage: 'Could not get institutions licences',
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -40,7 +40,7 @@ const InstitutionsAPI = {
|
|||
method: 'GET',
|
||||
path: `/api/v2/institutions/${institutionId.toString()}/institution_licences`,
|
||||
body: { start_date: startDate, end_date: endDate, lag },
|
||||
defaultErrorMessage: "Couldn't get institution licences"
|
||||
defaultErrorMessage: "Couldn't get institution licences",
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -52,7 +52,7 @@ const InstitutionsAPI = {
|
|||
method: 'GET',
|
||||
path: `/api/v2/institutions/${institutionId.toString()}/new_institution_licences`,
|
||||
body: { start_date: startDate, end_date: endDate, lag },
|
||||
defaultErrorMessage: "Couldn't get institution new licences"
|
||||
defaultErrorMessage: "Couldn't get institution new licences",
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -63,7 +63,7 @@ const InstitutionsAPI = {
|
|||
{
|
||||
method: 'GET',
|
||||
path: `/api/v2/users/${userId.toString()}/affiliations`,
|
||||
defaultErrorMessage: "Couldn't get user affiliations"
|
||||
defaultErrorMessage: "Couldn't get user affiliations",
|
||||
},
|
||||
(error, body) => callback(error, body || [])
|
||||
)
|
||||
|
@ -82,7 +82,7 @@ const InstitutionsAPI = {
|
|||
role,
|
||||
confirmedAt,
|
||||
entitlement,
|
||||
rejectIfBlocklisted
|
||||
rejectIfBlocklisted,
|
||||
} = affiliationOptions
|
||||
makeAffiliationRequest(
|
||||
{
|
||||
|
@ -95,9 +95,9 @@ const InstitutionsAPI = {
|
|||
role,
|
||||
confirmedAt,
|
||||
entitlement,
|
||||
rejectIfBlocklisted
|
||||
rejectIfBlocklisted,
|
||||
},
|
||||
defaultErrorMessage: "Couldn't create affiliation"
|
||||
defaultErrorMessage: "Couldn't create affiliation",
|
||||
},
|
||||
function (error, body) {
|
||||
if (error) {
|
||||
|
@ -137,7 +137,7 @@ const InstitutionsAPI = {
|
|||
path: `/api/v2/users/${userId.toString()}/affiliations/remove`,
|
||||
body: { email },
|
||||
extraSuccessStatusCodes: [404], // `Not Found` responses are considered successful
|
||||
defaultErrorMessage: "Couldn't remove affiliation"
|
||||
defaultErrorMessage: "Couldn't remove affiliation",
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -149,7 +149,7 @@ const InstitutionsAPI = {
|
|||
method: 'POST',
|
||||
path: `/api/v2/users/${userId.toString()}/affiliations/endorse`,
|
||||
body: { email, role, department },
|
||||
defaultErrorMessage: "Couldn't endorse affiliation"
|
||||
defaultErrorMessage: "Couldn't endorse affiliation",
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -160,7 +160,7 @@ const InstitutionsAPI = {
|
|||
{
|
||||
method: 'DELETE',
|
||||
path: `/api/v2/users/${userId.toString()}/affiliations`,
|
||||
defaultErrorMessage: "Couldn't delete affiliations"
|
||||
defaultErrorMessage: "Couldn't delete affiliations",
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -172,7 +172,7 @@ const InstitutionsAPI = {
|
|||
method: 'POST',
|
||||
path: `/api/v2/users/${userId}/affiliations/add_entitlement`,
|
||||
body: { email },
|
||||
defaultErrorMessage: "Couldn't add entitlement"
|
||||
defaultErrorMessage: "Couldn't add entitlement",
|
||||
},
|
||||
callback
|
||||
)
|
||||
|
@ -184,11 +184,11 @@ const InstitutionsAPI = {
|
|||
method: 'POST',
|
||||
path: `/api/v2/users/${userId}/affiliations/remove_entitlement`,
|
||||
body: { email },
|
||||
defaultErrorMessage: "Couldn't remove entitlement"
|
||||
defaultErrorMessage: "Couldn't remove entitlement",
|
||||
},
|
||||
callback
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var makeAffiliationRequest = function (requestOptions, callback) {
|
||||
|
@ -205,7 +205,7 @@ var makeAffiliationRequest = function (requestOptions, callback) {
|
|||
body: requestOptions.body,
|
||||
auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass },
|
||||
json: true,
|
||||
timeout: 20 * 1000
|
||||
timeout: 20 * 1000,
|
||||
},
|
||||
function (error, response, body) {
|
||||
if (error) {
|
||||
|
@ -221,8 +221,8 @@ var makeAffiliationRequest = function (requestOptions, callback) {
|
|||
message: 'error getting affiliations from v1',
|
||||
info: {
|
||||
status: response.statusCode,
|
||||
body: body
|
||||
}
|
||||
body: body,
|
||||
},
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ var makeAffiliationRequest = function (requestOptions, callback) {
|
|||
'getInstitutionAffiliations',
|
||||
'getUserAffiliations',
|
||||
'addAffiliation',
|
||||
'removeAffiliation'
|
||||
'removeAffiliation',
|
||||
].map(method =>
|
||||
metrics.timeAsyncMethod(
|
||||
InstitutionsAPI,
|
||||
|
|
|
@ -14,7 +14,7 @@ module.exports = {
|
|||
}
|
||||
res.sendStatus(200)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var affiliateUsers = function (hostname, callback) {
|
||||
|
@ -57,7 +57,7 @@ var affiliateUserByReversedHostname = function (
|
|||
{
|
||||
confirmedAt: email.confirmedAt,
|
||||
entitlement:
|
||||
email.samlIdentifier && email.samlIdentifier.hasEntitlement
|
||||
email.samlIdentifier && email.samlIdentifier.hasEntitlement,
|
||||
},
|
||||
error => {
|
||||
if (error) {
|
||||
|
|
|
@ -42,5 +42,5 @@ module.exports = InstitutionsFeatures = {
|
|||
|
||||
callback(null, hasLicence)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -48,5 +48,5 @@ module.exports = InstitutionsGetter = {
|
|||
userId,
|
||||
callback
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -24,5 +24,5 @@ function emailHasLicence(emailData) {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
emailHasLicence
|
||||
emailHasLicence,
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ module.exports = {
|
|||
async.eachLimit(affiliations, ASYNC_LIMIT, refreshFunction, err =>
|
||||
cb(err)
|
||||
)
|
||||
}
|
||||
},
|
||||
],
|
||||
callback
|
||||
)
|
||||
|
@ -59,12 +59,12 @@ module.exports = {
|
|||
)
|
||||
Subscription.find({
|
||||
admin_id: userIds,
|
||||
planCode: { $not: /trial/ }
|
||||
planCode: { $not: /trial/ },
|
||||
})
|
||||
.populate('admin_id', 'email')
|
||||
.exec(callback)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var fetchInstitutionAndAffiliations = (institutionId, callback) =>
|
||||
|
@ -79,7 +79,7 @@ var fetchInstitutionAndAffiliations = (institutionId, callback) =>
|
|||
(institution, cb) =>
|
||||
getInstitutionAffiliations(institutionId, (err, affiliations) =>
|
||||
cb(err, institution, affiliations)
|
||||
)
|
||||
),
|
||||
],
|
||||
callback
|
||||
)
|
||||
|
@ -103,7 +103,7 @@ var refreshFeaturesAndNotify = function (affiliation, callback) {
|
|||
cb(error, user, subscription, featuresChanged)
|
||||
),
|
||||
(user, subscription, featuresChanged, cb) =>
|
||||
notifyUser(user, affiliation, subscription, featuresChanged, cb)
|
||||
notifyUser(user, affiliation, subscription, featuresChanged, cb),
|
||||
],
|
||||
callback
|
||||
)
|
||||
|
@ -116,7 +116,7 @@ var getUserInfo = (userId, callback) =>
|
|||
(user, cb) =>
|
||||
SubscriptionLocator.getUsersSubscription(user, (err, subscription) =>
|
||||
cb(err, user, subscription)
|
||||
)
|
||||
),
|
||||
],
|
||||
callback
|
||||
)
|
||||
|
@ -147,7 +147,7 @@ var notifyUser = (user, affiliation, subscription, featuresChanged, callback) =>
|
|||
} else {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
callback
|
||||
)
|
||||
|
@ -158,14 +158,14 @@ var checkFeatures = function (institutionId, users) {
|
|||
total: users.length, // all users are confirmed email users
|
||||
totalProUsers: 0,
|
||||
totalNonProUsers: 0,
|
||||
nonProUsers: []
|
||||
nonProUsers: [],
|
||||
},
|
||||
entitledSSOUsers: {
|
||||
total: 0,
|
||||
totalProUsers: 0,
|
||||
totalNonProUsers: 0,
|
||||
nonProUsers: []
|
||||
}
|
||||
nonProUsers: [],
|
||||
},
|
||||
}
|
||||
users.forEach(function (user) {
|
||||
let isSSOEntitled = SAMLIdentityManager.userHasEntitlement(
|
||||
|
|
|
@ -33,7 +33,7 @@ const {
|
|||
NotOriginalImporterError,
|
||||
FeatureNotAvailableError,
|
||||
RemoteServiceError,
|
||||
FileCannotRefreshError
|
||||
FileCannotRefreshError,
|
||||
} = require('./LinkedFilesErrors')
|
||||
const Modules = require('../../infrastructure/Modules')
|
||||
|
||||
|
@ -42,7 +42,7 @@ module.exports = LinkedFilesController = {
|
|||
{
|
||||
url: require('./UrlAgent'),
|
||||
project_file: require('./ProjectFileAgent'),
|
||||
project_output_file: require('./ProjectOutputFileAgent')
|
||||
project_output_file: require('./ProjectOutputFileAgent'),
|
||||
},
|
||||
Modules.linkedFileAgentsIncludes()
|
||||
),
|
||||
|
@ -174,5 +174,5 @@ module.exports = LinkedFilesController = {
|
|||
} else {
|
||||
return next(error)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -39,5 +39,5 @@ module.exports = {
|
|||
NotOriginalImporterError,
|
||||
FeatureNotAvailableError,
|
||||
RemoteServiceError,
|
||||
FileCannotRefreshError
|
||||
FileCannotRefreshError,
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ const _ = require('underscore')
|
|||
const {
|
||||
ProjectNotFoundError,
|
||||
V1ProjectNotFoundError,
|
||||
BadDataError
|
||||
BadDataError,
|
||||
} = require('./LinkedFilesErrors')
|
||||
|
||||
module.exports = LinkedFilesHandler = {
|
||||
|
@ -34,7 +34,7 @@ module.exports = LinkedFilesHandler = {
|
|||
{
|
||||
project_id,
|
||||
element_id: file_id,
|
||||
type: 'file'
|
||||
type: 'file',
|
||||
},
|
||||
function (err, file, path, parentFolder) {
|
||||
if (err != null) {
|
||||
|
@ -159,5 +159,5 @@ module.exports = LinkedFilesHandler = {
|
|||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ module.exports = {
|
|||
endpointName: 'create-linked-file',
|
||||
params: ['project_id'],
|
||||
maxRequests: 100,
|
||||
timeInterval: 60
|
||||
timeInterval: 60,
|
||||
}),
|
||||
LinkedFilesController.createLinkedFile
|
||||
)
|
||||
|
@ -36,9 +36,9 @@ module.exports = {
|
|||
endpointName: 'refresh-linked-file',
|
||||
params: ['project_id'],
|
||||
maxRequests: 100,
|
||||
timeInterval: 60
|
||||
timeInterval: 60,
|
||||
}),
|
||||
LinkedFilesController.refreshLinkedFile
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ const {
|
|||
BadEntityTypeError,
|
||||
SourceFileNotFoundError,
|
||||
ProjectNotFoundError,
|
||||
V1ProjectNotFoundError
|
||||
V1ProjectNotFoundError,
|
||||
} = require('./LinkedFilesErrors')
|
||||
|
||||
module.exports = ProjectFileAgent = {
|
||||
|
@ -193,7 +193,7 @@ module.exports = ProjectFileAgent = {
|
|||
{
|
||||
project_id: source_project_id,
|
||||
path: source_entity_path,
|
||||
exactCaseMatch: true
|
||||
exactCaseMatch: true,
|
||||
},
|
||||
function (err, entity, type) {
|
||||
if (err != null) {
|
||||
|
@ -258,5 +258,5 @@ module.exports = ProjectFileAgent = {
|
|||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ const {
|
|||
BadDataError,
|
||||
AccessDeniedError,
|
||||
BadEntityTypeError,
|
||||
OutputFileFetchFailedError
|
||||
OutputFileFetchFailedError,
|
||||
} = require('./LinkedFilesErrors')
|
||||
const LinkedFilesHandler = require('./LinkedFilesHandler')
|
||||
const logger = require('logger-sharelatex')
|
||||
|
@ -173,7 +173,7 @@ module.exports = ProjectOutputFileAgent = {
|
|||
provider: data.provider,
|
||||
source_project_id: data.source_project_id,
|
||||
source_output_file_path: data.source_output_file_path,
|
||||
build_id: data.build_id
|
||||
build_id: data.build_id,
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -294,5 +294,5 @@ module.exports = ProjectOutputFileAgent = {
|
|||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ module.exports = UrlAgent = {
|
|||
_sanitizeData(data) {
|
||||
return {
|
||||
provider: data.provider,
|
||||
url: UrlHelper.prependHttpIfNeeded(data.url)
|
||||
url: UrlHelper.prependHttpIfNeeded(data.url),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -106,5 +106,5 @@ module.exports = UrlAgent = {
|
|||
const readStream = request.get(url)
|
||||
readStream.pause()
|
||||
return callback(null, readStream)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ module.exports = MetaController = {
|
|||
err,
|
||||
'[MetaController] error getting all labels from project',
|
||||
{
|
||||
project_id
|
||||
project_id,
|
||||
}
|
||||
)
|
||||
return next(err)
|
||||
|
@ -51,7 +51,7 @@ module.exports = MetaController = {
|
|||
if (err != null) {
|
||||
OError.tag(err, '[MetaController] error getting labels from doc', {
|
||||
project_id,
|
||||
doc_id
|
||||
doc_id,
|
||||
})
|
||||
return next(err)
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ module.exports = MetaController = {
|
|||
if (broadcast !== false) {
|
||||
EditorRealTimeController.emitToRoom(project_id, 'broadcastDocMeta', {
|
||||
docId: doc_id,
|
||||
meta: docMeta
|
||||
meta: docMeta,
|
||||
})
|
||||
return res.sendStatus(200)
|
||||
} else {
|
||||
|
@ -67,5 +67,5 @@ module.exports = MetaController = {
|
|||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -128,5 +128,5 @@ module.exports = MetaHandler = {
|
|||
projectMeta[doc._id] = MetaHandler.extractMetaFromDoc(doc.lines)
|
||||
}
|
||||
return projectMeta
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,7 +11,7 @@ module.exports = {
|
|||
subscribe: callbackify(provider.subscribe),
|
||||
unsubscribe: callbackify(provider.unsubscribe),
|
||||
changeEmail: callbackify(provider.changeEmail),
|
||||
promises: provider
|
||||
promises: provider,
|
||||
}
|
||||
|
||||
class NonFatalEmailUpdateError extends OError {
|
||||
|
@ -41,7 +41,7 @@ function makeMailchimpProvider() {
|
|||
return {
|
||||
subscribe,
|
||||
unsubscribe,
|
||||
changeEmail
|
||||
changeEmail,
|
||||
}
|
||||
|
||||
async function subscribe(user) {
|
||||
|
@ -51,12 +51,12 @@ function makeMailchimpProvider() {
|
|||
email_address: user.email,
|
||||
status: 'subscribed',
|
||||
status_if_new: 'subscribed',
|
||||
merge_fields: getMergeFields(user)
|
||||
merge_fields: getMergeFields(user),
|
||||
})
|
||||
logger.info({ user }, 'finished subscribing user to newsletter')
|
||||
} catch (err) {
|
||||
throw OError.tag(err, 'error subscribing user to newsletter', {
|
||||
userId: user._id
|
||||
userId: user._id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ function makeMailchimpProvider() {
|
|||
} else {
|
||||
await mailchimp.patch(path, {
|
||||
status: 'unsubscribed',
|
||||
merge_fields: getMergeFields(user)
|
||||
merge_fields: getMergeFields(user),
|
||||
})
|
||||
}
|
||||
logger.info(
|
||||
|
@ -91,7 +91,7 @@ function makeMailchimpProvider() {
|
|||
}
|
||||
|
||||
throw OError.tag(err, 'error unsubscribing user from newsletter', {
|
||||
userId: user._id
|
||||
userId: user._id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -135,14 +135,14 @@ function makeMailchimpProvider() {
|
|||
'could not be validated':
|
||||
'user has previously unsubscribed or new email already exist on list',
|
||||
'is already a list member': 'new email is already on mailing list',
|
||||
'looks fake or invalid': 'mail looks fake to mailchimp'
|
||||
'looks fake or invalid': 'mail looks fake to mailchimp',
|
||||
}
|
||||
|
||||
try {
|
||||
const path = getSubscriberPath(oldEmail)
|
||||
await mailchimp.patch(path, {
|
||||
email_address: newEmail,
|
||||
merge_fields: getMergeFields(user)
|
||||
merge_fields: getMergeFields(user),
|
||||
})
|
||||
logger.info('finished changing email in the newsletter')
|
||||
} catch (err) {
|
||||
|
@ -169,7 +169,7 @@ function makeMailchimpProvider() {
|
|||
// if we didn't find an expected error, generate something to throw
|
||||
throw OError.tag(err, 'error changing email in newsletter', {
|
||||
oldEmail,
|
||||
newEmail
|
||||
newEmail,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ function makeMailchimpProvider() {
|
|||
return {
|
||||
FNAME: user.first_name,
|
||||
LNAME: user.last_name,
|
||||
MONGO_ID: user._id.toString()
|
||||
MONGO_ID: user._id.toString(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ function makeNullProvider() {
|
|||
return {
|
||||
subscribe,
|
||||
unsubscribe,
|
||||
changeEmail
|
||||
changeEmail,
|
||||
}
|
||||
|
||||
async function subscribe(user) {
|
||||
|
|
|
@ -25,7 +25,7 @@ function dropboxDuplicateProjectNames(userId) {
|
|||
callback = function () {}
|
||||
}
|
||||
NotificationsHandler.markAsReadWithKey(userId, this.key, callback)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ function featuresUpgradedByAffiliation(affiliation, user) {
|
|||
callback = function () {}
|
||||
}
|
||||
NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ function redundantPersonalSubscription(affiliation, user) {
|
|||
callback = function () {}
|
||||
}
|
||||
NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ function projectInvite(invite, project, sendingUser, user) {
|
|||
userName: sendingUser.first_name,
|
||||
projectName: project.name,
|
||||
projectId: project._id.toString(),
|
||||
token: invite.token
|
||||
token: invite.token,
|
||||
}
|
||||
NotificationsHandler.createNotification(
|
||||
user._id,
|
||||
|
@ -110,7 +110,7 @@ function projectInvite(invite, project, sendingUser, user) {
|
|||
callback = function () {}
|
||||
}
|
||||
NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ function ipMatcherAffiliation(userId) {
|
|||
auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass },
|
||||
body: { ip },
|
||||
json: true,
|
||||
timeout: 20 * 1000
|
||||
timeout: 20 * 1000,
|
||||
},
|
||||
function (error, response, body) {
|
||||
if (error != null) {
|
||||
|
@ -150,7 +150,7 @@ function ipMatcherAffiliation(userId) {
|
|||
institutionId: body.id,
|
||||
content: body.enrolment_ad_html,
|
||||
portalPath,
|
||||
ssoEnabled: body.sso_enabled
|
||||
ssoEnabled: body.sso_enabled,
|
||||
}
|
||||
NotificationsHandler.createNotification(
|
||||
userId,
|
||||
|
@ -171,7 +171,7 @@ function ipMatcherAffiliation(userId) {
|
|||
}
|
||||
const key = `ip-matched-affiliation-${universityId}`
|
||||
NotificationsHandler.markAsReadWithKey(userId, key, callback)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ function tpdsFileLimit(userId) {
|
|||
callback = function () {}
|
||||
}
|
||||
const messageOpts = {
|
||||
projectName: projectName
|
||||
projectName: projectName,
|
||||
}
|
||||
NotificationsHandler.createNotification(
|
||||
userId,
|
||||
|
@ -200,7 +200,7 @@ function tpdsFileLimit(userId) {
|
|||
callback = function () {}
|
||||
}
|
||||
NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,13 +211,13 @@ const NotificationsBuilder = {
|
|||
redundantPersonalSubscription,
|
||||
projectInvite,
|
||||
ipMatcherAffiliation,
|
||||
tpdsFileLimit
|
||||
tpdsFileLimit,
|
||||
}
|
||||
|
||||
NotificationsBuilder.promises = {
|
||||
redundantPersonalSubscription: function (affiliation, user) {
|
||||
return promisifyAll(redundantPersonalSubscription(affiliation, user))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = NotificationsBuilder
|
||||
|
|
|
@ -41,5 +41,5 @@ module.exports = {
|
|||
NotificationsHandler.markAsRead(user_id, notification_id, () =>
|
||||
res.sendStatus(200)
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ module.exports = {
|
|||
}/user/${user_id}`,
|
||||
json: true,
|
||||
timeout: oneSecond,
|
||||
method: 'GET'
|
||||
method: 'GET',
|
||||
}
|
||||
return makeRequest(opts, function (err, res, unreadNotifications) {
|
||||
const statusCode = res != null ? res.statusCode : 500
|
||||
|
@ -75,7 +75,7 @@ module.exports = {
|
|||
key,
|
||||
messageOpts,
|
||||
templateKey,
|
||||
forceCreate
|
||||
forceCreate,
|
||||
}
|
||||
if (expiryDateTime != null) {
|
||||
payload.expires = expiryDateTime
|
||||
|
@ -88,7 +88,7 @@ module.exports = {
|
|||
}/user/${user_id}`,
|
||||
timeout: oneSecond,
|
||||
method: 'POST',
|
||||
json: payload
|
||||
json: payload,
|
||||
}
|
||||
return makeRequest(opts, callback)
|
||||
},
|
||||
|
@ -103,8 +103,8 @@ module.exports = {
|
|||
method: 'DELETE',
|
||||
timeout: oneSecond,
|
||||
json: {
|
||||
key
|
||||
}
|
||||
key,
|
||||
},
|
||||
}
|
||||
return makeRequest(opts, callback)
|
||||
},
|
||||
|
@ -117,7 +117,7 @@ module.exports = {
|
|||
? settings.apis.notifications.url
|
||||
: undefined
|
||||
}/user/${user_id}/notification/${notification_id}`,
|
||||
timeout: oneSecond
|
||||
timeout: oneSecond,
|
||||
}
|
||||
return makeRequest(opts, callback)
|
||||
},
|
||||
|
@ -132,8 +132,8 @@ module.exports = {
|
|||
: undefined
|
||||
}/key/${key}`,
|
||||
method: 'DELETE',
|
||||
timeout: oneSecond
|
||||
timeout: oneSecond,
|
||||
}
|
||||
return makeRequest(opts, callback)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ async function setNewUserPassword(req, res, next) {
|
|||
// password reset via tokens can be done while logged in, or not
|
||||
const auditLog = {
|
||||
initiatorId,
|
||||
ip: req.ip
|
||||
ip: req.ip,
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -66,7 +66,7 @@ module.exports = {
|
|||
endpointName: 'password_reset_rate_limit',
|
||||
timeInterval: 60,
|
||||
subjectName: req.ip,
|
||||
throttle: 6
|
||||
throttle: 6,
|
||||
}
|
||||
RateLimiter.addCount(opts, (err, canContinue) => {
|
||||
if (err != null) {
|
||||
|
@ -76,26 +76,26 @@ module.exports = {
|
|||
}
|
||||
if (!canContinue) {
|
||||
return res.status(429).send({
|
||||
message: req.i18n.translate('rate_limit_hit_wait')
|
||||
message: req.i18n.translate('rate_limit_hit_wait'),
|
||||
})
|
||||
}
|
||||
PasswordResetHandler.generateAndEmailResetToken(email, (err, status) => {
|
||||
if (err != null) {
|
||||
OError.tag(err, 'failed to generate and email password reset token', {
|
||||
email
|
||||
email,
|
||||
})
|
||||
next(err)
|
||||
} else if (status === 'primary') {
|
||||
res.status(200).send({
|
||||
message: { text: req.i18n.translate('password_reset_email_sent') }
|
||||
message: { text: req.i18n.translate('password_reset_email_sent') },
|
||||
})
|
||||
} else if (status === 'secondary') {
|
||||
res.status(404).send({
|
||||
message: req.i18n.translate('secondary_email_password_reset')
|
||||
message: req.i18n.translate('secondary_email_password_reset'),
|
||||
})
|
||||
} else {
|
||||
res.status(404).send({
|
||||
message: req.i18n.translate('cant_find_email')
|
||||
message: req.i18n.translate('cant_find_email'),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -119,9 +119,9 @@ module.exports = {
|
|||
}
|
||||
res.render('user/setPassword', {
|
||||
title: 'set_password',
|
||||
passwordResetToken: req.session.resetToken
|
||||
passwordResetToken: req.session.resetToken,
|
||||
})
|
||||
},
|
||||
|
||||
setNewUserPassword: expressify(setNewUserPassword)
|
||||
setNewUserPassword: expressify(setNewUserPassword),
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue