From 1fd843a4248ffccbfc29f854a3b8cc4d21d9b899 Mon Sep 17 00:00:00 2001 From: Marco Otte-Witte Date: Mon, 7 Apr 2014 16:37:36 +0200 Subject: [PATCH] refresh access token on restore if expired, closes #102 --- .../authenticators/oauth2.js | 10 ++- .../tests/authenticators/oauth2_test.js | 82 +++++++++++-------- 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/packages/ember-simple-auth-oauth2/lib/ember-simple-auth-oauth2/authenticators/oauth2.js b/packages/ember-simple-auth-oauth2/lib/ember-simple-auth-oauth2/authenticators/oauth2.js index fd9eedaf9..de00c0066 100644 --- a/packages/ember-simple-auth-oauth2/lib/ember-simple-auth-oauth2/authenticators/oauth2.js +++ b/packages/ember-simple-auth-oauth2/lib/ember-simple-auth-oauth2/authenticators/oauth2.js @@ -62,7 +62,13 @@ var OAuth2 = Ember.SimpleAuth.Authenticators.Base.extend({ if (!Ember.isEmpty(data.access_token)) { var now = (new Date()).getTime(); if (!Ember.isEmpty(data.expires_at) && data.expires_at < now) { - reject(); + if (_this.refreshAccessTokens) { + _this.refreshAccessToken(data.expires_in, data.refresh_token).then(function(data) { + resolve(data); + }, reject); + } else { + reject(); + } } else { _this.scheduleAccessTokenRefresh(data.expires_in, data.expires_at, data.refresh_token); resolve(data); @@ -186,7 +192,7 @@ var OAuth2 = Ember.SimpleAuth.Authenticators.Base.extend({ var data = Ember.$.extend(response, { expires_in: expiresIn, expires_at: expiresAt, refresh_token: refreshToken }); _this.scheduleAccessTokenRefresh(expiresIn, null, refreshToken); _this.trigger('updated', data); - resolve(); + resolve(data); }); }, function(xhr, status, error) { Ember.Logger.warn('Access token could not be refreshed - server responded with ' + error + '.'); diff --git a/packages/ember-simple-auth-oauth2/tests/authenticators/oauth2_test.js b/packages/ember-simple-auth-oauth2/tests/authenticators/oauth2_test.js index beeabfaf3..1e9ae8891 100644 --- a/packages/ember-simple-auth-oauth2/tests/authenticators/oauth2_test.js +++ b/packages/ember-simple-auth-oauth2/tests/authenticators/oauth2_test.js @@ -2,7 +2,11 @@ import { OAuth2 } from 'ember-simple-auth-oauth2/authenticators/oauth2'; describe('OAuth2', function() { beforeEach(function() { - this.authenticator = OAuth2.create(); + this.authenticator = OAuth2.create(); + this.xhr = sinon.useFakeXMLHttpRequest(); + this.server = sinon.fakeServer.create(); + this.server.autoRespond = true; + sinon.spy(Ember.$, 'ajax'); }); describe('#restore', function() { @@ -23,10 +27,46 @@ describe('OAuth2', function() { }); describe('when the data includes an expiration time in the past', function() { - it('returns a rejecting promise', function(done) { - this.authenticator.restore({ access_token: 'secret token!', expires_at: 1 }).then(null, function() { - expect(true).to.be.true; - done(); + describe('when automatic token refreshing is enabled', function() { + describe('when the refresh request is successful', function() { + beforeEach(function() { + this.server.respondWith('POST', '/token', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "access_token": "secret token 2!", "expires_in": 67890, "refresh_token": "refresh token 2!" }' + ]); + }); + + it('resolves with the correct data', function(done) { + this.authenticator.restore({ access_token: 'secret token!', expires_at: 1 }).then(function(data) { + expect(data.expires_at).to.be.greaterThan(new Date().getTime()); + delete data.expires_at; + expect(data).to.eql({ access_token: 'secret token 2!', expires_in: 67890, refresh_token: 'refresh token 2!' }); + done(); + }); + }); + }); + + describe('when the access token is not refreshed successfully', function() { + it('returns a rejecting promise', function(done) { + this.authenticator.restore({ access_token: 'secret token!', expires_at: 1 }).then(null, function() { + expect(true).to.be.true; + done(); + }); + }); + }); + }); + + describe('when automatic token refreshing is disabled', function() { + beforeEach(function() { + this.authenticator.set('refreshAccessTokens', false); + }); + + it('returns a rejecting promise', function(done) { + this.authenticator.restore({ access_token: 'secret token!', expires_at: 1 }).then(null, function() { + expect(true).to.be.true; + done(); + }); }); }); }); @@ -87,13 +127,6 @@ describe('OAuth2', function() { }); describe('#authenticate', function() { - beforeEach(function() { - this.xhr = sinon.useFakeXMLHttpRequest(); - this.server = sinon.fakeServer.create(); - this.server.autoRespond = true; - sinon.spy(Ember.$, 'ajax'); - }); - it('sends an AJAX request to the token endpoint', function(done) { this.authenticator.authenticate({ identification: 'username', password: 'password' }); @@ -141,9 +174,6 @@ describe('OAuth2', function() { delete data.expires_at; expect(data).to.eql({ access_token: 'secret token!', expires_in: 12345, refresh_token: 'refresh token!' }); done(); - }, function() { - expect(true).to.be.false; - done(); }); }); @@ -208,11 +238,6 @@ describe('OAuth2', function() { }); }); }); - - afterEach(function() { - this.xhr.restore(); - Ember.$.ajax.restore(); - }); }); describe('#invalidate', function() { @@ -226,13 +251,6 @@ describe('OAuth2', function() { // testing private API here ;( describe('#refreshAccessToken', function() { - beforeEach(function() { - this.xhr = sinon.useFakeXMLHttpRequest(); - this.server = sinon.fakeServer.create(); - this.server.autoRespond = true; - sinon.spy(Ember.$, 'ajax'); - }); - it('sends an AJAX request to the token endpoint', function(done) { this.authenticator.refreshAccessToken(12345, 'refresh token!'); @@ -248,7 +266,7 @@ describe('OAuth2', function() { }); }); - describe('when the authentication request is successful', function() { + describe('when the refresh request is successful', function() { beforeEach(function() { this.server.respondWith('POST', '/token', [ 200, @@ -293,10 +311,10 @@ describe('OAuth2', function() { }); }); }); + }); - afterEach(function() { - this.xhr.restore(); - Ember.$.ajax.restore(); - }); + afterEach(function() { + this.xhr.restore(); + Ember.$.ajax.restore(); }); });