From 0a78368217e45044f2ec3294342b95927740277b Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Wed, 2 Apr 2014 13:12:24 -0700 Subject: [PATCH] Refactored user authentication again. Now the user object is inserted into main.html, which was renamed from index.html so the express static middleware wouldn't serve it. --- app/assets/{index.html => main.html} | 5 +++ app/initialize.coffee | 10 +---- app/lib/FacebookHandler.coffee | 3 +- app/lib/GPlusHandler.coffee | 3 +- app/lib/Router.coffee | 2 - app/lib/auth.coffee | 66 ++++++++-------------------- server/routes/auth.coffee | 41 +++++++++-------- server_setup.coffee | 16 ++++++- 8 files changed, 63 insertions(+), 83 deletions(-) rename app/assets/{index.html => main.html} (99%) diff --git a/app/assets/index.html b/app/assets/main.html similarity index 99% rename from app/assets/index.html rename to app/assets/main.html index b558ff66f..96306649e 100644 --- a/app/assets/index.html +++ b/app/assets/main.html @@ -35,6 +35,11 @@ + + + diff --git a/app/initialize.coffee b/app/initialize.coffee index 7670088db..80c33c9b7 100644 --- a/app/initialize.coffee +++ b/app/initialize.coffee @@ -1,5 +1,4 @@ app = require 'application' -auth = require 'lib/auth' init = -> app.initialize() @@ -10,15 +9,8 @@ init = -> treemaExt.setup() filepicker.setKey('AvlkNoldcTOU4PvKi2Xm7z') -$ -> - # Make sure we're "logged in" first. - if auth.me.id - init() - else - Backbone.Mediator.subscribeOnce 'me:synced', init +$ -> init() -window.init = init - handleNormalUrls = -> # http://artsy.github.com/blog/2012/06/25/replacing-hashbang-routes-with-pushstate/ $(document).on "click", "a[href^='/']", (event) -> diff --git a/app/lib/FacebookHandler.coffee b/app/lib/FacebookHandler.coffee index ffd61b5a1..10a59c40c 100644 --- a/app/lib/FacebookHandler.coffee +++ b/app/lib/FacebookHandler.coffee @@ -1,5 +1,5 @@ CocoClass = require 'lib/CocoClass' -{me, CURRENT_USER_KEY} = require 'lib/auth' +{me} = require 'lib/auth' {backboneFailure} = require 'lib/errors' storage = require 'lib/storage' @@ -59,7 +59,6 @@ module.exports = FacebookHandler = class FacebookHandler extends CocoClass error: backboneFailure, url: "/db/user?facebookID=#{r.id}&facebookAccessToken=#{@authResponse.accessToken}" success: (model) -> - storage.save(CURRENT_USER_KEY, model.attributes) window.location.reload() if model.get('email') isnt oldEmail }) diff --git a/app/lib/GPlusHandler.coffee b/app/lib/GPlusHandler.coffee index 2ffd27805..8565a2075 100644 --- a/app/lib/GPlusHandler.coffee +++ b/app/lib/GPlusHandler.coffee @@ -1,5 +1,5 @@ CocoClass = require 'lib/CocoClass' -{me, CURRENT_USER_KEY} = require 'lib/auth' +{me} = require 'lib/auth' {backboneFailure} = require 'lib/errors' storage = require 'lib/storage' GPLUS_TOKEN_KEY = 'gplusToken' @@ -102,7 +102,6 @@ module.exports = GPlusHandler = class GPlusHandler extends CocoClass error: backboneFailure, url: "/db/user?gplusID=#{gplusID}&gplusAccessToken=#{@accessToken.access_token}" success: (model) -> - storage.save(CURRENT_USER_KEY, model.attributes) window.location.reload() if wasAnonymous and not model.get('anonymous') }) diff --git a/app/lib/Router.coffee b/app/lib/Router.coffee index 65915dd56..7c12e1cb8 100644 --- a/app/lib/Router.coffee +++ b/app/lib/Router.coffee @@ -1,5 +1,3 @@ -{me} = require 'lib/auth' - gplusClientID = "800329290710-j9sivplv2gpcdgkrsis9rff3o417mlfa.apps.googleusercontent.com" go = (path) -> -> @routeDirectly path, arguments diff --git a/app/lib/auth.coffee b/app/lib/auth.coffee index 78862d733..d46733089 100644 --- a/app/lib/auth.coffee +++ b/app/lib/auth.coffee @@ -1,20 +1,24 @@ {backboneFailure, genericFailure} = require 'lib/errors' User = require 'models/User' storage = require 'lib/storage' - -module.exports.CURRENT_USER_KEY = CURRENT_USER_KEY = 'whoami' BEEN_HERE_BEFORE_KEY = 'beenHereBefore' +init = -> + module.exports.me = window.me = new User(window.userObject) # inserted into main.html + trackFirstArrival() + if me and not me.get('testGroupNumber')? + # Assign testGroupNumber to returning visitors; new ones in server/routes/auth + me.set 'testGroupNumber', Math.floor(Math.random() * 256) + me.save() + + me.loadGravatarProfile() if me.get('email') + Backbone.listenTo(me, 'sync', Backbone.Mediator.publish('me:synced', {me:me})) + module.exports.createUser = (userObject, failure=backboneFailure, nextURL=null) -> user = new User(userObject) user.save({}, { - error: failure, - success: (model) -> - storage.save(CURRENT_USER_KEY, model) - if nextURL - window.location.href = nextURL - else - window.location.reload() + error: failure, + success: -> if nextURL then window.location.href = nextURL else window.location.reload() }) module.exports.loginUser = (userObject, failure=genericFailure) -> @@ -23,52 +27,15 @@ module.exports.loginUser = (userObject, failure=genericFailure) -> username:userObject.email, password:userObject.password }, - (model) -> - storage.save(CURRENT_USER_KEY, model) - window.location.reload() + (model) -> window.location.reload() ) jqxhr.fail(failure) module.exports.logoutUser = -> FB?.logout?() - res = $.post('/auth/logout', {}, -> - storage.save(CURRENT_USER_KEY, null) - window.location.reload() - ) + res = $.post('/auth/logout', {}, -> window.location.reload()) res.fail(genericFailure) -init = -> - # Load the user from local storage, and refresh it from the server. - # Also refresh and cache the gravatar info. - - storedUser = storage.load(CURRENT_USER_KEY) - firstTime = not storedUser - module.exports.me = window.me = new User(storedUser) - me.url = -> '/auth/whoami' - me.fetch() - - retry = -> me.fetch() # blindly try again - error = -> setTimeout(retry, 1000) # blindly try again - me.on 'error', error, @ - me.on 'sync', -> - me.off 'error', error, @ if firstTime - me.url = -> "/db/user/#{me.id}" - trackFirstArrival() if firstTime - if me and not me.get('testGroupNumber')? - # Assign testGroupNumber to returning visitors; new ones in server/handlers/user - me.set 'testGroupNumber', Math.floor(Math.random() * 256) - me.save() - storage.save(CURRENT_USER_KEY, me.attributes) - - me.loadGravatarProfile() if me.get('email') - Backbone.listenTo(me, 'sync', userSynced) - -userSynced = (user) -> - Backbone.Mediator.publish('me:synced', {me:user}) - storage.save(CURRENT_USER_KEY, user) - -init() - onSetVolume = (e) -> return if e.volume is me.get('volume') me.set('volume', e.volume) @@ -83,3 +50,6 @@ trackFirstArrival = -> return if beenHereBefore window.tracker?.trackEvent 'First Arrived' storage.save(BEEN_HERE_BEFORE_KEY, true) + +init() + diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee index dcb8ea12a..76612e2e0 100644 --- a/server/routes/auth.coffee +++ b/server/routes/auth.coffee @@ -71,9 +71,7 @@ module.exports.setup = (app) -> if req.user sendSelf(req, res) else - user = new User({anonymous:true}) - user.set 'testGroupNumber', Math.floor(Math.random() * 256) # also in app/lib/auth - user.set 'preferredLanguage', languages.languageCodeFromAcceptedLanguages req.acceptedLanguages + user = makeNewUser(req) makeNext = (req, res) -> -> sendSelf(req, res) next = makeNext(req, res) loginUser(req, res, user, false, next) @@ -84,21 +82,6 @@ module.exports.setup = (app) -> res.send(UserHandler.formatEntity(req, req.user)) res.end() - loginUser = (req, res, user, send=true, next=null) -> - user.save((err) -> - if err - return @sendDatabaseError(res, err) - - req.logIn(user, (err) -> - if err - return @sendDatabaseError(res, err) - - if send - return @sendSuccess(res, user) - next() if next - ) - ) - app.post('/auth/logout', (req, res) -> req.logout() res.end() @@ -155,6 +138,26 @@ module.exports.setup = (app) -> res.send "Unsubscribed #{req.query.email} from all CodeCombat emails. Sorry to see you go!

Account settings

" res.end() +module.exports.loginUser = loginUser = (req, res, user, send=true, next=null) -> + user.save((err) -> + if err + return @sendDatabaseError(res, err) + + req.logIn(user, (err) -> + if err + return @sendDatabaseError(res, err) + + if send + return @sendSuccess(res, user) + next() if next + ) + ) + +module.exports.makeNewUser = makeNewUser = (req) -> + user = new User({anonymous:true}) + user.set 'testGroupNumber', Math.floor(Math.random() * 256) # also in app/lib/auth + user.set 'preferredLanguage', languages.languageCodeFromAcceptedLanguages req.acceptedLanguages + createMailOptions = (receiver, password) -> # TODO: use email templates here options = @@ -163,4 +166,4 @@ createMailOptions = (receiver, password) -> replyTo: config.mail.username subject: "[CodeCombat] Password Reset" text: "You can log into your account with: #{password}" -# + diff --git a/server_setup.coffee b/server_setup.coffee index e0a72f4dc..c06482a85 100644 --- a/server_setup.coffee +++ b/server_setup.coffee @@ -9,6 +9,8 @@ baseRoute = require './server/routes/base' user = require './server/users/user_handler' logging = require './server/commons/logging' config = require './server_config' +auth = require './server/routes/auth' +UserHandler = require('./server/users/user_handler') ###Middleware setup functions implementation### # 2014-03-03: Try not using this and see if it's still a problem @@ -85,7 +87,19 @@ exports.setupMiddleware = (app) -> setupFallbackRouteToIndex = (app) -> app.all '*', (req, res) -> - res.sendfile path.join(__dirname, 'public', 'index.html') + if req.user + sendMain(req, res) + else + user = auth.makeNewUser(req) + makeNext = (req, res) -> -> sendMain(req, res) + next = makeNext(req, res) + auth.loginUser(req, res, user, false, next) + +sendMain = (req, res) -> + fs.readFile path.join(__dirname, 'public', 'main.html'), 'utf8', (err,data) -> + # insert the user object directly into the html so the application can have it immediately + data = data.replace('"userObjectTag"', JSON.stringify(UserHandler.formatEntity(req, req.user))) + res.send data setupFacebookCrossDomainCommunicationRoute = (app) -> app.get '/channel.html', (req, res) ->