oauth2 postman import fix and include client certs and proxy config while fetching access token

This commit is contained in:
lohxt1
2025-02-05 16:06:41 +05:30
parent c5eeb190d3
commit f668e93f52
7 changed files with 109 additions and 15 deletions

View File

@@ -49,7 +49,7 @@ const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAu
requestCopy.headers = {};
toggleFetchingToken(true);
try {
await dispatch(fetchOauth2Credentials({ request: requestCopy, collection }));
await dispatch(fetchOauth2Credentials({ itemUid: item.uid, request: requestCopy, collection }));
toggleFetchingToken(false);
toast.success('token fetched successfully!');
}

View File

@@ -30,7 +30,7 @@ const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAu
requestCopy.headers = {};
toggleFetchingToken(true);
try {
await dispatch(fetchOauth2Credentials({ request: requestCopy, collection }));
await dispatch(fetchOauth2Credentials({ itemUid: item.uid, request: requestCopy, collection }));
toggleFetchingToken(false);
toast.success('Token fetched successfully!');
}

View File

@@ -30,7 +30,7 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update
requestCopy.headers = {};
toggleFetchingToken(true);
try {
await dispatch(fetchOauth2Credentials({ request: requestCopy, collection }));
await dispatch(fetchOauth2Credentials({ itemUid: item.uid, request: requestCopy, collection }));
toggleFetchingToken(false);
toast.success('Token fetched successfully!');
}

View File

@@ -1196,10 +1196,10 @@ export const hydrateCollectionWithUiStateSnapshot = (payload) => (dispatch, getS
};
export const fetchOauth2Credentials = (payload) => async (dispatch, getState) => {
const { request, collection } = payload;
const { request, collection, itemUid } = payload;
return new Promise((resolve, reject) => {
ipcRenderer
.invoke('renderer:fetch-oauth2-credentials', { request, collection })
.invoke('renderer:fetch-oauth2-credentials', { itemUid, request, collection })
.then(({ credentials, url, collectionUid, credentialsId }) => {
dispatch(collectionAddOauth2CredentialsByUrl({ credentials, url, collectionUid, credentialsId }));
resolve(credentials);

View File

@@ -425,6 +425,63 @@ const importPostmanV2CollectionItem = (brunoParent, item, parentAuth, options) =
value: authValues.value,
placement: "header" //By default we are placing the apikey values in headers!
}
} else if (auth.type === 'oauth2'){
const findValueUsingKey = (key) => {
return auth?.oauth2?.find(v => v?.key == key)?.value || ''
}
const oauth2GrantTypeMaps = {
'authorization_code_with_pkce': 'authorization_code',
'authorization_code': 'authorization_code',
'client_credentials': 'client_credentials',
'password_credentials': 'password_credentials'
}
const grantType = oauth2GrantTypeMaps[findValueUsingKey('grant_type')];
if (grantType) {
brunoRequestItem.request.auth.mode = 'oauth2';
switch(grantType) {
case 'authorization_code':
brunoRequestItem.request.auth.oauth2 = {
grantType: 'authorization_code',
authorizationUrl: findValueUsingKey('authUrl'),
callbackUrl: findValueUsingKey('redirect_uri'),
accessTokenUrl: findValueUsingKey('accessTokenUrl'),
clientId: findValueUsingKey('clientId'),
clientSecret: findValueUsingKey('clientSecret'),
scope: findValueUsingKey('scope'),
state: findValueUsingKey('state'),
pkce: Boolean(findValueUsingKey('grant_type') == 'authorization_code_with_pkce'),
tokenPlacement: findValueUsingKey('addTokenTo') == 'header' ? 'header' : 'url',
credentialsPlacement: findValueUsingKey('client_authentication') == 'body' ? 'body' : 'basic_auth_header'
};
break;
case 'password_credentials':
brunoRequestItem.request.auth.oauth2 = {
grantType: 'password',
accessTokenUrl: findValueUsingKey('accessTokenUrl'),
username: findValueUsingKey('username'),
password: findValueUsingKey('password'),
clientId: findValueUsingKey('clientId'),
clientSecret: findValueUsingKey('clientSecret'),
scope: findValueUsingKey('scope'),
state: findValueUsingKey('state'),
tokenPlacement: findValueUsingKey('addTokenTo') == 'header' ? 'header' : 'url',
credentialsPlacement: findValueUsingKey('client_authentication') == 'body' ? 'body' : 'basic_auth_header'
};
break;
case 'client_credentials':
brunoRequestItem.request.auth.oauth2 = {
grantType: 'client_credentials',
accessTokenUrl: findValueUsingKey('accessTokenUrl'),
clientId: findValueUsingKey('clientId'),
clientSecret: findValueUsingKey('clientSecret'),
scope: findValueUsingKey('scope'),
state: findValueUsingKey('state'),
tokenPlacement: findValueUsingKey('addTokenTo') == 'header' ? 'header' : 'url',
credentialsPlacement: findValueUsingKey('client_authentication') == 'body' ? 'body' : 'basic_auth_header'
};
break;
}
}
}
}

View File

@@ -34,9 +34,10 @@ const CollectionSecurityStore = require('../store/collection-security');
const UiStateSnapshotStore = require('../store/ui-state-snapshot');
const Oauth2Store = require('../store/oauth2');
const interpolateVars = require('./network/interpolate-vars');
const { getEnvVars } = require('../utils/collection');
const { getEnvVars, getTreePathFromCollectionToItem, mergeVars } = require('../utils/collection');
const { getProcessEnvVars } = require('../store/process-env');
const { getOAuth2TokenUsingAuthorizationCode, getOAuth2TokenUsingClientCredentials, getOAuth2TokenUsingPasswordCredentials, refreshOauth2Token } = require('../utils/oauth2');
const { configureRequestWithCertsAndProxy } = require('../utils/request');
const environmentSecretsStore = new EnvironmentSecretsStore();
const collectionSecurityStore = new CollectionSecurityStore();
@@ -792,15 +793,29 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
}
});
ipcMain.handle('renderer:fetch-oauth2-credentials', async (event, { request, collection }) => {
ipcMain.handle('renderer:fetch-oauth2-credentials', async (event, { itemUid, request, collection }) => {
try {
if (request.oauth2) {
let requestCopy = _.cloneDeep(request);
const { uid: collectionUid, runtimeVariables, environments = [], activeEnvironmentUid } = collection;
const { uid: collectionUid, pathname: collectionPath, runtimeVariables, environments = [], activeEnvironmentUid } = collection;
const environment = _.find(environments, (e) => e.uid === activeEnvironmentUid);
const envVars = getEnvVars(environment);
const processEnvVars = getProcessEnvVars(collectionUid);
const partialItem = { uid: itemUid };
const requestTreePath = getTreePathFromCollectionToItem(collection, partialItem);
if (requestTreePath && requestTreePath.length > 0) {
mergeVars(collection, requestCopy, requestTreePath);
}
interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars);
requestCopy = await configureRequestWithCertsAndProxy({
collectionUid,
request: requestCopy,
envVars,
runtimeVariables,
processEnvVars,
collectionPath
});
const { oauth2: { grantType }} = requestCopy || {};
let credentials, url, credentialsId;
switch (grantType) {

View File

@@ -432,19 +432,14 @@ const mapHeaders = (requestHeaders, collectionHeaders) => {
return headers;
};
const configureRequest = async (
const configureRequestWithCertsAndProxy = async ({
collectionUid,
request,
envVars,
runtimeVariables,
processEnvVars,
collectionPath
) => {
const protocolRegex = /^([-+\w]{1,25})(:?\/\/|:)/;
if (!protocolRegex.test(request.url)) {
request.url = `http://${request.url}`;
}
}) => {
/**
* @see https://github.com/usebruno/bruno/issues/211 set keepAlive to true, this should fix socket hang up errors
* @see https://github.com/nodejs/node/pull/43522 keepAlive was changed to true globally on Node v19+
@@ -604,6 +599,32 @@ const configureRequest = async (
...httpsAgentRequestFields
});
}
return request;
}
const configureRequest = async (
collectionUid,
request,
envVars,
runtimeVariables,
processEnvVars,
collectionPath
) => {
const protocolRegex = /^([-+\w]{1,25})(:?\/\/|:)/;
if (!protocolRegex.test(request.url)) {
request.url = `http://${request.url}`;
}
request = await configureRequestWithCertsAndProxy({
collectionUid,
request,
envVars,
runtimeVariables,
processEnvVars,
collectionPath
});
const axiosInstance = makeAxiosInstance();
if (request.ntlmConfig) {
@@ -751,6 +772,7 @@ module.exports = {
prepareGqlIntrospectionRequest,
setAuthHeaders,
getJsSandboxRuntime,
configureRequestWithCertsAndProxy,
configureRequest,
parseDataFromResponse
}