Commit a23437ec authored by Robert Knight's avatar Robert Knight

Reload tokens when another client refreshes them.

Listen for "storage" events that are emitted when another client
refreshes access/refresh tokens and reload them when that occurs.
parent 28bdb52f
...@@ -204,6 +204,20 @@ function auth($http, $window, flash, localStorage, random, settings) { ...@@ -204,6 +204,20 @@ function auth($http, $window, flash, localStorage, random, settings) {
}); });
} }
/**
* Listen for updated access & refresh tokens saved by other instances of the
* client.
*/
function listenForTokenStorageEvents() {
$window.addEventListener('storage', ({ key }) => {
if (key === storageKey()) {
// Reset cached token information. Tokens will be reloaded from storage
// on the next call to `tokenGetter()`.
tokenInfoPromise = null;
}
});
}
/** /**
* Retrieve an access token for the API. * Retrieve an access token for the API.
* *
...@@ -357,6 +371,8 @@ function auth($http, $window, flash, localStorage, random, settings) { ...@@ -357,6 +371,8 @@ function auth($http, $window, flash, localStorage, random, settings) {
}); });
} }
listenForTokenStorageEvents();
return { return {
clearCache, clearCache,
login, login,
......
...@@ -31,18 +31,22 @@ class FakeWindow { ...@@ -31,18 +31,22 @@ class FakeWindow {
removeEventListener(event, callback) { removeEventListener(event, callback) {
this.callbacks = this.callbacks.filter((cb) => this.callbacks = this.callbacks.filter((cb) =>
cb.event === event && cb.callback === callback !(cb.event === event && cb.callback === callback)
); );
} }
sendMessage(data) { trigger(event) {
var evt = new MessageEvent('message', { data }); this.callbacks.forEach((cb) => {
this.callbacks.forEach(({event, callback}) => { if (cb.event === event.type) {
if (event === 'message') { cb.callback(event);
callback(evt);
} }
}); });
} }
sendMessage(data) {
var evt = new MessageEvent('message', { data });
this.trigger(evt);
}
} }
describe('sidebar.oauth-auth', function () { describe('sidebar.oauth-auth', function () {
...@@ -440,6 +444,30 @@ describe('sidebar.oauth-auth', function () { ...@@ -440,6 +444,30 @@ describe('sidebar.oauth-auth', function () {
}); });
}); });
}); });
it('reloads tokens when refreshed by another client instance', () => {
return login().then(() => {
return auth.tokenGetter();
}).then(token => {
assert.equal(token, 'firstAccessToken');
// Trigger "storage" event as if another client refreshed the token.
var storageEvent = new Event('storage');
storageEvent.key = TOKEN_KEY;
fakeLocalStorage.getObject.returns({
accessToken: 'storedAccessToken',
refreshToken: 'storedRefreshToken',
expiresAt: Date.now() + 100,
});
fakeWindow.trigger(storageEvent);
return auth.tokenGetter();
}).then(token => {
assert.equal(token, 'storedAccessToken');
});
});
}); });
describe('#login', () => { describe('#login', () => {
......
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