Fixed refresh token.
This fix corrects two things. Firstly, it corrects a bug in scheduleRefresh where the current scheduled token id was being compared against a function, resulting in a permanent false. Secondly, it adds promise-checking to tryRefresh, so that the system will never issue more than one token refresh request at a time. This should address intermittent logout issues in storyboard. Change-Id: Ie929b061ab1389c21e9c1bfdf4d580b85a778832
This commit is contained in:
@@ -1,71 +1,76 @@
|
||||
angular.module('sb.auth').service('RefreshManager',
|
||||
function($q, $log, $timeout, preExpireDelta, AccessToken, OpenId) {
|
||||
function ($q, $log, $timeout, preExpireDelta, AccessToken, OpenId) {
|
||||
'use strict';
|
||||
|
||||
var currentRefresh = null;
|
||||
var nextRefreshPromise = null;
|
||||
var scheduledForToken = null;
|
||||
|
||||
// Try to refresh the expired access_token
|
||||
var tryRefresh = function() {
|
||||
var deferred = $q.defer();
|
||||
var resolved = false;
|
||||
var tryRefresh = function () {
|
||||
|
||||
var refresh_token = AccessToken.getRefreshToken();
|
||||
if (!refresh_token) {
|
||||
$log.info('No refresh token found. Aborting refresh.');
|
||||
deferred.reject();
|
||||
resolved = true;
|
||||
}
|
||||
if (!currentRefresh) {
|
||||
// Create our promise, since we should always return one.
|
||||
currentRefresh = $q.defer();
|
||||
currentRefresh.promise.then(
|
||||
function () {
|
||||
currentRefresh = null;
|
||||
},
|
||||
function () {
|
||||
currentRefresh = null;
|
||||
}
|
||||
);
|
||||
|
||||
if (!resolved && !AccessToken.isExpired() &&
|
||||
!AccessToken.expiresSoon()) {
|
||||
$log.info('No refresh is required for existing access token.');
|
||||
deferred.resolve(true);
|
||||
resolved = true;
|
||||
}
|
||||
var refresh_token = AccessToken.getRefreshToken();
|
||||
var is_expired = AccessToken.isExpired();
|
||||
var expires_soon = AccessToken.expiresSoon();
|
||||
|
||||
if (resolved) {
|
||||
return deferred.promise;
|
||||
}
|
||||
// Do we have a refresh token to try?
|
||||
if (!refresh_token) {
|
||||
$log.info('No refresh token found. Aborting refresh.');
|
||||
currentRefresh.reject();
|
||||
} else if (!is_expired && !expires_soon) {
|
||||
$log.info('No refresh required for current access token.');
|
||||
currentRefresh.resolve(true);
|
||||
} else {
|
||||
|
||||
$log.info('Trying to refresh token');
|
||||
var params = {
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: refresh_token
|
||||
};
|
||||
|
||||
|
||||
OpenId.token(params).then(
|
||||
function(data) {
|
||||
AccessToken.setToken(data);
|
||||
deferred.resolve(true);
|
||||
scheduleRefresh();
|
||||
},
|
||||
function() {
|
||||
AccessToken.clear();
|
||||
deferred.reject();
|
||||
$log.info('Trying to refresh token');
|
||||
OpenId.token({
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: refresh_token
|
||||
}).then(
|
||||
function (data) {
|
||||
AccessToken.setToken(data);
|
||||
currentRefresh.resolve(true);
|
||||
scheduleRefresh();
|
||||
},
|
||||
function () {
|
||||
AccessToken.clear();
|
||||
currentRefresh.reject();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
return currentRefresh.promise;
|
||||
};
|
||||
|
||||
|
||||
var scheduleRefresh = function() {
|
||||
if (!AccessToken.getRefreshToken()) {
|
||||
var scheduleRefresh = function () {
|
||||
if (!AccessToken.getRefreshToken() || AccessToken.isExpired()) {
|
||||
$log.info('Current token does not require deferred refresh.');
|
||||
return;
|
||||
}
|
||||
|
||||
var expiresAt = AccessToken.getIssueDate() +
|
||||
AccessToken.getExpiresIn();
|
||||
|
||||
|
||||
if (!!nextRefreshPromise &&
|
||||
AccessToken.getAccessToken === scheduledForToken) {
|
||||
|
||||
AccessToken.getAccessToken() === scheduledForToken) {
|
||||
|
||||
$log.info('The refresh is already scheduled.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var now = Math.round((new Date()).getTime() / 1000);
|
||||
var delay = (expiresAt - preExpireDelta - now) * 1000;
|
||||
nextRefreshPromise = $timeout(tryRefresh, delay, false);
|
||||
|
||||
Reference in New Issue
Block a user