Merge branch 'develop' into Hus274-7793

This commit is contained in:
Blade Barringer
2016-08-05 12:55:00 -05:00
333 changed files with 14467 additions and 24545 deletions

View File

@@ -4,22 +4,22 @@ import passport from 'passport';
import nconf from 'nconf';
import {
authWithHeaders,
} from '../../middlewares/api-v3/auth';
} from '../../middlewares/auth';
import {
NotAuthorized,
BadRequest,
NotFound,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import Bluebird from 'bluebird';
import * as passwordUtils from '../../libs/api-v3/password';
import logger from '../../libs/api-v3/logger';
import * as passwordUtils from '../../libs/password';
import logger from '../../libs/logger';
import { model as User } from '../../models/user';
import { model as Group } from '../../models/group';
import { model as EmailUnsubscription } from '../../models/emailUnsubscription';
import { sendTxn as sendTxnEmail } from '../../libs/api-v3/email';
import { decrypt } from '../../libs/api-v3/encryption';
import { send as sendEmail } from '../../libs/api-v3/email';
import pusher from '../../libs/api-v3/pusher';
import { sendTxn as sendTxnEmail } from '../../libs/email';
import { decrypt } from '../../libs/encryption';
import { send as sendEmail } from '../../libs/email';
import pusher from '../../libs/pusher';
let api = {};
@@ -163,7 +163,7 @@ api.registerLocal = {
function _loginRes (user, req, res) {
if (user.auth.blocked) throw new NotAuthorized(res.t('accountSuspended', {userId: user._id}));
return res.respond(200, {id: user._id, apiToken: user.apiToken});
return res.respond(200, {id: user._id, apiToken: user.apiToken, newUser: user.newUser || false});
}
/**
@@ -178,6 +178,7 @@ function _loginRes (user, req, res) {
*
* @apiSuccess {String} data._id The user's unique identifier
* @apiSuccess {String} data.apiToken The user's api token that must be used to authenticate requests.
* @apiSuccess {Boolean} data.newUser Returns true if the user was just created (always false for local login).
*/
api.loginLocal = {
method: 'POST',
@@ -260,6 +261,7 @@ api.loginSocial = {
let savedUser = await user.save();
user.newUser = true;
_loginRes(user, ...arguments);
// Clean previous email preferences
@@ -359,8 +361,8 @@ api.pusherAuth = {
* @apiName UpdateUsername
* @apiGroup User
*
* @apiParam {string} password Body parameter - The current user password
* @apiParam {string} username Body parameter - The new username
* @apiParam {String} password Body parameter - The current user password
* @apiParam {String} username Body parameter - The new username
* @apiSuccess {String} data.username The new username
**/
@@ -407,9 +409,9 @@ api.updateUsername = {
* @apiName UpdatePassword
* @apiGroup User
*
* @apiParam {string} password Body parameter - The old password
* @apiParam {string} newPassword Body parameter - The new password
* @apiParam {string} confirmPassword Body parameter - New password confirmation
* @apiParam {String} password Body parameter - The old password
* @apiParam {String} newPassword Body parameter - The new password
* @apiParam {String} confirmPassword Body parameter - New password confirmation
*
* @apiSuccess {Object} data An empty object
**/
@@ -458,9 +460,9 @@ api.updatePassword = {
* @apiName ResetPassword
* @apiGroup User
*
* @apiParam {string} email Body parameter - The email address of the user
* @apiParam {String} email Body parameter - The email address of the user
*
* @apiSuccess {string} message The localized success message
* @apiSuccess {String} message The localized success message
**/
api.resetPassword = {
method: 'POST',
@@ -513,10 +515,10 @@ api.resetPassword = {
* @apiName UpdateEmail
* @apiGroup User
*
* @apiParam {string} Body parameter - newEmail The new email address.
* @apiParam {string} Body parameter - password The user password.
* @apiParam {String} Body parameter - newEmail The new email address.
* @apiParam {String} Body parameter - password The user password.
*
* @apiSuccess {string} data.email The updated email address
* @apiSuccess {String} data.email The updated email address
*/
api.updateEmail = {
method: 'PUT',

View File

@@ -1,4 +1,4 @@
import { authWithHeaders, authWithSession } from '../../middlewares/api-v3/auth';
import { authWithHeaders, authWithSession } from '../../middlewares/auth';
import _ from 'lodash';
import { model as Challenge } from '../../models/challenge';
import {
@@ -13,10 +13,10 @@ import {
import {
NotFound,
NotAuthorized,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import * as Tasks from '../../models/task';
import Bluebird from 'bluebird';
import csvStringify from '../../libs/api-v3/csvStringify';
import csvStringify from '../../libs/csvStringify';
let api = {};
@@ -26,7 +26,7 @@ let api = {};
* @apiName CreateChallenge
* @apiGroup Challenge
*
* @apiSuccess {object} data The newly created challenge
* @apiSuccess {Object} data The newly created challenge
*/
api.createChallenge = {
method: 'POST',
@@ -117,7 +117,7 @@ api.createChallenge = {
* @apiGroup Challenge
* @apiParam {UUID} challengeId The challenge _id
*
* @apiSuccess {object} data The challenge the user joined
* @apiSuccess {Object} data The challenge the user joined
*/
api.joinChallenge = {
method: 'POST',
@@ -164,7 +164,7 @@ api.joinChallenge = {
* @apiGroup Challenge
* @apiParam {UUID} challengeId The challenge _id
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.leaveChallenge = {
method: 'POST',
@@ -246,7 +246,7 @@ api.getUserChallenges = {
* @apiName GetGroupChallenges
* @apiGroup Challenge
*
* @apiParam {groupId} groupId The group _id
* @apiParam {UUID} groupId The group _id
*
* @apiSuccess {Array} data An array of challenges sorted with official challenges first, followed by the challenges in order from newest to oldest
*/
@@ -291,7 +291,7 @@ api.getGroupChallenges = {
*
* @apiParam {UUID} challengeId The challenge _id
*
* @apiSuccess {object} data The challenge object
* @apiSuccess {Object} data The challenge object
*/
api.getChallenge = {
method: 'GET',
@@ -334,7 +334,7 @@ api.getChallenge = {
*
* @apiParam {UUID} challengeId The challenge _id
*
* @apiSuccess {string} challenge A csv file
* @apiSuccess {String} challenge A csv file
*/
api.exportChallengeCsv = {
method: 'GET',
@@ -407,7 +407,7 @@ api.exportChallengeCsv = {
*
* @apiParam {UUID} challengeId The challenge _id
*
* @apiSuccess {object} data The updated challenge
* @apiSuccess {Object} data The updated challenge
*/
api.updateChallenge = {
method: 'PUT',
@@ -453,7 +453,7 @@ api.updateChallenge = {
*
* @apiParam {UUID} challengeId The _id for the challenge to delete
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.deleteChallenge = {
method: 'DELETE',
@@ -486,7 +486,7 @@ api.deleteChallenge = {
* @apiParam {UUID} challengeId The _id for the challenge to close with a winner
* @apiParam {UUID} winnerId The _id of the winning user
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.selectChallengeWinner = {
method: 'POST',

View File

@@ -1,14 +1,14 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { authWithHeaders } from '../../middlewares/auth';
import { model as Group } from '../../models/group';
import { model as User } from '../../models/user';
import {
NotFound,
NotAuthorized,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import _ from 'lodash';
import { removeFromArray } from '../../libs/api-v3/collectionManipulators';
import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/api-v3/email';
import pusher from '../../libs/api-v3/pusher';
import { removeFromArray } from '../../libs/collectionManipulators';
import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/email';
import pusher from '../../libs/pusher';
import nconf from 'nconf';
import Bluebird from 'bluebird';
@@ -24,7 +24,7 @@ let api = {};
* @apiName GetChat
* @apiGroup Chat
*
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
*
* @apiSuccess {Array} data An array of chat messages
*/
@@ -54,7 +54,7 @@ api.getChat = {
* @apiGroup Chat
*
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {string} message Body parameter - message The message to post
* @apiParam {String} message Body parameter - message The message to post
* @apiParam {UUID} previousMsg Query parameter - The previous chat message which will force a return of the full group chat
*
* @apiSuccess data An array of chat messages if a new message was posted after previousMsg, otherwise the posted message
@@ -166,7 +166,7 @@ api.likeChat = {
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {UUID} chatId The chat message id
*
* @apiSuccess {object} data The flagged chat message
* @apiSuccess {Object} data The flagged chat message
*/
api.flagChat = {
method: 'POST',
@@ -362,7 +362,7 @@ api.seenChat = {
* @apiName DeleteChat
* @apiGroup Chat
*
* @apiParam {string} previousMsg Query parameter - The last message fetched by the client so that the whole chat will be returned only if new messages have been posted in the meantime
* @apiParam {String} previousMsg Query parameter - The last message fetched by the client so that the whole chat will be returned only if new messages have been posted in the meantime
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {UUID} chatId The chat message id
*

View File

@@ -1,10 +1,10 @@
import common from '../../../../common';
import _ from 'lodash';
import { langCodes } from '../../libs/api-v3/i18n';
import { langCodes } from '../../libs/i18n';
import Bluebird from 'bluebird';
import fsCallback from 'fs';
import path from 'path';
import logger from '../../libs/api-v3/logger';
import logger from '../../libs/logger';
// Transform fs methods that accept callbacks in ones that return promises
const fs = {
@@ -67,7 +67,7 @@ async function saveContentToDisk (language, content) {
* @apiName ContentGet
* @apiGroup Content
*
* @apiParam {string} language Query parameter, the language code used for the items' strings. Defaulting to english
* @apiParam {String} language Query parameter, the language code used for the items' strings. Defaulting to english
*
* @apiSuccess {Object} data All the content available on Habitica
*/

View File

@@ -1,9 +1,9 @@
import csvStringify from '../../libs/api-v3/csvStringify';
import csvStringify from '../../libs/csvStringify';
import {
authWithHeaders,
authWithSession,
} from '../../middlewares/api-v3/auth';
import { ensureSudo } from '../../middlewares/api-v3/ensureAccessRight';
} from '../../middlewares/auth';
import { ensureSudo } from '../../middlewares/ensureAccessRight';
import { model as Coupon } from '../../models/coupon';
import _ from 'lodash';
import couponCode from 'coupon-code';
@@ -17,7 +17,7 @@ let api = {};
* @apiName GetCoupons
* @apiGroup Coupon
*
* @apiSuccess {string} Coupons in CSV format
* @apiSuccess {String} Coupons in CSV format
*/
api.getCoupons = {
method: 'GET',
@@ -46,10 +46,10 @@ api.getCoupons = {
* @apiName GenerateCoupons
* @apiGroup Coupon
*
* @apiParam {string} event The event for which the coupon should be generated
* @apiParam {number} count Query parameter to specify the number of coupon codes to generate
* @apiParam {String} event The event for which the coupon should be generated
* @apiParam {Number} count Query parameter to specify the number of coupon codes to generate
*
* @apiSuccess {array} data Generated coupons
* @apiSuccess {Array} data Generated coupons
*/
api.generateCoupons = {
method: 'POST',
@@ -73,9 +73,9 @@ api.generateCoupons = {
* @apiName EnterCouponCode
* @apiGroup Coupon
*
* @apiParam {string} code The coupon code to apply
* @apiParam {String} code The coupon code to apply
*
* @apiSuccess {object} data User object
* @apiSuccess {Object} data User object
*/
api.enterCouponCode = {
method: 'POST',
@@ -100,7 +100,7 @@ api.enterCouponCode = {
* @apiName ValidateCoupon
* @apiGroup Coupon
*
* @apiSuccess {boolean} data.valid True or false
* @apiSuccess {Boolean} data.valid True or false
*/
api.validateCoupon = {
method: 'POST',

View File

@@ -1,6 +1,6 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import ensureDevelpmentMode from '../../middlewares/api-v3/ensureDevelpmentMode';
import { BadRequest } from '../../libs/api-v3/errors';
import { authWithHeaders } from '../../middlewares/auth';
import ensureDevelpmentMode from '../../middlewares/ensureDevelpmentMode';
import { BadRequest } from '../../libs/errors';
import { content } from '../../../../common';
import _ from 'lodash';

View File

@@ -1,4 +1,4 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { authWithHeaders } from '../../middlewares/auth';
import Bluebird from 'bluebird';
import _ from 'lodash';
import {
@@ -15,12 +15,12 @@ import {
NotFound,
BadRequest,
NotAuthorized,
} from '../../libs/api-v3/errors';
import { removeFromArray } from '../../libs/api-v3/collectionManipulators';
import { sendTxn as sendTxnEmail } from '../../libs/api-v3/email';
import { encrypt } from '../../libs/api-v3/encryption';
import sendPushNotification from '../../libs/api-v3/pushNotifications';
import pusher from '../../libs/api-v3/pusher';
} from '../../libs/errors';
import { removeFromArray } from '../../libs/collectionManipulators';
import { sendTxn as sendTxnEmail } from '../../libs/email';
import { encrypt } from '../../libs/encryption';
import sendPushNotification from '../../libs/pushNotifications';
import pusher from '../../libs/pusher';
let api = {};
@@ -76,7 +76,7 @@ api.createGroup = {
* @apiName GetGroups
* @apiGroup Group
*
* @apiParam {string} type The type of groups to retrieve. Must be a query string representing a list of values like 'tavern,party'. Possible values are party, guilds, privateGuilds, publicGuilds, tavern
* @apiParam {String} type The type of groups to retrieve. Must be a query string representing a list of values like 'tavern,party'. Possible values are party, guilds, privateGuilds, publicGuilds, tavern
*
* @apiSuccess {Array} data An array of the requested groups
*/
@@ -107,7 +107,7 @@ api.getGroups = {
* @apiName GetGroup
* @apiGroup Group
*
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
*
* @apiSuccess {Object} data The group object
*/
@@ -142,7 +142,7 @@ api.getGroup = {
* @apiName UpdateGroup
* @apiGroup Group
*
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
*
* @apiSuccess {Object} data The updated group
*/
@@ -328,8 +328,8 @@ api.rejectGroupInvite = {
* @apiName LeaveGroup
* @apiGroup Group
*
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {string="remove-all","keep-all"} keep Query parameter - Whether to keep or not challenges' tasks. Defaults to keep-all
* @apiParam {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {String="remove-all","keep-all"} keep Query parameter - Whether to keep or not challenges' tasks. Defaults to keep-all
*
* @apiSuccess {Object} data An empty object
*/
@@ -384,9 +384,9 @@ function _sendMessageToRemoved (group, removedUser, message) {
* @apiName RemoveGroupMember
* @apiGroup Group
*
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {UUID} memberId The _id of the member to remove
* @apiParam {string} message Query parameter - The message to send to the removed members
* @apiParam {String} message Query parameter - The message to send to the removed members
*
* @apiSuccess {Object} data An empty object
*/
@@ -436,7 +436,7 @@ api.removeGroupMember = {
group.quest.leader = undefined;
} else if (group.quest && group.quest.members) {
// remove member from quest
group.quest.members[member._id] = undefined;
delete group.quest.members[member._id];
group.markModified('quest.members');
}
@@ -606,13 +606,13 @@ async function _inviteByEmail (invite, group, inviter, req, res) {
* @apiName InviteToGroup
* @apiGroup Group
*
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
*
* @apiParam {array} emails Body parameter - An array of emails addresses to invite (optional)
* @apiParam {array} uuids Body parameter - An array of uuids to invite (optional)
* @apiParam {string} inviter Body parameter - The inviters' name (optional)
* @apiParam {Array} emails Body parameter - An array of emails addresses to invite (optional)
* @apiParam {Array} uuids Body parameter - An array of uuids to invite (optional)
* @apiParam {String} inviter Body parameter - The inviters' name (optional)
*
* @apiSuccess {array} data The invites
* @apiSuccess {Array} data The invites
*/
api.inviteToGroup = {
method: 'POST',

View File

@@ -1,9 +1,9 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { ensureAdmin } from '../../middlewares/api-v3/ensureAccessRight';
import { authWithHeaders } from '../../middlewares/auth';
import { ensureAdmin } from '../../middlewares/ensureAccessRight';
import { model as User } from '../../models/user';
import {
NotFound,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import _ from 'lodash';
let api = {};

View File

@@ -1,4 +1,4 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { authWithHeaders } from '../../middlewares/auth';
import {
model as User,
publicFields as memberFields,
@@ -9,14 +9,14 @@ import { model as Challenge } from '../../models/challenge';
import {
NotFound,
NotAuthorized,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import * as Tasks from '../../models/task';
import {
getUserInfo,
sendTxn as sendTxnEmail,
} from '../../libs/api-v3/email';
} from '../../libs/email';
import Bluebird from 'bluebird';
import sendPushNotification from '../../libs/api-v3/pushNotifications';
import sendPushNotification from '../../libs/pushNotifications';
let api = {};
@@ -28,7 +28,7 @@ let api = {};
*
* @apiParam {UUID} memberId The member's id
*
* @apiSuccess {object} data The member object
* @apiSuccess {Object} data The member object
*/
api.getMember = {
method: 'GET',
@@ -50,7 +50,10 @@ api.getMember = {
if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId}));
// manually call toJSON with minimize: true so empty paths aren't returned
res.respond(200, member.toJSON({minimize: true}));
let memberToJSON = member.toJSON({minimize: true});
member.addComputedStatsToJSONObj(memberToJSON);
res.respond(200, memberToJSON);
},
};
@@ -100,6 +103,7 @@ function _getMembersForItem (type) {
let query = {};
let fields = nameFields;
let addComputedStats = false; // add computes stats to the member info when items and stats are available
if (type === 'challenge-members') {
query.challenges = challenge._id;
@@ -111,6 +115,7 @@ function _getMembersForItem (type) {
if (req.query.includeAllPublicFields === 'true') {
fields = memberFields;
addComputedStats = true;
}
}
} else if (type === 'group-invites') {
@@ -138,7 +143,13 @@ function _getMembersForItem (type) {
.exec();
// manually call toJSON with minimize: true so empty paths aren't returned
res.respond(200, members.map(member => member.toJSON({minimize: true})));
let membersToJSON = members.map(member => {
let memberToJSON = member.toJSON({minimize: true});
if (addComputedStats) member.addComputedStatsToJSONObj(memberToJSON);
return memberToJSON;
});
res.respond(200, membersToJSON);
};
}
@@ -194,7 +205,7 @@ api.getInvitesForGroup = {
*
* @apiParam {UUID} challengeId The challenge id
* @apiParam {UUID} lastId Query parameter to specify the last member returned in a previous request to this route and get the next batch of results
* @apiParam {string} includeAllMembers BETA Query parameter - If 'true' all challenge members are returned
* @apiParam {String} includeAllMembers BETA Query parameter - If 'true' all challenge members are returned
* @apiSuccess {array} data An array of members, sorted by _id
*/
@@ -214,7 +225,7 @@ api.getMembersForChallenge = {
* @apiParam {UUID} challengeId The challenge _id
* @apiParam {UUID} member The member _id
*
* @apiSuccess {object} data Return an object with member _id, profile.name and a tasks object with the challenge tasks for the member
* @apiSuccess {Object} data Return an object with member _id, profile.name and a tasks object with the challenge tasks for the member
*/
api.getChallengeMemberProgress = {
method: 'GET',

View File

@@ -12,9 +12,9 @@ let allModels = ['user', 'tag', 'challenge', 'group'].concat(tasksModels);
* @apiName GetUserModelPaths
* @apiGroup Meta
*
* @apiParam {string="user","group","challenge","tag","habit","daily","todo","reward"} model The name of the model
* @apiParam {String="user","group","challenge","tag","habit","daily","todo","reward"} model The name of the model
*
* @apiSuccess {object} data A key-value object made of fieldPath: fieldType (like {'field.nested': Boolean})
* @apiSuccess {Object} data A key-value object made of fieldPath: fieldType (like {'field.nested': Boolean})
*/
api.getModelPaths = {
method: 'GET',

View File

@@ -1,8 +1,8 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { authWithHeaders } from '../../middlewares/auth';
import _ from 'lodash';
import {
NotFound,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
let api = {};

View File

@@ -1,8 +1,8 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { authWithHeaders } from '../../middlewares/auth';
import {
NotAuthorized,
NotFound,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
let api = {};
@@ -13,11 +13,11 @@ let api = {};
* @apiName UserAddPushDevice
* @apiGroup User
*
* @apiParam {string} regId The id of the push device
* @apiParam {string} type The type of push device
* @apiParam {String} regId The id of the push device
* @apiParam {String} type The type of push device
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.addPushDevice = {
method: 'POST',
@@ -58,10 +58,10 @@ api.addPushDevice = {
* @apiName UserRemovePushDevice
* @apiGroup User
*
* @apiParam {string} regId The id of the push device
* @apiParam {String} regId The id of the push device
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.removePushDevice = {
method: 'DELETE',

View File

@@ -1,7 +1,7 @@
import _ from 'lodash';
import Bluebird from 'bluebird';
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import analytics from '../../libs/api-v3/analyticsService';
import { authWithHeaders } from '../../middlewares/auth';
import analytics from '../../libs/analyticsService';
import {
model as Group,
} from '../../models/group';
@@ -10,13 +10,13 @@ import {
NotFound,
NotAuthorized,
BadRequest,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import {
getUserInfo,
sendTxn as sendTxnEmail,
} from '../../libs/api-v3/email';
} from '../../libs/email';
import common from '../../../../common';
import sendPushNotification from '../../libs/api-v3/pushNotifications';
import sendPushNotification from '../../libs/pushNotifications';
const questScrolls = common.content.quests;
@@ -34,8 +34,8 @@ let api = {};
* @apiName InviteToQuest
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {string} questKey
* @apiParam {String} groupId The group _id (or 'party')
* @apiParam {String} questKey
*
* @apiSuccess {Object} data Quest object
*/
@@ -145,7 +145,7 @@ api.inviteToQuest = {
* @apiName AcceptQuest
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {String} groupId The group _id (or 'party')
*
* @apiSuccess {Object} data Quest Object
*/
@@ -161,6 +161,9 @@ api.acceptQuest = {
let validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
user.party.quest.RSVPNeeded = false;
await user.save();
let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest'});
if (!group) throw new NotFound(res.t('groupNotFound'));
@@ -171,16 +174,12 @@ api.acceptQuest = {
group.markModified('quest');
group.quest.members[user._id] = true;
user.party.quest.RSVPNeeded = false;
if (canStartQuestAutomatically(group)) {
await group.startQuest(user);
}
let [savedGroup] = await Bluebird.all([
group.save(),
user.save(),
]);
let savedGroup = await group.save();
res.respond(200, savedGroup.quest);
@@ -202,7 +201,7 @@ api.acceptQuest = {
* @apiName RejectQuest
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {String} groupId The group _id (or 'party')
*
* @apiSuccess {Object} data Quest Object
*/
@@ -218,6 +217,10 @@ api.rejectQuest = {
let validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
user.party.quest = Group.cleanQuestProgress();
user.markModified('party.quest');
await user.save();
let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest'});
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
@@ -229,17 +232,11 @@ api.rejectQuest = {
group.quest.members[user._id] = false;
group.markModified('quest.members');
user.party.quest = Group.cleanQuestProgress();
user.markModified('party.quest');
if (canStartQuestAutomatically(group)) {
await group.startQuest(user);
}
let [savedGroup] = await Bluebird.all([
group.save(),
user.save(),
]);
let savedGroup = await group.save();
res.respond(200, savedGroup.quest);
@@ -261,7 +258,7 @@ api.rejectQuest = {
* @apiName ForceQuestStart
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {String} groupId The group _id (or 'party')
*
* @apiSuccess {Object} data Quest Object
*/
@@ -313,7 +310,7 @@ api.forceStart = {
* @apiName CancelQuest
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {String} groupId The group _id (or 'party')
*
* @apiSuccess {Object} data Quest Object
*/
@@ -362,7 +359,7 @@ api.cancelQuest = {
* @apiName AbortQuest
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {String} groupId The group _id (or 'party')
*
* @apiSuccess {Object} data Quest Object
*/
@@ -415,7 +412,7 @@ api.abortQuest = {
* @apiName LeaveQuest
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {String} groupId The group _id (or 'party')
*
* @apiSuccess {Object} data Quest Object
*/

View File

@@ -0,0 +1,123 @@
import { authWithHeaders } from '../../middlewares/auth';
import { shops } from '../../../../common/';
let api = {};
/**
* @apiIgnore
* @api {get} /api/v3/shops/market get the available items for the market
* @apiVersion 3.0.0
* @apiName GetMarketItems
* @apiGroup Shops
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
*/
api.getMarketItems = {
method: 'GET',
url: '/shops/market',
middlewares: [authWithHeaders()],
async handler (req, res) {
let user = res.locals.user;
let resObject = {
identifier: 'market',
text: res.t('market'),
notes: res.t('welcomeMarketMobile'),
imageName: 'npc_alex',
categories: shops.getMarketCategories(user, req.language),
};
res.respond(200, resObject);
},
};
/**
* @apiIgnore
* @api {get} /api/v3/shops/quests get the available items for the quests shop
* @apiVersion 3.0.0
* @apiName GetQuestShopItems
* @apiGroup Shops
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
*/
api.getQuestShopItems = {
method: 'GET',
url: '/shops/quests',
middlewares: [authWithHeaders()],
async handler (req, res) {
let user = res.locals.user;
let resObject = {
identifier: 'questShop',
text: res.t('quests'),
notes: res.t('ianTextMobile'),
imageName: 'npc_ian',
categories: shops.getQuestShopCategories(user, req.language),
};
res.respond(200, resObject);
},
};
/**
* @apiIgnore
* @api {get} /api/v3/shops/time-travelers get the available items for the time travelers shop
* @apiVersion 3.0.0
* @apiName GetTimeTravelersShopItems
* @apiGroup Shops
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
*/
api.getTimeTravelerShopItems = {
method: 'GET',
url: '/shops/time-travelers',
middlewares: [authWithHeaders()],
async handler (req, res) {
let user = res.locals.user;
let hasTrinkets = user.purchased.plan.consecutive.trinkets > 0;
let resObject = {
identifier: 'timeTravelersShop',
text: res.t('timeTravelers'),
notes: hasTrinkets ? res.t('timeTravelersPopover') : res.t('timeTravelersPopoverNoSubMobile'),
imageName: hasTrinkets ? 'npc_timetravelers_active' : 'npc_timetravelers',
categories: shops.getTimeTravelersCategories(user, req.language),
};
res.respond(200, resObject);
},
};
/**
* @apiIgnore
* @api {get} /api/v3/shops/seasonal get the available items for the seasonal shop
* @apiVersion 3.0.0
* @apiName GetSeasonalShopItems
* @apiGroup Shops
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
*/
api.getSeasonalShopItems = {
method: 'GET',
url: '/shops/seasonal',
middlewares: [authWithHeaders()],
async handler (req, res) {
let user = res.locals.user;
let resObject = {
identifier: 'seasonalShop',
text: res.t('seasonalShop'),
notes: res.t('seasonalShopClosedText'),
imageName: 'seasonalshop_closed',
categories: shops.getSeasonalShopCategories(user, req.language),
};
res.respond(200, resObject);
},
};
module.exports = api;

View File

@@ -6,7 +6,7 @@ let api = {};
* @apiName GetStatus
* @apiGroup Status
*
* @apiSuccess {status} data.status 'up' if everything is ok
* @apiSuccess {String} data.status 'up' if everything is ok
*/
api.getStatus = {
method: 'GET',

View File

@@ -1,11 +1,11 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { authWithHeaders } from '../../middlewares/auth';
import { model as Tag } from '../../models/tag';
import * as Tasks from '../../models/task';
import {
NotFound,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import _ from 'lodash';
import { removeFromArray } from '../../libs/api-v3/collectionManipulators';
import { removeFromArray } from '../../libs/collectionManipulators';
let api = {};
@@ -59,7 +59,7 @@ api.getTags = {
*
* @apiParam {UUID} tagId The tag _id
*
* @apiSuccess {object} data The tag object
* @apiSuccess {Object} data The tag object
*/
api.getTag = {
method: 'GET',
@@ -87,7 +87,7 @@ api.getTag = {
*
* @apiParam {UUID} tagId The tag _id
*
* @apiSuccess {object} data The updated tag
* @apiSuccess {Object} data The updated tag
*/
api.updateTag = {
method: 'PUT',
@@ -119,10 +119,10 @@ api.updateTag = {
* @apiName ReorderTags
* @apiGroup Tag
*
* @apiParam {tagId} UUID Id of the tag to move
* @apiParam {to} number Position the tag is moving to
* @apiParam {UUID} tagId Id of the tag to move
* @apiParam {Number} to Position the tag is moving to
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.reorderTags = {
method: 'POST',
@@ -156,7 +156,7 @@ api.reorderTags = {
*
* @apiParam {UUID} tagId The tag _id
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.deleteTag = {
method: 'DELETE',

View File

@@ -1,6 +1,6 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { sendTaskWebhook } from '../../libs/api-v3/webhook';
import { removeFromArray } from '../../libs/api-v3/collectionManipulators';
import { authWithHeaders } from '../../middlewares/auth';
import { sendTaskWebhook } from '../../libs/webhook';
import { removeFromArray } from '../../libs/collectionManipulators';
import * as Tasks from '../../models/task';
import { model as Challenge } from '../../models/challenge';
import { model as Group } from '../../models/group';
@@ -8,11 +8,11 @@ import {
NotFound,
NotAuthorized,
BadRequest,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import common from '../../../../common';
import Bluebird from 'bluebird';
import _ from 'lodash';
import logger from '../../libs/api-v3/logger';
import logger from '../../libs/logger';
let api = {};
@@ -259,9 +259,9 @@ api.getChallengeTasks = {
* @apiName GetTask
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
*
* @apiSuccess {object} data The task object
* @apiSuccess {Object} data The task object
*/
api.getTask = {
method: 'GET',
@@ -293,9 +293,9 @@ api.getTask = {
* @apiName UpdateTask
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
*
* @apiSuccess {object} data The updated task
* @apiSuccess {Object} data The updated task
*/
api.updateTask = {
method: 'PUT',
@@ -379,12 +379,12 @@ function _generateWebhookTaskData (task, direction, delta, stats, user) {
* @apiName ScoreTask
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {string="up","down"} direction The direction for scoring the task
* @apiParam {String} taskId The task _id or alias
* @apiParam {String="up","down"} direction The direction for scoring the task
*
* @apiSuccess {object} data._tmp If an item was dropped it'll be returned in te _tmp object
* @apiSuccess {number} data.delta
* @apiSuccess {object} data The user stats
* @apiSuccess {Object} data._tmp If an item was dropped it'll be returned in te _tmp object
* @apiSuccess {Number} data.delta The delta
* @apiSuccess {Object} data The user stats
*/
api.scoreTask = {
method: 'POST',
@@ -462,10 +462,10 @@ api.scoreTask = {
* @apiName MoveTask
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
* @apiParam {Number} position Query parameter - Where to move the task (-1 means push to bottom). First position is 0
*
* @apiSuccess {array} data The new tasks order (user.tasksOrder.{task.type}s)
* @apiSuccess {Array} data The new tasks order (user.tasksOrder.{task.type}s)
*/
api.moveTask = {
method: 'POST',
@@ -515,9 +515,9 @@ api.moveTask = {
* @apiName AddChecklistItem
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
*
* @apiSuccess {object} data The updated task
* @apiSuccess {Object} data The updated task
*/
api.addChecklistItem = {
method: 'POST',
@@ -563,10 +563,10 @@ api.addChecklistItem = {
* @apiName ScoreChecklistItem
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
* @apiParam {UUID} itemId The checklist item _id
*
* @apiSuccess {object} data The updated task
* @apiSuccess {Object} data The updated task
*/
api.scoreCheckListItem = {
method: 'POST',
@@ -603,10 +603,10 @@ api.scoreCheckListItem = {
* @apiName UpdateChecklistItem
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
* @apiParam {UUID} itemId The checklist item _id
*
* @apiSuccess {object} data The updated task
* @apiSuccess {Object} data The updated task
*/
api.updateChecklistItem = {
method: 'PUT',
@@ -655,10 +655,10 @@ api.updateChecklistItem = {
* @apiName RemoveChecklistItem
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
* @apiParam {UUID} itemId The checklist item _id
*
* @apiSuccess {object} data The updated task
* @apiSuccess {Object} data The updated task
*/
api.removeChecklistItem = {
method: 'DELETE',
@@ -705,10 +705,10 @@ api.removeChecklistItem = {
* @apiName AddTagToTask
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
* @apiParam {UUID} tagId The tag id
*
* @apiSuccess {object} data The updated task
* @apiSuccess {Object} data The updated task
*/
api.addTagToTask = {
method: 'POST',
@@ -746,10 +746,10 @@ api.addTagToTask = {
* @apiName RemoveTagFromTask
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
* @apiParam {UUID} tagId The tag id
*
* @apiSuccess {object} data The updated task
* @apiSuccess {Object} data The updated task
*/
api.removeTagFromTask = {
method: 'DELETE',
@@ -784,9 +784,9 @@ api.removeTagFromTask = {
* @apiGroup Task
*
* @apiParam {UUID} challengeId The challenge _id
* @apiParam {string} keep Query parameter - keep-all or remove-all
* @apiParam {String} keep Query parameter - keep-all or remove-all
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.unlinkAllTasks = {
method: 'POST',
@@ -845,10 +845,10 @@ api.unlinkAllTasks = {
* @apiName UnlinkOneTask
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {string} keep Query parameter - keep or remove
* @apiParam {String} taskId The task _id or alias
* @apiParam {String} keep Query parameter - keep or remove
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.unlinkOneTask = {
method: 'POST',
@@ -893,7 +893,7 @@ api.unlinkOneTask = {
* @apiName ClearCompletedTodos
* @apiGroup Task
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.clearCompletedTodos = {
method: 'POST',
@@ -924,9 +924,9 @@ api.clearCompletedTodos = {
* @apiName DeleteTask
* @apiGroup Task
*
* @apiParam {string} taskId The task _id or alias
* @apiParam {String} taskId The task _id or alias
*
* @apiSuccess {object} data An empty object
* @apiSuccess {Object} data An empty object
*/
api.deleteTask = {
method: 'DELETE',

View File

@@ -1,10 +1,10 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import { authWithHeaders } from '../../middlewares/auth';
import common from '../../../../common';
import {
NotFound,
BadRequest,
NotAuthorized,
} from '../../libs/api-v3/errors';
} from '../../libs/errors';
import * as Tasks from '../../models/task';
import {
basicFields as basicGroupFields,
@@ -13,7 +13,7 @@ import {
import { model as User } from '../../models/user';
import Bluebird from 'bluebird';
import _ from 'lodash';
import * as passwordUtils from '../../libs/api-v3/password';
import * as passwordUtils from '../../libs/password';
let api = {};
@@ -30,19 +30,14 @@ api.getUser = {
middlewares: [authWithHeaders()],
url: '/user',
async handler (req, res) {
let user = res.locals.user.toJSON();
let user = res.locals.user;
let userToJSON = user.toJSON();
// Remove apiToken from response TODO make it private at the user level? returned in signup/login
delete user.apiToken;
delete userToJSON.apiToken;
// TODO move to model? (maybe virtuals, maybe in toJSON)
// NOTE: if an item is manually added to user.stats common/fns/predictableRandom must be tweaked
// so it's not considered. Otherwise the client will have it while the server won't and the results will be different.
user.stats.toNextLevel = common.tnl(user.stats.lvl);
user.stats.maxHealth = common.maxHealth;
user.stats.maxMP = common.statsComputed(user).maxMP;
return res.respond(200, user);
user.addComputedStatsToJSONObj(userToJSON);
return res.respond(200, userToJSON);
},
};
@@ -149,7 +144,7 @@ let checkPreferencePurchase = (user, path, item) => {
* @apiName UserUpdate
* @apiGroup User
*
* @apiSuccess {object} data The updated user object
* @apiSuccess {Object} data The updated user object
*/
api.updateUser = {
method: 'PUT',
@@ -183,7 +178,7 @@ api.updateUser = {
* @apiName UserDelete
* @apiGroup User
*
* @apiParam {string} password The user's password (unless it's a Facebook account)
* @apiParam {String} password The user's password (unless it's a Facebook account)
*
* @apiSuccess {Object} data An empty Object
*/
@@ -309,7 +304,7 @@ const partyMembersFields = 'profile.name stats achievements items.special';
* @apiName UserCast
* @apiGroup User
*
* @apiParam {string} spellId The skill to cast
* @apiParam {String} spellId The skill to cast
* @apiParam {UUID} targetId Optional query parameter, the id of the target when casting a skill on a party member or a task
*
* @apiSuccess data Will return the modified targets. For party members only the necessary fields will be populated. The user is always returned.
@@ -485,7 +480,7 @@ api.sleep = {
* @apiName UserAllocate
* @apiGroup User
*
* @apiParam {string} stat Query parameter - Defaults to 'str', mast be one of be of str, con, int or per
* @apiParam {String} stat Query parameter - Defaults to 'str', mast be one of be of str, con, int or per
*
* @apiSuccess {Object} data user.stats
*/
@@ -529,7 +524,7 @@ api.allocateNow = {
* @apiName UserBuy
* @apiGroup User
*
* @apiParam {string} key The item to buy
* @apiParam {String} key The item to buy
*/
api.buy = {
method: 'POST',
@@ -549,13 +544,13 @@ api.buy = {
* @apiName UserBuyGear
* @apiGroup User
*
* @apiParam {string} key The item to buy
* @apiParam {String} key The item to buy
*
* @apiSuccess {object} data.items user.items
* @apiSuccess {object} data.flags user.flags
* @apiSuccess {object} data.achievements user.achievements
* @apiSuccess {object} data.stats user.stats
* @apiSuccess {string} message Success message
* @apiSuccess {Object} data.items user.items
* @apiSuccess {Object} data.flags user.flags
* @apiSuccess {Object} data.achievements user.achievements
* @apiSuccess {Object} data.stats user.stats
* @apiSuccess {String} message Success message
*/
api.buyGear = {
method: 'POST',
@@ -575,10 +570,10 @@ api.buyGear = {
* @apiName UserBuyArmoire
* @apiGroup User
*
* @apiSuccess {object} data.items user.items
* @apiSuccess {object} data.flags user.flags
* @apiSuccess {object} data.armoire Extra item given by the armoire
* @apiSuccess {string} message Success message
* @apiSuccess {Object} data.items user.items
* @apiSuccess {Object} data.flags user.flags
* @apiSuccess {Object} data.armoire Extra item given by the armoire
* @apiSuccess {String} message Success message
*/
api.buyArmoire = {
method: 'POST',
@@ -599,7 +594,7 @@ api.buyArmoire = {
* @apiGroup User
*
* @apiSuccess {Object} data user.stats
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.buyHealthPotion = {
method: 'POST',
@@ -619,11 +614,11 @@ api.buyHealthPotion = {
* @apiName UserBuyMysterySet
* @apiGroup User
*
* @apiParam {string} key The mystery set to buy
* @apiParam {String} key The mystery set to buy
*
* @apiSuccess {Object} data.items user.items
* @apiSuccess {Object} data.purchasedPlanConsecutive user.purchased.plan.consecutive
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.buyMysterySet = {
method: 'POST',
@@ -643,10 +638,10 @@ api.buyMysterySet = {
* @apiName UserBuyQuest
* @apiGroup User
*
* @apiParam {string} key The quest scroll to buy
* @apiParam {String} key The quest scroll to buy
*
* @apiSuccess {Object} data `user.items.quests`
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.buyQuest = {
method: 'POST',
@@ -667,11 +662,11 @@ api.buyQuest = {
* @apiName UserBuySpecialSpell
* @apiGroup User
*
* @apiParam {string} key The special item to buy. Must be one of the keys from "content.special", such as birthday, snowball, salt.
* @apiParam {String} key The special item to buy. Must be one of the keys from "content.special", such as birthday, snowball, salt.
*
* @apiSuccess {Object} data.stats user.stats
* @apiSuccess {Object} data.items user.items
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.buySpecialSpell = {
method: 'POST',
@@ -691,11 +686,11 @@ api.buySpecialSpell = {
* @apiName UserHatch
* @apiGroup User
*
* @apiParam {string} egg The egg to use
* @apiParam {string} hatchingPotion The hatching potion to use
* @apiParam {String} egg The egg to use
* @apiParam {String} hatchingPotion The hatching potion to use
*
* @apiSuccess {Object} data user.items
* @apiSuccess {string} message
* @apiSuccess {String} message
*/
api.hatch = {
method: 'POST',
@@ -715,11 +710,11 @@ api.hatch = {
* @apiName UserEquip
* @apiGroup User
*
* @apiParam {string} type The type of item to equip (mount, pet, costume or equipped)
* @apiParam {string} key The item to equip
* @apiParam {String} type The type of item to equip (mount, pet, costume or equipped)
* @apiParam {String} key The item to equip
*
* @apiSuccess {Object} data user.items
* @apiSuccess {string} message Optional success message
* @apiSuccess {String} message Optional success message
*/
api.equip = {
method: 'POST',
@@ -739,11 +734,11 @@ api.equip = {
* @apiName UserFeed
* @apiGroup User
*
* @apiParam {string} pet
* @apiParam {string} food
* @apiParam {String} pet
* @apiParam {String} food
*
* @apiSuccess {number} data The pet value
* @apiSuccess {string} message Success message
* @apiSuccess {Number} data The pet value
* @apiSuccess {String} message Success message
*/
api.feed = {
method: 'POST',
@@ -764,12 +759,12 @@ api.feed = {
* @apiName UserChangeClass
* @apiGroup User
*
* @apiParam {string} class Query parameter - ?class={warrior|rogue|wizard|healer}
* @apiParam {String} class Query parameter - ?class={warrior|rogue|wizard|healer}
*
* @apiSuccess {object} data.flags user.flags
* @apiSuccess {object} data.stats user.stats
* @apiSuccess {object} data.preferences user.preferences
* @apiSuccess {object} data.items user.items
* @apiSuccess {Object} data.flags user.flags
* @apiSuccess {Object} data.stats user.stats
* @apiSuccess {Object} data.preferences user.preferences
* @apiSuccess {Object} data.items user.items
*/
api.changeClass = {
method: 'POST',
@@ -789,9 +784,9 @@ api.changeClass = {
* @apiName UserDisableClasses
* @apiGroup User
*
* @apiSuccess {object} data.flags user.flags
* @apiSuccess {object} data.stats user.stats
* @apiSuccess {object} data.preferences user.preferences
* @apiSuccess {Object} data.flags user.flags
* @apiSuccess {Object} data.stats user.stats
* @apiSuccess {Object} data.preferences user.preferences
*/
api.disableClasses = {
method: 'POST',
@@ -811,12 +806,12 @@ api.disableClasses = {
* @apiName UserPurchase
* @apiGroup User
*
* @apiParam {string} type Type of item to purchase. Must be one of: gems, eggs, hatchingPotions, food, quests, or gear
* @apiParam {string} key Item's key (use "gem" for purchasing gems)
* @apiParam {String} type Type of item to purchase. Must be one of: gems, eggs, hatchingPotions, food, quests, or gear
* @apiParam {String} key Item's key (use "gem" for purchasing gems)
*
* @apiSuccess {object} data.items user.items
* @apiSuccess {number} data.balance user.balance
* @apiSuccess {string} message Success message
* @apiSuccess {Object} data.items user.items
* @apiSuccess {Number} data.balance user.balance
* @apiSuccess {String} message Success message
*/
api.purchase = {
method: 'POST',
@@ -836,12 +831,12 @@ api.purchase = {
* @apiName UserPurchaseHourglass
* @apiGroup User
*
* @apiParam {string} type The type of item to purchase (pets or mounts)
* @apiParam {string} key Ex: {MantisShrimp-Base}. The key for the mount/pet
* @apiParam {String} type The type of item to purchase (pets or mounts)
* @apiParam {String} key Ex: {MantisShrimp-Base}. The key for the mount/pet
*
* @apiSuccess {object} data.items user.items
* @apiSuccess {object} data.purchasedPlanConsecutive user.purchased.plan.consecutive
* @apiSuccess {string} message Success message
* @apiSuccess {Object} data.items user.items
* @apiSuccess {Object} data.purchasedPlanConsecutive user.purchased.plan.consecutive
* @apiSuccess {String} message Success message
*/
api.userPurchaseHourglass = {
method: 'POST',
@@ -861,11 +856,11 @@ api.userPurchaseHourglass = {
* @apiName UserReadCard
* @apiGroup User
*
* @apiParam {string} cardType Type of card to read
* @apiParam {String} cardType Type of card to read
*
* @apiSuccess {object} data.specialItems user.items.special
* @apiSuccess {boolean} data.cardReceived user.flags.cardReceived
* @apiSuccess {string} message Success message
* @apiSuccess {Object} data.specialItems user.items.special
* @apiSuccess {Boolean} data.cardReceived user.flags.cardReceived
* @apiSuccess {String} message Success message
*/
api.readCard = {
method: 'POST',
@@ -886,7 +881,7 @@ api.readCard = {
* @apiGroup User
*
* @apiSuccess {Object} data The item obtained
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.userOpenMysteryItem = {
method: 'POST',
@@ -906,8 +901,8 @@ api.userOpenMysteryItem = {
* @apiName UserAddWebhook
* @apiGroup User
*
* @apiParam {string} url Body parameter - The webhook's URL
* @apiParam {boolean} enabled Body parameter - If the webhook should be enabled
* @apiParam {String} url Body parameter - The webhook's URL
* @apiParam {Boolean} enabled Body parameter - If the webhook should be enabled
*
* @apiSuccess {Object} data The created webhook
*/
@@ -930,8 +925,8 @@ api.addWebhook = {
* @apiGroup User
*
* @apiParam {UUID} id The id of the webhook to update
* @apiParam {string} url Body parameter - The webhook's URL
* @apiParam {boolean} enabled Body parameter - If the webhook should be enabled
* @apiParam {String} url Body parameter - The webhook's URL
* @apiParam {Boolean} enabled Body parameter - If the webhook should be enabled
*
* @apiSuccess {Object} data The updated webhook
*/
@@ -976,7 +971,7 @@ api.deleteWebhook = {
* @apiGroup User
*
* @apiSuccess {Object} data.items `user.items.pets`
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.userReleasePets = {
method: 'POST',
@@ -998,8 +993,8 @@ api.userReleasePets = {
* @apiSuccess {Object} data.achievements
* @apiSuccess {Object} data.items
* @apiSuccess {number} data.balance
* @apiSuccess {string} message Success message
* @apiSuccess {Number} data.balance
* @apiSuccess {String} message Success message
*/
api.userReleaseBoth = {
method: 'POST',
@@ -1020,7 +1015,7 @@ api.userReleaseBoth = {
* @apiGroup User
*
* @apiSuccess {Object} data user.items.mounts
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.userReleaseMounts = {
method: 'POST',
@@ -1040,12 +1035,12 @@ api.userReleaseMounts = {
* @apiName UserSell
* @apiGroup User
*
* @apiParam {string} type The type of item to sell. Must be one of: eggs, hatchingPotions, or food
* @apiParam {string} key The key of the item
* @apiParam {String} type The type of item to sell. Must be one of: eggs, hatchingPotions, or food
* @apiParam {String} key The key of the item
*
* @apiSuccess {Object} data.stats
* @apiSuccess {Object} data.items
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.userSell = {
method: 'POST',
@@ -1065,12 +1060,12 @@ api.userSell = {
* @apiName UserUnlock
* @apiGroup User
*
* @apiParam {string} path Query parameter. The path to unlock
* @apiParam {String} path Query parameter. The path to unlock
*
* @apiSuccess {Object} data.purchased
* @apiSuccess {Object} data.items
* @apiSuccess {Object} data.preferences
* @apiSuccess {string} message
* @apiSuccess {String} message
*/
api.userUnlock = {
method: 'POST',
@@ -1091,7 +1086,7 @@ api.userUnlock = {
* @apiGroup User
*
* @apiSuccess {Object} data user.items
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.userRevive = {
method: 'POST',
@@ -1112,8 +1107,8 @@ api.userRevive = {
* @apiGroup User
*
* @apiSuccess {Object} data.user
* @apiSuccess {array} data.tasks User's modified tasks (no rewards)
* @apiSuccess {string} message Success message
* @apiSuccess {Array} data.tasks User's modified tasks (no rewards)
* @apiSuccess {String} message Success message
*/
api.userRebirth = {
method: 'POST',
@@ -1151,7 +1146,7 @@ api.userRebirth = {
*
* @apiParam {UUID} uuid The uuid of the user to block / unblock
*
* @apiSuccess {array} data user.inbox.blocks
* @apiSuccess {Array} data user.inbox.blocks
**/
api.blockUser = {
method: 'POST',
@@ -1173,7 +1168,7 @@ api.blockUser = {
*
* @apiParam {UUID} id The id of the message to delete
*
* @apiSuccess {object} data user.inbox.messages
* @apiSuccess {Object} data user.inbox.messages
**/
api.deleteMessage = {
method: 'DELETE',
@@ -1193,7 +1188,7 @@ api.deleteMessage = {
* @apiName clearMessages
* @apiGroup User
*
* @apiSuccess {object} data user.inbox.messages
* @apiSuccess {Object} data user.inbox.messages
**/
api.clearMessages = {
method: 'DELETE',
@@ -1213,7 +1208,7 @@ api.clearMessages = {
* @apiName markPmsRead
* @apiGroup User
*
* @apiSuccess {object} data user.inbox.messages
* @apiSuccess {Object} data user.inbox.messages
**/
api.markPmsRead = {
method: 'POST',
@@ -1271,7 +1266,7 @@ api.userReroll = {
*
* @apiSuccess {Object} data.user
* @apiSuccess {Object} data.tasksToRemove IDs of removed tasks
* @apiSuccess {string} message Success message
* @apiSuccess {String} message Success message
*/
api.userReset = {
method: 'POST',