Skip to content

Commit

Permalink
Fix: OAuth2 auth is successful but token endpoint is returned instead…
Browse files Browse the repository at this point in the history
… of api endpoint

Setting oauth2 authorization no longer equals overwriting user-specified data in a request. The pre-requests made to obtain oauth2 access_token are now separated from actual API request.

usebruno#1999
  • Loading branch information
pietrygamat authored and Mateusz Pietryga committed Apr 16, 2024
1 parent 25e8ca2 commit 55e6c80
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 53 deletions.
47 changes: 19 additions & 28 deletions packages/bruno-electron/src/ipc/network/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ const { shouldUseProxy, PatchedHttpsProxyAgent } = require('../../utils/proxy-ut
const { chooseFileToSave, writeBinaryFile } = require('../../utils/filesystem');
const { getCookieStringForUrl, addCookieToJar, getDomainsWithCookies } = require('../../utils/cookies');
const {
resolveOAuth2AuthorizationCodeAccessToken,
transformClientCredentialsRequest,
transformPasswordCredentialsRequest,
getOAuth2ImplicitToken
getOAuth2AuthorizationCodeAccessToken,
getOAuth2ClientCredentialsAccessToken,
getOAuth2PasswordCredentialsAccessToken,
getOAuth2ImplicitAccessToken
} = require('./oauth2-helper');
const Oauth2Store = require('../../store/oauth2');

Expand Down Expand Up @@ -205,39 +205,30 @@ const configureRequest = async (
if (request.oauth2) {
let requestCopy = cloneDeep(request);
switch (request?.oauth2?.grantType) {
case 'authorization_code':
case 'authorization_code': {
interpolateVars(requestCopy, envVars, collectionVariables, processEnvVars);
const { data: authorizationCodeData, url: authorizationCodeAccessTokenUrl } =
await resolveOAuth2AuthorizationCodeAccessToken(requestCopy, collectionUid);
request.method = 'POST';
request.headers['content-type'] = 'application/x-www-form-urlencoded';
request.data = authorizationCodeData;
request.url = authorizationCodeAccessTokenUrl;
const { accessToken } = await getOAuth2AuthorizationCodeAccessToken(requestCopy, collectionUid);
request.headers['Authorization'] = `Bearer ${accessToken}`;
break;
case 'client_credentials':
}
case 'client_credentials': {
interpolateVars(requestCopy, envVars, collectionVariables, processEnvVars);
const { data: clientCredentialsData, url: clientCredentialsAccessTokenUrl } =
await transformClientCredentialsRequest(requestCopy);
request.method = 'POST';
request.headers['content-type'] = 'application/x-www-form-urlencoded';
request.data = clientCredentialsData;
request.url = clientCredentialsAccessTokenUrl;
const { accessToken } = await getOAuth2ClientCredentialsAccessToken(requestCopy, collectionUid);
request.headers['Authorization'] = `Bearer ${accessToken}`;
break;
case 'password':
}
case 'password': {
interpolateVars(requestCopy, envVars, collectionVariables, processEnvVars);
const { data: passwordData, url: passwordAccessTokenUrl } = await transformPasswordCredentialsRequest(
requestCopy
);
request.method = 'POST';
request.headers['content-type'] = 'application/x-www-form-urlencoded';
request.data = passwordData;
request.url = passwordAccessTokenUrl;
const { accessToken } = await getOAuth2PasswordCredentialsAccessToken(requestCopy, collectionUid);
request.headers['Authorization'] = `Bearer ${accessToken}`;
break;
case 'implicit':
}
case 'implicit': {
interpolateVars(requestCopy, envVars, collectionVariables, processEnvVars);
const { accessToken } = await getOAuth2ImplicitToken(requestCopy, collectionUid);
const { accessToken } = await getOAuth2ImplicitAccessToken(requestCopy, collectionUid);
request.headers['Authorization'] = `Bearer ${accessToken}`;
break;
}
}
}

Expand Down
64 changes: 39 additions & 25 deletions packages/bruno-electron/src/ipc/network/oauth2-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const { get, cloneDeep } = require('lodash');
const crypto = require('crypto');
const { authorizeUserInWindow, authorizeUserInWindowImplicit } = require('./authorize-user-in-window');
const Oauth2Store = require('../../store/oauth2');
const { makeAxiosInstance } = require('./axios-instance');

const generateCodeVerifier = () => {
return crypto.randomBytes(22).toString('hex');
Expand All @@ -16,7 +17,7 @@ const generateCodeChallenge = (codeVerifier) => {

// AUTHORIZATION CODE

const resolveOAuth2AuthorizationCodeAccessToken = async (request, collectionUid) => {
const getOAuth2AuthorizationCodeAccessToken = async (request, collectionUid) => {
let codeVerifier = generateCodeVerifier();
let codeChallenge = generateCodeChallenge(codeVerifier);

Expand All @@ -37,10 +38,16 @@ const resolveOAuth2AuthorizationCodeAccessToken = async (request, collectionUid)
}

const url = requestCopy?.oauth2?.accessTokenUrl;
return {
data,
url
};

request.method = 'POST';
request.headers['content-type'] = 'application/x-www-form-urlencoded';
request.data = data;
request.url = url;

const axiosInstance = makeAxiosInstance();
let response = await axiosInstance(request);
let accessToken = JSON.parse(response.data).access_token;
return { accessToken };
};

const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {
Expand Down Expand Up @@ -76,7 +83,7 @@ const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {

// CLIENT CREDENTIALS

const transformClientCredentialsRequest = async (request) => {
const getOAuth2ClientCredentialsAccessToken = async (request) => {
let requestCopy = cloneDeep(request);
const oAuth = get(requestCopy, 'oauth2', {});
const { clientId, clientSecret, scope } = oAuth;
Expand All @@ -86,18 +93,22 @@ const transformClientCredentialsRequest = async (request) => {
client_secret: clientSecret,
scope
};
const url = requestCopy?.oauth2?.accessTokenUrl;
return {
data,
url
};
request.method = 'POST';
request.headers['content-type'] = 'application/x-www-form-urlencoded';
request.data = data;
request.url = requestCopy?.oauth2?.accessTokenUrl;

const axiosInstance = makeAxiosInstance();
let response = await axiosInstance(request);
let accessToken = JSON.parse(response.data).access_token;

return { accessToken };
};

// PASSWORD CREDENTIALS

const transformPasswordCredentialsRequest = async (request) => {
let requestCopy = cloneDeep(request);
const oAuth = get(requestCopy, 'oauth2', {});
const getOAuth2PasswordCredentialsAccessToken = async (request) => {
const oAuth = get(request, 'oauth2', {});
const { username, password, clientId, clientSecret, scope } = oAuth;
const data = {
grant_type: 'password',
Expand All @@ -107,16 +118,20 @@ const transformPasswordCredentialsRequest = async (request) => {
client_secret: clientSecret,
scope
};
const url = requestCopy?.oauth2?.accessTokenUrl;
return {
data,
url
};
request.method = 'POST';
request.headers['content-type'] = 'application/x-www-form-urlencoded';
request.data = data;
request.url = request?.oauth2?.accessTokenUrl;

const axiosInstance = makeAxiosInstance();
let response = await axiosInstance(request);
let accessToken = JSON.parse(response.data).access_token;
return { accessToken };
};

// IMPLICIT

const getOAuth2ImplicitToken = async (request, collectionUid) => {
const getOAuth2ImplicitAccessToken = async (request, collectionUid) => {
return new Promise(async (resolve, reject) => {
const { oauth2 } = request;
const { callbackUrl, authorizationUrl, clientId, scope } = oauth2;
Expand All @@ -143,9 +158,8 @@ const getOAuth2ImplicitToken = async (request, collectionUid) => {
};

module.exports = {
resolveOAuth2AuthorizationCodeAccessToken,
getOAuth2AuthorizationCode,
transformClientCredentialsRequest,
transformPasswordCredentialsRequest,
getOAuth2ImplicitToken
getOAuth2AuthorizationCodeAccessToken,
getOAuth2ClientCredentialsAccessToken,
getOAuth2PasswordCredentialsAccessToken,
getOAuth2ImplicitAccessToken
};

0 comments on commit 55e6c80

Please sign in to comment.