mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #1845 from overleaf/ta-invite-self
Don't Send Invite when Group Manager Invite Self GitOrigin-RevId: 35d7aecc82cf1124fbdac7fe986081b9556c23f9
This commit is contained in:
parent
f6c2cfe727
commit
8caea13193
2 changed files with 160 additions and 165 deletions
|
@ -1,16 +1,3 @@
|
||||||
/* eslint-disable
|
|
||||||
handle-callback-err,
|
|
||||||
max-len,
|
|
||||||
no-unused-vars,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
let TeamInvitesHandler
|
let TeamInvitesHandler
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
|
@ -19,7 +6,6 @@ const async = require('async')
|
||||||
const settings = require('settings-sharelatex')
|
const settings = require('settings-sharelatex')
|
||||||
const { ObjectId } = require('mongojs')
|
const { ObjectId } = require('mongojs')
|
||||||
|
|
||||||
const { TeamInvite } = require('../../models/TeamInvite')
|
|
||||||
const { Subscription } = require('../../models/Subscription')
|
const { Subscription } = require('../../models/Subscription')
|
||||||
|
|
||||||
const UserGetter = require('../User/UserGetter')
|
const UserGetter = require('../User/UserGetter')
|
||||||
|
@ -38,54 +24,45 @@ module.exports = TeamInvitesHandler = {
|
||||||
err,
|
err,
|
||||||
subscription
|
subscription
|
||||||
) {
|
) {
|
||||||
if (err != null) {
|
if (err) {
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
if (subscription == null) {
|
if (!subscription) {
|
||||||
return callback(new Errors.NotFoundError('team not found'))
|
return callback(new Errors.NotFoundError('team not found'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const invite = subscription.teamInvites.find(i => i.token === token)
|
const invite = subscription.teamInvites.find(i => i.token === token)
|
||||||
return callback(null, invite, subscription)
|
callback(null, invite, subscription)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
createInvite(teamManagerId, subscription, email, callback) {
|
createInvite(teamManagerId, subscription, email, callback) {
|
||||||
email = EmailHelper.parseEmail(email)
|
email = EmailHelper.parseEmail(email)
|
||||||
if (email == null) {
|
if (!email) {
|
||||||
return callback(new Error('invalid email'))
|
return callback(new Error('invalid email'))
|
||||||
}
|
}
|
||||||
logger.log({ teamManagerId, email }, 'Creating manager team invite')
|
logger.log({ teamManagerId, email }, 'Creating manager team invite')
|
||||||
return UserGetter.getUser(teamManagerId, function(error, teamManager) {
|
return UserGetter.getUser(teamManagerId, function(error, teamManager) {
|
||||||
let inviterName
|
if (error) {
|
||||||
if (error != null) {
|
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (teamManager.first_name && teamManager.last_name) {
|
removeLegacyInvite(subscription.id, email, function(error) {
|
||||||
inviterName = `${teamManager.first_name} ${teamManager.last_name} (${
|
if (error) {
|
||||||
teamManager.email
|
|
||||||
})`
|
|
||||||
} else {
|
|
||||||
inviterName = teamManager.email
|
|
||||||
}
|
|
||||||
|
|
||||||
return removeLegacyInvite(subscription.id, email, function(error) {
|
|
||||||
if (error != null) {
|
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
return createInvite(subscription, email, inviterName, callback)
|
createInvite(subscription, email, teamManager, callback)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
importInvite(subscription, inviterName, email, token, sentAt, callback) {
|
importInvite(subscription, inviterName, email, token, sentAt, callback) {
|
||||||
return checkIfInviteIsPossible(subscription, email, function(
|
checkIfInviteIsPossible(subscription, email, function(
|
||||||
error,
|
error,
|
||||||
possible,
|
possible,
|
||||||
reason
|
reason
|
||||||
) {
|
) {
|
||||||
if (error != null) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
if (!possible) {
|
if (!possible) {
|
||||||
|
@ -99,60 +76,51 @@ module.exports = TeamInvitesHandler = {
|
||||||
sentAt
|
sentAt
|
||||||
})
|
})
|
||||||
|
|
||||||
return subscription.save(callback)
|
subscription.save(callback)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
acceptInvite(token, userId, callback) {
|
acceptInvite(token, userId, callback) {
|
||||||
logger.log({ userId }, 'Accepting invite')
|
logger.log({ userId }, 'Accepting invite')
|
||||||
return TeamInvitesHandler.getInvite(token, function(
|
TeamInvitesHandler.getInvite(token, function(err, invite, subscription) {
|
||||||
err,
|
if (err) {
|
||||||
invite,
|
|
||||||
subscription
|
|
||||||
) {
|
|
||||||
if (err != null) {
|
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
if (invite == null) {
|
if (!invite) {
|
||||||
return callback(new Errors.NotFoundError('invite not found'))
|
return callback(new Errors.NotFoundError('invite not found'))
|
||||||
}
|
}
|
||||||
|
|
||||||
return SubscriptionUpdater.addUserToGroup(
|
SubscriptionUpdater.addUserToGroup(subscription._id, userId, function(
|
||||||
subscription._id,
|
err
|
||||||
userId,
|
) {
|
||||||
function(err) {
|
if (err) {
|
||||||
if (err != null) {
|
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return removeInviteFromTeam(subscription.id, invite.email, callback)
|
removeInviteFromTeam(subscription.id, invite.email, callback)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
revokeInvite(teamManagerId, subscription, email, callback) {
|
revokeInvite(teamManagerId, subscription, email, callback) {
|
||||||
email = EmailHelper.parseEmail(email)
|
email = EmailHelper.parseEmail(email)
|
||||||
if (email == null) {
|
if (!email) {
|
||||||
return callback(new Error('invalid email'))
|
return callback(new Error('invalid email'))
|
||||||
}
|
}
|
||||||
logger.log({ teamManagerId, email }, 'Revoking invite')
|
logger.log({ teamManagerId, email }, 'Revoking invite')
|
||||||
return removeInviteFromTeam(subscription.id, email, callback)
|
removeInviteFromTeam(subscription.id, email, callback)
|
||||||
},
|
},
|
||||||
|
|
||||||
// Legacy method to allow a user to receive a confirmation email if their
|
// Legacy method to allow a user to receive a confirmation email if their
|
||||||
// email is in Subscription.invited_emails when they join. We'll remove this
|
// email is in Subscription.invited_emails when they join. We'll remove this
|
||||||
// after a short while.
|
// after a short while.
|
||||||
createTeamInvitesForLegacyInvitedEmail(email, callback) {
|
createTeamInvitesForLegacyInvitedEmail(email, callback) {
|
||||||
return SubscriptionLocator.getGroupsWithEmailInvite(email, function(
|
SubscriptionLocator.getGroupsWithEmailInvite(email, function(err, teams) {
|
||||||
err,
|
if (err) {
|
||||||
teams
|
|
||||||
) {
|
|
||||||
if (err != null) {
|
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return async.map(
|
async.map(
|
||||||
teams,
|
teams,
|
||||||
(team, cb) =>
|
(team, cb) =>
|
||||||
TeamInvitesHandler.createInvite(team.admin_id, team, email, cb),
|
TeamInvitesHandler.createInvite(team.admin_id, team, email, cb),
|
||||||
|
@ -162,26 +130,48 @@ module.exports = TeamInvitesHandler = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var createInvite = function(subscription, email, inviterName, callback) {
|
var createInvite = function(subscription, email, inviter, callback) {
|
||||||
logger.log(
|
logger.log(
|
||||||
{ subscriptionId: subscription.id, email, inviterName },
|
{ subscriptionId: subscription.id, email, inviterId: inviter._id },
|
||||||
'Creating invite'
|
'Creating invite'
|
||||||
)
|
)
|
||||||
return checkIfInviteIsPossible(subscription, email, function(
|
checkIfInviteIsPossible(subscription, email, function(
|
||||||
error,
|
error,
|
||||||
possible,
|
possible,
|
||||||
reason
|
reason
|
||||||
) {
|
) {
|
||||||
if (error != null) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
if (!possible) {
|
if (!possible) {
|
||||||
return callback(reason)
|
return callback(reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't send invites when inviting self; add user directly to the group
|
||||||
|
const isInvitingSelf = inviter.emails.some(
|
||||||
|
emailData => emailData.email === email
|
||||||
|
)
|
||||||
|
if (isInvitingSelf) {
|
||||||
|
return SubscriptionUpdater.addUserToGroup(
|
||||||
|
subscription._id,
|
||||||
|
inviter._id,
|
||||||
|
err => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy: remove any invite that might have been created in the past
|
||||||
|
removeInviteFromTeam(subscription._id, email, callback)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const inviterName = getInviterName(inviter)
|
||||||
let invite = subscription.teamInvites.find(invite => invite.email === email)
|
let invite = subscription.teamInvites.find(invite => invite.email === email)
|
||||||
|
|
||||||
if (invite == null) {
|
if (invite) {
|
||||||
|
invite.sentAt = new Date()
|
||||||
|
} else {
|
||||||
invite = {
|
invite = {
|
||||||
email,
|
email,
|
||||||
inviterName,
|
inviterName,
|
||||||
|
@ -189,12 +179,10 @@ var createInvite = function(subscription, email, inviterName, callback) {
|
||||||
sentAt: new Date()
|
sentAt: new Date()
|
||||||
}
|
}
|
||||||
subscription.teamInvites.push(invite)
|
subscription.teamInvites.push(invite)
|
||||||
} else {
|
|
||||||
invite.sentAt = new Date()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return subscription.save(function(error) {
|
subscription.save(function(error) {
|
||||||
if (error != null) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +194,7 @@ var createInvite = function(subscription, email, inviterName, callback) {
|
||||||
}/`,
|
}/`,
|
||||||
appName: settings.appName
|
appName: settings.appName
|
||||||
}
|
}
|
||||||
return EmailHandler.sendEmail('verifyEmailToJoinTeam', opts, error =>
|
EmailHandler.sendEmail('verifyEmailToJoinTeam', opts, error =>
|
||||||
callback(error, invite)
|
callback(error, invite)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -221,7 +209,7 @@ var removeInviteFromTeam = function(subscriptionId, email, callback) {
|
||||||
'removeInviteFromTeam'
|
'removeInviteFromTeam'
|
||||||
)
|
)
|
||||||
|
|
||||||
return async.series(
|
async.series(
|
||||||
[
|
[
|
||||||
cb => Subscription.update(searchConditions, removeInvite, cb),
|
cb => Subscription.update(searchConditions, removeInvite, cb),
|
||||||
cb => removeLegacyInvite(subscriptionId, email, cb)
|
cb => removeLegacyInvite(subscriptionId, email, cb)
|
||||||
|
@ -244,9 +232,6 @@ var removeLegacyInvite = (subscriptionId, email, callback) =>
|
||||||
)
|
)
|
||||||
|
|
||||||
var checkIfInviteIsPossible = function(subscription, email, callback) {
|
var checkIfInviteIsPossible = function(subscription, email, callback) {
|
||||||
if (callback == null) {
|
|
||||||
callback = function(error, possible, reason) {}
|
|
||||||
}
|
|
||||||
if (!subscription.groupPlan) {
|
if (!subscription.groupPlan) {
|
||||||
logger.log(
|
logger.log(
|
||||||
{ subscriptionId: subscription.id },
|
{ subscriptionId: subscription.id },
|
||||||
|
@ -263,11 +248,11 @@ var checkIfInviteIsPossible = function(subscription, email, callback) {
|
||||||
return callback(null, false, { limitReached: true })
|
return callback(null, false, { limitReached: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
return UserGetter.getUserByAnyEmail(email, function(error, existingUser) {
|
UserGetter.getUserByAnyEmail(email, function(error, existingUser) {
|
||||||
if (error != null) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
if (existingUser == null) {
|
if (!existingUser) {
|
||||||
return callback(null, true)
|
return callback(null, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,9 +265,22 @@ var checkIfInviteIsPossible = function(subscription, email, callback) {
|
||||||
{ subscriptionId: subscription.id, email },
|
{ subscriptionId: subscription.id, email },
|
||||||
'user already in team'
|
'user already in team'
|
||||||
)
|
)
|
||||||
return callback(null, false, { alreadyInTeam: true })
|
callback(null, false, { alreadyInTeam: true })
|
||||||
} else {
|
} else {
|
||||||
return callback(null, true)
|
callback(null, true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var getInviterName = function(inviter) {
|
||||||
|
let inviterName
|
||||||
|
if (inviter.first_name && inviter.last_name) {
|
||||||
|
inviterName = `${inviter.first_name} ${inviter.last_name} (${
|
||||||
|
inviter.email
|
||||||
|
})`
|
||||||
|
} else {
|
||||||
|
inviterName = inviter.email
|
||||||
|
}
|
||||||
|
|
||||||
|
return inviterName
|
||||||
|
}
|
||||||
|
|
|
@ -1,21 +1,6 @@
|
||||||
/* eslint-disable
|
|
||||||
handle-callback-err,
|
|
||||||
max-len,
|
|
||||||
no-return-assign,
|
|
||||||
no-unused-vars,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
const SandboxedModule = require('sandboxed-module')
|
const SandboxedModule = require('sandboxed-module')
|
||||||
const should = require('chai').should()
|
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
const { expect } = require('chai')
|
const { expect } = require('chai')
|
||||||
const querystring = require('querystring')
|
|
||||||
const modulePath =
|
const modulePath =
|
||||||
'../../../../app/src/Features/Subscription/TeamInvitesHandler'
|
'../../../../app/src/Features/Subscription/TeamInvitesHandler'
|
||||||
|
|
||||||
|
@ -25,10 +10,11 @@ const Errors = require('../../../../app/src/Features/Errors/Errors')
|
||||||
describe('TeamInvitesHandler', function() {
|
describe('TeamInvitesHandler', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.manager = {
|
this.manager = {
|
||||||
id: '666666',
|
_id: '666666',
|
||||||
first_name: 'Daenerys',
|
first_name: 'Daenerys',
|
||||||
last_name: 'Targaryen',
|
last_name: 'Targaryen',
|
||||||
email: 'daenerys@example.com'
|
email: 'daenerys@example.com',
|
||||||
|
emails: [{ email: 'daenerys@example.com' }]
|
||||||
}
|
}
|
||||||
|
|
||||||
this.token = 'aaaaaaaaaaaaaaaaaaaaaa'
|
this.token = 'aaaaaaaaaaaaaaaaaaaaaa'
|
||||||
|
@ -41,7 +27,7 @@ describe('TeamInvitesHandler', function() {
|
||||||
this.subscription = {
|
this.subscription = {
|
||||||
id: '55153a8014829a865bbf700d',
|
id: '55153a8014829a865bbf700d',
|
||||||
_id: new ObjectId('55153a8014829a865bbf700d'),
|
_id: new ObjectId('55153a8014829a865bbf700d'),
|
||||||
admin_id: this.manager.id,
|
admin_id: this.manager._id,
|
||||||
groupPlan: true,
|
groupPlan: true,
|
||||||
member_ids: [],
|
member_ids: [],
|
||||||
teamInvites: [this.teamInvite],
|
teamInvites: [this.teamInvite],
|
||||||
|
@ -83,7 +69,9 @@ describe('TeamInvitesHandler', function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.UserGetter.getUser.withArgs(this.manager.id).yields(null, this.manager)
|
this.UserGetter.getUser
|
||||||
|
.withArgs(this.manager._id)
|
||||||
|
.yields(null, this.manager)
|
||||||
this.UserGetter.getUserByAnyEmail
|
this.UserGetter.getUserByAnyEmail
|
||||||
.withArgs(this.manager.email)
|
.withArgs(this.manager.email)
|
||||||
.yields(null, this.manager)
|
.yields(null, this.manager)
|
||||||
|
@ -94,7 +82,7 @@ describe('TeamInvitesHandler', function() {
|
||||||
)
|
)
|
||||||
this.Subscription.findOne.yields(null, this.subscription)
|
this.Subscription.findOne.yields(null, this.subscription)
|
||||||
|
|
||||||
return (this.TeamInvitesHandler = SandboxedModule.require(modulePath, {
|
this.TeamInvitesHandler = SandboxedModule.require(modulePath, {
|
||||||
requires: {
|
requires: {
|
||||||
'logger-sharelatex': { log() {} },
|
'logger-sharelatex': { log() {} },
|
||||||
crypto: this.crypto,
|
crypto: this.crypto,
|
||||||
|
@ -108,40 +96,40 @@ describe('TeamInvitesHandler', function() {
|
||||||
'../Email/EmailHandler': this.EmailHandler,
|
'../Email/EmailHandler': this.EmailHandler,
|
||||||
'../Errors/Errors': Errors
|
'../Errors/Errors': Errors
|
||||||
}
|
}
|
||||||
}))
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('getInvite', function() {
|
describe('getInvite', function() {
|
||||||
it("returns the invite if there's one", function(done) {
|
it("returns the invite if there's one", function(done) {
|
||||||
return this.TeamInvitesHandler.getInvite(
|
this.TeamInvitesHandler.getInvite(
|
||||||
this.token,
|
this.token,
|
||||||
(err, invite, subscription) => {
|
(err, invite, subscription) => {
|
||||||
expect(err).to.eq(null)
|
expect(err).to.eq(null)
|
||||||
expect(invite).to.deep.eq(this.teamInvite)
|
expect(invite).to.deep.eq(this.teamInvite)
|
||||||
expect(subscription).to.deep.eq(this.subscription)
|
expect(subscription).to.deep.eq(this.subscription)
|
||||||
return done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
return it("returns teamNotFound if there's none", function(done) {
|
it("returns teamNotFound if there's none", function(done) {
|
||||||
this.Subscription.findOne = sinon.stub().yields(null, null)
|
this.Subscription.findOne = sinon.stub().yields(null, null)
|
||||||
|
|
||||||
return this.TeamInvitesHandler.getInvite(this.token, function(
|
this.TeamInvitesHandler.getInvite(this.token, function(
|
||||||
err,
|
err,
|
||||||
invite,
|
invite,
|
||||||
subscription
|
subscription
|
||||||
) {
|
) {
|
||||||
expect(err).to.be.instanceof(Errors.NotFoundError)
|
expect(err).to.be.instanceof(Errors.NotFoundError)
|
||||||
return done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('createInvite', function() {
|
describe('createInvite', function() {
|
||||||
it('adds the team invite to the subscription', function(done) {
|
it('adds the team invite to the subscription', function(done) {
|
||||||
return this.TeamInvitesHandler.createInvite(
|
this.TeamInvitesHandler.createInvite(
|
||||||
this.manager.id,
|
this.manager._id,
|
||||||
this.subscription,
|
this.subscription,
|
||||||
'John.Snow@example.com',
|
'John.Snow@example.com',
|
||||||
(err, invite) => {
|
(err, invite) => {
|
||||||
|
@ -152,14 +140,14 @@ describe('TeamInvitesHandler', function() {
|
||||||
'Daenerys Targaryen (daenerys@example.com)'
|
'Daenerys Targaryen (daenerys@example.com)'
|
||||||
)
|
)
|
||||||
expect(this.subscription.teamInvites).to.deep.include(invite)
|
expect(this.subscription.teamInvites).to.deep.include(invite)
|
||||||
return done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('sends an email', function(done) {
|
it('sends an email', function(done) {
|
||||||
return this.TeamInvitesHandler.createInvite(
|
this.TeamInvitesHandler.createInvite(
|
||||||
this.manager.id,
|
this.manager._id,
|
||||||
this.subscription,
|
this.subscription,
|
||||||
'John.Snow@example.com',
|
'John.Snow@example.com',
|
||||||
(err, invite) => {
|
(err, invite) => {
|
||||||
|
@ -175,7 +163,7 @@ describe('TeamInvitesHandler', function() {
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
return done()
|
done(err)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -183,8 +171,8 @@ describe('TeamInvitesHandler', function() {
|
||||||
it('refreshes the existing invite if the email has already been invited', function(done) {
|
it('refreshes the existing invite if the email has already been invited', function(done) {
|
||||||
const originalInvite = Object.assign({}, this.teamInvite)
|
const originalInvite = Object.assign({}, this.teamInvite)
|
||||||
|
|
||||||
return this.TeamInvitesHandler.createInvite(
|
this.TeamInvitesHandler.createInvite(
|
||||||
this.manager.id,
|
this.manager._id,
|
||||||
this.subscription,
|
this.subscription,
|
||||||
originalInvite.email,
|
originalInvite.email,
|
||||||
(err, invite) => {
|
(err, invite) => {
|
||||||
|
@ -198,14 +186,14 @@ describe('TeamInvitesHandler', function() {
|
||||||
|
|
||||||
this.subscription.save.calledOnce.should.eq(true)
|
this.subscription.save.calledOnce.should.eq(true)
|
||||||
|
|
||||||
return done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
return it('removes any legacy invite from the subscription', function(done) {
|
it('removes any legacy invite from the subscription', function(done) {
|
||||||
return this.TeamInvitesHandler.createInvite(
|
this.TeamInvitesHandler.createInvite(
|
||||||
this.manager.id,
|
this.manager._id,
|
||||||
this.subscription,
|
this.subscription,
|
||||||
'John.Snow@example.com',
|
'John.Snow@example.com',
|
||||||
(err, invite) => {
|
(err, invite) => {
|
||||||
|
@ -215,7 +203,24 @@ describe('TeamInvitesHandler', function() {
|
||||||
{ $pull: { invited_emails: 'john.snow@example.com' } }
|
{ $pull: { invited_emails: 'john.snow@example.com' } }
|
||||||
)
|
)
|
||||||
.should.eq(true)
|
.should.eq(true)
|
||||||
return done()
|
done(err)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('add user to subscription if inviting self', function(done) {
|
||||||
|
this.TeamInvitesHandler.createInvite(
|
||||||
|
this.manager._id,
|
||||||
|
this.subscription,
|
||||||
|
this.manager.email,
|
||||||
|
(err, invite) => {
|
||||||
|
sinon.assert.calledWith(
|
||||||
|
this.SubscriptionUpdater.addUserToGroup,
|
||||||
|
this.subscription._id,
|
||||||
|
this.manager._id
|
||||||
|
)
|
||||||
|
sinon.assert.notCalled(this.subscription.save)
|
||||||
|
done(err)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -223,11 +228,11 @@ describe('TeamInvitesHandler', function() {
|
||||||
|
|
||||||
describe('importInvite', function() {
|
describe('importInvite', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return (this.sentAt = new Date())
|
this.sentAt = new Date()
|
||||||
})
|
})
|
||||||
|
|
||||||
return it('can imports an invite from v1', function() {
|
it('can imports an invite from v1', function() {
|
||||||
return this.TeamInvitesHandler.importInvite(
|
this.TeamInvitesHandler.importInvite(
|
||||||
this.subscription,
|
this.subscription,
|
||||||
'A-Team',
|
'A-Team',
|
||||||
'hannibal@a-team.org',
|
'hannibal@a-team.org',
|
||||||
|
@ -242,7 +247,7 @@ describe('TeamInvitesHandler', function() {
|
||||||
i => i.email === 'hannibal@a-team.org'
|
i => i.email === 'hannibal@a-team.org'
|
||||||
)
|
)
|
||||||
expect(invite.token).to.eq('secret')
|
expect(invite.token).to.eq('secret')
|
||||||
return expect(invite.sentAt).to.eq(this.sentAt)
|
expect(invite.sentAt).to.eq(this.sentAt)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -261,7 +266,7 @@ describe('TeamInvitesHandler', function() {
|
||||||
.withArgs(this.user.email)
|
.withArgs(this.user.email)
|
||||||
.yields(null, this.user)
|
.yields(null, this.user)
|
||||||
|
|
||||||
return this.subscription.teamInvites.push({
|
this.subscription.teamInvites.push({
|
||||||
email: 'john.snow@example.com',
|
email: 'john.snow@example.com',
|
||||||
token: 'dddddddd',
|
token: 'dddddddd',
|
||||||
inviterName: 'Daenerys Targaryen (daenerys@example.com)'
|
inviterName: 'Daenerys Targaryen (daenerys@example.com)'
|
||||||
|
@ -269,39 +274,31 @@ describe('TeamInvitesHandler', function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('adds the user to the team', function(done) {
|
it('adds the user to the team', function(done) {
|
||||||
return this.TeamInvitesHandler.acceptInvite(
|
this.TeamInvitesHandler.acceptInvite('dddddddd', this.user.id, () => {
|
||||||
'dddddddd',
|
|
||||||
this.user.id,
|
|
||||||
() => {
|
|
||||||
this.SubscriptionUpdater.addUserToGroup
|
this.SubscriptionUpdater.addUserToGroup
|
||||||
.calledWith(this.subscription._id, this.user.id)
|
.calledWith(this.subscription._id, this.user.id)
|
||||||
.should.eq(true)
|
.should.eq(true)
|
||||||
return done()
|
done()
|
||||||
}
|
})
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return it('removes the invite from the subscription', function(done) {
|
it('removes the invite from the subscription', function(done) {
|
||||||
return this.TeamInvitesHandler.acceptInvite(
|
this.TeamInvitesHandler.acceptInvite('dddddddd', this.user.id, () => {
|
||||||
'dddddddd',
|
|
||||||
this.user.id,
|
|
||||||
() => {
|
|
||||||
this.Subscription.update
|
this.Subscription.update
|
||||||
.calledWith(
|
.calledWith(
|
||||||
{ _id: new ObjectId('55153a8014829a865bbf700d') },
|
{ _id: new ObjectId('55153a8014829a865bbf700d') },
|
||||||
{ $pull: { teamInvites: { email: 'john.snow@example.com' } } }
|
{ $pull: { teamInvites: { email: 'john.snow@example.com' } } }
|
||||||
)
|
)
|
||||||
.should.eq(true)
|
.should.eq(true)
|
||||||
return done()
|
done()
|
||||||
}
|
})
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('revokeInvite', () =>
|
describe('revokeInvite', () =>
|
||||||
it('removes the team invite from the subscription', function(done) {
|
it('removes the team invite from the subscription', function(done) {
|
||||||
return this.TeamInvitesHandler.revokeInvite(
|
this.TeamInvitesHandler.revokeInvite(
|
||||||
this.manager.id,
|
this.manager._id,
|
||||||
this.subscription,
|
this.subscription,
|
||||||
'jorah@example.com',
|
'jorah@example.com',
|
||||||
() => {
|
() => {
|
||||||
|
@ -318,7 +315,7 @@ describe('TeamInvitesHandler', function() {
|
||||||
{ $pull: { invited_emails: 'jorah@example.com' } }
|
{ $pull: { invited_emails: 'jorah@example.com' } }
|
||||||
)
|
)
|
||||||
.should.eq(true)
|
.should.eq(true)
|
||||||
return done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}))
|
}))
|
||||||
|
@ -330,13 +327,13 @@ describe('TeamInvitesHandler', function() {
|
||||||
'robert@example.com'
|
'robert@example.com'
|
||||||
]
|
]
|
||||||
this.TeamInvitesHandler.createInvite = sinon.stub().yields(null)
|
this.TeamInvitesHandler.createInvite = sinon.stub().yields(null)
|
||||||
return (this.SubscriptionLocator.getGroupsWithEmailInvite = sinon
|
this.SubscriptionLocator.getGroupsWithEmailInvite = sinon
|
||||||
.stub()
|
.stub()
|
||||||
.yields(null, [this.subscription]))
|
.yields(null, [this.subscription])
|
||||||
})
|
})
|
||||||
|
|
||||||
return it('sends an invitation email to addresses in the legacy invited_emails field', function(done) {
|
it('sends an invitation email to addresses in the legacy invited_emails field', function(done) {
|
||||||
return this.TeamInvitesHandler.createTeamInvitesForLegacyInvitedEmail(
|
this.TeamInvitesHandler.createTeamInvitesForLegacyInvitedEmail(
|
||||||
'eddard@example.com',
|
'eddard@example.com',
|
||||||
(err, invite) => {
|
(err, invite) => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
|
@ -351,42 +348,42 @@ describe('TeamInvitesHandler', function() {
|
||||||
|
|
||||||
this.TeamInvitesHandler.createInvite.callCount.should.eq(1)
|
this.TeamInvitesHandler.createInvite.callCount.should.eq(1)
|
||||||
|
|
||||||
return done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return describe('validation', function() {
|
describe('validation', function() {
|
||||||
it("doesn't create an invite if the team limit has been reached", function(done) {
|
it("doesn't create an invite if the team limit has been reached", function(done) {
|
||||||
this.LimitationsManager.teamHasReachedMemberLimit = sinon
|
this.LimitationsManager.teamHasReachedMemberLimit = sinon
|
||||||
.stub()
|
.stub()
|
||||||
.returns(true)
|
.returns(true)
|
||||||
return this.TeamInvitesHandler.createInvite(
|
this.TeamInvitesHandler.createInvite(
|
||||||
this.manager.id,
|
this.manager._id,
|
||||||
this.subscription,
|
this.subscription,
|
||||||
'John.Snow@example.com',
|
'John.Snow@example.com',
|
||||||
(err, invite) => {
|
(err, invite) => {
|
||||||
expect(err).to.deep.equal({ limitReached: true })
|
expect(err).to.deep.equal({ limitReached: true })
|
||||||
return done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("doesn't create an invite if the subscription is not in a group plan", function(done) {
|
it("doesn't create an invite if the subscription is not in a group plan", function(done) {
|
||||||
this.subscription.groupPlan = false
|
this.subscription.groupPlan = false
|
||||||
return this.TeamInvitesHandler.createInvite(
|
this.TeamInvitesHandler.createInvite(
|
||||||
this.manager.id,
|
this.manager._id,
|
||||||
this.subscription,
|
this.subscription,
|
||||||
'John.Snow@example.com',
|
'John.Snow@example.com',
|
||||||
(err, invite) => {
|
(err, invite) => {
|
||||||
expect(err).to.deep.equal({ wrongPlan: true })
|
expect(err).to.deep.equal({ wrongPlan: true })
|
||||||
return done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
return it("doesn't create an invite if the user is already part of the team", function(done) {
|
it("doesn't create an invite if the user is already part of the team", function(done) {
|
||||||
const member = {
|
const member = {
|
||||||
id: '1a2b',
|
id: '1a2b',
|
||||||
_id: '1a2b',
|
_id: '1a2b',
|
||||||
|
@ -398,14 +395,14 @@ describe('TeamInvitesHandler', function() {
|
||||||
.withArgs(member.email)
|
.withArgs(member.email)
|
||||||
.yields(null, member)
|
.yields(null, member)
|
||||||
|
|
||||||
return this.TeamInvitesHandler.createInvite(
|
this.TeamInvitesHandler.createInvite(
|
||||||
this.manager.id,
|
this.manager._id,
|
||||||
this.subscription,
|
this.subscription,
|
||||||
'tyrion@example.com',
|
'tyrion@example.com',
|
||||||
(err, invite) => {
|
(err, invite) => {
|
||||||
expect(err).to.deep.equal({ alreadyInTeam: true })
|
expect(err).to.deep.equal({ alreadyInTeam: true })
|
||||||
expect(invite).not.to.exist
|
expect(invite).not.to.exist
|
||||||
return done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue