Merge branch 'develop' into common-convert

This commit is contained in:
Blade Barringer
2015-02-10 16:27:46 -06:00
8 changed files with 178 additions and 143 deletions
+129 -61
View File
@@ -508,80 +508,148 @@ api.leave = function(req, res, next) {
})
}
api.invite = function(req, res, next) {
var group = res.locals.group;
var uuid = req.query.uuid;
User.findById(uuid, function(err,invite){
if (err) return next(err);
if (!invite)
return res.json(400,{err:'User with id "' + uuid + '" not found'});
if (group.type == 'guild') {
if (_.contains(group.members,uuid))
return res.json(400,{err: "User already in that group"});
if (invite.invitations && invite.invitations.guilds && _.find(invite.invitations.guilds, {id:group._id}))
return res.json(400, {err:"User already invited to that group"});
sendInvite();
} else if (group.type == 'party') {
if (invite.invitations && !_.isEmpty(invite.invitations.party))
return res.json(400,{err:"User already pending invitation."});
Group.find({type:'party', members:{$in:[uuid]}}, function(err, groups){
if (err) return next(err);
if (!_.isEmpty(groups))
return res.json(400,{err:"User already in a party."})
var inviteByUUIDs = function(uuids, group, req, res, next){
async.each(uuids, function(uuid, cb){
User.findById(uuid, function(err,invite){
if (err) return cb(err);
if (!invite)
return cb({code:400,err:'User with id "' + uuid + '" not found'});
if (group.type == 'guild') {
if (_.contains(group.members,uuid))
return cb({code:400,err: "User already in that group"});
if (invite.invitations && invite.invitations.guilds && _.find(invite.invitations.guilds, {id:group._id}))
return cb({code:400,err:"User already invited to that group"});
sendInvite();
});
}
function sendInvite (){
if(group.type === 'guild'){
invite.invitations.guilds.push({id: group._id, name: group.name, inviter:res.locals.user._id});
}else{
//req.body.type in 'guild', 'party'
invite.invitations.party = {id: group._id, name: group.name, inviter:res.locals.user._id};
} else if (group.type == 'party') {
if (invite.invitations && !_.isEmpty(invite.invitations.party))
return cb({code:400,err:"User already pending invitation."});
Group.find({type:'party', members:{$in:[uuid]}}, function(err, groups){
if (err) return cb(err);
if (!_.isEmpty(groups))
return cb({code:400,err:"User already in a party."})
sendInvite();
});
}
group.invites.push(invite._id);
async.series([
function(cb){
invite.save(cb);
},
function(cb){
group.save(cb);
},
function(cb){
populateQuery(group.type, Group.findById(group._id)).exec(cb);
function sendInvite (){
if(group.type === 'guild'){
invite.invitations.guilds.push({id: group._id, name: group.name, inviter:res.locals.user._id});
}else{
//req.body.type in 'guild', 'party'
invite.invitations.party = {id: group._id, name: group.name, inviter:res.locals.user._id};
}
], function(err, results){
if (err) return next(err);
if(invite.preferences.emailNotifications['invited' + (group.type == 'guild' ? 'Guild' : 'Party')] !== false){
var emailVars = [
{name: 'INVITER', content: utils.getUserInfo(res.locals.user, ['name']).name}
group.invites.push(invite._id);
async.series([
function(cb){
invite.save(cb);
},
function(cb){
group.save(cb);
}
], function(err, results){
if (err) return cb(err);
if(invite.preferences.emailNotifications['invited' + (group.type == 'guild' ? 'Guild' : 'Party')] !== false){
var emailVars = [
{name: 'INVITER', content: utils.getUserInfo(res.locals.user, ['name']).name}
];
if(group.type == 'guild'){
emailVars.push(
{name: 'GUILD_NAME', content: group.name},
{name: 'GUILD_URL', content: nconf.get('BASE_URL') + '/#/options/groups/guilds/public'}
);
}else{
emailVars.push(
{name: 'PARTY_NAME', content: group.name},
{name: 'PARTY_URL', content: nconf.get('BASE_URL') + '/#/options/groups/party'}
)
}
utils.txnEmail(invite, ('invited-' + (group.type == 'guild' ? 'guild' : 'party')), emailVars);
}
cb();
});
}
});
}, function(err){
if(err) return err.code ? res.json(err.code, {err: err.err}) : next(err);
// TODO pass group from save above don't find it again, or you have to find it again in order to run populate?
populateQuery(group.type, Group.findById(group._id)).exec(function(err, populatedGroup){
if(err) return next(err);
res.json(populatedGroup);
});
});
};
var inviteByEmails = function(invites, group, req, res, next){
var usersAlreadyRegistered = [];
async.each(invites, function(invite, cb){
if (invite.email) {
User.findOne({$or: [
{'auth.local.email': invite.email},
{'auth.facebook.emails.value': invite.email}
]}).select({_id: true, 'preferences.emailNotifications': true})
.exec(function(err, userToContact){
if(err) return next(err);
if(userToContact){
usersAlreadyRegistered.push(userToContact._id);
return cb();
}
// yeah, it supports guild too but for backward compatibility we'll use partyInvite as query
var link = nconf.get('BASE_URL')+'?partyInvite='+ utils.encrypt(JSON.stringify({id:group._id, inviter:res.locals.user._id, name:group.name}));
var variables = [
{name: 'LINK', content: link},
{name: 'INVITER', content: req.body.inviter || utils.getUserInfo(res.locals.user, ['name']).name}
];
if(group.type == 'guild'){
emailVars.push(
{name: 'GUILD_NAME', content: group.name},
{name: 'GUILD_URL', content: nconf.get('BASE_URL') + '/#/options/groups/guilds/public'}
);
}else{
emailVars.push(
{name: 'PARTY_NAME', content: group.name},
{name: 'PARTY_URL', content: nconf.get('BASE_URL') + '/#/options/groups/party'}
)
variables.push({name: 'GUILD_NAME', content: group.name});
}
utils.txnEmail(invite, ('invited-' + (group.type == 'guild' ? 'guild' : 'party')), emailVars);
}
// TODO implement "users can only be invited once"
invite.canSend = true; // Requested by utils.txnEmail
utils.txnEmail(invite, ('invite-friend' + (group.type == 'guild' ? '-guild' : '')), variables);
// Have to return whole group and its members for angular to show the invited user
res.json(results[2]);
group = uuid = null;
});
cb();
});
}else{
cb();
}
}, function(err){
if(err) return err.code ? res.json(err.code, {err: err.err}) : next(err);
if(usersAlreadyRegistered.length > 0){
inviteByUUIDs(usersAlreadyRegistered, group, req, res, next);
}else{
// Send only status code down the line because it doesn't need
// info on invited users since they are not yet registered
res.send(200);
}
});
};
api.invite = function(req, res, next){
var group = res.locals.group;
if(req.body.uuids){
inviteByUUIDs(req.body.uuids, group, req, res, next);
}else if(req.body.emails){
inviteByEmails(req.body.emails, group, req, res, next)
}else{
return res.json(400,{err: "Can invite only by email or uuid"});
}
}
api.removeMember = function(req, res, next){
+10 -42
View File
@@ -409,54 +409,15 @@ api.cast = function(req, res, next) {
}
}
/**
* POST /user/invite-friends
*/
api.inviteFriends = function(req, res, next) {
Group.findOne({type:'party', members:{'$in': [res.locals.user._id]}}).select('_id name').exec(function(err,party){
if (err) return next(err);
_.each(req.body.emails, function(invite){
if (invite.email) {
User.findOne({$or: [
{'auth.local.email': invite.email},
{'auth.facebook.emails.value': invite.email}
]}).select({_id: true, 'preferences.emailNotifications': true})
.exec(function(err, userToContact){
if(err) return next(err);
var link = nconf.get('BASE_URL')+'?partyInvite='+ utils.encrypt(JSON.stringify({id:party._id, inviter:res.locals.user._id, name:party.name}));
var variables = [
{name: 'LINK', content: link},
{name: 'INVITER', content: req.body.inviter || utils.getUserInfo(res.locals.user, ['name']).name}
];
invite.canSend = true;
// We check for unsubscribeFromAll here because don't pass through utils.getUserInfo
if(!userToContact || (userToContact.preferences.emailNotifications.invitedParty !== false &&
userToContact.preferences.emailNotifications.unsubscribeFromAll !== true)){
// TODO implement "users can only be invited once"
utils.txnEmail(invite, 'invite-friend', variables);
}
});
}
});
res.send(200);
})
}
// It supports guild too now but we'll stick to partyInvite for backward compatibility
api.sessionPartyInvite = function(req,res,next){
if (!req.session.partyInvite) return next();
var inv = res.locals.user.invitations;
if (inv.party && inv.party.id) return next(); // already invited to a party
async.waterfall([
function(cb){
Group.findOne({_id:req.session.partyInvite.id, type:'party', members:{$in:[req.session.partyInvite.inviter]}})
.select('invites members').exec(cb);
Group.findOne({_id:req.session.partyInvite.id, members:{$in:[req.session.partyInvite.inviter]}})
.select('invites members type').exec(cb);
},
function(group, cb){
if (!group){
@@ -464,6 +425,13 @@ api.sessionPartyInvite = function(req,res,next){
delete req.session.partyInvite;
return cb();
}
if(group.type == 'guild'){
inv.guilds.push(req.session.partyInvite);
}else{
//req.body.type in 'guild', 'party'
inv.party = req.session.partyInvite;
}
inv.party = req.session.partyInvite;
delete req.session.partyInvite;
if (!~group.invites.indexOf(res.locals.user._id))