v3: move tavern to valid UUID and set Leslie as the leader

This commit is contained in:
Matteo Pagliazzi
2016-04-13 21:52:53 +02:00
parent 2458f92e1b
commit 99e201fc07
9 changed files with 62 additions and 43 deletions
+2 -1
View File
@@ -10,6 +10,7 @@ import {
import {
model as Group,
basicFields as basicGroupFields,
TAVERN_ID,
} from '../../models/group';
import {
model as Challenge,
@@ -152,7 +153,7 @@ api.create = async function(req, res, next){
return res.status(401).json({err:"Only the group leader can create challenges"});
}
if (groupId === 'habitrpg' && prize < 1) {
if (group._id === TAVERN_ID && prize < 1) {
return res.status(401).json({err: 'Prize must be at least 1 Gem for public challenges.'})
}
+8 -2
View File
@@ -19,6 +19,7 @@ import {
} from './../../models/user';
import {
model as Group,
TAVERN_ID,
} from './../../models/group';
import {
model as Challenge,
@@ -127,7 +128,7 @@ api.list = function(req, res, next) {
// unecessary given our ui-router setup
tavern: function(cb) {
if (!~type.indexOf('tavern')) return cb(null, {});
Group.findById('habitrpg').select(groupFields).exec(function(err, tavern){
Group.findById(TAVERN_ID).select(groupFields).exec(function(err, tavern){
if (err) return cb(err);
tavern.getTransformedData({cb: function (err, transformedTavern) {
if (err) return cb(err);
@@ -169,6 +170,8 @@ api.get = function(req, res, next) {
if (isUserGuild) {
q = Group.findOne({type: 'guild', _id: gid});
} else if (gid === 'habitrpg') {
q = Group.findOne({_id: TAVERN_ID});
} else {
q = Group.findOne({type: 'guild', privacy: 'public', _id: gid});
}
@@ -284,6 +287,7 @@ api.update = function(req, res, next) {
api.attachGroup = function(req, res, next) {
var user = res.locals.user;
var gid = req.params.gid === 'party' ? user.party._id : req.params.gid;
if (gid === 'habitrpg') gid = TAVERN_ID;
let q = Group.findOne({_id: gid})
@@ -313,6 +317,8 @@ api.getChat = function(req, res, next) {
} else {
if (isUserGuild) {
q = Group.findOne({type: 'guild', _id: gid});
} else if (gid === 'habitrpg') {
q = Group.findOne({_id: TAVERN_ID});
} else {
q = Group.findOne({type: 'guild', privacy: 'public', _id: gid});
}
@@ -423,7 +429,7 @@ api.flagChatMessage = function(req, res, next){
{name: "GROUP_NAME", content: group.name},
{name: "GROUP_TYPE", content: group.type},
{name: "GROUP_ID", content: group._id},
{name: "GROUP_URL", content: group._id == 'habitrpg' ? '/#/options/groups/tavern' : (group.type === 'guild' ? ('/#/options/groups/guilds/' + group._id) : 'party')},
{name: "GROUP_URL", content: group._id == TAVERN_ID ? '/#/options/groups/tavern' : (group.type === 'guild' ? ('/#/options/groups/guilds/' + group._id) : 'party')},
]);
return res.sendStatus(204);
+3 -2
View File
@@ -5,6 +5,7 @@ import { model as Challenge } from '../../models/challenge';
import {
model as Group,
basicFields as basicGroupFields,
TAVERN_ID,
} from '../../models/group';
import {
model as User,
@@ -54,7 +55,7 @@ api.createChallenge = {
throw new NotAuthorized(res.t('onlyGroupLeaderChal'));
}
if (groupId === 'habitrpg' && prize < 1) {
if (group._id === TAVERN_ID && prize < 1) {
throw new NotAuthorized(res.t('pubChalsMinPrize'));
}
@@ -454,7 +455,7 @@ export async function _closeChal (challenge, broken = {}) {
await Challenge.remove({_id: challenge._id}).exec();
// Refund the leader if the challenge is closed and the group not the tavern
if (challenge.group !== 'habitrpg' && brokenReason === 'CHALLENGE_DELETED') {
if (challenge.group !== TAVERN_ID && brokenReason === 'CHALLENGE_DELETED') {
await User.update({_id: challenge.leader}, {$inc: {balance: challenge.prize / 4}}).exec();
}
+7 -4
View File
@@ -1,6 +1,9 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import cron from '../../middlewares/api-v3/cron';
import { model as Group } from '../../models/group';
import {
model as Group,
TAVERN_ID,
} from '../../models/group';
import { model as User } from '../../models/user';
import {
NotFound,
@@ -23,7 +26,7 @@ let api = {};
* @apiName GetChat
* @apiGroup Chat
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
*
* @apiSuccess {Array} chat An array of chat messages
*/
@@ -219,7 +222,7 @@ api.flagChat = {
}
let groupUrl;
if (group._id === 'habitrpg') {
if (group._id === TAVERN_ID) {
groupUrl = '/#/options/groups/tavern';
} else if (group.type === 'guild') {
groupUrl = `/#/options/groups/guilds/{$group._id}`;
@@ -336,7 +339,7 @@ api.seenChat = {
* @apiName DeleteChat
* @apiGroup Chat
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {string} chatId The chat _id
*
* @apiSuccess {Array} The update chat array
+5 -5
View File
@@ -118,7 +118,7 @@ api.getGroups = {
* @apiName GetGroup
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
*
* @apiSuccess {Object} group The group object
*/
@@ -152,7 +152,7 @@ api.getGroup = {
* @apiName UpdateGroup
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
*
* @apiSuccess {Object} group The updated group object
*/
@@ -334,7 +334,7 @@ api.rejectGroupInvite = {
* @apiName LeaveGroup
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
* @apiParam {string="remove-all","keep-all"} keep Wheter to keep or not challenges' tasks, as an optional query string
*
* @apiSuccess {Object} empty An empty object
@@ -390,7 +390,7 @@ function _sendMessageToRemoved (group, removedUser, message) {
* @apiName RemoveGroupMember
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @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 The message to send to the removed members, as a query string // TODO in req.body?
*
@@ -591,7 +591,7 @@ async function _inviteByEmail (invite, group, inviter, req, res) {
* @apiName InviteToGroup
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
*
* @apiParam {array} emails An array of emails addresses to invite (optional) (inside body)
* @apiParam {array} uuids An array of uuids to invite (optional) (inside body)
+7 -5
View File
@@ -6,6 +6,8 @@ var firebaseConfig = nconf.get('FIREBASE');
var firebaseRef;
var isFirebaseEnabled = (nconf.get('NODE_ENV') === 'production') && (firebaseConfig.ENABLED === 'true');
import { TAVERN_ID } from '../../models/group';
// Setup
if(isFirebaseEnabled){
firebaseRef = new Firebase('https://' + firebaseConfig.APP + '.firebaseio.com');
@@ -24,7 +26,7 @@ api.updateGroupData = function(group){
// TODO is throw ok? we don't have callbacks
if(!group) throw new Error('group is required.');
// Return in case of tavern (comparison working because we use string for _id)
if(group._id === 'habitrpg') return;
if(group._id === TAVERN_ID) return;
firebaseRef.child('rooms/' + group._id)
.set({
@@ -35,7 +37,7 @@ api.updateGroupData = function(group){
api.addUserToGroup = function(groupId, userId){
if(!isFirebaseEnabled) return;
if(!userId || !groupId) throw new Error('groupId, userId are required.');
if(groupId === 'habitrpg') return;
if(groupId === TAVERN_ID) return;
firebaseRef.child('members/' + groupId + '/' + userId)
.set(true);
@@ -47,7 +49,7 @@ api.addUserToGroup = function(groupId, userId){
api.removeUserFromGroup = function(groupId, userId){
if(!isFirebaseEnabled) return;
if(!userId || !groupId) throw new Error('groupId, userId are required.');
if(groupId === 'habitrpg') return;
if(groupId === TAVERN_ID) return;
firebaseRef.child('members/' + groupId + '/' + userId)
.remove();
@@ -59,7 +61,7 @@ api.removeUserFromGroup = function(groupId, userId){
api.deleteGroup = function(groupId){
if(!isFirebaseEnabled) return;
if(!groupId) throw new Error('groupId is required.');
if(groupId === 'habitrpg') return;
if(groupId === TAVERN_ID) return;
firebaseRef.child('rooms/' + groupId)
.remove();
@@ -78,4 +80,4 @@ api.deleteUser = function(userId){
firebaseRef.child('users/' + userId)
.remove();
};
};
+7 -5
View File
@@ -1,5 +1,7 @@
import Firebase from 'firebase';
import nconf from 'nconf';
import { TAVERN_ID } from '../../models/group';
const FIREBASE_CONFIG = nconf.get('FIREBASE');
const FIREBASE_ENABLED = FIREBASE_CONFIG.ENABLED === 'true';
@@ -20,7 +22,7 @@ export function updateGroupData (group) {
// TODO is throw ok? we don't have callbacks
if (!group) throw new Error('group obj is required.');
// Return in case of tavern (comparison working because we use string for _id)
if (group._id === 'habitrpg') return;
if (group._id === TAVERN_ID) return;
firebaseRef.child(`rooms/${group._id}`)
.set({
@@ -31,7 +33,7 @@ export function updateGroupData (group) {
export function addUserToGroup (groupId, userId) {
if (!FIREBASE_ENABLED) return;
if (!userId || !groupId) throw new Error('groupId, userId are required.');
if (groupId === 'habitrpg') return;
if (groupId === TAVERN_ID) return;
firebaseRef.child(`members/${groupId}/${userId}`).set(true);
firebaseRef.child(`users/${userId}/rooms/${groupId}`).set(true);
@@ -40,7 +42,7 @@ export function addUserToGroup (groupId, userId) {
export function removeUserFromGroup (groupId, userId) {
if (!FIREBASE_ENABLED) return;
if (!userId || !groupId) throw new Error('groupId, userId are required.');
if (groupId === 'habitrpg') return;
if (groupId === TAVERN_ID) return;
firebaseRef.child(`members/${groupId}/${userId}`).remove();
firebaseRef.child(`users/${userId}/rooms/${groupId}`).remove();
@@ -49,7 +51,7 @@ export function removeUserFromGroup (groupId, userId) {
export function deleteGroup (groupId) {
if (!FIREBASE_ENABLED) return;
if (!groupId) throw new Error('groupId is required.');
if (groupId === 'habitrpg') return;
if (groupId === TAVERN_ID) return;
firebaseRef.child(`members/${groupId}`).remove();
// FIXME not really necessary as long as we only store room data,
@@ -64,4 +66,4 @@ export function deleteUser (userId) {
if (!userId) throw new Error('userId is required.');
firebaseRef.child(`users/${userId}`).remove();
}
}
+18 -16
View File
@@ -17,8 +17,10 @@ import nconf from 'nconf';
import sendPushNotification from '../libs/api-v3/pushNotifications';
const questScrolls = shared.content.quests;
const Schema = mongoose.Schema;
let Schema = mongoose.Schema;
export const INVITES_LIMIT = 100;
export const TAVERN_ID = '00000000-0000-4000-A000-000000000000';
// NOTE once Firebase is enabled any change to groups' members in MongoDB will have to be run through the API
// changes made directly to the db will cause Firebase to get out of sync
@@ -126,15 +128,18 @@ schema.statics.getGroup = async function getGroup (options = {}) {
let isUserParty = groupId === 'party' || user.party._id === groupId;
let isUserGuild = user.guilds.indexOf(groupId) !== -1;
let isTavern = ['habitrpg', TAVERN_ID].indexOf(groupId) !== -1;
// When requireMembership is true check that user is member even in public guild
if (requireMembership && !isUserParty && !isUserGuild) {
if (requireMembership && !isUserParty && !isUserGuild && !isTavern) {
return null;
}
// When optionalMembership is true it's not required for the user to be a member of the group
if (isUserParty) {
query = {type: 'party', _id: user.party._id};
} else if (isTavern) {
query = {_id: TAVERN_ID};
} else if (optionalMembership === true) {
query = {_id: groupId};
} else if (isUserGuild) {
@@ -180,7 +185,7 @@ schema.statics.getGroups = async function getGroups (options = {}) {
break;
case 'tavern':
if (types.indexOf('publicGuilds') === -1) {
queries.push(this.getGroup({user, groupId: 'habitrpg', fields: groupFields}));
queries.push(this.getGroup({user, groupId: TAVERN_ID, fields: groupFields}));
}
break;
}
@@ -230,7 +235,7 @@ schema.methods.removeGroupInvitations = async function removeGroupInvitations ()
// Return true if user is a member of the group
schema.methods.isMember = function isGroupMember (user) {
if (this._id === 'habitrpg') {
if (this._id === TAVERN_ID) {
return true; // everyone is considered part of the tavern
} else if (this.type === 'party') {
return user.party._id === this._id ? true : false;
@@ -263,7 +268,7 @@ export function chatDefaults (msg, user) {
return message;
}
const NO_CHAT_NOTIFICATIONS = ['habitrpg'];
const NO_CHAT_NOTIFICATIONS = [TAVERN_ID];
schema.methods.sendChat = function sendChat (message, user) {
this.chat.unshift(chatDefaults(message, user));
this.chat.splice(200);
@@ -421,7 +426,7 @@ schema.methods.finishQuest = function finishQuest (quest) {
updates.$inc['stats.exp'] = Number(quest.drop.exp);
updates.$inc._v = 1;
if (this._id === 'habitrpg') {
if (this._id === TAVERN_ID) {
updates.$set['party.quest.completed'] = questK; // Just show the notif
} else {
updates.$set['party.quest'] = _cleanQuestProgress({completed: questK}); // clear quest progress
@@ -450,7 +455,7 @@ schema.methods.finishQuest = function finishQuest (quest) {
}
});
let q = this._id === 'habitrpg' ? {} : {_id: {$in: _.keys(this.quest.members)}};
let q = this._id === TAVERN_ID ? {} : {_id: {$in: _.keys(this.quest.members)}};
this.quest = {};
this.markModified('quest');
return User.update(q, updates, {multi: true}).exec();
@@ -539,10 +544,10 @@ schema.statics.bossQuest = async function bossQuest (user, progress) {
return group.save();
};
// to set a boss: `db.groups.update({_id:'habitrpg'},{$set:{quest:{key:'dilatory',active:true,progress:{hp:1000,rage:1500}}}})`
// to set a boss: `db.groups.update({_id:TAVERN_ID},{$set:{quest:{key:'dilatory',active:true,progress:{hp:1000,rage:1500}}}})`
// we export an empty object that is then populated with the query-returned data
export let tavernQuest = {};
let tavernQ = {_id: 'habitrpg', 'quest.key': {$ne: null}};
let tavernQ = {_id: TAVERN_ID, 'quest.key': {$ne: null}};
// we use process.nextTick because at this point the model is not yet available
process.nextTick(() => {
@@ -723,23 +728,20 @@ schema.methods.getTransformedData = function getTransformedData (options) {
};
// END API v2 compatibility methods
export const INVITES_LIMIT = 100;
export let model = mongoose.model('Group', schema);
// initialize tavern if !exists (fresh installs)
// do not run when testing as it's handled by the tests and can easily cause a race condition
if (!nconf.get('IS_TEST')) {
model.count({_id: 'habitrpg'}, (err, ct) => {
model.count({_id: TAVERN_ID}, (err, ct) => {
if (err) throw err;
if (ct > 0) return;
new model({ // eslint-disable-line babel/new-cap
_id: 'habitrpg',
leader: '9', // TODO change this user id
_id: TAVERN_ID,
leader: '7bde7864-ebc5-4ee2-a4b7-1070d464cdb0', // Siena Leslie
name: 'HabitRPG',
type: 'guild',
privacy: 'public',
}).save({
validateBeforeSave: false, // _id = 'habitrpg' would not be valid otherwise
});
}).save();
});
}
+5 -3
View File
@@ -7,9 +7,11 @@ import * as Tasks from './task';
import Q from 'q';
import { schema as TagSchema } from './tag';
import baseModel from '../libs/api-v3/baseModel';
import { chatDefaults } from './group';
import {
chatDefaults,
TAVERN_ID,
} from './group';
import { defaults } from 'lodash';
// import {model as Challenge} from './challenge';
let Schema = mongoose.Schema;
@@ -706,7 +708,7 @@ schema.methods.isSubscribed = function isSubscribed () {
schema.methods.getGroups = function getUserGroups () {
let userGroups = this.guilds.slice(0); // clone user.guilds so we don't modify the original
if (this.party._id) userGroups.push(this.party._id);
userGroups.push('habitrpg'); // tavern
userGroups.push(TAVERN_ID);
return userGroups;
};