2019-05-29 05:21:06 -04:00
|
|
|
/* eslint-disable
|
2020-12-15 05:23:54 -05:00
|
|
|
node/handle-callback-err,
|
2019-05-29 05:21:06 -04:00
|
|
|
max-len,
|
|
|
|
no-unused-vars,
|
|
|
|
*/
|
|
|
|
// TODO: This file was created by bulk-decaffeinate.
|
|
|
|
// Fix any style issues and re-enable lint.
|
|
|
|
/*
|
|
|
|
* decaffeinate suggestions:
|
|
|
|
* DS101: Remove unnecessary use of Array.from
|
|
|
|
* DS102: Remove unnecessary code created because of implicit returns
|
|
|
|
* DS207: Consider shorter variations of null checks
|
|
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
*/
|
2020-09-23 04:49:26 -04:00
|
|
|
const { ObjectId } = require('mongodb')
|
2019-05-29 05:21:06 -04:00
|
|
|
const async = require('async')
|
2019-09-24 04:44:13 -04:00
|
|
|
const { promisifyAll } = require('../../util/promises')
|
2019-05-29 05:21:06 -04:00
|
|
|
const Errors = require('../Errors/Errors')
|
|
|
|
const EntityModels = {
|
|
|
|
Institution: require('../../models/Institution').Institution,
|
|
|
|
Subscription: require('../../models/Subscription').Subscription,
|
2021-04-27 03:52:58 -04:00
|
|
|
Publisher: require('../../models/Publisher').Publisher,
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const UserMembershipViewModel = require('./UserMembershipViewModel')
|
|
|
|
const UserGetter = require('../User/UserGetter')
|
2021-11-10 08:40:18 -05:00
|
|
|
const logger = require('@overleaf/logger')
|
2019-05-29 05:21:06 -04:00
|
|
|
const UserMembershipEntityConfigs = require('./UserMembershipEntityConfigs')
|
2022-02-10 04:50:12 -05:00
|
|
|
const { UserIsManagerError } = require('./UserMembershipErrors')
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2019-09-24 04:44:13 -04:00
|
|
|
const UserMembershipHandler = {
|
2019-05-29 05:21:06 -04:00
|
|
|
getEntityWithoutAuthorizationCheck(entityId, entityConfig, callback) {
|
|
|
|
if (callback == null) {
|
2021-10-27 05:49:18 -04:00
|
|
|
callback = function () {}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const query = buildEntityQuery(entityId, entityConfig)
|
|
|
|
return EntityModels[entityConfig.modelName].findOne(query, callback)
|
|
|
|
},
|
|
|
|
|
|
|
|
createEntity(entityId, entityConfig, callback) {
|
|
|
|
if (callback == null) {
|
2021-10-27 05:49:18 -04:00
|
|
|
callback = function () {}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const data = buildEntityQuery(entityId, entityConfig)
|
|
|
|
return EntityModels[entityConfig.modelName].create(data, callback)
|
|
|
|
},
|
|
|
|
|
|
|
|
getUsers(entity, entityConfig, callback) {
|
|
|
|
if (callback == null) {
|
2021-10-27 05:49:18 -04:00
|
|
|
callback = function () {}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const attributes = entityConfig.fields.read
|
|
|
|
return getPopulatedListOfMembers(entity, attributes, callback)
|
|
|
|
},
|
|
|
|
|
|
|
|
addUser(entity, entityConfig, email, callback) {
|
|
|
|
if (callback == null) {
|
2021-10-27 05:49:18 -04:00
|
|
|
callback = function () {}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const attribute = entityConfig.fields.write
|
2021-04-14 09:17:21 -04:00
|
|
|
return UserGetter.getUserByAnyEmail(email, function (error, user) {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (error != null) {
|
|
|
|
return callback(error)
|
|
|
|
}
|
|
|
|
if (!user) {
|
2021-10-06 07:24:30 -04:00
|
|
|
const err = { userNotFound: true }
|
|
|
|
return callback(err)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
if (entity[attribute].some(managerId => managerId.equals(user._id))) {
|
2021-10-06 07:24:30 -04:00
|
|
|
error = { alreadyAdded: true }
|
|
|
|
return callback(error)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return addUserToEntity(entity, attribute, user, error =>
|
|
|
|
callback(error, UserMembershipViewModel.build(user))
|
|
|
|
)
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
removeUser(entity, entityConfig, userId, callback) {
|
|
|
|
if (callback == null) {
|
2021-10-27 05:49:18 -04:00
|
|
|
callback = function () {}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const attribute = entityConfig.fields.write
|
|
|
|
if (entity.admin_id != null ? entity.admin_id.equals(userId) : undefined) {
|
2022-02-10 04:50:12 -05:00
|
|
|
return callback(new UserIsManagerError())
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
return removeUserFromEntity(entity, attribute, userId, callback)
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
|
2019-09-24 04:44:13 -04:00
|
|
|
UserMembershipHandler.promises = promisifyAll(UserMembershipHandler)
|
|
|
|
module.exports = UserMembershipHandler
|
|
|
|
|
2021-10-26 04:08:56 -04:00
|
|
|
function getPopulatedListOfMembers(entity, attributes, callback) {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (callback == null) {
|
2021-10-27 05:49:18 -04:00
|
|
|
callback = function () {}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const userObjects = []
|
|
|
|
|
2021-05-05 09:05:04 -04:00
|
|
|
for (const attribute of Array.from(attributes)) {
|
|
|
|
for (const userObject of Array.from(entity[attribute] || [])) {
|
2019-05-29 05:21:06 -04:00
|
|
|
// userObject can be an email as String, a user id as ObjectId or an
|
|
|
|
// invite as Object with an email attribute as String. We want to pass to
|
|
|
|
// UserMembershipViewModel either an email as (String) or a user id (ObjectId)
|
|
|
|
const userIdOrEmail = userObject.email || userObject
|
|
|
|
userObjects.push(userIdOrEmail)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return async.map(userObjects, UserMembershipViewModel.buildAsync, callback)
|
|
|
|
}
|
|
|
|
|
2021-10-26 04:08:56 -04:00
|
|
|
function addUserToEntity(entity, attribute, user, callback) {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (callback == null) {
|
2021-10-27 05:49:18 -04:00
|
|
|
callback = function () {}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const fieldUpdate = {}
|
|
|
|
fieldUpdate[attribute] = user._id
|
2020-11-03 04:19:05 -05:00
|
|
|
return entity.updateOne({ $addToSet: fieldUpdate }, callback)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
|
2021-10-26 04:08:56 -04:00
|
|
|
function removeUserFromEntity(entity, attribute, userId, callback) {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (callback == null) {
|
2021-10-27 05:49:18 -04:00
|
|
|
callback = function () {}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
const fieldUpdate = {}
|
|
|
|
fieldUpdate[attribute] = userId
|
2020-11-03 04:19:05 -05:00
|
|
|
return entity.updateOne({ $pull: fieldUpdate }, callback)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
|
2021-10-26 04:08:56 -04:00
|
|
|
function buildEntityQuery(entityId, entityConfig, loggedInUser) {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (ObjectId.isValid(entityId.toString())) {
|
|
|
|
entityId = ObjectId(entityId)
|
|
|
|
}
|
|
|
|
const query = Object.assign({}, entityConfig.baseQuery)
|
|
|
|
query[entityConfig.fields.primaryKey] = entityId
|
|
|
|
return query
|
|
|
|
}
|