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) { ...@@ -141,11 +141,8 @@ function auth($http, $window, flash, localStorage, random, settings) {
// Exchange the JWT grant token for an access token. // Exchange the JWT grant token for an access token.
// See https://tools.ietf.org/html/rfc7523#section-4 // See https://tools.ietf.org/html/rfc7523#section-4
function exchangeToken(grantToken) { function exchangeJWT(grantToken) {
var data = { 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', grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: grantToken, assertion: grantToken,
}; };
...@@ -157,6 +154,24 @@ function auth($http, $window, flash, localStorage, random, settings) { ...@@ -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. * Exchange the refresh token for a new access token and refresh token pair.
* See https://tools.ietf.org/html/rfc6749#section-6 * See https://tools.ietf.org/html/rfc6749#section-6
...@@ -226,7 +241,7 @@ function auth($http, $window, flash, localStorage, random, settings) { ...@@ -226,7 +241,7 @@ function auth($http, $window, flash, localStorage, random, settings) {
if (grantToken) { if (grantToken) {
// Exchange host-page provided grant token for a new access token. // 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 }); refreshAccessTokenBeforeItExpires(tokenInfo, { persist: false });
return tokenInfo.accessToken; return tokenInfo.accessToken;
}).catch(function(err) { }).catch(function(err) {
...@@ -237,7 +252,7 @@ function auth($http, $window, flash, localStorage, random, settings) { ...@@ -237,7 +252,7 @@ function auth($http, $window, flash, localStorage, random, settings) {
} else if (authCode) { } else if (authCode) {
// Exchange authorization code retrieved from login popup for a new // Exchange authorization code retrieved from login popup for a new
// access token. // access token.
accessTokenPromise = exchangeToken(authCode).then((tokenInfo) => { accessTokenPromise = exchangeAuthCode(authCode).then((tokenInfo) => {
saveToken(tokenInfo); saveToken(tokenInfo);
refreshAccessTokenBeforeItExpires(tokenInfo, { persist: true }); refreshAccessTokenBeforeItExpires(tokenInfo, { persist: true });
return tokenInfo.accessToken; return tokenInfo.accessToken;
......
...@@ -506,8 +506,9 @@ describe('sidebar.oauth-auth', function () { ...@@ -506,8 +506,9 @@ describe('sidebar.oauth-auth', function () {
}).then(() => { }).then(() => {
// 2. Verify that auth code is exchanged for access & refresh tokens. // 2. Verify that auth code is exchanged for access & refresh tokens.
var expectedBody = var expectedBody =
'assertion=acode' + 'client_id=the-client-id' +
'&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer'; '&code=acode' +
'&grant_type=authorization_code';
assert.calledWith(fakeHttp.post, 'https://hypothes.is/api/token', expectedBody, { assert.calledWith(fakeHttp.post, 'https://hypothes.is/api/token', expectedBody, {
headers: {'Content-Type': 'application/x-www-form-urlencoded'}, 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