mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-27 09:33:55 +00:00
Use team invites to join domain licensed teams
This commit is contained in:
parent
39c8595c27
commit
d262de14d6
10 changed files with 109 additions and 118 deletions
|
@ -0,0 +1,47 @@
|
|||
SubscriptionGroupHandler = require("./SubscriptionGroupHandler")
|
||||
logger = require("logger-sharelatex")
|
||||
SubscriptionLocator = require("./SubscriptionLocator")
|
||||
ErrorsController = require("../Errors/ErrorController")
|
||||
SubscriptionDomainHandler = require("./SubscriptionDomainHandler")
|
||||
AuthenticationController = require('../Authentication/AuthenticationController')
|
||||
TeamInvitesHandler = require('./TeamInvitesHandler')
|
||||
|
||||
async = require("async")
|
||||
|
||||
module.exports =
|
||||
join: (req, res)->
|
||||
user = AuthenticationController.getSessionUser(req)
|
||||
licence = SubscriptionDomainHandler.getLicenceUserCanJoin(user)
|
||||
|
||||
if !licence?
|
||||
return ErrorsController.notFound(req, res)
|
||||
|
||||
jobs =
|
||||
partOfGroup: (cb)->
|
||||
SubscriptionGroupHandler.isUserPartOfGroup user.id, licence.group_subscription_id, cb
|
||||
subscription: (cb)->
|
||||
SubscriptionLocator.getUsersSubscription user.id, cb
|
||||
|
||||
async.series jobs, (err, results)->
|
||||
{ partOfGroup, subscription } = results
|
||||
if partOfGroup
|
||||
return res.redirect("/user/subscription/custom_account")
|
||||
else
|
||||
res.render "subscriptions/domain/join",
|
||||
title: "Group Invitation"
|
||||
group_subscription_id: licence.group_subscription_id
|
||||
licenceName: licence.name
|
||||
has_personal_subscription: subscription?
|
||||
|
||||
createInvite: (req, res)->
|
||||
user = AuthenticationController.getSessionUser(req)
|
||||
licence = SubscriptionDomainHandler.getLicenceUserCanJoin(user)
|
||||
|
||||
if !licence?
|
||||
return ErrorsController.notFound(req, res)
|
||||
|
||||
TeamInvitesHandler.createDomainInvite user, licence, (err) ->
|
||||
if err?
|
||||
res.sendStatus 500
|
||||
else
|
||||
res.sendStatus 200
|
|
@ -1,45 +0,0 @@
|
|||
SubscriptionGroupHandler = require("./SubscriptionGroupHandler")
|
||||
logger = require("logger-sharelatex")
|
||||
SubscriptionLocator = require("./SubscriptionLocator")
|
||||
ErrorsController = require("../Errors/ErrorController")
|
||||
SubscriptionDomainHandler = require("./SubscriptionDomainHandler")
|
||||
AuthenticationController = require('../Authentication/AuthenticationController')
|
||||
async = require("async")
|
||||
|
||||
module.exports =
|
||||
newInvite: (req, res)->
|
||||
group_subscription_id = req.params.subscription_id
|
||||
user_id = AuthenticationController.getLoggedInUserId(req)
|
||||
licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(group_subscription_id)
|
||||
if !licence?
|
||||
return ErrorsController.notFound(req, res)
|
||||
jobs =
|
||||
partOfGroup: (cb)->
|
||||
SubscriptionGroupHandler.isUserPartOfGroup user_id, licence.group_subscription_id, cb
|
||||
subscription: (cb)->
|
||||
SubscriptionLocator.getUsersSubscription user_id, cb
|
||||
async.series jobs, (err, results)->
|
||||
{partOfGroup, subscription} = results
|
||||
if partOfGroup
|
||||
return res.redirect("/user/subscription/custom_account")
|
||||
else
|
||||
res.render "subscriptions/group/join",
|
||||
title: "Group Invitation"
|
||||
group_subscription_id:group_subscription_id
|
||||
licenceName:licence.name
|
||||
has_personal_subscription: subscription?
|
||||
|
||||
createInvite: (req, res)->
|
||||
subscription_id = req.params.subscription_id
|
||||
currentUser = AuthenticationController.getSessionUser(req)
|
||||
if !currentUser?
|
||||
logger.err {subscription_id}, "error getting current user"
|
||||
return res.sendStatus 500
|
||||
licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id)
|
||||
if !licence?
|
||||
return ErrorsController.notFound(req, res)
|
||||
SubscriptionGroupHandler.sendVerificationEmail subscription_id, licence.name, currentUser.email, (err)->
|
||||
if err?
|
||||
res.sendStatus 500
|
||||
else
|
||||
res.sendStatus 200
|
|
@ -15,7 +15,7 @@ module.exports = SubscriptionDomainHandler =
|
|||
getDomainLicencePage: (user)->
|
||||
licence = SubscriptionDomainHandler._findDomainLicence(user.email)
|
||||
if licence?.verifyEmail
|
||||
return "/user/subscription/#{licence.subscription_id}/group/invited"
|
||||
return "/user/subscription/domain/join"
|
||||
else
|
||||
return undefined
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
AuthenticationController = require('../Authentication/AuthenticationController')
|
||||
SubscriptionController = require('./SubscriptionController')
|
||||
SubscriptionGroupController = require './SubscriptionGroupController'
|
||||
DomainSubscriptionController = require './DomainSubscriptionController'
|
||||
DomainLicenceController = require './DomainLicenceController'
|
||||
TeamInvitesController = require './TeamInvitesController'
|
||||
Settings = require "settings-sharelatex"
|
||||
|
||||
|
@ -38,8 +38,8 @@ module.exports =
|
|||
TeamInvitesController.revokeInvite
|
||||
|
||||
# Routes to join a domain licence team
|
||||
webRouter.get '/user/subscription/:subscription_id/group/join', AuthenticationController.requireLogin(), DomainSubscriptionController.newInvite
|
||||
webRouter.post '/user/subscription/:subscription_id/group/join', AuthenticationController.requireLogin(), DomainSubscriptionController.createInvite
|
||||
webRouter.get '/user/subscription/domain/join', AuthenticationController.requireLogin(), DomainLicenceController.join
|
||||
webRouter.post '/user/subscription/domain/join', AuthenticationController.requireLogin(), DomainLicenceController.createInvite
|
||||
|
||||
#recurly callback
|
||||
publicApiRouter.post '/user/subscription/callback', SubscriptionController.recurlyNotificationParser, SubscriptionController.recurlyCallback
|
||||
|
|
|
@ -2,6 +2,7 @@ settings = require "settings-sharelatex"
|
|||
logger = require("logger-sharelatex")
|
||||
TeamInvitesHandler = require('./TeamInvitesHandler')
|
||||
AuthenticationController = require("../Authentication/AuthenticationController")
|
||||
SubscriptionLocator = require("./SubscriptionLocator")
|
||||
ErrorController = require("../Errors/ErrorController")
|
||||
|
||||
module.exports =
|
||||
|
@ -20,19 +21,20 @@ module.exports =
|
|||
token = req.params.token
|
||||
userId = AuthenticationController.getLoggedInUserId(req)
|
||||
|
||||
TeamInvitesHandler.getInviteDetails token, userId, (err, results) ->
|
||||
TeamInvitesHandler.getInvite token, (err, invite, teamSubscription) ->
|
||||
next(err) if err?
|
||||
|
||||
{ invite, personalSubscription, inviterName } = results
|
||||
|
||||
unless invite?
|
||||
return ErrorController.notFound(req, res, next)
|
||||
|
||||
res.render "subscriptions/group/team_invite",
|
||||
inviterName: inviterName
|
||||
inviteToken: invite.token
|
||||
hasPersonalSubscription: personalSubscription?
|
||||
appName: settings.appName
|
||||
SubscriptionLocator.getUsersSubscription userId, (err, personalSubscription) ->
|
||||
return callback(err) if err?
|
||||
|
||||
res.render "subscriptions/team/invite",
|
||||
inviterName: invite.inviterName
|
||||
inviteToken: invite.token
|
||||
hasPersonalSubscription: personalSubscription?
|
||||
appName: settings.appName
|
||||
|
||||
|
||||
acceptInvite: (req, res, next) ->
|
||||
|
|
|
@ -19,47 +19,39 @@ module.exports = TeamInvitesHandler =
|
|||
getInvites: (subscriptionId, callback) ->
|
||||
TeamInvite.find(subscriptionId: subscriptionId, callback)
|
||||
|
||||
createInvite: (teamManagerId, email, callback) ->
|
||||
getInvite: (token, callback) ->
|
||||
Subscription.findOne 'teamInvites.token': token, (err, subscription) ->
|
||||
return callback(err, subscription) if err?
|
||||
return callback(teamNotFound: true) unless subscription?
|
||||
|
||||
invite = subscription.teamInvites.find (i) -> i.token == token
|
||||
return callback(null, invite, subscription)
|
||||
|
||||
createManagerInvite: (teamManagerId, email, callback) ->
|
||||
UserLocator.findById teamManagerId, (error, teamManager) ->
|
||||
return callback(error) if error?
|
||||
|
||||
SubscriptionLocator.getUsersSubscription teamManagerId, (error, subscription) ->
|
||||
return callback(error) if error?
|
||||
|
||||
if LimitationsManager.teamHasReachedMemberLimit(subscription)
|
||||
return callback(limitReached: true)
|
||||
if teamManager.first_name and teamManager.last_name
|
||||
inviterName = "#{teamManager.first_name} #{teamManager.last_name} (#{teamManager.email})"
|
||||
else
|
||||
inviterName = teamManager.email
|
||||
|
||||
existingInvite = subscription.teamInvites.find (invite) -> invite.email == email
|
||||
TeamInvitesHandler.createInvite(subscription, email, inviterName, callback)
|
||||
|
||||
if existingInvite
|
||||
return callback(alreadyInvited: true)
|
||||
|
||||
inviterName = TeamInvitesHandler.inviterName(teamManager)
|
||||
token = crypto.randomBytes(32).toString("hex")
|
||||
|
||||
invite = {
|
||||
email: email,
|
||||
token: token,
|
||||
sentAt: new Date(),
|
||||
}
|
||||
|
||||
subscription.teamInvites.push(invite)
|
||||
|
||||
subscription.save (error) ->
|
||||
return callback(error) if error?
|
||||
|
||||
# TODO: use standard way to canonalise email addresses
|
||||
opts =
|
||||
to: email.trim().toLowerCase()
|
||||
inviterName: inviterName
|
||||
acceptInviteUrl: "#{settings.siteUrl}/subscription/invites/#{token}/"
|
||||
EmailHandler.sendEmail "verifyEmailToJoinTeam", opts, (error) ->
|
||||
return callback(error, invite)
|
||||
createDomainInvite: (user, licence, callback) ->
|
||||
SubscriptionLocator.getSubscription licence.subscription_id, (error, subscription) ->
|
||||
return callback(error) if error?
|
||||
TeamInvitesHandler.createInvite(subscription, user.email, licence.name, callback)
|
||||
|
||||
acceptInvite: (token, userId, callback) ->
|
||||
TeamInvitesHandler.getInviteAndManager token, (err, invite, subscription, teamManager) ->
|
||||
TeamInvitesHandler.getInvite token, (err, invite, subscription) ->
|
||||
return callback(err) if err?
|
||||
return callback(inviteNoLongerValid: true) unless invite? and teamManager?
|
||||
return callback(inviteNoLongerValid: true) unless invite?
|
||||
|
||||
SubscriptionUpdater.addUserToGroup teamManager, userId, (err) ->
|
||||
SubscriptionUpdater.addUserToGroup subscription.admin_id, userId, (err) ->
|
||||
return callback(err) if err?
|
||||
|
||||
TeamInvitesHandler.removeInviteFromTeam(subscription.id, invite.email, callback)
|
||||
|
@ -70,45 +62,39 @@ module.exports = TeamInvitesHandler =
|
|||
|
||||
TeamInvitesHandler.removeInviteFromTeam(teamSubscription.id, email, callback)
|
||||
|
||||
getInviteDetails: (token, userId, callback) ->
|
||||
TeamInvitesHandler.getInviteAndManager token, (err, invite, teamSubscription, teamManager) ->
|
||||
return callback(err) if err?
|
||||
createInvite: (subscription, email, inviterName, callback) ->
|
||||
if LimitationsManager.teamHasReachedMemberLimit(subscription)
|
||||
return callback(limitReached: true)
|
||||
|
||||
SubscriptionLocator.getUsersSubscription userId, (err, personalSubscription) ->
|
||||
return callback(err) if err?
|
||||
existingInvite = subscription.teamInvites.find (invite) -> invite.email == email
|
||||
|
||||
return callback(null , {
|
||||
invite: invite,
|
||||
personalSubscription: personalSubscription,
|
||||
team: teamSubscription,
|
||||
inviterName: TeamInvitesHandler.inviterName(teamManager),
|
||||
teamManager: teamManager
|
||||
})
|
||||
if existingInvite
|
||||
return callback(alreadyInvited: true)
|
||||
|
||||
getInviteAndManager: (token, callback) ->
|
||||
TeamInvitesHandler.getInvite token, (err, invite, teamSubscription) ->
|
||||
return callback(err) if err?
|
||||
token = crypto.randomBytes(32).toString("hex")
|
||||
|
||||
UserLocator.findById teamSubscription.admin_id, (err, teamManager) ->
|
||||
return callback(err, invite, teamSubscription, teamManager)
|
||||
invite = {
|
||||
email: email,
|
||||
token: token,
|
||||
inviterName: inviterName,
|
||||
sentAt: new Date(),
|
||||
}
|
||||
|
||||
getInvite: (token, callback) ->
|
||||
Subscription.findOne 'teamInvites.token': token, (err, subscription) ->
|
||||
return callback(err, subscription) if err?
|
||||
return callback(teamNotFound: true) unless subscription?
|
||||
subscription.teamInvites.push(invite)
|
||||
|
||||
invite = subscription.teamInvites.find (i) -> i.token == token
|
||||
return callback(null, invite, subscription)
|
||||
subscription.save (error) ->
|
||||
return callback(error) if error?
|
||||
|
||||
# TODO: use standard way to canonalise email addresses
|
||||
opts =
|
||||
to: email.trim().toLowerCase()
|
||||
inviterName: inviterName
|
||||
acceptInviteUrl: "#{settings.siteUrl}/subscription/invites/#{token}/"
|
||||
EmailHandler.sendEmail "verifyEmailToJoinTeam", opts, (error) ->
|
||||
return callback(error, invite)
|
||||
|
||||
removeInviteFromTeam: (subscriptionId, email, callback) ->
|
||||
searchConditions = { _id: new ObjectId(subscriptionId.toString()) }
|
||||
updateOp = { $pull: { teamInvites: { email: email.trim().toLowerCase() } } }
|
||||
|
||||
Subscription.update(searchConditions, updateOp, callback)
|
||||
|
||||
inviterName: (teamManager) ->
|
||||
if teamManager.first_name and teamManager.last_name
|
||||
"#{teamManager.first_name} #{teamManager.last_name} (#{teamManager.email})"
|
||||
else
|
||||
teamManager.email
|
||||
|
|
|
@ -7,6 +7,7 @@ ObjectId = Schema.ObjectId
|
|||
TeamInviteSchema = new Schema
|
||||
email : { type: String, required: true }
|
||||
token : { type: String }
|
||||
inviterName : { type: String }
|
||||
sentAt : { type: Date }
|
||||
|
||||
mongoose.model 'TeamInvite', TeamInviteSchema
|
||||
|
|
|
@ -25,7 +25,7 @@ define [
|
|||
$scope.joinGroup = ->
|
||||
$scope.view = "requestSent"
|
||||
$scope.inflight = true
|
||||
request = $http.post "/user/subscription/#{group_subscription_id}/group/join", {_csrf:window.csrfToken}
|
||||
request = $http.post "/user/subscription/domain/join", {_csrf:window.csrfToken}
|
||||
request.then (response)->
|
||||
{ status } = response
|
||||
$scope.inflight = false
|
||||
|
|
Loading…
Add table
Reference in a new issue