Ember Simple Auth - injecting current user into every route

4.3k Views Asked by At

I am building a site using Ember Simple Auth.

I followed these instructions to try and add the current user object to the session and it worked, using this slightly adapted code:

import Ember from 'ember';
import Session from 'simple-auth/session';

export default {
  name: "current-user",
  before: "simple-auth",
  initialize: function(container) {
    Session.reopen({
      setCurrentUser: function() {
        var accessToken = this.get('secure.token');
        var _this = this;
        if (!Ember.isEmpty(accessToken)) {
          return container.lookup('store:main').find('user', 'me').then(function(user) {
            _this.set('content.currentUser', user);
          });
        }
      }.observes('secure.token'),
      setAccount: function() {
        var _this = this;
        return container.lookup('store:main').find('account', this.get('content.currentUser.account.content.id')).then(function(account) {
          _this.set('content.account', account);
        });
      }.observes('content.currentUser'),
    });
  }
};

However, using the latest version of Ember I'm getting the following:

DEPRECATION: lookup was called on a Registry. The initializer API no longer receives a container, and you should use an instanceInitializer to look up objects from the container. See http://emberjs.com/guides/deprecations#toc_deprecate-access-to-instances-in-initializers for more details.

I know that I need to split the above into /app/initializers and /app/instance-initializers (as per the notes here) but I'm not quite sure how to go about it.

Of course, if there is an easier/cleaner way to make the user and account objects available to every route/template I'd love to hear them :)

Thanks

3

There are 3 best solutions below

5
On BEST ANSWER

This works for me on:

  • ember-cli: 0.2.7 (ember: 1.12.0, ember-data: 1.0.0-beta.18)
  • ember-cli-simple-auth: 0.8.0-beta.3

Note:

  • ember-data: 1.13. Store is registered in an initializer, should work as is
  • ember-data: 1.0.0-beta.19. Store is registered in an instance-initializer, some adjustments needed

1) Customize session

//config/environment.js
ENV['simple-auth'] = {
  session: 'session:custom',
  ...
}

//app/sessions/custom.js
import Session from 'simple-auth/session';

export default Session.extend({

  // here _store is ember-data store injected by initializer
  // why "_store"? because "store" is already used by simple-auth as localStorage
  // why initializer? I tried 
  // _store: Ember.inject.service('store') and got error

  currentUser: function() {
    var userId = this.get('secure.userId');
    if (userId && this.get('isAuthenticated')) {
      return this._store.find('user', userId);
    }
  }.property('secure.userId', 'isAuthenticated')

});

2) Inject store to session by initializer (otherwise find() wouldn't work)

//app/initializers/session-store
export function initialize(container, application) {
  application.inject('session:custom', '_store', 'store:main')

  // "store:main" is highly dynamic depepeding on ember-data version
  // in 1.0.0-beta.19 (June 5, 2015) => "store:application"
  // in 1.13 (June 16, 2015) => "service:store"
}

export default {
  name: 'session-store',
  after: 'ember-data',
  initialize: initialize
}

3) In template

{{#if session.isAuthenticated}}
  {{session.currentUser.name}}
{{/if}}

Note: this does not relieve you from deprecations generated by ember-simple-auth itself.

0
On

Here's a before and after of an initializer/instance-initializer that I did the other day.

Before

export function initialize( container, application ) {
    var session = Ember.Object.create({
        user:null,
        authorization:null
    });

    application.register('session:main', session, { instantiate: false });
    application.inject('route', 'session', 'session:main');
    application.inject('controller', 'session', 'session:main');
    application.inject('adapter', 'session', 'session:main');
}

After

export function initialize( instance) {
    var session = Ember.Object.create({
        user:null,
        authorization:null
    });

    instance.registry.register('session:main', session, { instantiate: false });
    instance.registry.injection('route', 'session', 'session:main');
    instance.registry.injection('controller', 'session', 'session:main');
    instance.registry.injection('adapter', 'session', 'session:main');
}

Ember Data Stuff

Ember Data in the latest iterations should be fetched using store:application

export function initialize(instance) {
    var store = instance.container.lookup('store:application');
    ....
}

export default {
    name: 'socket',
    initialize: initialize,
    after:['ember-data']
};
4
On

First of all you shouldn't reopen the session but use a custom session instead (see this example: https://github.com/simplabs/ember-simple-auth/blob/master/examples/4-authenticated-account.html#L132). Also you you shouldn't only load the current user when the access token is set but when the session is authenticated ('session.get('isAuthenticated')') which makes your code not dependent on the authenticator.

The deprecation warnings regarding the use of the registry in the initializer will go away in ESA 0.9.0 hopefully.