From b7dfc21bac674924b89571e84b76807492477cea Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Thu, 21 Feb 2013 11:17:37 -0500 Subject: [PATCH 01/10] test '_userId' instead of session.userId --- src/server/index.coffee | 4 ++-- src/server/middleware.coffee | 2 +- src/server/private.coffee | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/index.coffee b/src/server/index.coffee index c0dac1619f..1fb7d7fd4d 100644 --- a/src/server/index.coffee +++ b/src/server/index.coffee @@ -69,10 +69,10 @@ mongo_store = new MongoStore {url: process.env.NODE_DB_URI}, -> cookie: { maxAge: TWO_WEEKS } # defaults to 2 weeks? aka, can delete this line? store: mongo_store ) - # Show splash page for newcomers - .use(middleware.splash) # Adds req.getModel method .use(store.modelMiddleware()) + # Show splash page for newcomers + .use(middleware.splash) .use(priv.middleware) .use(middleware.view) .use(auth.middleware(strategies, options)) diff --git a/src/server/middleware.coffee b/src/server/middleware.coffee index 44f53b90d0..03e388ffee 100644 --- a/src/server/middleware.coffee +++ b/src/server/middleware.coffee @@ -2,7 +2,7 @@ module.exports.splash = (req, res, next) -> # This was an API call, not a page load return next() if req.is('json') - if !req.session.userId? and !req.query?.play? + unless req.query?.play? or req.getModel().get('_userId') res.redirect('/splash.html') else next() diff --git a/src/server/private.coffee b/src/server/private.coffee index e9b5617053..5e7c148ab4 100644 --- a/src/server/private.coffee +++ b/src/server/private.coffee @@ -50,7 +50,7 @@ module.exports.routes = (expressApp) -> return res.send(500, err.response.error.message) else model = req.getModel() - userId = model.session.userId + userId = model.get('_userId') or model.session.userId req._isServer = true model.fetch "users.#{userId}", (err, user) -> model.ref '_user', "users.#{userId}" From 6e0caa6e7a229357038556cb5e624e05657d151f Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Thu, 21 Feb 2013 12:45:05 -0500 Subject: [PATCH 02/10] try only allowing _userId subscriptions on client routes (memory leak attempt, see see http://goo.gl/TPYIt) --- src/app/party.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/party.coffee b/src/app/party.coffee index 2e5c269671..0284d2444d 100644 --- a/src/app/party.coffee +++ b/src/app/party.coffee @@ -23,7 +23,7 @@ module.exports.partySubscribe = partySubscribe = (model, cb) -> # partyUnsubscribe model, -> # Restart subscription to the main user - selfQ = model.query('users').withId(model.get('_userId') or model.session.userId) + selfQ = model.query('users').withId model.get('_userId') #or model.session.userId # see http://goo.gl/TPYIt selfQ.subscribe (err, self) -> throw err if err u = self.at(0) @@ -166,7 +166,7 @@ module.exports.app = (appExports, model) -> # model.set '_party', null # model.set '_partyMembers', null # partyUnsubscribe model, -> -# selfQ = model.query('users').withId(model.get('_userId') or model.session.userId) +# selfQ = model.query('users').withId model.get('_userId') #or model.session.userId # see http://goo.gl/TPYIt # selfQ.subscribe (err, u) -> # model.ref '_user', u.at(0) # browser.resetDom model \ No newline at end of file From a649863308edcdb8f6d34ccf88221feef9b76e92 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Thu, 21 Feb 2013 12:45:30 -0500 Subject: [PATCH 03/10] try only allowing _userId subscriptions on client routes (memory leak attempt, see see http://goo.gl/TPYIt) --- src/server/private.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/private.coffee b/src/server/private.coffee index 5e7c148ab4..f882bac83b 100644 --- a/src/server/private.coffee +++ b/src/server/private.coffee @@ -50,7 +50,7 @@ module.exports.routes = (expressApp) -> return res.send(500, err.response.error.message) else model = req.getModel() - userId = model.get('_userId') or model.session.userId + userId = model.get('_userId') #or model.session.userId # see http://goo.gl/TPYIt req._isServer = true model.fetch "users.#{userId}", (err, user) -> model.ref '_user', "users.#{userId}" From 2d04dd4cb94ac0f5f9d23a047b897adb491ffa6b Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Thu, 21 Feb 2013 13:40:03 -0500 Subject: [PATCH 04/10] when redirecting to /?play=1, we get access-denied for model.session.userId for some reason. seems user initialization happens during that process, so we just do another page refresh and we're good --- src/app/index.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/index.coffee b/src/app/index.coffee index b4d27a9cb0..2c2f3340ca 100644 --- a/src/app/index.coffee +++ b/src/app/index.coffee @@ -24,6 +24,8 @@ _ = require('underscore') # ========== ROUTES ========== get '/', (page, model, next) -> + return page.redirect '/' if page.params?.query?.play? + # temporary view variables, so we don't call model.set() too fast _view = model.get '_view' || {} From 8fe548f70348a0fe1a8dedc6cb8631bd2021def4 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Thu, 21 Feb 2013 17:06:22 -0500 Subject: [PATCH 05/10] match derbyAuth errback on invalidated session --- src/server/store.coffee | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/server/store.coffee b/src/server/store.coffee index 38476d72cc..769b9098f5 100644 --- a/src/server/store.coffee +++ b/src/server/store.coffee @@ -1,3 +1,5 @@ +derbyAuth = require('derby-auth/store') + ### Setup read / write access @param store @@ -14,14 +16,18 @@ module.exports.customAccessControl = (store) -> userAccess = (store) -> store.readPathAccess "users.*", -> # captures, accept, err -> + err = arguments[arguments.length - 1] + return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + accept = arguments[arguments.length - 2] - return accept(true) unless @session?.userId # https://github.com/codeparty/racer/issues/37 uid = arguments[0] accept (uid is @session.userId) or @session.req?._isServer store.writeAccess "*", "users.*", -> # captures, value, accept, err -> + err = arguments[arguments.length - 1] + return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + accept = arguments[arguments.length-2] - return accept(true) unless @session?.userId # https://github.com/codeparty/racer/issues/37 captures = arguments[0].split('.') uid = captures.shift() attrPath = captures.join('.') # new array shifted left, after shift() was run @@ -37,14 +43,16 @@ userAccess = (store) -> accept(false) store.writeAccess "*", "users.*.balance", (id, newBalance, accept, err) -> - return accept(true) unless @session?.userId # https://github.com/codeparty/racer/issues/37 + return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + oldBalance = @session.req?._racerModel?.get("users.#{id}.balance") || 0 purchasingSomethingOnClient = newBalance < oldBalance accept(purchasingSomethingOnClient or @session.req?._isServer) store.writeAccess "*", "users.*.flags.ads", -> # captures, value, accept, err -> - accept = arguments[arguments.length - 1] - return accept(true) unless @session?.userId # https://github.com/codeparty/racer/issues/37 + err = arguments[arguments.length - 1] + return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + accept(@session.req?._isServer) @@ -53,14 +61,14 @@ userAccess = (store) -> Get user with API token ### REST = (store) -> - store.query.expose "users", "withIdAndToken", (id, apiToken) -> - @where("id").equals(id) - .where('apiToken').equals(apiToken) - .limit(1) + store.query.expose "users", "withIdAndToken", (uid, token) -> + @byId(uid) + .where('apiToken').equals(token) + .one - store.queryAccess "users", "withIdAndToken", (id, apiToken, accept, err) -> - return accept(true) unless @session?.userId # https://github.com/codeparty/racer/issues/37 - accept(true) # only user has id & token + store.queryAccess "users", "withIdAndToken", (uid, token, accept, err) -> + return accept(true) if uid && token + accept(false) # only user has id & token ### @@ -90,4 +98,4 @@ partySystem = (store) -> store.writeAccess "*", "parties.*", -> accept = arguments[arguments.length-2] - accept(true) \ No newline at end of file + accept(true) From c6efcea9cfa13bfc356380da69b0945c3d31e649 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Thu, 21 Feb 2013 21:06:29 -0500 Subject: [PATCH 06/10] check invalidated session on somre more paths --- src/server/store.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/server/store.coffee b/src/server/store.coffee index 769b9098f5..da73da1ca7 100644 --- a/src/server/store.coffee +++ b/src/server/store.coffee @@ -85,11 +85,15 @@ partySystem = (store) -> 'auth.facebook.displayName') store.queryAccess "users", "party", (ids, accept, err) -> + err = arguments[arguments.length - 1] + return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) accept(true) # no harm in public user stats store.query.expose "parties", "withId", (id) -> @where("id").equals(id) store.queryAccess "parties", "withId", (id, accept, err) -> + err = arguments[arguments.length - 1] + return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) accept(true) store.readPathAccess "parties.*", -> @@ -97,5 +101,7 @@ partySystem = (store) -> accept(true) store.writeAccess "*", "parties.*", -> + err = arguments[arguments.length - 1] + return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) accept = arguments[arguments.length-2] accept(true) From 4f5ebf31d310d090688af32097a35e53e93a62eb Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Fri, 22 Feb 2013 00:08:40 -0500 Subject: [PATCH 07/10] remove nodetime, freeze browserify@1.17.3 --- package.json | 4 ++-- server.js | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 965ee1113e..3590ffea94 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,8 @@ "mongoskin": "*", "nconf": "*", "icalendar": "git://github.com/lefnire/node-icalendar#master", - "nodetime": "*", - "resolve": "~0.2.3" + "resolve": "~0.2.3", + "browserify": "1.17.3" }, "private": true, "subdomain": "habitrpg", diff --git a/server.js b/server.js index 5709a5db48..db73ddd361 100644 --- a/server.js +++ b/server.js @@ -21,14 +21,6 @@ process.env.SMTP_PASS = conf.get("SMTP_PASS"); process.env.SMTP_SERVICE = conf.get("SMTP_SERVICE"); process.env.STRIPE_API_KEY = conf.get("STRIPE_API_KEY"); process.env.STRIPE_PUB_KEY = conf.get("STRIPE_PUB_KEY"); -process.env.NODETIME_KEY = conf.get("NODETIME_KEY"); - -if (process.env.NODETIME_KEY) { - require('nodetime').profile({ - accountKey: process.env.NODETIME_KEY, - appName: 'HabitRPG' - }); -} process.on('uncaughtException', function (error) { From 554ec66a7109fb75ad7423c9abdb47df648af1df Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Fri, 22 Feb 2013 12:46:23 -0500 Subject: [PATCH 08/10] for now accept invalidated sessions in sotre --- src/server/store.coffee | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/server/store.coffee b/src/server/store.coffee index da73da1ca7..56ad86377f 100644 --- a/src/server/store.coffee +++ b/src/server/store.coffee @@ -17,7 +17,8 @@ userAccess = (store) -> store.readPathAccess "users.*", -> # captures, accept, err -> err = arguments[arguments.length - 1] - return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + return accept(true) if derbyAuth.sessionInvalidated(@) accept = arguments[arguments.length - 2] uid = arguments[0] @@ -25,7 +26,8 @@ userAccess = (store) -> store.writeAccess "*", "users.*", -> # captures, value, accept, err -> err = arguments[arguments.length - 1] - return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + return accept(true) if derbyAuth.sessionInvalidated(@) accept = arguments[arguments.length-2] captures = arguments[0].split('.') @@ -43,7 +45,8 @@ userAccess = (store) -> accept(false) store.writeAccess "*", "users.*.balance", (id, newBalance, accept, err) -> - return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + return accept(true) if derbyAuth.sessionInvalidated(@) oldBalance = @session.req?._racerModel?.get("users.#{id}.balance") || 0 purchasingSomethingOnClient = newBalance < oldBalance @@ -51,7 +54,8 @@ userAccess = (store) -> store.writeAccess "*", "users.*.flags.ads", -> # captures, value, accept, err -> err = arguments[arguments.length - 1] - return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + return accept(true) if derbyAuth.sessionInvalidated(@) accept(@session.req?._isServer) @@ -86,14 +90,16 @@ partySystem = (store) -> store.queryAccess "users", "party", (ids, accept, err) -> err = arguments[arguments.length - 1] - return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + return accept(true) if derbyAuth.sessionInvalidated(@) accept(true) # no harm in public user stats store.query.expose "parties", "withId", (id) -> @where("id").equals(id) store.queryAccess "parties", "withId", (id, accept, err) -> err = arguments[arguments.length - 1] - return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + return accept(true) if derbyAuth.sessionInvalidated(@) accept(true) store.readPathAccess "parties.*", -> @@ -102,6 +108,7 @@ partySystem = (store) -> store.writeAccess "*", "parties.*", -> err = arguments[arguments.length - 1] - return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) + return accept(true) if derbyAuth.sessionInvalidated(@) accept = arguments[arguments.length-2] accept(true) From b15654b18bb0cf51ed85a853508af21d90f36f3d Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Fri, 22 Feb 2013 12:52:07 -0500 Subject: [PATCH 09/10] fix to previous --- src/server/store.coffee | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/server/store.coffee b/src/server/store.coffee index 56ad86377f..acc9f5b3b3 100644 --- a/src/server/store.coffee +++ b/src/server/store.coffee @@ -16,6 +16,7 @@ module.exports.customAccessControl = (store) -> userAccess = (store) -> store.readPathAccess "users.*", -> # captures, accept, err -> + accept = arguments[arguments.length-2] err = arguments[arguments.length - 1] # return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) return accept(true) if derbyAuth.sessionInvalidated(@) @@ -25,11 +26,11 @@ userAccess = (store) -> accept (uid is @session.userId) or @session.req?._isServer store.writeAccess "*", "users.*", -> # captures, value, accept, err -> + accept = arguments[arguments.length-2] err = arguments[arguments.length - 1] # return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) return accept(true) if derbyAuth.sessionInvalidated(@) - accept = arguments[arguments.length-2] captures = arguments[0].split('.') uid = captures.shift() attrPath = captures.join('.') # new array shifted left, after shift() was run @@ -89,7 +90,6 @@ partySystem = (store) -> 'auth.facebook.displayName') store.queryAccess "users", "party", (ids, accept, err) -> - err = arguments[arguments.length - 1] # return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) return accept(true) if derbyAuth.sessionInvalidated(@) accept(true) # no harm in public user stats @@ -97,7 +97,6 @@ partySystem = (store) -> store.query.expose "parties", "withId", (id) -> @where("id").equals(id) store.queryAccess "parties", "withId", (id, accept, err) -> - err = arguments[arguments.length - 1] # return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) return accept(true) if derbyAuth.sessionInvalidated(@) accept(true) @@ -107,8 +106,8 @@ partySystem = (store) -> accept(true) store.writeAccess "*", "parties.*", -> + accept = arguments[arguments.length-2] err = arguments[arguments.length - 1] # return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) return accept(true) if derbyAuth.sessionInvalidated(@) - accept = arguments[arguments.length-2] accept(true) From 2641670ebe0c31be9f89319de3d6a61b43c97794 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Fri, 22 Feb 2013 13:48:39 -0500 Subject: [PATCH 10/10] add check on isServer in busted session, accept(false) --- src/server/api.coffee | 2 +- src/server/store.coffee | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/server/api.coffee b/src/server/api.coffee index f394945f09..84531744f3 100644 --- a/src/server/api.coffee +++ b/src/server/api.coffee @@ -24,8 +24,8 @@ router.post '/users/:uid/tasks/:taskId/:direction', (req, res) -> return res.send(500, ':taskId required') unless taskId return res.send(500, ":direction must be 'up' or 'down'") unless direction in ['up','down'] - model = req.getModel() req._isServer = true + model = req.getModel() model.fetch model.query('users').withIdAndToken(uid, apiToken), (err, result) -> return res.send(500, err) if err user = result.at(0) diff --git a/src/server/store.coffee b/src/server/store.coffee index acc9f5b3b3..cebd70e5cd 100644 --- a/src/server/store.coffee +++ b/src/server/store.coffee @@ -18,18 +18,18 @@ userAccess = (store) -> store.readPathAccess "users.*", -> # captures, accept, err -> accept = arguments[arguments.length-2] err = arguments[arguments.length - 1] -# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) - return accept(true) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@) + return accept(false) if derbyAuth.bustedSession(@) accept = arguments[arguments.length - 2] uid = arguments[0] - accept (uid is @session.userId) or @session.req?._isServer + accept (uid is @session.userId) or derbyAuth.isServer(@) store.writeAccess "*", "users.*", -> # captures, value, accept, err -> accept = arguments[arguments.length-2] err = arguments[arguments.length - 1] -# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) - return accept(true) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@) + return accept(false) if derbyAuth.bustedSession(@) captures = arguments[0].split('.') uid = captures.shift() @@ -40,14 +40,14 @@ userAccess = (store) -> return accept(true) # Same session (user.id = this.session.userId) - if (uid is @session.userId) or @session.req?._isServer + if (uid is @session.userId) or derbyAuth.isServer(@) return accept(true) accept(false) store.writeAccess "*", "users.*.balance", (id, newBalance, accept, err) -> -# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) - return accept(true) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@) + return accept(false) if derbyAuth.bustedSession(@) oldBalance = @session.req?._racerModel?.get("users.#{id}.balance") || 0 purchasingSomethingOnClient = newBalance < oldBalance @@ -55,10 +55,10 @@ userAccess = (store) -> store.writeAccess "*", "users.*.flags.ads", -> # captures, value, accept, err -> err = arguments[arguments.length - 1] -# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) - return accept(true) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@) + return accept(false) if derbyAuth.bustedSession(@) - accept(@session.req?._isServer) + accept(derbyAuth.isServer(@)) ### @@ -90,15 +90,15 @@ partySystem = (store) -> 'auth.facebook.displayName') store.queryAccess "users", "party", (ids, accept, err) -> -# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) - return accept(true) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@) + return accept(false) if derbyAuth.bustedSession(@) accept(true) # no harm in public user stats store.query.expose "parties", "withId", (id) -> @where("id").equals(id) store.queryAccess "parties", "withId", (id, accept, err) -> -# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) - return accept(true) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@) + return accept(false) if derbyAuth.bustedSession(@) accept(true) store.readPathAccess "parties.*", -> @@ -108,6 +108,6 @@ partySystem = (store) -> store.writeAccess "*", "parties.*", -> accept = arguments[arguments.length-2] err = arguments[arguments.length - 1] -# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.sessionInvalidated(@) - return accept(true) if derbyAuth.sessionInvalidated(@) +# return err(derbyAuth.SESSION_INVALIDATED_ERROR) if derbyAuth.bustedSession(@) + return accept(false) if derbyAuth.bustedSession(@) accept(true)