Merge branch 'develop' into Horacious-APIv2

This commit is contained in:
Blade Barringer
2015-04-10 07:33:26 -05:00
920 changed files with 22194 additions and 30805 deletions
+19 -6
View File
@@ -7,6 +7,7 @@ var utils = require('../utils');
var nconf = require('nconf');
var request = require('request');
var User = require('../models/user').model;
var EmailUnsubscription = require('../models/emailUnsubscription').model;
var ga = require('./../utils').ga;
var i18n = require('./../i18n');
@@ -109,9 +110,14 @@ api.registerUser = function(req, res, next) {
newUser.preferences = newUser.preferences || {};
newUser.preferences.language = req.language; // User language detected from browser, not saved
var user = new User(newUser);
utils.txnEmail(user, 'welcome');
ga.event('register', 'Local').send();
user.save(cb);
ga.event('acquisition', 'register', 'local').send();
user.save(function(err, savedUser){
// Clean previous email preferences
EmailUnsubscription.remove({email: savedUser.auth.local.email}, function(){
utils.txnEmail(savedUser, 'welcome');
});
cb.apply(cb, arguments);
});
}
}]
}, function(err, data) {
@@ -178,10 +184,17 @@ api.loginSocial = function(req, res, next) {
};
user.auth[network] = prof;
user = new User(user);
user.save(cb);
user.save(function(err, savedUser){
// Clean previous email preferences
if(savedUser.auth.facebook.emails && savedUser.auth.facebook.emails[0] && savedUser.auth.facebook.emails[0].value){
EmailUnsubscription.remove({email: savedUser.auth.facebook.emails[0].value}, function(){
utils.txnEmail(savedUser, 'welcome');
});
}
cb.apply(cb, arguments);
});
utils.txnEmail(user, 'welcome');
ga.event('register', network).send();
ga.event('acquisition', 'register', network).send();
}]
}, function(err, results){
if (err) return res.json(401, {err: err.toString ? err.toString() : err});
+8 -2
View File
@@ -40,7 +40,7 @@ api.list = function(req, res, next) {
.select('name leader description group memberCount prize official')
.select({members:{$elemMatch:{$in:[user._id]}}})
.sort('-official -timestamp')
.populate('group', '_id name')
.populate('group', '_id name type')
.populate('leader', 'profile.name')
.exec(cb);
}
@@ -56,17 +56,23 @@ api.list = function(req, res, next) {
// GET
api.get = function(req, res, next) {
var user = res.locals.user;
// TODO use mapReduce() or aggregate() here to
// 1) Find the sum of users.tasks.values within the challnege (eg, {'profile.name':'tyler', 'sum': 100})
// 2) Sort by the sum
// 3) Limit 30 (only show the 30 users currently in the lead)
Challenge.findById(req.params.cid)
.populate('members', 'profile.name _id')
.populate('group', '_id name type')
.populate('leader', 'profile.name')
.exec(function(err, challenge){
if(err) return next(err);
if (!challenge) return res.json(404, {err: 'Challenge ' + req.params.cid + ' not found'});
challenge._isMember = !!(_.find(challenge.members, function(member) {
return member._id === user._id;
}));
res.json(challenge);
})
});
}
api.csv = function(req, res, next) {
+59 -27
View File
@@ -12,6 +12,7 @@ var shared = require('../../../common');
var User = require('./../models/user').model;
var Group = require('./../models/group').model;
var Challenge = require('./../models/challenge').model;
var EmailUnsubscription = require('./../models/emailUnsubscription').model;
var isProd = nconf.get('NODE_ENV') === 'production';
var api = module.exports;
@@ -627,10 +628,15 @@ var inviteByEmails = function(invites, group, req, res, next){
}
// 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);
// Check for the email address not to be unsubscribed
EmailUnsubscription.findOne({email: invite.email}, function(err, unsubscribed){
if(err) return cb(err);
if(unsubscribed) return cb();
cb();
utils.txnEmail(invite, ('invite-friend' + (group.type == 'guild' ? '-guild' : '')), variables);
cb();
});
});
}else{
cb();
@@ -664,8 +670,21 @@ api.invite = function(req, res, next){
api.removeMember = function(req, res, next){
var group = res.locals.group;
var uuid = req.query.uuid;
var message = req.query.message;
var user = res.locals.user;
// Send an email to the removed user with an optional message from the leader
var sendMessage = function(removedUser){
if(removedUser.preferences.emailNotifications.kickedGroup !== false){
utils.txnEmail(removedUser, ('kicked-from-' + group.type), [
{name: 'GROUP_NAME', content: group.name},
{name: 'MESSAGE', content: message},
{name: 'GUILDS_LINK', content: nconf.get('BASE_URL') + '/#/options/groups/guilds/public'},
{name: 'PARTY_WANTED_GUILD', content: nconf.get('BASE_URL') + '/#/options/groups/guilds/f2db2a7f-13c5-454d-b3ee-ea1f5089e601'}
]);
}
}
if(group.leader !== user._id){
return res.json(401, {err: "Only group leader can remove a member!"});
}
@@ -682,12 +701,21 @@ api.removeMember = function(req, res, next){
Group.update({_id:group._id},update, function(err, saved){
if (err) return next(err);
// Sending an empty 204 because Group.update doesn't return the group
// see http://mongoosejs.com/docs/api.html#model_Model.update
return res.send(204);
User.findById(uuid, function(err, removedUser){
if(err) return next(err);
sendMessage(removedUser);
// Sending an empty 204 because Group.update doesn't return the group
// see http://mongoosejs.com/docs/api.html#model_Model.update
group = uuid = null;
return res.send(204);
});
});
}else if(_.contains(group.invites, uuid)){
User.findById(uuid, function(err,invited){
if(err) return next(err);
var invitations = invited.invitations;
if(group.type === 'guild'){
invitations.guilds.splice(_.indexOf(invitations.guilds, group._id), 1);
@@ -707,8 +735,9 @@ api.removeMember = function(req, res, next){
// Sending an empty 204 because Group.update doesn't return the group
// see http://mongoosejs.com/docs/api.html#model_Model.update
return res.send(204);
sendMessage(invited);
group = uuid = null;
return res.send(204);
});
});
@@ -791,19 +820,22 @@ questStart = function(req, res, next) {
groupClone.members = results[lastIndex].members;
// Send quest started email and remove auth information
// Send quest started email
var usersToEmail = groupClone.members.filter(function(user){
return (
user.preferences.emailNotifications.questStarted !== false &&
user._id !== res.locals.user._id &&
group.quest.members[user._id] == true
)
});
utils.txnEmail(usersToEmail, 'quest-started', [
{name: 'PARTY_URL', content: nconf.get('BASE_URL') + '/#/options/groups/party'}
]);
_.each(groupClone.members, function(user){
if(user.preferences.emailNotifications.questStarted !== false &&
user._id !== res.locals.user._id &&
group.quest.members[user._id] == true
){
utils.txnEmail(user, 'quest-started', [
{name: 'PARTY_URL', content: nconf.get('BASE_URL') + '/#/options/groups/party'}
]);
}
// Remove sensitive data from what is sent to the public
// but after having sent emails as they are needed
user.auth.facebook = undefined;
user.auth.local = undefined;
});
@@ -850,17 +882,17 @@ api.questAccept = function(req, res, next) {
var inviterVars = utils.getUserInfo(user, ['name', 'email']);
_.each(members, function(member){
if(member.preferences.emailNotifications.invitedQuest !== false){
utils.txnEmail(member, ('invite-' + (quest.boss ? 'boss' : 'collection') + '-quest'), [
{name: 'QUEST_NAME', content: quest.text()},
{name: 'INVITER', content: inviterVars.name},
{name: 'REPLY_TO_ADDRESS', content: inviterVars.email},
{name: 'PARTY_URL', content: nconf.get('BASE_URL') + '/#/options/groups/party'}
]);
}
var membersToEmail = members.filter(function(member){
return member.preferences.emailNotifications.invitedQuest !== false;
});
utils.txnEmail(membersToEmail, ('invite-' + (quest.boss ? 'boss' : 'collection') + '-quest'), [
{name: 'QUEST_NAME', content: quest.text()},
{name: 'INVITER', content: inviterVars.name},
{name: 'REPLY_TO_ADDRESS', content: inviterVars.email},
{name: 'PARTY_URL', content: nconf.get('BASE_URL') + '/#/options/groups/party'}
]);
questStart(req,res,next);
});
+3 -3
View File
@@ -69,7 +69,7 @@ exports.createSubscription = function(data, cb) {
revealMysteryItems(recipient);
if(isProduction) {
if (!data.gift) utils.txnEmail(data.user, 'subscription-begins');
utils.ga.event('subscribe', data.paymentMethod).send();
utils.ga.event('commerce', 'subscribe', data.paymentMethod, block.price).send();
utils.ga.transaction(data.user._id, block.price).item(block.price, 1, data.paymentMethod.toLowerCase() + '-subscription', data.paymentMethod).send();
}
data.user.purchased.txnCount++;
@@ -105,7 +105,7 @@ exports.cancelSubscription = function(data, cb) {
data.user.save(cb);
utils.txnEmail(data.user, 'cancel-subscription');
utils.ga.event('unsubscribe', data.paymentMethod).send();
utils.ga.event('commerce', 'unsubscribe', data.paymentMethod).send();
}
exports.buyGems = function(data, cb) {
@@ -114,7 +114,7 @@ exports.buyGems = function(data, cb) {
data.user.purchased.txnCount++;
if(isProduction) {
if (!data.gift) utils.txnEmail(data.user, 'donation');
utils.ga.event('checkout', data.paymentMethod).send();
utils.ga.event('commerce', 'checkout', data.paymentMethod, amt).send();
//TODO ga.transaction to reflect whether this is gift or self-purchase
utils.ga.transaction(data.user._id, amt).item(amt, 1, data.paymentMethod.toLowerCase() + "-checkout", "Gems > " + data.paymentMethod).send();
}
+36
View File
@@ -0,0 +1,36 @@
var User = require('../models/user').model;
var EmailUnsubscription = require('../models/emailUnsubscription').model;
var utils = require('../utils');
var i18n = require('../../../common').i18n;
var api = module.exports = {};
api.unsubscribe = function(req, res, next){
if(!req.query.code) return res.json(500, {err: 'Missing unsubscription code.'});
var data = JSON.parse(utils.decrypt(req.query.code));
if(data._id){
User.update({_id: data._id}, {
$set: {'preferences.emailNotifications.unsubscribeFromAll': true}
}, {multi: false}, function(err, nAffected){
if(err) return next(err);
if(nAffected !== 1) return res.json(404, {err: 'User not found'});
res.send('<h1>' + i18n.t('unsubscribedSuccessfully', null, req.language) + '</h1>' + i18n.t('unsubscribedTextUsers', null, req.language));
});
}else{
EmailUnsubscription.findOne({email: data.email}, function(err, doc){
if(err) return next(err);
var okRes = '<h1>' + i18n.t('unsubscribedSuccessfully', null, req.language) + '</h1>' + i18n.t('unsubscribedTextOthers', null, req.language);
if(doc) return res.send(okRes);
EmailUnsubscription.create({email: data.email}, function(err, doc){
if(err) return next(err);
res.send(okRes);
})
});
}
};
+1 -1
View File
@@ -262,7 +262,7 @@ api.update = function(req, res, next) {
api.cron = function(req, res, next) {
var user = res.locals.user,
progress = user.fns.cron(),
progress = user.fns.cron({ga:ga}),
ranCron = user.isModified(),
quest = shared.content.quests[user.party.quest.key];