mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-23 04:35:40 +00:00
feat: OAuth2 - Do not make axios request when executing collection level Get Access Token action
The actual the authorization request is now part of request preparation, and its response is returned for post-request script processing.
This commit is contained in:
@@ -12,7 +12,6 @@ const { ipcMain } = require('electron');
|
||||
const { isUndefined, isNull, each, get, compact, cloneDeep, forOwn, extend } = require('lodash');
|
||||
const { VarsRuntime, AssertRuntime, ScriptRuntime, TestRuntime } = require('@usebruno/js');
|
||||
const prepareRequest = require('./prepare-request');
|
||||
const prepareCollectionRequest = require('./prepare-collection-request');
|
||||
const prepareGqlIntrospectionRequest = require('./prepare-gql-introspection-request');
|
||||
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token');
|
||||
const { uuid } = require('../../utils/common');
|
||||
@@ -268,22 +267,23 @@ const configureRequest = async (
|
||||
if (request.oauth2) {
|
||||
let requestCopy = cloneDeep(request);
|
||||
interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars);
|
||||
let credentials;
|
||||
let credentials, response;
|
||||
switch (request?.oauth2?.grantType) {
|
||||
case 'authorization_code': {
|
||||
({ credentials } = await oauth2AuthorizeWithAuthorizationCode(requestCopy, collectionUid));
|
||||
({ credentials, response } = await oauth2AuthorizeWithAuthorizationCode(requestCopy, collectionUid));
|
||||
break;
|
||||
}
|
||||
case 'client_credentials': {
|
||||
({ credentials } = await oauth2AuthorizeWithClientCredentials(requestCopy, collectionUid));
|
||||
({ credentials, response } = await oauth2AuthorizeWithClientCredentials(requestCopy, collectionUid));
|
||||
break;
|
||||
}
|
||||
case 'password': {
|
||||
({ credentials } = await oauth2AuthorizeWithPasswordCredentials(requestCopy, collectionUid));
|
||||
({ credentials, response } = await oauth2AuthorizeWithPasswordCredentials(requestCopy, collectionUid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
request.credentials = credentials;
|
||||
request.authRequestResponse = response;
|
||||
request.headers['Authorization'] = `Bearer ${credentials.access_token}`;
|
||||
}
|
||||
|
||||
@@ -704,7 +704,11 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
|
||||
const collectionRoot = get(collection, 'root', {});
|
||||
const _request = collectionRoot?.request;
|
||||
const request = prepareCollectionRequest(_request, collectionRoot, collectionPath);
|
||||
const request = prepareRequest(_request, collectionRoot, collectionPath);
|
||||
|
||||
// Script from this collection-level pseudo-request should be erased as it duplicates the collection script
|
||||
delete request.script;
|
||||
|
||||
const envVars = getEnvVars(environment);
|
||||
const processEnvVars = getProcessEnvVars(collectionUid);
|
||||
const brunoConfig = getBrunoConfig(collectionUid);
|
||||
@@ -724,7 +728,7 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
);
|
||||
|
||||
interpolateVars(request, envVars, collection.runtimeVariables, processEnvVars);
|
||||
const axiosInstance = await configureRequest(
|
||||
await configureRequest(
|
||||
collection.uid,
|
||||
request,
|
||||
envVars,
|
||||
@@ -733,19 +737,13 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
collectionPath
|
||||
);
|
||||
|
||||
try {
|
||||
response = await axiosInstance(request);
|
||||
} catch (error) {
|
||||
if (error?.response) {
|
||||
response = error.response;
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
const response = request.authRequestResponse;
|
||||
// When credentials are loaded from cache, authRequestResponse has no data
|
||||
if (response.data) {
|
||||
const { data } = parseDataFromResponse(response, request.__brunoDisableParsingResponseJson);
|
||||
response.data = data;
|
||||
}
|
||||
|
||||
const { data } = parseDataFromResponse(response, request.__brunoDisableParsingResponseJson);
|
||||
response.data = data;
|
||||
|
||||
await runPostResponse(
|
||||
request,
|
||||
response,
|
||||
@@ -763,7 +761,8 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: response.headers,
|
||||
data: response.data
|
||||
data: response.data,
|
||||
credentials: request.credentials
|
||||
};
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
|
||||
@@ -35,7 +35,7 @@ const oauth2AuthorizeWithAuthorizationCode = async (request, collectionUid) => {
|
||||
const { cachedCredentials } = getPersistedOauth2Credentials(collectionUid);
|
||||
if (cachedCredentials?.access_token) {
|
||||
console.log('Reusing Stored access token');
|
||||
return { credentials: cachedCredentials };
|
||||
return { credentials: cachedCredentials, response: {} };
|
||||
}
|
||||
|
||||
let codeVerifier = generateCodeVerifier();
|
||||
@@ -65,7 +65,7 @@ const oauth2AuthorizeWithAuthorizationCode = async (request, collectionUid) => {
|
||||
const response = await axiosInstance(request);
|
||||
const credentials = JSON.parse(response.data);
|
||||
persistOauth2Credentials(credentials, collectionUid);
|
||||
return { credentials };
|
||||
return { credentials, response };
|
||||
};
|
||||
|
||||
const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {
|
||||
@@ -108,7 +108,7 @@ const oauth2AuthorizeWithClientCredentials = async (request, collectionUid) => {
|
||||
const { cachedCredentials } = getPersistedOauth2Credentials(collectionUid);
|
||||
if (cachedCredentials?.access_token) {
|
||||
console.log('Reusing Stored access token');
|
||||
return { credentials: cachedCredentials };
|
||||
return { credentials: cachedCredentials, response: {} };
|
||||
}
|
||||
|
||||
let requestCopy = cloneDeep(request);
|
||||
@@ -132,7 +132,7 @@ const oauth2AuthorizeWithClientCredentials = async (request, collectionUid) => {
|
||||
let response = await axiosInstance(request);
|
||||
let credentials = JSON.parse(response.data);
|
||||
persistOauth2Credentials(credentials, collectionUid);
|
||||
return { credentials };
|
||||
return { credentials, response };
|
||||
};
|
||||
|
||||
// PASSWORD CREDENTIALS
|
||||
@@ -141,7 +141,7 @@ const oauth2AuthorizeWithPasswordCredentials = async (request, collectionUid) =>
|
||||
const { cachedCredentials } = getPersistedOauth2Credentials(collectionUid);
|
||||
if (cachedCredentials?.access_token) {
|
||||
console.log('Reusing Stored access token');
|
||||
return { credentials: cachedCredentials };
|
||||
return { credentials: cachedCredentials, response: {} };
|
||||
}
|
||||
|
||||
const oAuth = get(request, 'oauth2', {});
|
||||
@@ -166,7 +166,7 @@ const oauth2AuthorizeWithPasswordCredentials = async (request, collectionUid) =>
|
||||
let response = await axiosInstance(request);
|
||||
let credentials = JSON.parse(response.data);
|
||||
persistOauth2Credentials(credentials, collectionUid);
|
||||
return { credentials };
|
||||
return { credentials, response };
|
||||
};
|
||||
module.exports = {
|
||||
oauth2AuthorizeWithAuthorizationCode,
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
const { get, each } = require('lodash');
|
||||
const { setAuthHeaders } = require('./prepare-request');
|
||||
|
||||
const prepareCollectionRequest = (request, collectionRoot) => {
|
||||
const headers = {};
|
||||
let contentTypeDefined = false;
|
||||
let url = request.url;
|
||||
|
||||
// collection headers
|
||||
each(get(collectionRoot, 'request.headers', []), (h) => {
|
||||
if (h.enabled) {
|
||||
headers[h.name] = h.value;
|
||||
if (h.name.toLowerCase() === 'content-type') {
|
||||
contentTypeDefined = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
each(request.headers, (h) => {
|
||||
if (h.enabled) {
|
||||
headers[h.name] = h.value;
|
||||
if (h.name.toLowerCase() === 'content-type') {
|
||||
contentTypeDefined = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let axiosRequest = {
|
||||
mode: request?.body?.mode,
|
||||
method: request.method,
|
||||
url,
|
||||
headers,
|
||||
responseType: 'arraybuffer'
|
||||
};
|
||||
|
||||
axiosRequest = setAuthHeaders(axiosRequest, request, collectionRoot);
|
||||
|
||||
if (request.script) {
|
||||
axiosRequest.script = request.script;
|
||||
}
|
||||
|
||||
axiosRequest.vars = request.vars;
|
||||
|
||||
axiosRequest.method = 'POST';
|
||||
|
||||
return axiosRequest;
|
||||
};
|
||||
|
||||
module.exports = prepareCollectionRequest;
|
||||
@@ -383,7 +383,7 @@ const prepareRequest = (item, collection) => {
|
||||
});
|
||||
|
||||
let axiosRequest = {
|
||||
mode: request.body.mode,
|
||||
mode: request?.body?.mode,
|
||||
method: request.method,
|
||||
url,
|
||||
headers,
|
||||
@@ -393,7 +393,7 @@ const prepareRequest = (item, collection) => {
|
||||
|
||||
axiosRequest = setAuthHeaders(axiosRequest, request, collectionRoot);
|
||||
|
||||
if (request.body.mode === 'json') {
|
||||
if (request.body?.mode === 'json') {
|
||||
if (!contentTypeDefined) {
|
||||
axiosRequest.headers['content-type'] = 'application/json';
|
||||
}
|
||||
@@ -404,28 +404,28 @@ const prepareRequest = (item, collection) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (request.body.mode === 'text') {
|
||||
if (request.body?.mode === 'text') {
|
||||
if (!contentTypeDefined) {
|
||||
axiosRequest.headers['content-type'] = 'text/plain';
|
||||
}
|
||||
axiosRequest.data = request.body.text;
|
||||
}
|
||||
|
||||
if (request.body.mode === 'xml') {
|
||||
if (request.body?.mode === 'xml') {
|
||||
if (!contentTypeDefined) {
|
||||
axiosRequest.headers['content-type'] = 'text/xml';
|
||||
}
|
||||
axiosRequest.data = request.body.xml;
|
||||
}
|
||||
|
||||
if (request.body.mode === 'sparql') {
|
||||
if (request.body?.mode === 'sparql') {
|
||||
if (!contentTypeDefined) {
|
||||
axiosRequest.headers['content-type'] = 'application/sparql-query';
|
||||
}
|
||||
axiosRequest.data = request.body.sparql;
|
||||
}
|
||||
|
||||
if (request.body.mode === 'formUrlEncoded') {
|
||||
if (request.body?.mode === 'formUrlEncoded') {
|
||||
if (!contentTypeDefined) {
|
||||
axiosRequest.headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
@@ -433,7 +433,7 @@ const prepareRequest = (item, collection) => {
|
||||
axiosRequest.data = buildFormUrlEncodedPayload(enabledParams);
|
||||
}
|
||||
|
||||
if (request.body.mode === 'multipartForm') {
|
||||
if (request.body?.mode === 'multipartForm') {
|
||||
axiosRequest.headers['content-type'] = 'multipart/form-data';
|
||||
const params = {};
|
||||
const enabledParams = filter(request.body.multipartForm, (p) => p.enabled);
|
||||
@@ -441,7 +441,7 @@ const prepareRequest = (item, collection) => {
|
||||
axiosRequest.data = params;
|
||||
}
|
||||
|
||||
if (request.body.mode === 'graphql') {
|
||||
if (request.body?.mode === 'graphql') {
|
||||
const graphqlQuery = {
|
||||
query: get(request, 'body.graphql.query'),
|
||||
// https://github.com/usebruno/bruno/issues/884 - we must only parse the variables after the variable interpolation
|
||||
|
||||
Reference in New Issue
Block a user