From 06561bf70f2dda5edee8ea1e1ee66e2cad5a897d Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Tue, 10 Feb 2015 19:40:15 +0100 Subject: [PATCH] finash invites reworking --- public/js/controllers/groupsCtrl.js | 13 +++++---- src/controllers/groups.js | 41 ++++++++++++----------------- src/controllers/user.js | 10 ++++++- src/middleware.js | 3 ++- src/routes/apiv2.coffee | 2 +- 5 files changed, 37 insertions(+), 32 deletions(-) diff --git a/public/js/controllers/groupsCtrl.js b/public/js/controllers/groupsCtrl.js index 1b4fb9b42c..3f27ecd82e 100644 --- a/public/js/controllers/groupsCtrl.js +++ b/public/js/controllers/groupsCtrl.js @@ -97,21 +97,24 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' } ]) - .controller('InviteToGroupCtrl', ['$scope', 'User', 'Groups', 'injectedGroup', '$http', function($scope, User, Groups, injectedGroup, $http){ $scope.group = injectedGroup; + .controller('InviteToGroupCtrl', ['$scope', 'User', 'Groups', 'injectedGroup', '$http', 'Notification', function($scope, User, Groups, injectedGroup, $http, Notification){ + $scope.group = injectedGroup; $scope.inviter = User.user.profile.name; $scope.emails = [{name:"",email:""},{name:"",email:""}]; - // todo use Groups.Group.invite for everything not raw $http $scope.inviteEmails = function(){ - $http.post('/api/v2/user/social/invite-friends/' + $scope.group._id, {inviter:$scope.inviter, emails:$scope.emails}).success(function(){ - Notification.text("Invitations sent!"); + Groups.Group.invite({gid: $scope.group._id}, {inviter: $scope.inviter, emails: $scope.emails}, function(){ + Notification.text("Invitation(s) sent!"); + $scope.emails = [{name:'',email:''},{name:'',email:''}]; + }, function(){ $scope.emails = [{name:'',email:''},{name:'',email:''}]; }); }; $scope.invite = function(){ - Groups.Group.invite({gid: $scope.group._id, uuid: $scope.invitee}, undefined, function(){ + Groups.Group.invite({gid: $scope.group._id}, {uuids: [$scope.invitee]}, function(){ + Notification.text("Invitation(s) sent!"); $scope.invitee = ''; }, function(){ $scope.invitee = ''; diff --git a/src/controllers/groups.js b/src/controllers/groups.js index 24472b5b30..9003799722 100644 --- a/src/controllers/groups.js +++ b/src/controllers/groups.js @@ -508,9 +508,7 @@ api.leave = function(req, res, next) { }) } -var inviteByUUID = function(uuids, group, req, res, next){ - uuids = Array.isArray(uuids) ? uuids : [uuids]; - +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); @@ -573,7 +571,6 @@ var inviteByUUID = function(uuids, group, req, res, next){ utils.txnEmail(invite, ('invited-' + (group.type == 'guild' ? 'guild' : 'party')), emailVars); } - // TODO what does this cb calls? anything? cb(); }); } @@ -591,7 +588,7 @@ var inviteByUUID = function(uuids, group, req, res, next){ }; -var inviteByEmail = function(invites, group, req, res, next){ +var inviteByEmails = function(invites, group, req, res, next){ var usersAlreadyRegistered = []; async.each(invites, function(invite, cb){ @@ -608,35 +605,32 @@ var inviteByEmail = function(invites, group, req, res, next){ return cb(); } - var link = nconf.get('BASE_URL')+'?groupInvite='+ utils.encrypt(JSON.stringify({id:group._id, inviter:res.locals.user._id, name:group.name})); + // 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} ]; - // We check for unsubscribeFromAll here because don't pass through utils.getUserInfo - // Todo now this should be only for non registered users so no need to check preferences - if(!userToContact || - (invite.preferences.emailNotifications['invited' + (group.type == 'guild' ? 'Guild' : 'Party')] !== false && - userToContact.preferences.emailNotifications.unsubscribeFromAll !== true)){ - // TODO implement "users can only be invited once" - invite.canSend = true; - utils.txnEmail(invite, 'invite-friend', variables); - } + // 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); cb(); }); }else{ - cb('Email address is required.'); + cb({code: 400, err: 'Email address is required.'}); } }, function(err){ - if(err) return next(err); + if(err) return err.code ? res.json(err.code, {err: err.err}) : next(err); if(usersAlreadyRegistered.length > 0){ - inviteByUUID(usersAlreadyRegistered, group, req, res, next); + inviteByUUIDs(usersAlreadyRegistered, group, req, res, next); }else{ - // todo send back group here as we do when inviting by uuid? + + // 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); } }); @@ -644,12 +638,11 @@ var inviteByEmail = function(invites, group, req, res, next){ api.invite = function(req, res, next){ var group = res.locals.group; - var invitationType = req.query.invitationType; - if(invitationType == 'uuid'){ - inviteByUUID(req.query.uuid, group, req, res, next); - }else if(invitationType == 'email'){ - inviteByEmail(req.body.emails, group, req, res, next) + 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"}); } diff --git a/src/controllers/user.js b/src/controllers/user.js index 09c27ddd89..d3fd377e63 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -409,13 +409,14 @@ api.cast = function(req, res, next) { } } +// 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]}}) + Group.findOne({_id:req.session.partyInvite.id, members:{$in:[req.session.partyInvite.inviter]}}) .select('invites members').exec(cb); }, function(group, cb){ @@ -424,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)) diff --git a/src/middleware.js b/src/middleware.js index 0c6c70d5d8..a3b3f092ba 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -201,7 +201,8 @@ module.exports.locals = function(req, res, next) { worldDmg: (tavern && tavern.quest && tavern.quest.extra && tavern.quest.extra.worldDmg) || {} }); - // Put query-string party invitations into session to be handled later + // Put query-string party (& guild but use partyInvite for backward compatibility) + // invitations into session to be handled later try{ req.session.partyInvite = JSON.parse(utils.decrypt(req.query.partyInvite)) } catch(e){} diff --git a/src/routes/apiv2.coffee b/src/routes/apiv2.coffee index 2c8703734b..acfa448f53 100644 --- a/src/routes/apiv2.coffee +++ b/src/routes/apiv2.coffee @@ -460,7 +460,7 @@ module.exports = (swagger, v2) -> description: "Invite a user to a group" parameters: [ path 'gid','Group id','string' - query 'invitationType','The type of invitation to send (uuid or email)','string' + body '','a payload of invites either under body.uuids or body.emails, only one of them!','object' ] middleware: [auth.auth, i18n.getUserLanguage, groups.attachGroup] action:groups.invite