Commit cf7c778b authored by Robert Knight's avatar Robert Knight

Make access token expiry check more reliable

 * Start the clock just _before_ the access token exchange
   occurs, otherwise the client will incorrectly add the delay between
   the server sending the token and the client receiving it to the
   expiry timestamp.

 * Use performance.now() instead of Date.now() so that expiry checks
   are not affected by system clock changes.

   performance.now() is supported on IE >= 10 and all modern browsers.
parent eec82fc7
......@@ -41,13 +41,16 @@ function auth($http, settings) {
}
function tokenGetter() {
if (cachedToken && cachedToken.expiresAt > Date.now()) {
// performance.now() is used instead of Date.now() because it is
// monotonically increasing.
if (cachedToken && cachedToken.expiresAt > performance.now()) {
return Promise.resolve(cachedToken.token);
} else if (grantToken) {
var refreshStart = performance.now();
return exchangeToken(grantToken).then(function (tokenInfo) {
cachedToken = {
token: tokenInfo.access_token,
expiresAt: Date.now() + tokenInfo.expires_in * 1000,
expiresAt: refreshStart + tokenInfo.expires_in * 1000,
};
return cachedToken.token;
});
......
......@@ -7,12 +7,13 @@ var DEFAULT_TOKEN_EXPIRES_IN_SECS = 1000;
describe('oauth auth', function () {
var auth;
var clock;
var nowStub;
var fakeHttp;
var fakeSettings;
beforeEach(function () {
clock = sinon.useFakeTimers();
nowStub = sinon.stub(window.performance, 'now');
nowStub.returns(300);
fakeHttp = {
post: sinon.stub().returns(Promise.resolve({
......@@ -36,7 +37,7 @@ describe('oauth auth', function () {
});
afterEach(function () {
clock.restore();
performance.now.restore();
});
describe('#tokenGetter', function () {
......@@ -74,7 +75,8 @@ describe('oauth auth', function () {
it('should refresh the access token if it has expired', function () {
return auth.tokenGetter().then(function () {
clock.tick(DEFAULT_TOKEN_EXPIRES_IN_SECS * 1000 + 100);
var now = performance.now();
nowStub.returns(now + DEFAULT_TOKEN_EXPIRES_IN_SECS * 1000 + 100);
fakeHttp.post.returns(Promise.resolve({
status: 200,
data: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment