Commit 96b397ec authored by Robert Knight's avatar Robert Knight

Use correct request params when exchanging auth code for tokens

Since the h service now supports authorization codes rather than faking
them with JWT grant tokens, use the appropriate request parameters in
the call to exchange the auth code for tokens.
parent 19505853
......@@ -141,11 +141,8 @@ function auth($http, $window, flash, localStorage, random, settings) {
// Exchange the JWT grant token for an access token.
// See https://tools.ietf.org/html/rfc7523#section-4
function exchangeToken(grantToken) {
function exchangeJWT(grantToken) {
var data = {
// FIXME: This should be set to the appropriate grant type if we are
// exchanging an authorization code for a grant token, which
// is the case for first-party accounts.
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: grantToken,
};
......@@ -157,6 +154,24 @@ function auth($http, $window, flash, localStorage, random, settings) {
});
}
/**
* Exchange an authorization code from the `/oauth/authorize` endpoint for
* access and refresh tokens.
*/
function exchangeAuthCode(code) {
var data = {
client_id: settings.oauthClientId,
grant_type: 'authorization_code',
code,
};
return postToTokenUrl(data).then((response) => {
if (response.status !== 200) {
throw new Error('Authorization code exchange failed');
}
return tokenInfoFrom(response);
});
}
/**
* Exchange the refresh token for a new access token and refresh token pair.
* See https://tools.ietf.org/html/rfc6749#section-6
......@@ -226,7 +241,7 @@ function auth($http, $window, flash, localStorage, random, settings) {
if (grantToken) {
// Exchange host-page provided grant token for a new access token.
accessTokenPromise = exchangeToken(grantToken).then(function (tokenInfo) {
accessTokenPromise = exchangeJWT(grantToken).then((tokenInfo) => {
refreshAccessTokenBeforeItExpires(tokenInfo, { persist: false });
return tokenInfo.accessToken;
}).catch(function(err) {
......@@ -237,7 +252,7 @@ function auth($http, $window, flash, localStorage, random, settings) {
} else if (authCode) {
// Exchange authorization code retrieved from login popup for a new
// access token.
accessTokenPromise = exchangeToken(authCode).then((tokenInfo) => {
accessTokenPromise = exchangeAuthCode(authCode).then((tokenInfo) => {
saveToken(tokenInfo);
refreshAccessTokenBeforeItExpires(tokenInfo, { persist: true });
return tokenInfo.accessToken;
......
......@@ -506,8 +506,9 @@ describe('sidebar.oauth-auth', function () {
}).then(() => {
// 2. Verify that auth code is exchanged for access & refresh tokens.
var expectedBody =
'assertion=acode' +
'&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer';
'client_id=the-client-id' +
'&code=acode' +
'&grant_type=authorization_code';
assert.calledWith(fakeHttp.post, 'https://hypothes.is/api/token', expectedBody, {
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
});
......
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