diff --git a/addon/authenticators/jwt.js b/addon/authenticators/jwt.js index a830c27..286f6e2 100644 --- a/addon/authenticators/jwt.js +++ b/addon/authenticators/jwt.js @@ -65,6 +65,7 @@ export default TokenAuthenticator.extend({ this.refreshAccessTokens = Configuration.refreshAccessTokens; this.tokenExpireName = Configuration.tokenExpireName; this.timeFactor = Configuration.timeFactor; + this.headers = Configuration.headers; }, /** @@ -81,12 +82,13 @@ export default TokenAuthenticator.extend({ restore: function(data){ var _this = this; return new Ember.RSVP.Promise(function(resolve, reject){ - var now = (new Date()).getTime(); - if(!Ember.isEmpty(data.expiresAt) && !Ember.isEmpty(data.token) && data.expiresAt < now){ + var now = (new Date()).getTime(), + expiresAt = _this.resolveTime(data.expiresAt); + if(!Ember.isEmpty(data.expiresAt) && !Ember.isEmpty(data.token) && data.expiresAt > now){ if(_this.refreshAccessTokens){ _this.refreshAccessToken(data.token).then(function(data){ resolve(data); - }, reject()); + }, reject); }else{ reject(); } @@ -95,8 +97,8 @@ export default TokenAuthenticator.extend({ reject(); }else{ var tokenData = _this.getTokenData({'token': data.token}), - tokenExpiresAt = tokenData[_this.tokenExpireName], - expiresAt = _this.resolveTime(tokenExpiresAt); + tokenExpiresAt = tokenData[_this.tokenExpireName]; + expiresAt = _this.resolveTime(tokenExpiresAt); _this.scheduleAccessTokenRefresh(expiresAt, data.token); resolve(data); } @@ -168,7 +170,7 @@ export default TokenAuthenticator.extend({ Ember.run(function() { var tokenData = _this.getTokenData(response), expiresAt = tokenData[_this.tokenExpireName], - data = Ember.merge(response, {expiresAt: expiresAt}); + data = Ember.merge(response, {expiresAt: expiresAt, token: response.token}); _this.scheduleAccessTokenRefresh(expiresAt, response.token); _this.trigger('sessionDataUpdated', data); resolve(response); @@ -211,7 +213,8 @@ export default TokenAuthenticator.extend({ contentType: 'application/json', beforeSend: function(xhr, settings) { xhr.setRequestHeader('Accept', settings.accepts.json); - } + }, + headers: this.headers }); }, diff --git a/tests/unit/authenticators/jwt-test.js b/tests/unit/authenticators/jwt-test.js index db0c37c..9021797 100644 --- a/tests/unit/authenticators/jwt-test.js +++ b/tests/unit/authenticators/jwt-test.js @@ -56,7 +56,7 @@ test('assigns timeFactor from the configuration object', function() { test('#restore resolves when the data includes `token` and `expiresAt`', function() { var jwt = JWT.create(), - expiresAt = (new Date()).getTime() - 60000; + expiresAt = (new Date()).getTime() + 60000; var token = {}; token[jwt.identificationField] = 'test@test.com'; @@ -78,6 +78,7 @@ test('#restore resolves when the data includes `token` and `expiresAt`', functio Ember.run(function(){ App.authenticator.restore(data).then(function(content){ + // Check that the resolved data matches the init data. deepEqual(content, data); }); }); @@ -85,7 +86,7 @@ test('#restore resolves when the data includes `token` and `expiresAt`', functio test('#restore resolves when the data includes `token` and excludes `expiresAt`', function() { var jwt = JWT.create(), - expiresAt = (new Date()).getTime() - 60000; + expiresAt = (new Date()).getTime() + 60000; var token = {}; token[jwt.identificationField] = 'test@test.com'; @@ -106,6 +107,7 @@ test('#restore resolves when the data includes `token` and excludes `expiresAt`' Ember.run(function(){ App.authenticator.restore(data).then(function(content){ + // Check that the resolved data matches the init data. deepEqual(content, data); }); }); @@ -113,7 +115,7 @@ test('#restore resolves when the data includes `token` and excludes `expiresAt`' test('#restore rejects when `refreshAccessTokens` is false', function() { var jwt = JWT.create(), - expiresAt = (new Date()).getTime() - 60000; + expiresAt = (new Date()).getTime() + 60000; var token = {}; token[jwt.identificationField] = 'test@test.com'; @@ -137,14 +139,15 @@ test('#restore rejects when `refreshAccessTokens` is false', function() { Ember.run(function(){ App.authenticator.restore(data).then(null, function(){ - ok(true, 'If we are there then the promise was rejected.'); + // Check that Ember.run.later was not called. + deepEqual(Ember.run.later.getCall(0), null); }); }); }); test('#restore rejects when `token` is excluded.', function() { var jwt = JWT.create(), - expiresAt = (new Date()).getTime() - 60000; + expiresAt = (new Date()).getTime() + 60000; var token = {}; token[jwt.identificationField] = 'test@test.com'; @@ -167,7 +170,8 @@ test('#restore rejects when `token` is excluded.', function() { Ember.run(function(){ App.authenticator.restore(data).then(null, function(){ - ok(true, 'If we are there then the promise was rejected.'); + // Check that Ember.run.later was not called. + deepEqual(Ember.run.later.getCall(0), null); }); }); }); @@ -198,7 +202,8 @@ test('#restore resolves when `expiresAt` is greater than `now`', function() { Ember.run(function(){ App.authenticator.restore(data).then(function(content){ - deepEqual(content, data); + // Check that Ember.run.later was not called. + deepEqual(Ember.run.later.getCall(0), null); }); }); }); @@ -222,6 +227,7 @@ test('#restore schedules a token refresh when `refreshAccessTokens` is true.', f Ember.run(function(){ App.authenticator.restore(data).then(function(content){ + // Check that Ember.run.later ran. var spyCall = Ember.run.later.getCall(0); deepEqual(spyCall.args[1], App.authenticator.refreshAccessToken); deepEqual(spyCall.args[2], token); @@ -247,12 +253,35 @@ test('#restore does not schedule a token refresh when `refreshAccessTokens` is f Ember.run(function(){ App.authenticator.restore(data).then(function(content){ + // Check that Ember.run.later ran. var spyCall = Ember.run.later.getCall(0); deepEqual(spyCall, null); }); }); }); +test('#restore does not schedule a token refresh when `expiresAt` < now.', function() { + var jwt = JWT.create(), + expiresAt = (new Date()).getTime() + 60000; + + var token = {}; + token[jwt.identificationField] = 'test@test.com'; + token[jwt.tokenExpireName] = expiresAt; + + token = window.btoa(JSON.stringify(token)); + + var data = {}; + data[jwt.tokenPropertyName] = token; + data[jwt.tokenExpireName] = expiresAt; + + Ember.run(function(){ + App.authenticator.restore(data).then(function(){ + // Check that Ember.run.later was not called. + deepEqual(Ember.run.later.getCall(0), null); + }); + }); +}); + test('#authenticate sends an ajax request to the token endpoint', function() { sinon.spy(Ember.$, 'ajax'); @@ -274,6 +303,7 @@ test('#authenticate sends an ajax request to the token endpoint', function() { data: '{"password":"password","username":"username"}', dataType: 'json', contentType: 'application/json', + headers: {} }); Ember.$.ajax.restore(); }); @@ -306,8 +336,9 @@ test('#authenticate rejects with invalid credentials', function() { Ember.testing = false; Ember.run(function(){ - App.authenticator.authenticate(credentials).then(null, function(err){ - ok(true, 'Exited with: ' + err.message); + App.authenticator.authenticate(credentials).then(null, function(){ + // Check that Ember.run.later was not called. + deepEqual(Ember.run.later.getCall(0), null); }); }); }); @@ -377,6 +408,7 @@ test('#authenticate does not schedule a token refresh when `refreshAccessTokens` Ember.run(function(){ App.authenticator.authenticate(credentials).then(function(content){ + // Check that Ember.run.later ran. var spyCall = Ember.run.later.getCall(0); deepEqual(spyCall, null); }); @@ -406,6 +438,7 @@ test('#refreshAccessToken makes an AJAX request to the token endpoint.', functio data: JSON.stringify({'token': token}), dataType: 'json', contentType: 'application/json', + headers: {} }); Ember.$.ajax.restore(); });