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)) window.addEventListener('message', (e) => @receiveMessage(e))
accessToken: (-> accessToken: (->
sessionStorage.getItem('travis.token') Travis.sessionStorage.getItem('travis.token')
).property() ).property()
# if the user is in the session storage, we're using it. if we have a flag # 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. # for auto signin then we're trying to sign in.
autoSignIn: (path) -> autoSignIn: (path) ->
console.log 'autoSignIn' console.log 'autoSignIn'
global = localStorage.getItem('travis.user') global = Travis.storage.getItem('travis.user')
session = sessionStorage.getItem('travis.user') session = Travis.sessionStorage.getItem('travis.user')
user = session || global user = session || global
if user if user
localStorage.setItem('travis.user', user) unless global Travis.storage.setItem('travis.user', user) unless global
data = JSON.parse(user) data = JSON.parse(user)
data = { user: data } unless data.user? data = { user: data } unless data.user?
@setData(data) @setData(data)
else if localStorage.getItem('travis.auto_signin') else if Travis.storage.getItem('travis.auto_signin')
console.log 'travis.auto_signin', localStorage.getItem('travis.auto_signin') console.log 'travis.auto_signin', Travis.storage.getItem('travis.auto_signin')
@signIn() @signIn()
# try signing in, but check later in case we have a timeout # try signing in, but check later in case we have a timeout
@ -36,11 +36,11 @@
Ember.run.later(this, @checkSignIn.bind(this), @timeout) Ember.run.later(this, @checkSignIn.bind(this), @timeout)
signOut: -> signOut: ->
localStorage.removeItem('travis.auto_signin') Travis.storage.removeItem('travis.auto_signin')
localStorage.removeItem('travis.locale') Travis.storage.removeItem('travis.locale')
localStorage.removeItem('travis.user') Travis.storage.removeItem('travis.user')
localStorage.removeItem('travis.token') Travis.storage.removeItem('travis.token')
sessionStorage.clear() Travis.sessionStorage.clear()
@setData() @setData()
trySignIn: -> trySignIn: ->
@ -52,7 +52,7 @@
forceSignIn: -> forceSignIn: ->
console.log '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}" window.location = "#{@endpoint}/auth/handshake?redirect_uri=#{location}"
# TODO should have clearData() to clean this up # TODO should have clearData() to clean this up
@ -69,26 +69,26 @@
@get('app.router').send('afterSignIn', @readAfterSignInPath()) @get('app.router').send('afterSignIn', @readAfterSignInPath())
storeToken: (token) -> storeToken: (token) ->
token = token || localStorage.getItem('travis.token') token = token || Travis.storage.getItem('travis.token')
if token if token
localStorage.setItem('travis.token', token) Travis.storage.setItem('travis.token', token)
sessionStorage.setItem('travis.token', token) Travis.sessionStorage.setItem('travis.token', token)
@notifyPropertyChange('accessToken') @notifyPropertyChange('accessToken')
storeUser: (user) -> storeUser: (user) ->
localStorage.setItem('travis.auto_signin', 'true') Travis.storage.setItem('travis.auto_signin', 'true')
sessionStorage.setItem('travis.user', JSON.stringify(user)) Travis.sessionStorage.setItem('travis.user', JSON.stringify(user))
@app.store.load(Travis.User, user) @app.store.load(Travis.User, user)
user = @app.store.find(Travis.User, user.id) user = @app.store.find(Travis.User, user.id)
user.get('permissions') user.get('permissions')
user user
storeAfterSignInPath: (path) -> storeAfterSignInPath: (path) ->
sessionStorage.setItem('travis.after_signin_path', path) Travis.sessionStorage.setItem('travis.after_signin_path', path)
readAfterSignInPath: -> readAfterSignInPath: ->
path = sessionStorage.getItem('travis.after_signin_path') path = Travis.sessionStorage.getItem('travis.after_signin_path')
sessionStorage.removeItem('travis.after_signin_path') Travis.sessionStorage.removeItem('travis.after_signin_path')
path path
receiveMessage: (event) -> receiveMessage: (event) ->

View File

@ -12,11 +12,15 @@ require 'travis/model'
setSeen: -> setSeen: ->
Travis.Broadcast.seen.pushObject(@get('id')) 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') @notifyPropertyChange('isSeen')
@Travis.Broadcast.reopenClass @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 # TODO fix or monkey-patch the adapter's url and key lookup/generation crap
# url: 'users/broadcasts' # url: 'users/broadcasts'

View File

@ -71,6 +71,6 @@ require 'travis/model'
setWithSession: (name, value) -> setWithSession: (name, value) ->
@set(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) 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 = -> @Travis.Slider = ->
@minimize() if localStorage?.getItem('travis.maximized') == 'true' @minimize() if Travis.storage.getItem('travis.maximized') == 'true'
this this
$.extend Travis.Slider.prototype, $.extend Travis.Slider.prototype,
persist: -> persist: ->
localStorage?.setItem('travis.maximized', @isMinimized()) Travis.storage.setItem('travis.maximized', @isMinimized())
isMinimized: -> isMinimized: ->
return $('body').hasClass('maximized'); return $('body').hasClass('maximized');

View File

@ -15,7 +15,7 @@ jQuery.support.cors = true
endpoint = Travis.config.api_endpoint || '' endpoint = Travis.config.api_endpoint || ''
options = options || {} options = options || {}
if token = sessionStorage.getItem('travis.token') if token = Travis.sessionStorage.getItem('travis.token')
options.headers ||= {} options.headers ||= {}
options.headers['Authorization'] ||= "token #{token}" options.headers['Authorization'] ||= "token #{token}"

View File

@ -13,6 +13,22 @@ if window.history.state == undefined
window.history.state = state window.history.state = state
oldReplaceState.apply this, arguments 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, @Travis = Em.Namespace.create Ember.Evented,
config: config:
api_endpoint: $('meta[rel="travis.api_endpoint"]').attr('href') api_endpoint: $('meta[rel="travis.api_endpoint"]').attr('href')
@ -48,16 +64,39 @@ if window.history.state == undefined
setLocale: (locale) -> setLocale: (locale) ->
return unless locale return unless locale
I18n.locale = locale I18n.locale = locale
localStorage.setItem('travis.locale', locale) @storage.setItem('travis.locale', locale)
needsLocaleChange: (locale) -> needsLocaleChange: (locale) ->
I18n.locale != 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) -> run: (attrs) ->
location.href = location.href.replace('#!/', '') if location.hash.slice(0, 2) == '#!' location.href = location.href.replace('#!/', '') if location.hash.slice(0, 2) == '#!'
I18n.fallbacks = true I18n.fallbacks = true
@setLocale localStorage.getItem('travis.locale') || 'en' @setLocale @storage.getItem('travis.locale') || 'en'
Ember.run.next this, -> Ember.run.next this, ->
app = Travis.App.create(attrs || {}) app = Travis.App.create(attrs || {})