chore(Merge): branch 'develop' into bs3

Conflicts:
	views/options/inventory/inventory.jade
This commit is contained in:
Tyler Renelle 2014-02-07 17:42:12 -07:00
commit 3473b73452
8 changed files with 91 additions and 21 deletions

View file

@ -1,8 +1,3 @@
{
"directory": "public/bower_components",
"storage": {
"packages": ".bower-cache",
"registry": ".bower-registry"
},
"tmp": ".bower-tmp"
"directory": "public/bower_components"
}

View file

@ -39,7 +39,7 @@ api.authWithSession = function(req, res, next) { //[todo] there is probably a mo
if (!(req.session && req.session.userId))
return res.json(401, NO_SESSION_FOUND);
User.findOne({_id: uid}, function(err, user) {
if (err) return res.json(500, {err: err});
if (err) return next(err);
if (_.isEmpty(user)) return res.json(401, NO_USER_FOUND);
res.locals.user = user;
next();
@ -107,14 +107,14 @@ api.loginLocal = function(req, res, next) {
var password = req.body.password;
if (!(username && password)) return res.json(401, {err:'Missing :username or :password in request body, please provide both'});
User.findOne({'auth.local.username': username}, function(err, user){
if (err) return res.json(500,{err:err});
if (err) return next(err);
if (!user) return res.json(401, {err:"Username '" + username + "' not found. Usernames are case-sensitive, click 'Forgot Password' if you can't remember the capitalization."});
// We needed the whole user object first so we can get his salt to encrypt password comparison
User.findOne({
'auth.local.username': username,
'auth.local.hashed_password': utils.encryptPassword(password, user.auth.local.salt)
}, function(err, user){
if (err) return res.json(500,{err:err});
if (err) return next(err);
if (!user) return res.json(401,{err:'Incorrect password'});
res.json({id: user._id,token: user.apiToken});
});
@ -164,7 +164,7 @@ api.resetPassword = function(req, res, next){
hashed_password = utils.encryptPassword(newPassword, salt);
User.findOne({'auth.local.email':email}, function(err, user){
if (err) return res.json(500,{err:err});
if (err) return next(err);
if (!user) return res.send(500, {err:"Couldn't find a user registered for email " + email});
user.auth.local.salt = salt;
user.auth.local.hashed_password = hashed_password;
@ -187,18 +187,18 @@ api.changePassword = function(req, res, next) {
confirmNewPassword = req.body.confirmNewPassword;
if (newPassword != confirmNewPassword)
return res.json(500, {err: "Password & Confirm don't match"});
return res.json(401, {err: "Password & Confirm don't match"});
var salt = user.auth.local.salt,
hashed_old_password = utils.encryptPassword(oldPassword, salt),
hashed_new_password = utils.encryptPassword(newPassword, salt);
if (hashed_old_password !== user.auth.local.hashed_password)
return res.json(500, {err:"Old password doesn't match"});
return res.json(401, {err:"Old password doesn't match"});
user.auth.local.hashed_password = hashed_new_password;
user.save(function(err, saved){
if (err) res.json(500,{err:err});
if (err) next(err);
res.send(200);
})
}

View file

@ -5,6 +5,8 @@ var path = require('path');
var User = require('./models/user').model
var limiter = require('connect-ratelimit');
var logging = require('./logging');
var domainMiddleware = require('domain-middleware');
var cluster = require('cluster');
module.exports.apiThrottle = function(app) {
if (nconf.get('NODE_ENV') !== 'production') return;
@ -24,6 +26,18 @@ module.exports.apiThrottle = function(app) {
});
}
module.exports.domainMiddleware = function(server,mongoose) {
return domainMiddleware({
server: {
close:function(){
server.close();
mongoose.connection.close();
}
},
killTimeout: 10000
});
}
module.exports.errorHandler = function(err, req, res, next) {
//res.locals.domain.emit('error', err);
// when we hit an error, send it to admin as an email. If no ADMIN_EMAIL is present, just send it to yourself (SMTP_USER)

View file

@ -68,7 +68,8 @@ var UserSchema = new Schema({
level: Number, // 1-7, see https://trello.com/c/wkFzONhE/277-contributor-gear
admin: Boolean,
text: String, // Artisan, Friend, Blacksmith, etc
contributions: String // a markdown textarea to list their contributions + links
contributions: String, // a markdown textarea to list their contributions + links
critical: String
},
balance: {type: Number, 'default':0},

View file

@ -1,4 +1,5 @@
// Only do the minimal amount of work before forking just in case of a dyno restart
var cluster = require("cluster");
var _ = require('lodash');
var nconf = require('nconf');
var utils = require('./utils');
@ -7,6 +8,18 @@ var logging = require('./logging');
var isProd = nconf.get('NODE_ENV') === 'production';
var isDev = nconf.get('NODE_ENV') === 'development';
if (cluster.isMaster && (isDev || isProd)) {
// Fork workers.
_.times(_.min([require('os').cpus().length,2]), function(){
cluster.fork();
});
cluster.on('disconnect', function(worker, code, signal) {
var w = cluster.fork(); // replace the dead worker
logging.info('[%s] [master:%s] worker:%s disconnect! new worker:%s fork', new Date(), process.pid, worker.process.pid, w.process.pid);
});
} else {
require('coffee-script'); // remove this once we've fully converted over
var express = require("express");
var http = require("http");
@ -79,6 +92,7 @@ var isDev = nconf.get('NODE_ENV') === 'development';
app.set("port", nconf.get('PORT'));
middleware.apiThrottle(app);
app.use(middleware.domainMiddleware(server,mongoose));
if (!isProd) app.use(express.logger("dev"));
app.use(express.compress());
app.set("views", __dirname + "/../views");
@ -120,4 +134,5 @@ var isDev = nconf.get('NODE_ENV') === 'development';
return logging.info("Express server listening on port " + app.get("port"));
});
module.exports = server;
module.exports = server;
}

View file

@ -66,6 +66,11 @@ script(type='text/ng-template', id='partials/options.inventory.drops.html')
button.customize-option(popover='{{Content.special.snowball.notes}}', popover-title='{{Content.special.snowball.text}}', popover-trigger='mouseenter', popover-placement='right', ng-click='castStart(Content.special.snowball)', class='inventory_special_snowball')
.badge.badge-info.stack-count {{user.items.special.snowball}}
li.customize-menu(ng-if='user.purchased.plan.customerId')
menu.pets-menu(label=env.t('subscriberItem'))
div
button.customize-option(popover=env.t('subscriberItemText'), popover-trigger='mouseenter', popover-placement='right', class='inventory_present')
.col-md-6
h2=env.t('market')
.row-fluid

View file

@ -40,6 +40,12 @@ script(id='partials/options.profile.avatar.html', type='text/ng-template')
each color in ['candycane','frost','winternight','holly']
button(type='button', ng-if='user.purchased.hair.color.#{color}', class='customize-option hair_bangs_1_#{color}', style='width: 40px; height: 40px;', ng-click='unlock("hair.color.#{color}")')
li.customize-menu
menu(label=env.t('rainbowColors'))
each color in ['rainbow','yellow','green','purple','blue','TRUred']
button(type='button', ng-class='{locked: !user.purchased.hair.color.#{color}}', class='customize-option hair_bangs_1_#{color}', style='width: 40px; height: 40px;', ng-click='unlock("hair.color.#{color}")')
button.btn.btn-small.btn-primary(ng-hide='user.purchased.hair.color.rainbow && user.purchased.hair.color.yellow && user.purchased.hair.color.green && user.purchased.hair.color.purple && user.purchased.hair.color.blue && user.purchased.hair.color.TRUred', ng-click='unlock("hair.color.rainbow,hair.color.yellow,hair.color.green,hair.color.purple,hair.color.blue,hair.color.TRUred")')!= env.t('unlockSet5') + ' <span class="Pet_Currency_Gem1x inline-gems"/>'
h5=env.t('bodyHair')
// Bangs
li.customize-menu

View file

@ -26,14 +26,48 @@ script(type='text/ng-template', id='modals/newStuff.html')
h3.popover-title
a(target='_blank', href='https://twitter.com/Mihakuu') Bailey
.popover-content
h5 Vice
p You awaken after the Winter Wonderland festivities and birthday celebrations with a smile. It's been a snowy, cheerful couple months, and the NPCs have finally returned to their normal attire. But today something is very wrong. Shadowy whisps cover the ground of Habitica, the sky has darkened. At the tavern you hear @DanielTheBard struming dark tales on his lute, and @Baconsaur peering into a mug, grumbling about her mounts swallowed in the shadows. They speak of the same thing: <strong>Vice</strong>, a dark an terrible foe. This new boss arc is a 3-part quest that requires level 30 to begin. Bring your strongest party members, and don't miss your dailies - there's a powerful weapon at the end!
table.table.table-striped
tr
td
h5 February Mystery Item
p
.pull-right.inventory_present
| We're excited to announce a new feature a s a big thank-you to the awesome people who <a href='https://habitrpg.com/#/options/settings/subscription' target='_blank'>subscribe</a> to HabitRPG! Every month, all subscribers will now receive a limited-edition mystery item! The mystery item will be a stats-free costume piece (like the Absurd Party Robes) that will <strong>only</strong> be available to the people who are subscribers each month. The February 2014 item will be revealed on the 23rd to everyone, but all people who are subscribers during the month of February will receive it. <a href='https://habitrpg.com/#/options/settings/subscription' target='_blank'>Subscribe now</a>, get excited, and thank you so much for helping to support HabitRPG! We love you.
tr
td
h5 Critical Hammer Of Bug-Crushing
p
.pull-right.weapon_special_critical
| Some of you may have noticed that we periodically have some bugs that are nastier than the norm - the dreaded critical bugs. These monstrous apparitions have been snapping at the heels of many a player. For updates on what we're currently working on to improve site stability, read <a href='https://github.com/HabitRPG/habitrpg/issues/milestones' target='_blank'>this link</a> - and then jump in to help! Not only will programming assistance reward you with the usual contributor levels, but if you actually manage to fix a bug marked <a href='http://goo.gl/v4DnzB' target='_blank'>"critical,"</a> you will now receive the <em>Critical Hammer of Bug-Crushing</em> as your reward!
tr
td
h5 Rainbow Hair Colors
p
.pull-right.customize-option.hair_bangs_1_rainbow
| Want to spruce up your avatar? Rainbow hair colors are now available! Dye your luscious locks purple, green, or even rainbow-striped, and passersby will look at you with envy.
tr
td
h5 Stability Update
p We've stabilized the site a lot (we're still working out kinks, but we're way better now). Follow the <a href='https://github.com/HabitRPG/habitrpg/issues/milestones' target='_blank'>progress here</a>, but here are some workarounds for now:
ul
li Click slower. <a href='https://github.com/HabitRPG/habitrpg/issues/2301#issuecomment-34398206' target='_blank'>VersionError</a> is caused by clicking things off too fast (we're working on a fix).
li If you see an error, refresh before proceeding.
p
small.muted by @baconsaur & @DanielTheBard
p
small.muted 02/01/2014
small.muted By Lemoness, mariahm, crystalphoenix, aiseant, zoebeagle, cole, lefnire
hr
h5 02/01/2014
table.table.table-striped
tr
td
h5 Vice
p You awaken after the Winter Wonderland festivities and birthday celebrations with a smile. It's been a snowy, cheerful couple months, and the NPCs have finally returned to their normal attire. But today something is very wrong. Shadowy whisps cover the ground of Habitica, the sky has darkened. At the tavern you hear @DanielTheBard struming dark tales on his lute, and @Baconsaur peering into a mug, grumbling about her mounts swallowed in the shadows. They speak of the same thing: <strong>Vice</strong>, a dark an terrible foe. This new boss arc is a 3-part quest that requires level 30 to begin. Bring your strongest party members, and don't miss your dailies - there's a powerful weapon at the end!
p
small.muted by @baconsaur & @DanielTheBard
h5 01/30/2014
table.table.table-striped
tr
@ -468,4 +502,4 @@ script(type='text/ng-template', id='modals/newStuff.html')
.modal-footer
button.btn.btn-default.cancel(ng-click='$close()') Cool
button.btn.btn-warning.cancel(ng-click='dismissAlert(); $close()') Dismiss This Alert
button.btn.btn-warning.cancel(ng-click='dismissAlert(); $close()') Dismiss This Alert