From c2d64556360d2141cece99fc20aee1130068645f Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 3 Nov 2017 19:43:40 +0100 Subject: [PATCH] Handle hostless OAuth redirects (Closes #404) --- .../grant-authorization-code.test.js | 48 +++++++++++++++++++ app/network/o-auth-2/misc.js | 15 ++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/app/network/o-auth-2/__tests__/grant-authorization-code.test.js b/app/network/o-auth-2/__tests__/grant-authorization-code.test.js index a0d57a09c6..6d5f00f537 100644 --- a/app/network/o-auth-2/__tests__/grant-authorization-code.test.js +++ b/app/network/o-auth-2/__tests__/grant-authorization-code.test.js @@ -107,4 +107,52 @@ describe('authorization_code', () => { error_description: null }); }); + + it('handles hostless redirects', async () => { + createBWRedirectMock(`/redirect?code=code_123&state=${STATE}`); + window.fetch = jest.fn(() => new window.Response( + `access_token=token_123&token_type=token_type&scope=${SCOPE}`, + {headers: {'Content-Type': 'application/x-www-form-urlencoded'}} + )); + + const result = await getToken( + AUTHORIZE_URL, + ACCESS_TOKEN_URL, + true, + CLIENT_ID, + CLIENT_SECRET, + REDIRECT_URI, + SCOPE, + STATE + ); + + // Check the request to fetch the token + expect(window.fetch.mock.calls).toEqual([[ACCESS_TOKEN_URL, { + body: [ + 'grant_type=authorization_code', + 'code=code_123', + `redirect_uri=${encodeURIComponent(REDIRECT_URI)}`, + `state=${STATE}`, + `client_id=${CLIENT_ID}`, + `client_secret=${CLIENT_SECRET}` + ].join('&'), + method: 'POST', + headers: { + 'Accept': 'application/x-www-form-urlencoded, application/json', + 'Content-Type': 'application/x-www-form-urlencoded' + } + }]]); + + // Check the expected value + expect(result).toEqual({ + access_token: 'token_123', + refresh_token: null, + expires_in: null, + token_type: 'token_type', + scope: SCOPE, + error: null, + error_uri: null, + error_description: null + }); + }); }); diff --git a/app/network/o-auth-2/misc.js b/app/network/o-auth-2/misc.js index 4cab445843..883b82e344 100644 --- a/app/network/o-auth-2/misc.js +++ b/app/network/o-auth-2/misc.js @@ -1,5 +1,6 @@ import electron from 'electron'; import uuid from 'uuid'; +import {resolve as urlResolve} from 'url'; import querystring from 'querystring'; const AUTH_WINDOW_SESSION_ID = uuid.v4(); @@ -51,13 +52,17 @@ export function authorizeUserInWindow (url, urlRegex = /.*/) { // Catch the redirect after login child.webContents.on('did-navigate', () => { - const url = child.webContents.getURL(); - if (url.match(urlRegex)) { - console.log(`[oauth2] Matched redirect to "${url}" with ${urlRegex.toString()}`); - finalUrl = url; + // Be sure to resolve URL so that we can handle redirects with no host like /foo/bar + const currentUrl = urlResolve(url, child.webContents.getURL()); + if (currentUrl.match(urlRegex)) { + console.log(`[oauth2] Matched redirect to "${currentUrl}" with ${urlRegex.toString()}`); + finalUrl = currentUrl; child.close(); + } else if (currentUrl === url) { + // It's the first one, so it's not a redirect + console.log(`[oauth2] Loaded "${currentUrl}"`); } else { - console.log(`[oauth2] Ignoring redirect to "${url}" with match ${urlRegex.toString()}`); + console.log(`[oauth2] Ignoring URL "${currentUrl}". Didn't match ${urlRegex.toString()}`); } });