Merge branch 'api-v3' into api-v3-client
This commit is contained in:
@@ -52,7 +52,9 @@ api.list = async function(req, res, next) {
|
||||
let obj = challenge.toJSON();
|
||||
|
||||
obj._isMember = user.challenges.indexOf(challenge._id) !== -1;
|
||||
return obj;
|
||||
});
|
||||
|
||||
// TODO Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
|
||||
await Q.all(resChals.map((chal, index) => {
|
||||
return Q.all([
|
||||
@@ -195,7 +197,8 @@ api.create = async function(req, res, next){
|
||||
req.body.rewards = req.body.rewards || [];
|
||||
|
||||
var chalTasks = req.body.habits.concat(req.body.rewards)
|
||||
.concat(req.body.dailys).concat(req.body.todos);
|
||||
.concat(req.body.dailys).concat(req.body.todos)
|
||||
.map(v2Task => Tasks.Task.fromJSONV2(v2Task));
|
||||
|
||||
chalTasks = chalTasks.map(function(task) {
|
||||
var newTask = new Tasks[task.type](Tasks.Task.sanitize(task));
|
||||
@@ -318,7 +321,7 @@ api.selectWinner = async function(req, res, next) {
|
||||
if (!challenge) return next('Challenge ' + req.params.cid + ' not found');
|
||||
if (!challenge.canModify(res.locals.user)) return next(shared.i18n.t('noPermissionCloseChallenge'));
|
||||
|
||||
let winner = await User.findOne({_id: req.params.uid}).exec();
|
||||
let winner = await User.findOne({_id: req.query.uid}).exec();
|
||||
if (!winner || winner.challenges.indexOf(challenge._id) === -1) return next('Winner ' + req.query.uid + ' not found.');
|
||||
|
||||
// Close channel in background, some ops are run in the background without `await`ing
|
||||
|
||||
@@ -676,7 +676,14 @@ api.cast = async function(req, res, next) {
|
||||
|
||||
if (!partyMembers) throw new NotFound(res.t('userWithIDNotFound', {userId: targetId}));
|
||||
spell.cast(user, partyMembers, req);
|
||||
await partyMembers.save();
|
||||
if (partyMembers === user) {
|
||||
await partyMembers.save();
|
||||
} else {
|
||||
await Q.all([
|
||||
await partyMembers.save(),
|
||||
await user.save(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (party && !spell.silent) {
|
||||
|
||||
@@ -83,7 +83,7 @@ api.createChallenge = {
|
||||
group.challengeCount += 1;
|
||||
|
||||
req.body.leader = user._id;
|
||||
req.body.official = user.contributor.admin && req.body.official;
|
||||
req.body.official = user.contributor.admin && req.body.official ? true : false;
|
||||
let challenge = new Challenge(Challenge.sanitize(req.body));
|
||||
|
||||
// First validate challenge so we don't save group if it's invalid (only runs sync validators)
|
||||
@@ -108,6 +108,7 @@ api.createChallenge = {
|
||||
type: group.type,
|
||||
privacy: group.privacy,
|
||||
};
|
||||
|
||||
res.respond(201, response);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -350,7 +350,15 @@ api.castSpell = {
|
||||
if (task.challenge.id) throw new BadRequest(res.t('challengeTasksNoCast'));
|
||||
|
||||
spell.cast(user, task, req);
|
||||
await task.save();
|
||||
if (user.isModified()) {
|
||||
await Q.all([
|
||||
user.save(),
|
||||
task.save(),
|
||||
]);
|
||||
} else {
|
||||
await task.save();
|
||||
}
|
||||
|
||||
res.respond(200, task);
|
||||
} else if (targetType === 'self') {
|
||||
spell.cast(user, null, req);
|
||||
@@ -370,7 +378,8 @@ api.castSpell = {
|
||||
|
||||
let toSave = tasks.filter(t => t.isModified());
|
||||
let isUserModified = user.isModified();
|
||||
toSave.unshift(user.save());
|
||||
|
||||
if (isUserModified) toSave.unshift(user.save());
|
||||
let saved = await Q.all(toSave);
|
||||
|
||||
let response = {
|
||||
@@ -403,7 +412,14 @@ api.castSpell = {
|
||||
|
||||
if (!partyMembers) throw new NotFound(res.t('userWithIDNotFound', {userId: targetId}));
|
||||
spell.cast(user, partyMembers, req);
|
||||
await partyMembers.save();
|
||||
if (user.isModified()) {
|
||||
await Q.all([
|
||||
user.save(),
|
||||
partyMembers.save(),
|
||||
]);
|
||||
} else {
|
||||
await partyMembers.save();
|
||||
}
|
||||
}
|
||||
res.respond(200, partyMembers);
|
||||
|
||||
|
||||
@@ -23,7 +23,10 @@ let schema = new Schema({
|
||||
leader: {type: String, ref: 'User', validate: [validator.isUUID, 'Invalid uuid.'], required: true},
|
||||
group: {type: String, ref: 'Group', validate: [validator.isUUID, 'Invalid uuid.'], required: true},
|
||||
memberCount: {type: Number, default: 1},
|
||||
prize: {type: Number, default: 0, min: 0}, // TODO no update?
|
||||
prize: {type: Number, default: 0, min: 0},
|
||||
}, {
|
||||
strict: true,
|
||||
minimize: false, // So empty objects are returned
|
||||
});
|
||||
|
||||
schema.plugin(baseModel, {
|
||||
@@ -153,6 +156,7 @@ schema.methods.addTasks = async function challengeAddTasks (tasks) {
|
||||
|
||||
// Sync each user sequentially
|
||||
// TODO are we sure it's the best solution?
|
||||
// use bulk ops? http://stackoverflow.com/questions/16726330/mongoose-mongodb-batch-insert
|
||||
for (let memberId of membersIds) {
|
||||
let updateTasksOrderQ = {$push: {}};
|
||||
let toSave = [];
|
||||
|
||||
@@ -13,6 +13,9 @@ import {
|
||||
export let schema = new mongoose.Schema({
|
||||
event: {type: String, enum: ['wondercon', 'google_6mo']},
|
||||
user: {type: String, ref: 'User'},
|
||||
}, {
|
||||
strict: true,
|
||||
minimize: false, // So empty objects are returned
|
||||
});
|
||||
|
||||
schema.plugin(baseModel, {
|
||||
|
||||
@@ -15,6 +15,9 @@ export let schema = new mongoose.Schema({
|
||||
lowercase: true, // TODO migrate existing to lowerCase
|
||||
validator: [validator.isEmail, 'Invalid email.'],
|
||||
},
|
||||
}, {
|
||||
strict: true,
|
||||
minimize: false, // So empty objects are returned
|
||||
});
|
||||
|
||||
export let model = mongoose.model('EmailUnsubscription', schema);
|
||||
|
||||
+18
-33
@@ -91,21 +91,6 @@ schema.statics.sanitizeUpdate = function sanitizeUpdate (updateObj) {
|
||||
// Basic fields to fetch for populating a group info
|
||||
export let basicFields = 'name type privacy';
|
||||
|
||||
// TODO migration
|
||||
/**
|
||||
* Derby duplicated stuff. This is a temporary solution, once we're completely off derby we'll run an mongo migration
|
||||
* to remove duplicates, then take these fucntions out
|
||||
*/
|
||||
/* function removeDuplicates(doc){
|
||||
// Remove duplicate members
|
||||
if (doc.members) {
|
||||
var uniqMembers = _.uniq(doc.members);
|
||||
if (uniqMembers.length != doc.members.length) {
|
||||
doc.members = uniqMembers;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// TODO test
|
||||
schema.pre('remove', true, async function preRemoveGroup (next, done) {
|
||||
next();
|
||||
@@ -646,32 +631,32 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all') {
|
||||
|
||||
let promises = [];
|
||||
|
||||
// If user is the last one in group and group is private, delete it
|
||||
if (group.memberCount <= 1 && group.privacy === 'private') {
|
||||
return await group.remove();
|
||||
}
|
||||
|
||||
// otherwise just remove a member TODO create User.methods.removeFromGroup?
|
||||
// remove the group from the user's groups
|
||||
if (group.type === 'guild') {
|
||||
promises.push(User.update({_id: user._id}, {$pull: {guilds: group._id}}).exec());
|
||||
} else {
|
||||
promises.push(User.update({_id: user._id}, {$set: {party: {}}}).exec());
|
||||
}
|
||||
|
||||
// If the leader is leaving (or if the leader previously left, and this wasn't accounted for)
|
||||
let update = {
|
||||
$inc: {memberCount: -1},
|
||||
};
|
||||
// If user is the last one in group and group is private, delete it
|
||||
if (group.memberCount <= 1 && group.privacy === 'private') {
|
||||
return await group.remove();
|
||||
} else { // otherwise If the leader is leaving (or if the leader previously left, and this wasn't accounted for)
|
||||
let update = {
|
||||
$inc: {memberCount: -1},
|
||||
};
|
||||
|
||||
if (group.leader === user._id) {
|
||||
let query = group.type === 'party' ? {'party._id': group._id} : {guilds: group._id};
|
||||
query._id = {$ne: user._id};
|
||||
let seniorMember = await User.findOne(query).select('_id').exec();
|
||||
if (group.leader === user._id) {
|
||||
let query = group.type === 'party' ? {'party._id': group._id} : {guilds: group._id};
|
||||
query._id = {$ne: user._id};
|
||||
let seniorMember = await User.findOne(query).select('_id').exec();
|
||||
|
||||
// could be missing in case of public guild (that can have 0 members) with 1 member who is leaving
|
||||
if (seniorMember) update.$set = {leader: seniorMember._id};
|
||||
// could be missing in case of public guild (that can have 0 members) with 1 member who is leaving
|
||||
if (seniorMember) update.$set = {leader: seniorMember._id};
|
||||
}
|
||||
promises.push(group.update(update).exec());
|
||||
}
|
||||
promises.push(group.update(update).exec());
|
||||
|
||||
firebase.removeUserFromGroup(group._id, user._id);
|
||||
|
||||
return Q.all(promises);
|
||||
@@ -745,7 +730,7 @@ if (!nconf.get('IS_TEST')) {
|
||||
new model({ // eslint-disable-line babel/new-cap
|
||||
_id: TAVERN_ID,
|
||||
leader: '7bde7864-ebc5-4ee2-a4b7-1070d464cdb0', // Siena Leslie
|
||||
name: 'HabitRPG',
|
||||
name: 'Tavern',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
}).save();
|
||||
|
||||
@@ -7,8 +7,8 @@ export let schema = new Schema({
|
||||
name: {type: String, required: true},
|
||||
challenge: {type: String},
|
||||
}, {
|
||||
minimize: true, // So empty objects are returned
|
||||
strict: true,
|
||||
minimize: false, // So empty objects are returned
|
||||
});
|
||||
|
||||
schema.plugin(baseModel, {
|
||||
|
||||
@@ -115,10 +115,10 @@ export let schema = new Schema({
|
||||
},
|
||||
|
||||
balance: {type: Number, default: 0},
|
||||
// Not saved on the user TODO remove with migration
|
||||
/* filters: {type: Schema.Types.Mixed, default: () => {
|
||||
// Not saved on the user right now
|
||||
filters: {type: Schema.Types.Mixed, default: () => {
|
||||
return {};
|
||||
}}, */
|
||||
}},
|
||||
|
||||
purchased: {
|
||||
ads: {type: Boolean, default: false},
|
||||
@@ -524,7 +524,7 @@ export let schema = new Schema({
|
||||
},
|
||||
}, {
|
||||
strict: true,
|
||||
minimize: false, // So empty objects are returned TODO make sure it's in every model
|
||||
minimize: false, // So empty objects are returned
|
||||
});
|
||||
|
||||
schema.plugin(baseModel, {
|
||||
|
||||
@@ -4,8 +4,7 @@ var router = express.Router();
|
||||
var _ = require('lodash');
|
||||
var locals = require('../middlewares/api-v2/locals');
|
||||
var i18n = require('../libs/api-v2/i18n');
|
||||
var Remarkable = require('remarkable');
|
||||
var md = new Remarkable({
|
||||
var md = require('markdown-it')({
|
||||
html: true,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user