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) {
});
}
/**
* 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.
*
......@@ -357,6 +371,8 @@ function auth($http, $window, flash, localStorage, random, settings) {
});
}
listenForTokenStorageEvents();
return {
clearCache,
login,
......
......@@ -31,18 +31,22 @@ class FakeWindow {
removeEventListener(event, callback) {
this.callbacks = this.callbacks.filter((cb) =>
cb.event === event && cb.callback === callback
!(cb.event === event && cb.callback === callback)
);
}
sendMessage(data) {
var evt = new MessageEvent('message', { data });
this.callbacks.forEach(({event, callback}) => {
if (event === 'message') {
callback(evt);
trigger(event) {
this.callbacks.forEach((cb) => {
if (cb.event === event.type) {
cb.callback(event);
}
});
}
sendMessage(data) {
var evt = new MessageEvent('message', { data });
this.trigger(evt);
}
}
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', () => {
......
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