Search code examples
ember.jsdependency-injectionember-simple-auth

Ember Simple Auth - injecting current user into every route


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


Solution

  • 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.