Commit edb9c257 authored by Robert Knight's avatar Robert Knight

Simplify control flow in `AuthService` using async/await

Make several functions/methods in the service easier to follow by
refactoring promise chains to async/await.
parent e3d67074
......@@ -116,24 +116,6 @@ export class AuthService extends TinyEmitter {
localStorage.setObject(storageKey(), token);
}
/**
* Exchange the refresh token for a new access token and refresh token pair.
*
* @param {string} refreshToken
* @param {RefreshOptions} options
* @return {Promise<TokenInfo>} Promise for the new access token
*/
function refreshAccessToken(refreshToken, options) {
return oauthClient()
.then(client => client.refreshToken(refreshToken))
.then(tokenInfo => {
if (options.persist) {
saveToken(tokenInfo);
}
return tokenInfo;
});
}
/**
* Listen for updated access & refresh tokens saved by other instances of the
* client.
......@@ -149,11 +131,11 @@ export class AuthService extends TinyEmitter {
});
};
function oauthClient() {
const oauthClient = async () => {
if (client) {
return Promise.resolve(client);
return client;
}
return apiRoutes.links().then(links => {
const links = await apiRoutes.links();
client = new OAuthClient({
clientId: settings.oauthClientId,
authorizationEndpoint: links['oauth.authorize'],
......@@ -161,15 +143,30 @@ export class AuthService extends TinyEmitter {
tokenEndpoint: tokenUrl,
});
return client;
});
};
/**
* Exchange the refresh token for a new access token and refresh token pair.
*
* @param {string} refreshToken
* @param {RefreshOptions} options
* @return {Promise<TokenInfo>} Promise for the new access token
*/
const refreshAccessToken = async (refreshToken, options) => {
const client = await oauthClient();
const tokenInfo = await client.refreshToken(refreshToken);
if (options.persist) {
saveToken(tokenInfo);
}
return tokenInfo;
};
/**
* Retrieve an access token for the API.
*
* @return {Promise<string|null>} The API access token or `null` if not logged in.
*/
function tokenGetter() {
const tokenGetter = async () => {
if (!tokenInfoPromise) {
const cfg = serviceConfig(settings);
......@@ -209,9 +206,8 @@ export class AuthService extends TinyEmitter {
}
const origToken = tokenInfoPromise;
const token = await tokenInfoPromise;
return /** @type {Promise<TokenInfo|null>} */ (tokenInfoPromise).then(
token => {
if (!token) {
// No token available. User will need to log in.
return null;
......@@ -252,13 +248,11 @@ export class AuthService extends TinyEmitter {
});
return tokenGetter();
} else {
return token.accessToken;
}
}
);
}
return token.accessToken;
};
/**
* Login to the annotation service using OAuth.
*
......@@ -266,18 +260,15 @@ export class AuthService extends TinyEmitter {
* (if necessary) and then responds with an auth code which the client can
* then exchange for access and refresh tokens.
*/
function login() {
async function login() {
const authWindow = OAuthClient.openAuthPopupWindow($window);
return oauthClient()
.then(client => {
return client.authorize($window, authWindow);
})
.then(code => {
const client = await oauthClient();
const code = await client.authorize($window, authWindow);
// Save the auth code. It will be exchanged for an access token when the
// next API request is made.
authCode = code;
tokenInfoPromise = null;
});
}
/**
......
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