From f9ab04e4f9b14bbb9eb421298f946d0e6c359ed9 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Sat, 15 Aug 2015 19:50:09 +0200 Subject: [PATCH 01/10] upgrade to express 4.x cleanup package.json put errorHandler middleware as the last one use accepts module instead of req.acceptedLanguages use normal object notation as it is supported is es5 remove deprecations from auth controller remove deprecations from groups controller Revert "remove deprecations from groups controller" This reverts commit 7cf36295ebbc50c1f2b210a8ab447d7f2c41dba9. Revert "remove deprecations from auth controller" This reverts commit deecd701e0551862ba53ea894f2d87a746384fed. request limit upped to 1mb and 10k chars for query parameters Upgrade to Express 4.x --- package.json | 14 ++-- website/src/controllers/challenges.js | 2 +- website/src/controllers/groups.js | 3 +- website/src/controllers/user.js | 2 +- website/src/i18n.js | 19 +++--- website/src/routes/apiv1.js | 2 +- website/src/routes/apiv2.coffee | 4 +- website/src/server.js | 94 +++++++++++++++------------ 8 files changed, 80 insertions(+), 60 deletions(-) diff --git a/package.json b/package.json index 57b8a4cbc9..f59ab6d71c 100644 --- a/package.json +++ b/package.json @@ -4,20 +4,25 @@ "version": "0.0.0-152", "main": "./website/src/server.js", "dependencies": { + "accepts": "^1.2.12", "amazon-payments": "0.0.4", "amplitude": "^2.0.1", "async": "~0.9.0", "aws-sdk": "^2.0.25", "babel": "^5.5.4", "gulp-babel": "^5.2.1", + "body-parser": "^1.13.3", "bower": "~1.3.12", "browserify": "~3.30.2", "coffee-script": "1.6.x", "coffeeify": "0.6.0", + "compression": "^1.5.2", "connect-ratelimit": "0.0.7", + "cookie-parser": "^1.3.5", + "cookie-session": "^1.2.0", "coupon-code": "~0.3.0", "domain-middleware": "~0.1.0", - "express": "~3.17.5", + "express": "~4.13.3", "express-csv": "~0.6.0", "firebase": "^2.2.9", "firebase-token-generator": "^2.0.0", @@ -55,6 +60,7 @@ "moment": "~2.8.3", "mongoose": "~3.8.23", "mongoose-id-autoinc": "~2013.7.14-4", + "morgan": "^1.6.1", "nconf": "~0.6.9", "newrelic": "~1.11.2", "nib": "~1.0.1", @@ -71,6 +77,7 @@ "qs": "^2.3.2", "request": "~2.44.0", "s3-upload-stream": "^1.0.6", + "serve-favicon": "^2.3.0", "stripe": "*", "superagent": "~1.4.0", "swagger-node-express": "lefnire/swagger-node-express#habitrpg", @@ -81,11 +88,6 @@ "winston-newrelic": "~0.1.4" }, "private": true, - "subdomain": "habitrpg", - "domains": [ - "habitrpg.com", - "www.habitrpg.com" - ], "engines": { "node": "0.10.x" }, diff --git a/website/src/controllers/challenges.js b/website/src/controllers/challenges.js index a8bc4dc244..5219503537 100644 --- a/website/src/controllers/challenges.js +++ b/website/src/controllers/challenges.js @@ -297,7 +297,7 @@ function closeChal(cid, broken, cb) { /** * Delete & close */ -api['delete'] = function(req, res, next){ +api.delete = function(req, res, next){ var user = res.locals.user; var cid = req.params.cid; diff --git a/website/src/controllers/groups.js b/website/src/controllers/groups.js index c96a6420b1..800aa0eabf 100644 --- a/website/src/controllers/groups.js +++ b/website/src/controllers/groups.js @@ -521,6 +521,7 @@ api.leave = function(req, res, next) { group.leave(user, keep, function(err){ if (err) return next(err); user = group = keep = null; + return res.send(204); }); }; @@ -683,7 +684,7 @@ api.invite = function(req, res, next){ } else if (req.body.emails) { inviteByEmails(req.body.emails, group, req, res, next) } else { - return res.json(400,{err: "Can invite only by email or uuid"}); + return res.json(400, {err: "Can only invite by email or uuid"}); } } diff --git a/website/src/controllers/user.js b/website/src/controllers/user.js index 71cd4c5450..f33c65970e 100644 --- a/website/src/controllers/user.js +++ b/website/src/controllers/user.js @@ -364,7 +364,7 @@ api.cron = function(req, res, next) { // api.reroll // Shared.ops // api.reset // Shared.ops -api['delete'] = function(req, res, next) { +api.delete = function(req, res, next) { var user = res.locals.user; var plan = user.purchased.plan; diff --git a/website/src/i18n.js b/website/src/i18n.js index 2f0f14eeb6..19444f89f0 100644 --- a/website/src/i18n.js +++ b/website/src/i18n.js @@ -1,9 +1,10 @@ -var fs = require('fs'), - path = require('path'), - _ = require('lodash'), - User = require('./models/user').model, - shared = require('../../common'), - translations = {}; +var fs = require('fs'); +var path = require('path'); +var _ = require('lodash'); +var accepts = require('accepts'); +var User = require('./models/user').model; +var shared = require('../../common'); +var translations = {}; var localePath = path.join(__dirname, "/../../common/locales/") @@ -74,7 +75,9 @@ var chineseVersions = ['zh-tw']; var getUserLanguage = function(req, res, next){ var getFromBrowser = function(){ - var acceptable = _(req.acceptedLanguages).map(function(lang){ + var acceptedLanguages = accepts(req).languages(); + + var acceptable = _(acceptedLanguages).map(function(lang){ return lang.slice(0, 2); }).uniq().value(); @@ -83,7 +86,7 @@ var getUserLanguage = function(req, res, next){ var iAcceptedCompleteLang = (matches.length > 0) ? multipleVersionsLanguages.indexOf(matches[0].toLowerCase()) : -1; if(iAcceptedCompleteLang !== -1){ - var acceptedCompleteLang = _.find(req.acceptedLanguages, function(accepted){ + var acceptedCompleteLang = _.find(acceptedLanguages, function(accepted){ return accepted.slice(0, 2) == multipleVersionsLanguages[iAcceptedCompleteLang]; }); diff --git a/website/src/routes/apiv1.js b/website/src/routes/apiv1.js index 5a28ef8f3b..f2876fedc4 100644 --- a/website/src/routes/apiv1.js +++ b/website/src/routes/apiv1.js @@ -155,7 +155,7 @@ router.post('/user/tasks/:id/:direction', auth.auth, i18n.getUserLanguage, cron, // Tasks router.get('/user/tasks', auth.auth, i18n.getUserLanguage, cron, api.getTasks); router.get('/user/task/:id', auth.auth, i18n.getUserLanguage, cron, api.getTask); -router["delete"]('/user/task/:id', auth.auth, i18n.getUserLanguage, cron, api.deleteTask); +router.delete('/user/task/:id', auth.auth, i18n.getUserLanguage, cron, api.deleteTask); router.post('/user/task', auth.auth, i18n.getUserLanguage, cron, api.addTask); // User diff --git a/website/src/routes/apiv2.coffee b/website/src/routes/apiv2.coffee index 8edc2277aa..746423684f 100644 --- a/website/src/routes/apiv2.coffee +++ b/website/src/routes/apiv2.coffee @@ -265,7 +265,7 @@ module.exports = (swagger, v2) -> method: 'DELETE' description: "Delete a user object entirely, USE WITH CAUTION!" middleware: [auth.auth, i18n.getUserLanguage] - action: user["delete"] + action: user.delete "/user/revive": spec: @@ -774,7 +774,7 @@ module.exports = (swagger, v2) -> description: "Delete a challenge" parameters: [path('cid','Challenge id','string')] middleware: [auth.auth, i18n.getUserLanguage] - action: challenges["delete"] + action: challenges.delete "/challenges/{cid}/close": spec: diff --git a/website/src/server.js b/website/src/server.js index 52919d523c..a211216cc2 100644 --- a/website/src/server.js +++ b/website/src/server.js @@ -1,5 +1,5 @@ // Only do the minimal amount of work before forking just in case of a dyno restart -var cluster = require("cluster"); +var cluster = require('cluster'); var _ = require('lodash'); var nconf = require('nconf'); var utils = require('./utils'); @@ -8,7 +8,7 @@ var logging = require('./logging'); var isProd = nconf.get('NODE_ENV') === 'production'; var isDev = nconf.get('NODE_ENV') === 'development'; var DISABLE_LOGGING = nconf.get('DISABLE_REQUEST_LOGGING'); -var cores = +nconf.get("WEB_CONCURRENCY") || 0; +var cores = +nconf.get('WEB_CONCURRENCY') || 0; if (cores!==0 && cluster.isMaster && (isDev || isProd)) { // Fork workers. If config.json has CORES=x, use that - otherwise, use all cpus-1 (production) @@ -21,10 +21,10 @@ if (cores!==0 && cluster.isMaster && (isDev || isProd)) { } else { require('coffee-script'); // remove this once we've fully converted over - var express = require("express"); - var http = require("http"); - var path = require("path"); - var swagger = require("swagger-node-express"); + var express = require('express'); + var http = require('http'); + var path = require('path'); + var swagger = require('swagger-node-express'); var autoinc = require('mongoose-id-autoinc'); var shared = require('../../common'); @@ -77,8 +77,8 @@ if (cores!==0 && cluster.isMaster && (isDev || isProd)) { // This auth strategy is no longer used. It's just kept around for auth.js#loginFacebook() (passport._strategies.facebook.userProfile) // The proper fix would be to move to a general OAuth module simply to verify accessTokens passport.use(new FacebookStrategy({ - clientID: nconf.get("FACEBOOK_KEY"), - clientSecret: nconf.get("FACEBOOK_SECRET"), + clientID: nconf.get('FACEBOOK_KEY'), + clientSecret: nconf.get('FACEBOOK_SECRET'), //callbackURL: nconf.get("BASE_URL") + "/auth/facebook/callback" }, function(accessToken, refreshToken, profile, done) { @@ -87,61 +87,75 @@ if (cores!==0 && cluster.isMaster && (isDev || isProd)) { )); // ------------ Server Configuration ------------ - var publicDir = path.join(__dirname, "/../public"); + var publicDir = path.join(__dirname, '/../public'); - app.set("port", nconf.get('PORT')); + app.set('port', nconf.get('PORT')); require('./middlewares/apiThrottle')(app); app.use(require('./middlewares/domain')(server,mongoose)); - if (!isProd && !DISABLE_LOGGING) app.use(express.logger("dev")); - app.use(express.compress()); - app.set("views", __dirname + "/../views"); - app.set("view engine", "jade"); - app.use(express.favicon(publicDir + '/favicon.ico')); + if (!isProd && !DISABLE_LOGGING) app.use(require('morgan')('dev')); + app.use(require('compression')()); + app.set('views', __dirname + '/../views'); + app.set('view engine', 'jade'); + app.use(require('serve-favicon')(publicDir + '/favicon.ico')); app.use(require('./middlewares/cors')); var redirects = require('./middlewares/redirects'); app.use(redirects.forceHabitica); app.use(redirects.forceSSL); - app.use(express.urlencoded()); - app.use(express.json()); + + var bodyParser = require('body-parser'); + // Default limit is 100kb, need that because we actually send whole groups to the server + // FIXME as soon as possible (need to move on the client from $resource -> $http) + app.use(bodyParser.urlencoded({ + limit: '1mb', + parameterLimit: 10000, // Upped for safety from 1k, FIXME as above + extended: true // Uses 'qs' library as old connect middleware + })); + app.use(bodyParser.json({ + limit: '1mb' + })); + app.use(require('method-override')()); //app.use(express.cookieParser(nconf.get('SESSION_SECRET'))); - app.use(express.cookieParser()); - app.use(express.cookieSession({ secret: nconf.get('SESSION_SECRET'), httpOnly: false, cookie: { maxAge: TWO_WEEKS }})); - //app.use(express.session()); + app.use(require('cookie-parser')()); + app.use(require('cookie-session')({ + name: 'connect:sess', // Used to keep backward compatibility with Express 3 cookies + secret: nconf.get('SESSION_SECRET'), + httpOnly: false, + maxAge: TWO_WEEKS + })); // Initialize Passport! Also use passport.session() middleware, to support // persistent login sessions (recommended). app.use(passport.initialize()); app.use(passport.session()); - app.use(app.router); + // Custom Directives + app.use(require('./routes/pages')); + app.use(require('./routes/payments')); + app.use(require('./routes/auth')); + app.use(require('./routes/coupon')); + app.use(require('./routes/unsubscription')); + var v2 = express(); + app.use('/api/v2', v2); + app.use('/api/v1', require('./routes/apiv1')); + app.use('/export', require('./routes/dataexport')); + require('./routes/apiv2.coffee')(swagger, v2); var maxAge = isProd ? 31536000000 : 0; // Cache emojis without copying them to build, they are too many - app.use(express['static'](path.join(__dirname, "/../build"), { maxAge: maxAge })); - app.use('/common/dist', express['static'](publicDir + "/../../common/dist", { maxAge: maxAge })); - app.use('/common/audio', express['static'](publicDir + "/../../common/audio", { maxAge: maxAge })); - app.use('/common/script/public', express['static'](publicDir + "/../../common/script/public", { maxAge: maxAge })); - app.use('/common/img', express['static'](publicDir + "/../../common/img", { maxAge: maxAge })); - app.use(express['static'](publicDir)); + app.use(express.static(path.join(__dirname, '/../build'), { maxAge: maxAge })); + app.use('/common/dist', express.static(publicDir + '/../../common/dist', { maxAge: maxAge })); + app.use('/common/audio', express.static(publicDir + '/../../common/audio', { maxAge: maxAge })); + app.use('/common/script/public', express.static(publicDir + '/../../common/script/public', { maxAge: maxAge })); + app.use('/common/img', express.static(publicDir + '/../../common/img', { maxAge: maxAge })); + app.use(express.static(publicDir)); - // Custom Directives - app.use(require('./routes/pages').middleware); - app.use(require('./routes/payments').middleware); - app.use(require('./routes/auth').middleware); - app.use(require('./routes/coupon').middleware); - app.use(require('./routes/unsubscription').middleware); - var v2 = express(); - app.use('/api/v2', v2); - app.use('/api/v1', require('./routes/apiv1').middleware); - app.use('/export', require('./routes/dataexport').middleware); - require('./routes/apiv2.coffee')(swagger, v2); app.use(require('./middlewares/errorHandler')); server.on('request', app); - server.listen(app.get("port"), function() { - return logging.info("Express server listening on port " + app.get("port")); + server.listen(app.get('port'), function() { + return logging.info('Express server listening on port ' + app.get('port')); }); module.exports = server; From 92fc2683c64eca7ccb85f84c3a18816d2c47846f Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Mon, 12 Oct 2015 19:16:47 +0200 Subject: [PATCH 02/10] fix(cluster): use for loop instead of _.times --- website/src/server.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/src/server.js b/website/src/server.js index a211216cc2..92f5df84e1 100644 --- a/website/src/server.js +++ b/website/src/server.js @@ -12,7 +12,9 @@ var cores = +nconf.get('WEB_CONCURRENCY') || 0; if (cores!==0 && cluster.isMaster && (isDev || isProd)) { // Fork workers. If config.json has CORES=x, use that - otherwise, use all cpus-1 (production) - _.times(cores, cluster.fork); + for (var i = 0, n = cores; i < n; i += 1) { + cluster.fork(); + } cluster.on('disconnect', function(worker, code, signal) { var w = cluster.fork(); // replace the dead worker From 8ea69e90dd4c72ce41d82492ceb8fb9ed2ddc794 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Thu, 29 Oct 2015 16:11:56 +0100 Subject: [PATCH 03/10] enable new relic, node 4 and npm 3 --- .travis.yml | 2 +- package.json | 5 +++-- website/src/utils.js | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index dcd028fd9e..2f0f880ebd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - '0.10' + - '4.1' before_install: - "sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10" - "echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list" diff --git a/package.json b/package.json index f59ab6d71c..da8eff1113 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "mongoose-id-autoinc": "~2013.7.14-4", "morgan": "^1.6.1", "nconf": "~0.6.9", - "newrelic": "~1.11.2", + "newrelic": "~1.22.2", "nib": "~1.0.1", "nodemailer": "~0.5.2", "pageres": "^1.0.1", @@ -89,7 +89,8 @@ }, "private": true, "engines": { - "node": "0.10.x" + "node": "~4.1.1", + "npm": "^3.3.4" }, "scripts": { "test": "gulp test", diff --git a/website/src/utils.js b/website/src/utils.js index 4f17cc1c9d..f83d730b31 100644 --- a/website/src/utils.js +++ b/website/src/utils.js @@ -174,8 +174,8 @@ module.exports.setupConfig = function(){ if (nconf.get('NODE_ENV') === "development") Error.stackTraceLimit = Infinity; - //if (nconf.get('NODE_ENV') === 'production') - // require('newrelic'); + if (nconf.get('NODE_ENV') === 'production') + require('newrelic'); isProd = nconf.get('NODE_ENV') === 'production'; baseUrl = nconf.get('BASE_URL'); From 37d83fdade6bec593f1829db223c801abd7b7832 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Thu, 29 Oct 2015 16:35:02 +0100 Subject: [PATCH 04/10] mongoo 4 and new travis ci infrastructure --- .travis.yml | 8 +++----- package.json | 2 +- test/api-legacy/challenges.coffee | 11 +++++++---- test/api-legacy/coupons.coffee | 2 +- test/api-legacy/party.coffee | 3 +++ test/api-legacy/users.coffee | 2 ++ website/src/controllers/challenges.js | 8 ++++---- website/src/controllers/unsubscription.js | 4 ++-- 8 files changed, 23 insertions(+), 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2f0f880ebd..5354360f8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,9 @@ language: node_js +sudo: false +services: + - mongodb node_js: - '4.1' -before_install: - - "sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10" - - "echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list" - - "sudo apt-get update" - - "sudo apt-get install mongodb-org-server" before_script: - 'npm install -g grunt-cli mocha' - cp config.json.example config.json diff --git a/package.json b/package.json index da8eff1113..d089129b97 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "merge-stream": "^1.0.0", "method-override": "~2.2.0", "moment": "~2.8.3", - "mongoose": "~3.8.23", + "mongoose": "~4.2.3", "mongoose-id-autoinc": "~2013.7.14-4", "morgan": "^1.6.1", "nconf": "~0.6.9", diff --git a/test/api-legacy/challenges.coffee b/test/api-legacy/challenges.coffee index 8fa3afe9ce..30e5ccad8d 100644 --- a/test/api-legacy/challenges.coffee +++ b/test/api-legacy/challenges.coffee @@ -161,7 +161,7 @@ describe "Challenges", -> # Now let's handle if challenge was deleted, but didn't get to update all the users (an error) unset = $unset: {} unset["$unset"]["dailys." + len + ".challenge.broken"] = 1 - User.findByIdAndUpdate user._id, unset, (err, user) -> + User.findByIdAndUpdate user._id, unset, {new: true}, (err, user) -> expect(err).to.not.exist expect(user.dailys[len].challenge.broken).to.not.exist request.post(baseURL + "/user/tasks/" + daily.id + "/up").end (err, res) -> @@ -175,6 +175,7 @@ describe "Challenges", -> User.findByIdAndUpdate user._id, $set: "contributor.admin": true + , {new: true} , (err, _user) -> expect(err).to.not.exist async.parallel [ @@ -205,7 +206,8 @@ describe "Challenges", -> it "User creates a non-tavern challenge with prize, deletes it, gets refund", (done) -> User.findByIdAndUpdate user._id, $set: - "balance": 8 + "balance": 8, + , {new: true} , (err, user) -> expect(err).to.not.be.ok request.post(baseURL + "/challenges").send( @@ -234,7 +236,8 @@ describe "Challenges", -> it "User creates a tavern challenge with prize, deletes it, and does not get refund", (done) -> User.findByIdAndUpdate user._id, $set: - "balance": 8 + "balance": 8, + , {new: true} , (err, user) -> expect(err).to.not.be.ok request.post(baseURL + "/challenges").send( @@ -312,7 +315,7 @@ describe "Challenges", -> context "non-owner that is an admin", () -> beforeEach (done) -> - User.findByIdAndUpdate(user._id, { 'contributor.admin': true }, done) + User.findByIdAndUpdate(user._id, { 'contributor.admin': true }, {new: true}, done) it 'can edit challenge', (done) -> challenge.name = 'foobar' diff --git a/test/api-legacy/coupons.coffee b/test/api-legacy/coupons.coffee index c6fb4f36d7..e0fd380bf5 100644 --- a/test/api-legacy/coupons.coffee +++ b/test/api-legacy/coupons.coffee @@ -6,7 +6,7 @@ Coupon = require("../../website/src/models/coupon").model makeSudoUser = (usr, cb) -> registerNewUser -> sudoUpdate = { "$set" : { "contributor.sudo" : true } } - User.findByIdAndUpdate user._id, sudoUpdate, (err, _user) -> + User.findByIdAndUpdate user._id, sudoUpdate, {new: true}, (err, _user) -> usr = _user cb() , true diff --git a/test/api-legacy/party.coffee b/test/api-legacy/party.coffee index 83adc7df0c..93dadf5b12 100644 --- a/test/api-legacy/party.coffee +++ b/test/api-legacy/party.coffee @@ -58,6 +58,7 @@ describe "Party", -> User.findByIdAndUpdate user._id, $set: "stats.lvl": 50 + , {new: true} , (err, _user) -> cb(null, _user) (_user, cb) -> @@ -142,6 +143,7 @@ describe "Party", -> User.findByIdAndUpdate user._id, $set: "items.quests.vice3": 1 + , {new: true} , cb (_user, cb) -> @@ -281,6 +283,7 @@ describe "Party", -> Group.findByIdAndUpdate group._id, $set: "quest.progress.hp": 0 + , {new: true} , cb2 ], cb (_group, cb) -> diff --git a/test/api-legacy/users.coffee b/test/api-legacy/users.coffee index 5e992cbcf6..69411cf792 100644 --- a/test/api-legacy/users.coffee +++ b/test/api-legacy/users.coffee @@ -27,6 +27,7 @@ describe "Users", -> User.findByIdAndUpdate userToDelete._id, $set: "balance": 4 + , {new: true} , (err, _user) -> cb() @@ -88,6 +89,7 @@ describe "Users", -> User.findByIdAndUpdate user._id, $set: "balance": 4 + , {new: true} , (err, _user) -> async.waterfall [ (cb) -> diff --git a/website/src/controllers/challenges.js b/website/src/controllers/challenges.js index 5219503537..6ac40b2571 100644 --- a/website/src/controllers/challenges.js +++ b/website/src/controllers/challenges.js @@ -230,7 +230,7 @@ api.update = function(req, res, next){ // before-save / after-save comparison to determine if we need to sync to users before = _before; var attrs = _.pick(req.body, 'name shortName description habits dailys todos rewards date'.split(' ')); - Challenge.findByIdAndUpdate(cid, {$set:attrs}, cb); + Challenge.findByIdAndUpdate(cid, {$set:attrs}, {new: true}, cb); }, function(saved, cb) { @@ -271,7 +271,7 @@ function closeChal(cid, broken, cb) { function(_removed, cb2) { removed = _removed; var pull = {'$pull':{}}; pull['$pull'][_removed._id] = 1; - Group.findByIdAndUpdate(_removed.group, pull); + Group.findByIdAndUpdate(_removed.group, {new: true}, pull); User.find({_id:{$in: removed.members}}, cb2); }, function(users, cb2) { @@ -370,7 +370,7 @@ api.join = function(req, res, next){ async.waterfall([ function(cb) { - Challenge.findByIdAndUpdate(cid, {$addToSet:{members:user._id}}, cb); + Challenge.findByIdAndUpdate(cid, {$addToSet:{members:user._id}}, {new: true}, cb); }, function(chal, cb) { @@ -403,7 +403,7 @@ api.leave = function(req, res, next){ async.waterfall([ function(cb){ - Challenge.findByIdAndUpdate(cid, {$pull:{members:user._id}}, cb); + Challenge.findByIdAndUpdate(cid, {$pull:{members:user._id}}, {new: true}, cb); }, function(chal, cb){ diff --git a/website/src/controllers/unsubscription.js b/website/src/controllers/unsubscription.js index d0ef89f920..f839b11551 100644 --- a/website/src/controllers/unsubscription.js +++ b/website/src/controllers/unsubscription.js @@ -13,9 +13,9 @@ api.unsubscribe = function(req, res, next){ if(data._id){ User.update({_id: data._id}, { $set: {'preferences.emailNotifications.unsubscribeFromAll': true} - }, {multi: false}, function(err, nAffected){ + }, {multi: false}, function(err, updateRes){ if(err) return next(err); - if(nAffected !== 1) return res.json(404, {err: 'User not found'}); + if(updateRes.n !== 1) return res.json(404, {err: 'User not found'}); res.send('

' + i18n.t('unsubscribedSuccessfully', null, req.language) + '

' + i18n.t('unsubscribedTextUsers', null, req.language)); }); From 8c99cc1d3b0138560235e5a2c624a10ae496a110 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Thu, 29 Oct 2015 16:41:54 +0100 Subject: [PATCH 05/10] add mongodb to travis ci --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5354360f8c..421961e910 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,13 @@ language: node_js sudo: false -services: - - mongodb node_js: - '4.1' before_script: + - wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.7.tgz -O /tmp/mongodb.tgz + - tar -xvf /tmp/mongodb.tgz + - mkdir /tmp/data + - ${PWD}/mongodb-linux-x86_64-3.0.4/bin/mongod --dbpath /tmp/data --bind_ip 127.0.0.1 --auth &> /dev/null & + - until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done - 'npm install -g grunt-cli mocha' - cp config.json.example config.json - "until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done" From 64852ae2bd991a7394ed4f5b5f9143157994f90d Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Thu, 29 Oct 2015 17:09:03 +0100 Subject: [PATCH 06/10] Revert "add mongodb to travis ci" This reverts commit 8c99cc1d3b0138560235e5a2c624a10ae496a110. --- .travis.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 421961e910..5354360f8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,10 @@ language: node_js sudo: false +services: + - mongodb node_js: - '4.1' before_script: - - wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.7.tgz -O /tmp/mongodb.tgz - - tar -xvf /tmp/mongodb.tgz - - mkdir /tmp/data - - ${PWD}/mongodb-linux-x86_64-3.0.4/bin/mongod --dbpath /tmp/data --bind_ip 127.0.0.1 --auth &> /dev/null & - - until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done - 'npm install -g grunt-cli mocha' - cp config.json.example config.json - "until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done" From 23984a7543706376bb9df6fe763d386dc22eaf31 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Thu, 29 Oct 2015 17:12:53 +0100 Subject: [PATCH 07/10] revert to old travis file --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5354360f8c..025cfe8a18 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,15 @@ language: node_js -sudo: false -services: - - mongodb node_js: - '4.1' +before_install: + - "sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10" + - "echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list" + - "sudo apt-get update" + - "sudo apt-get install mongodb-org-server" before_script: - 'npm install -g grunt-cli mocha' - cp config.json.example config.json - "until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done" - "export DISPLAY=:99" after_script: - - "./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js" + - "./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js" \ No newline at end of file From e813b756acb799a50c4951a7dddd43fa82aedf7e Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Thu, 29 Oct 2015 17:26:35 +0100 Subject: [PATCH 08/10] use higher npm version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d089129b97..4a4eea0542 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "private": true, "engines": { "node": "~4.1.1", - "npm": "^3.3.4" + "npm": "^3.3.8" }, "scripts": { "test": "gulp test", From b4d45834d1baea69dbf329ca7d6b402c6233541f Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Thu, 29 Oct 2015 12:59:10 -0500 Subject: [PATCH 09/10] Update travis to use mongo 3 and npm v3 --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 025cfe8a18..79a863bede 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,16 @@ language: node_js node_js: - '4.1' before_install: + - "npm install -g npm@3.3.8" - "sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10" - - "echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list" - - "sudo apt-get update" - - "sudo apt-get install mongodb-org-server" + - "sudo wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.4.tgz -O /tmp/mongodb.tgz" + - "sudo tar -xvf /tmp/mongodb.tgz" + - "sudo mkdir /tmp/data" + - "sudo ${PWD}/mongodb-linux-x86_64-3.0.4/bin/mongod --dbpath /tmp/data --bind_ip 127.0.0.1 &> /dev/null &" before_script: - 'npm install -g grunt-cli mocha' - cp config.json.example config.json - "until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done" - "export DISPLAY=:99" after_script: - - "./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js" \ No newline at end of file + - "./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js" From 9844d3dc76f8f816ef08cf085d30e30ec1f312ec Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Thu, 29 Oct 2015 13:07:50 -0500 Subject: [PATCH 10/10] Use most recent version of npm 3 in travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 79a863bede..915e677edf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: node_js node_js: - '4.1' before_install: - - "npm install -g npm@3.3.8" + - "npm install -g npm@3" - "sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10" - "sudo wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.4.tgz -O /tmp/mongodb.tgz" - "sudo tar -xvf /tmp/mongodb.tgz"