1

My authenticators/custom.js:

import Ember from 'ember';
import Base from 'simple-auth/authenticators/base';

export default Base.extend({
  restore: function(data) {

  },
  authenticate: function(email, password, authenticateCallback) {
    return new Ember.RSVP.Promise((resolve, reject) => {
      Ember.$.ajax({
        type: 'POST',
        url: apiOrigin + '/api/v1/login',
        data: {
          email: email,
          password: password
        },
        dataType: 'json'
      }).then(function(userData){
        console.log('login post success', userData)
        authenticateCallback(userData)
        Ember.run(function() {
          resolve(userData.uuid)
        })
      })['catch'](function(main){
        alert('login error ' + JSON.stringify(main))
        console.error('\'caught\' error from login post request', arguments);
      })
    })
  },
  invalidate: function(data) {

  }
});

And login/controller.js:

import Ember from 'ember';

export default Ember.Controller.extend({
  session: Ember.inject.service('session'),
  application: Ember.inject.controller(),
  actions: {
    authenticate() {
      let { identification, password } = this.getProperties('identification', 'password');
      this.get('session').authenticate('authenticator:custom', identification, password, (userData) => {
        //TODO set these properties on ember-simple-auth's session object instead of application controller
        this.get('application').setProperties(userData)
        this.transitionToRoute('associate-device')
      }).catch((reason) => {
        this.set('errorMessage', reason.error);
      })
    }
  }
});

My associate-device route is an AuthenticatedRoute.. I don't get an error, but instead, the last thing printed to the console is "Preparing to transition from 'login' to 'associate-device'"

Basically, ember simple auth documents here http://ember-simple-auth.com/api/classes/BaseAuthenticator.html#method_authenticate that "A resolving promise will result in the session becoming authenticated. Any data the promise resolves with will be saved in and accessible via the session service's data.authenticated property (see data). A rejecting promise indicates that authentication failed and will result in the session remaining unauthenticated." However, my session does not seem to be authenticated after I successfully resolve my promise.

Devin Rhode
  • 23,026
  • 8
  • 58
  • 72
  • looks correct so far, you should implement the authenticator's `restore` method as well though to make sure the problem isn't related to it not being implemented. – marcoow Nov 12 '15 at 13:28
  • Searched the source for "theAuthenticator.authenticate.apply(theAuthenticator" and now fiddling with the massive assets/dist/vendor.js, and I see that for some reason the .then callback on line 21 is not getting called.. https://github.com/simplabs/ember-simple-auth/blob/52c3ede0762fcf46412e0bb0a2d7cbfdd6cfbb45/addon/internal-session.js#L21 – Devin Rhode Nov 12 '15 at 16:45
  • Put this in the restore method and it's actually not getting called: alert('restore'); return new Ember.RSVP.Promise((resolve, reject) => { resolve('foo') }) – Devin Rhode Nov 12 '15 at 16:52
  • But I removed my promise wrapper, and am returning my ajax promise instead, and that's working. I guess I don't know how to use promises? – Devin Rhode Nov 12 '15 at 16:58
  • So actually my authenticators reject callback is being called somehow. theAuthenticators.authenticate(.....).then(*resolve function*, *reject callback is being called* Maybe the error has to do with some missing config? – Devin Rhode Nov 12 '15 at 17:47

1 Answers1

0

$.ajax has no catch method. This exception was hidden because I was copy-pasting away from the documentation for writing custom authenticators. To expose any exceptions occurring in your custom authenticators authenticate method, you should probably console.log them like so:

// app/controllers/login.js
import Ember from 'ember';

export default Ember.Controller.extend({
  session: Ember.inject.service('session'),

  actions: {
    authenticate() {
      let { identification, password } = this.getProperties('identification', 'password');
      this.get('session').authenticate('authenticator:oauth2', identification, password).catch((reason) => {
        // **CHANGE THE BELOW LINE**
        console.error('exception in your authenticators authenticate method', reason)
      });
    }
  }
});
Devin Rhode
  • 23,026
  • 8
  • 58
  • 72
  • 1
    `Session.authenticate` returning a rejecting promise doesn't mean that there was an exception in your authenticator. It might also mean that the authenticator rejects authentication because the credentials were invalid. – marcoow Nov 13 '15 at 09:16
  • Perhaps RSVP.js should be changed to send exceptions to window.onerror, or at least handle actual programmer errors differently..? – Devin Rhode Nov 14 '15 at 00:59
  • ember simple auth does theAuthenticator.authenticate.apply(theAuthenticator, args).then(...success function..., ...reject function...). The authenticate method returns a promise, and RSVP invokes the supplied function for the promise. The function supplied to RSVP creates an exception, so then RSVP decides to call the reject function. Based in this thread: https://github.com/tildeio/rsvp.js/issues/196 I think there's a way I can log these types of errors.. – Devin Rhode Nov 14 '15 at 01:11