From 8e97b683133f75284bcb15f25e83e7687a199f65 Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Mon, 10 Dec 2012 17:29:29 +0100 Subject: [PATCH] Make the app work with disabled cookies Browsers disable local storage and session storage when cookies are disabled - any call to one of those will cause an error. This commit provides fallback storage, which will store items in memory. --- assets/scripts/app/auth.coffee | 40 ++++++++++---------- assets/scripts/app/models/broadcast.coffee | 8 +++- assets/scripts/app/models/user.coffee | 4 +- assets/scripts/app/slider.coffee | 4 +- assets/scripts/lib/travis/ajax.coffee | 2 +- assets/scripts/travis.coffee | 43 +++++++++++++++++++++- 6 files changed, 72 insertions(+), 29 deletions(-) diff --git a/assets/scripts/app/auth.coffee b/assets/scripts/app/auth.coffee index 61e0b868..6d23cb4c 100644 --- a/assets/scripts/app/auth.coffee +++ b/assets/scripts/app/auth.coffee @@ -9,23 +9,23 @@ window.addEventListener('message', (e) => @receiveMessage(e)) accessToken: (-> - sessionStorage.getItem('travis.token') + Travis.sessionStorage.getItem('travis.token') ).property() # if the user is in the session storage, we're using it. if we have a flag # for auto signin then we're trying to sign in. autoSignIn: (path) -> console.log 'autoSignIn' - global = localStorage.getItem('travis.user') - session = sessionStorage.getItem('travis.user') + global = Travis.storage.getItem('travis.user') + session = Travis.sessionStorage.getItem('travis.user') user = session || global if user - localStorage.setItem('travis.user', user) unless global + Travis.storage.setItem('travis.user', user) unless global data = JSON.parse(user) data = { user: data } unless data.user? @setData(data) - else if localStorage.getItem('travis.auto_signin') - console.log 'travis.auto_signin', localStorage.getItem('travis.auto_signin') + else if Travis.storage.getItem('travis.auto_signin') + console.log 'travis.auto_signin', Travis.storage.getItem('travis.auto_signin') @signIn() # try signing in, but check later in case we have a timeout @@ -36,11 +36,11 @@ Ember.run.later(this, @checkSignIn.bind(this), @timeout) signOut: -> - localStorage.removeItem('travis.auto_signin') - localStorage.removeItem('travis.locale') - localStorage.removeItem('travis.user') - localStorage.removeItem('travis.token') - sessionStorage.clear() + Travis.storage.removeItem('travis.auto_signin') + Travis.storage.removeItem('travis.locale') + Travis.storage.removeItem('travis.user') + Travis.storage.removeItem('travis.token') + Travis.sessionStorage.clear() @setData() trySignIn: -> @@ -52,7 +52,7 @@ forceSignIn: -> console.log 'forceSignIn' - localStorage.setItem('travis.auto_signin', 'true') + Travis.storage.setItem('travis.auto_signin', 'true') window.location = "#{@endpoint}/auth/handshake?redirect_uri=#{location}" # TODO should have clearData() to clean this up @@ -69,26 +69,26 @@ @get('app.router').send('afterSignIn', @readAfterSignInPath()) storeToken: (token) -> - token = token || localStorage.getItem('travis.token') + token = token || Travis.storage.getItem('travis.token') if token - localStorage.setItem('travis.token', token) - sessionStorage.setItem('travis.token', token) + Travis.storage.setItem('travis.token', token) + Travis.sessionStorage.setItem('travis.token', token) @notifyPropertyChange('accessToken') storeUser: (user) -> - localStorage.setItem('travis.auto_signin', 'true') - sessionStorage.setItem('travis.user', JSON.stringify(user)) + Travis.storage.setItem('travis.auto_signin', 'true') + Travis.sessionStorage.setItem('travis.user', JSON.stringify(user)) @app.store.load(Travis.User, user) user = @app.store.find(Travis.User, user.id) user.get('permissions') user storeAfterSignInPath: (path) -> - sessionStorage.setItem('travis.after_signin_path', path) + Travis.sessionStorage.setItem('travis.after_signin_path', path) readAfterSignInPath: -> - path = sessionStorage.getItem('travis.after_signin_path') - sessionStorage.removeItem('travis.after_signin_path') + path = Travis.sessionStorage.getItem('travis.after_signin_path') + Travis.sessionStorage.removeItem('travis.after_signin_path') path receiveMessage: (event) -> diff --git a/assets/scripts/app/models/broadcast.coffee b/assets/scripts/app/models/broadcast.coffee index df61f901..dab4fe4d 100644 --- a/assets/scripts/app/models/broadcast.coffee +++ b/assets/scripts/app/models/broadcast.coffee @@ -12,11 +12,15 @@ require 'travis/model' setSeen: -> Travis.Broadcast.seen.pushObject(@get('id')) - localStorage.setItem('travis.seen_broadcasts', JSON.stringify(Travis.Broadcast.seen)) + Travis.storage.setItem('travis.seen_broadcasts', JSON.stringify(Travis.Broadcast.seen)) @notifyPropertyChange('isSeen') @Travis.Broadcast.reopenClass - seen: Ember.A(JSON.parse(localStorage.getItem('travis.seen_broadcasts')) || []) + seen: (-> + seenBroadcasts = Travis.storage.getItem('travis.seen_broadcasts') + seenBroadcasts = JSON.parse(seenBroadcasts) if seenBroadcasts? + Ember.A(seenBroadcasts || []) + )() # TODO fix or monkey-patch the adapter's url and key lookup/generation crap # url: 'users/broadcasts' diff --git a/assets/scripts/app/models/user.coffee b/assets/scripts/app/models/user.coffee index 58bb3710..4194dee7 100644 --- a/assets/scripts/app/models/user.coffee +++ b/assets/scripts/app/models/user.coffee @@ -71,6 +71,6 @@ require 'travis/model' setWithSession: (name, value) -> @set(name, value) - user = JSON.parse(sessionStorage?.getItem('travis.user')) + user = JSON.parse(Travis.sessionStorage.getItem('travis.user')) user[$.underscore(name)] = @get(name) - sessionStorage?.setItem('travis.user', JSON.stringify(user)) + Travis.sessionStorage.setItem('travis.user', JSON.stringify(user)) diff --git a/assets/scripts/app/slider.coffee b/assets/scripts/app/slider.coffee index f983fccc..470f42c1 100644 --- a/assets/scripts/app/slider.coffee +++ b/assets/scripts/app/slider.coffee @@ -1,10 +1,10 @@ @Travis.Slider = -> - @minimize() if localStorage?.getItem('travis.maximized') == 'true' + @minimize() if Travis.storage.getItem('travis.maximized') == 'true' this $.extend Travis.Slider.prototype, persist: -> - localStorage?.setItem('travis.maximized', @isMinimized()) + Travis.storage.setItem('travis.maximized', @isMinimized()) isMinimized: -> return $('body').hasClass('maximized'); diff --git a/assets/scripts/lib/travis/ajax.coffee b/assets/scripts/lib/travis/ajax.coffee index 07630660..d8ff2deb 100644 --- a/assets/scripts/lib/travis/ajax.coffee +++ b/assets/scripts/lib/travis/ajax.coffee @@ -15,7 +15,7 @@ jQuery.support.cors = true endpoint = Travis.config.api_endpoint || '' options = options || {} - if token = sessionStorage.getItem('travis.token') + if token = Travis.sessionStorage.getItem('travis.token') options.headers ||= {} options.headers['Authorization'] ||= "token #{token}" diff --git a/assets/scripts/travis.coffee b/assets/scripts/travis.coffee index 09f2a9c7..3a977000 100644 --- a/assets/scripts/travis.coffee +++ b/assets/scripts/travis.coffee @@ -13,6 +13,22 @@ if window.history.state == undefined window.history.state = state oldReplaceState.apply this, arguments +# TODO: how can I put it in Travis namespace and use immediately? +Storage = Em.Object.extend + init: -> + @set('storage', {}) + key: (key) -> + "__#{key.replace('.', '__')}" + getItem: (k) -> + return @get("storage.#{@key(k)}") + setItem: (k,v) -> + @set("storage.#{@key(k)}", v) + removeItem: (k) -> + @setItem(k, null) + clear: -> + @set('storage', {}) + + @Travis = Em.Namespace.create Ember.Evented, config: api_endpoint: $('meta[rel="travis.api_endpoint"]').attr('href') @@ -48,16 +64,39 @@ if window.history.state == undefined setLocale: (locale) -> return unless locale I18n.locale = locale - localStorage.setItem('travis.locale', locale) + @storage.setItem('travis.locale', locale) needsLocaleChange: (locale) -> I18n.locale != locale + storage: (-> + storage = null + try + storage = window.localStorage || throw('no storage') + catch err + storage = Storage.create() + + storage + )() + + sessionStorage: (-> + storage = null + try + # firefox will not throw error on access for sessionStorage var, + # you need to actually get something from session + sessionStorage.getItem('foo') + storage = sessionStorage + catch err + storage = Storage.create() + + storage + )() + run: (attrs) -> location.href = location.href.replace('#!/', '') if location.hash.slice(0, 2) == '#!' I18n.fallbacks = true - @setLocale localStorage.getItem('travis.locale') || 'en' + @setLocale @storage.getItem('travis.locale') || 'en' Ember.run.next this, -> app = Travis.App.create(attrs || {})