Ember-simple-auth: `Ember.set` on session `data` does not update the LocalStorage (but `session.set` works)

Created on 9 Mar 2016  路  6Comments  路  Source: simplabs/ember-simple-auth

This works and _does_ update the LocalStorage:

session.set('data.with-session-set', true);

But this _does not_ update the LocalStorage:

Ember.set(session, 'data.with-ember-set', true);

If you do session.set after an Ember.set both values will be written.

This is unexpected and undocumented behaviour.

Here is minimal git Project demonstrating the Problem.

bug

Most helpful comment

I believe we might still be seeing this issue (Ember 2.7.2 / ESA 1.1.0)? We're using devise-token-auth on the backend and need to update the client's token after each response from the server.

Doesn't work

handleResponse(status, headers) {
  ...
  this.get('session').set('data.authenticated.access-token', headers['Access-Token']);
  this.get('session').set('data.authenticated.expiry', headers['Expiry']);
  ...
}

Works

handleResponse(status, headers) {
  ...
  this.get('session').set('data.authenticated.access-token', headers['Access-Token']);
  this.get('session').set('data.authenticated.expiry', headers['Expiry']);
  this.get('session').set('data.foo', 'bar'); //Hack
  ...
}

Also Works

handleResponse(status, headers) {
  ...
  var new_session = this.get('session.data');
  new_session["authenticated"]["access-token"] = headers['Access-Token'];
  new_session["authenticated"]["expiry"] = headers['Expiry'];
  this.get('session.store').persist(new_session);
  ...
}

I found my way here via #946 and #375

All 6 comments

This is a known bug which I hope to fix in 1.2.

I'm starting to dive into this.

I have tested this on multiple versions of Ember and different scenarios, as well as written a test for it and it seems to be fixed.

I believe we might still be seeing this issue (Ember 2.7.2 / ESA 1.1.0)? We're using devise-token-auth on the backend and need to update the client's token after each response from the server.

Doesn't work

handleResponse(status, headers) {
  ...
  this.get('session').set('data.authenticated.access-token', headers['Access-Token']);
  this.get('session').set('data.authenticated.expiry', headers['Expiry']);
  ...
}

Works

handleResponse(status, headers) {
  ...
  this.get('session').set('data.authenticated.access-token', headers['Access-Token']);
  this.get('session').set('data.authenticated.expiry', headers['Expiry']);
  this.get('session').set('data.foo', 'bar'); //Hack
  ...
}

Also Works

handleResponse(status, headers) {
  ...
  var new_session = this.get('session.data');
  new_session["authenticated"]["access-token"] = headers['Access-Token'];
  new_session["authenticated"]["expiry"] = headers['Expiry'];
  this.get('session.store').persist(new_session);
  ...
}

I found my way here via #946 and #375

@steveclarkin Thank you for the hack.

I took sometime and looked into it, the reason this hack works as following

Since internal-session itself is ObjectProxy[Link] (https://www.emberjs.com/api/ember/2.14.1/classes/Ember.ObjectProxy) object.

this.get('session').set('data.foo', 'bar'), it update content to content.data.foo = bar .
Will trigger setUnknownProperty(in internal-session) and cause content object to update.

Then setUnknownProperty will call _updateStore(), which calls _callStoreAsync('persist', data)

persist calls adaptive.js 's persist, which eventually calls local-storage.js 's persist to update browser's _localStorage_ to store the latestcontent`.

I definitely like

  var new_session = this.get('session.data');
  new_session["authenticated"]["access-token"] = headers['Access-Token'];
  new_session["authenticated"]["expiry"] = headers['Expiry'];
  this.get('session.store').persist(new_session);

better, wondering if there's a better way than calling persist explicitly.

BTW, in _ember-simple-auth 1.3_ data object became oneway in internal-session so, we need to change above code to

    this.set('session.content.authenticated.user.activated', true);
    let newSession = this.get('session.content');
    this.get('session.store').persist(newSession);

yes, this is the same as #805 - we'll track everything there

Was this page helpful?
0 / 5 - 0 ratings