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.
This commit is contained in:
Piotr Sarnacki 2012-12-10 17:29:29 +01:00
parent 7759061d4e
commit 8e97b68313
6 changed files with 72 additions and 29 deletions

View File

@ -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) ->

View File

@ -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'

View File

@ -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))

View File

@ -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');

View File

@ -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}"

View File

@ -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 || {})