From 3c0d0c95ea55489fac321aea215f40729e8e1066 Mon Sep 17 00:00:00 2001 From: lohxt1 Date: Wed, 2 Apr 2025 19:42:15 +0530 Subject: [PATCH 01/15] oauth2 changes --- .../Auth/OAuth2/AdditionalParams/index.js | 216 ++++++++++++++++++ .../Auth/OAuth2/AuthorizationCode/index.js | 2 + packages/bruno-lang/v2/src/bruToJson.js | 161 ++++++++++++- .../bruno-lang/v2/src/collectionBruToJson.js | 145 +++++++++++- packages/bruno-lang/v2/src/jsonToBru.js | 29 +++ 5 files changed, 549 insertions(+), 4 deletions(-) create mode 100644 packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js new file mode 100644 index 000000000..cdee10a49 --- /dev/null +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js @@ -0,0 +1,216 @@ +import { useDispatch } from "react-redux"; +import React, { useRef, forwardRef, useState } from 'react'; +import get from 'lodash/get'; +import { useTheme } from 'providers/Theme'; +import { IconPlus } from '@tabler/icons'; +import Dropdown from 'components/Dropdown'; +import { cloneDeep } from "lodash"; + +const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { + const dispatch = useDispatch(); + const { storedTheme } = useTheme(); + const dropdownTippyRef = useRef(); + const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); + const [activeTab, setActiveTab] = useState('authorization'); + + const oAuth = get(request, 'auth.oauth2', {}); + const { + grantType, + callbackUrl, + authorizationUrl, + accessTokenUrl, + clientId, + clientSecret, + scope, + credentialsPlacement, + state, + pkce, + credentialsId, + tokenPlacement, + tokenHeaderPrefix, + tokenQueryKey, + refreshTokenUrl, + autoRefreshToken, + autoFetchToken, + additionalParams = {} + } = oAuth; + + const handleUpdateAdditionalParam = ({ paramType, key, paramIndex, value }) => { + const updatedAdditionalParams = cloneDeep(additionalParams); + + updatedAdditionalParams[paramType][paramIndex][key] = value; + + dispatch( + updateAuth({ + mode: 'oauth2', + collectionUid: collection.uid, + itemUid: item.uid, + content: { + grantType, + callbackUrl, + authorizationUrl, + accessTokenUrl, + clientId, + clientSecret, + state, + scope, + pkce, + credentialsPlacement, + credentialsId, + tokenPlacement, + tokenHeaderPrefix, + tokenQueryKey, + refreshTokenUrl, + autoRefreshToken, + autoFetchToken, + additionalParams: updatedAdditionalParams, + } + }) + ); + } + + const handleAddNewAdditionalParam = () => { + const paramType = activeTab; + const updatedAdditionalParams = cloneDeep(additionalParams); + if (!updatedAdditionalParams?.[paramType]) { + updatedAdditionalParams[paramType] = []; + } + updatedAdditionalParams[paramType] = [ + ...updatedAdditionalParams[paramType], + { + name: '', + value: '', + sendIn: 'header' + } + ]; + + dispatch( + updateAuth({ + mode: 'oauth2', + collectionUid: collection.uid, + itemUid: item.uid, + content: { + grantType, + callbackUrl, + authorizationUrl, + accessTokenUrl, + clientId, + clientSecret, + state, + scope, + pkce, + credentialsPlacement, + credentialsId, + tokenPlacement, + tokenHeaderPrefix, + tokenQueryKey, + refreshTokenUrl, + autoRefreshToken, + autoFetchToken, + additionalParams: updatedAdditionalParams, + } + }) + ); + } + return ( +
+
+
Authorization
+
Token
+
Refresh
+
+ + + + + + + + + + {additionalParams?.[activeTab]?.map((param, index) => + + + + } placement="bottom-end"> +
{ + dropdownTippyRef.current.hide(); + handleUpdateAdditionalParam({ + paramType: activeTab, + key: 'sendIn', + paramIndex: index, + value: 'header' + }) + }} + > + Header +
+
{ + dropdownTippyRef.current.hide(); + handleUpdateAdditionalParam({ + paramType: activeTab, + key: 'sendIn', + paramIndex: index, + value: 'queryparams' + }) + }} + > + Query Params +
+
{ + dropdownTippyRef.current.hide(); + handleUpdateAdditionalParam({ + paramType: activeTab, + key: 'sendIn', + paramIndex: index, + value: 'body' + }) + }} + > + Body +
+
+ + )} + +
KeyValueSend In
+ handleUpdateAdditionalParam({ + paramType: activeTab, + key: 'name', + paramIndex: index, + value + })} + collection={collection} + /> + + handleUpdateAdditionalParam({ + paramType: activeTab, + key: 'value', + paramIndex: index, + value + })} + collection={collection} + /> +
+
+ +
+
+ ) +} + +export default AdditionalParams; \ No newline at end of file diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js index c00964d82..bc2feb019 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js @@ -9,6 +9,7 @@ import StyledWrapper from './StyledWrapper'; import { inputsConfig } from './inputsConfig'; import Oauth2TokenViewer from '../Oauth2TokenViewer/index'; import Oauth2ActionButtons from '../Oauth2ActionButtons/index'; +import AdditionalParams from '../AdditionalParams/index'; const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAuth, collection, folder }) => { const dispatch = useDispatch(); @@ -326,6 +327,7 @@ const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAu + ); diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index 819272240..7c84c7e8a 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -22,12 +22,18 @@ const { safeParseJson, outdentString } = require('./utils'); * */ const grammar = ohm.grammar(`Bru { - BruFile = (meta | http | query | params | headers | auths | bodies | varsandassert | script | tests | docs)* + BruFile = (meta | http | query | params | headers | auths | bodies | varsandassert | script | tests | docs | authOAuth2Configs)* auths = authawsv4 | authbasic | authbearer | authdigest | authNTLM | authOAuth2 | authwsse | authapikey bodies = bodyjson | bodytext | bodyxml | bodysparql | bodygraphql | bodygraphqlvars | bodyforms | body bodyforms = bodyformurlencoded | bodymultipart | bodyfile params = paramspath | paramsquery - + + // Oauth2 additional parameters + authOAuth2Configs = oAuth2AuthorizationConfig | oAuth2TokenConfig | oAuth2RefreshConfig + oAuth2AuthorizationConfig = oAuth2AuthorizationHeaders | oAuth2AuthorizationQueryParams + oAuth2TokenConfig = oAuth2TokenHeaders | oAuth2TokenQueryParams | oAuth2TokenBodyValues + oAuth2RefreshConfig = oAuth2RefreshHeaders | oAuth2RefreshQueryParams | oAuth2RefreshBodyValues + nl = "\\r"? "\\n" st = " " | "\\t" stnl = st | nl @@ -92,6 +98,15 @@ const grammar = ohm.grammar(`Bru { authwsse = "auth:wsse" dictionary authapikey = "auth:apikey" dictionary + oAuth2AuthorizationHeaders = "auth:oauth2:authorization_headers" dictionary + oAuth2AuthorizationQueryParams = "auth:oauth2:authorization_queryparams" dictionary + oAuth2TokenHeaders = "auth:oauth2:token_headers" dictionary + oAuth2TokenQueryParams = "auth:oauth2:token_queryparams" dictionary + oAuth2TokenBodyValues = "auth:oauth2:token_bodyvalues" dictionary + oAuth2RefreshHeaders = "auth:oauth2:authorization_headers" dictionary + oAuth2RefreshQueryParams = "auth:oauth2:authorization_queryparams" dictionary + oAuth2RefreshBodyValues = "auth:oauth2:authorization_bodyvalues" dictionary + body = "body" st* "{" nl* textblock tagend bodyjson = "body:json" st* "{" nl* textblock tagend bodytext = "body:text" st* "{" nl* textblock tagend @@ -588,6 +603,146 @@ const sem = grammar.createSemantics().addAttribute('ast', { } }; }, + oAuth2AuthorizationHeaders(_1, dictionary) { + const authorizationHeaders = [...mapPairListToKeyValPairs(dictionary.ast)]?.map(_ => ({ + ..._, + sendIn: 'headers' + })); + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + authorization: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.authorization || []), + ...authorizationHeaders + ] + } + } + } + }; + }, + oAuth2AuthorizationQueryParams(_1, dictionary) { + const authorizationQueryParams = [...mapPairListToKeyValPairs(dictionary.ast)]?.map(_ => ({ + ..._, + sendIn: 'queryparams' + })); + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + authorization: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.authorization || []), + ...authorizationQueryParams + ] + } + } + } + }; + }, + oAuth2TokenHeaders(_1, dictionary) { + const tokenHeaders = [...mapPairListToKeyValPairs(dictionary.ast)]?.map(_ => ({ + ..._, + sendIn: 'headers' + })); + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + token: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.token || []), + ...tokenHeaders + ] + } + } + } + }; + }, + oAuth2TokenQueryParams(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + tokenQueryParams: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenQueryParams || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2TokenBodyValues(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + tokenBodyValues: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenBodyValues || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2RefreshHeaders(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + refreshHeaders: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshHeaders || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2RefreshQueryParams(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + refreshQueryParams: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshQueryParams || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2RefreshBodyValues(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + refreshBodyValues: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshBodyValues || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, authwsse(_1, dictionary) { const auth = mapPairListToKeyValPairs(dictionary.ast, false); @@ -782,4 +937,4 @@ const parser = (input) => { }; module.exports = parser; - \ No newline at end of file + diff --git a/packages/bruno-lang/v2/src/collectionBruToJson.js b/packages/bruno-lang/v2/src/collectionBruToJson.js index 16a0c8d79..4c49fc39f 100644 --- a/packages/bruno-lang/v2/src/collectionBruToJson.js +++ b/packages/bruno-lang/v2/src/collectionBruToJson.js @@ -3,9 +3,15 @@ const _ = require('lodash'); const { safeParseJson, outdentString } = require('./utils'); const grammar = ohm.grammar(`Bru { - BruFile = (meta | query | headers | auth | auths | vars | script | tests | docs)* + BruFile = (meta | query | headers | auth | auths | vars | script | tests | docs | authOAuth2Configs)* auths = authawsv4 | authbasic | authbearer | authdigest | authNTLM |authOAuth2 | authwsse | authapikey + // Oauth2 additional parameters + authOAuth2Configs = oAuth2AuthorizationConfig | oAuth2TokenConfig | oAuth2RefreshConfig + oAuth2AuthorizationConfig = oAuth2AuthorizationHeaders | oAuth2AuthorizationQueryParams + oAuth2TokenConfig = oAuth2TokenHeaders | oAuth2TokenQueryParams | oAuth2TokenBodyValues + oAuth2RefreshConfig = oAuth2RefreshHeaders | oAuth2RefreshQueryParams | oAuth2RefreshBodyValues + nl = "\\r"? "\\n" st = " " | "\\t" stnl = st | nl @@ -30,6 +36,15 @@ const grammar = ohm.grammar(`Bru { auth = "auth" dictionary + oAuth2AuthorizationHeaders = "auth:oauth2:authorization_headers" dictionary + oAuth2AuthorizationQueryParams = "auth:oauth2:authorization_queryparams" dictionary + oAuth2TokenHeaders = "auth:oauth2:token_headers" dictionary + oAuth2TokenQueryParams = "auth:oauth2:token_queryparams" dictionary + oAuth2TokenBodyValues = "auth:oauth2:token_bodyvalues" dictionary + oAuth2RefreshHeaders = "auth:oauth2:authorization_headers" dictionary + oAuth2RefreshQueryParams = "auth:oauth2:authorization_queryparams" dictionary + oAuth2RefreshBodyValues = "auth:oauth2:authorization_bodyvalues" dictionary + headers = "headers" dictionary query = "query" dictionary @@ -348,6 +363,134 @@ const sem = grammar.createSemantics().addAttribute('ast', { } }; }, + oAuth2AuthorizationHeaders(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + authorizationHeaders: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.authorizationHeaders || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2AuthorizationQueryParams(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + authorizationQueryParams: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.authorizationQueryParams || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2TokenHeaders(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + tokenHeaders: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenHeaders || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2TokenQueryParams(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + tokenQueryParams: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenQueryParams || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2TokenBodyValues(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + tokenBodyValues: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenBodyValues || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2RefreshHeaders(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + refreshHeaders: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshHeaders || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2RefreshQueryParams(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + refreshQueryParams: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshQueryParams || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, + oAuth2RefreshBodyValues(_1, dictionary) { + return { + auth: { + oauth2: { + ...(dictionary?.ast?.auth?.oauth2 || {}), + additionalParameters: { + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), + refreshBodyValues: [ + ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshBodyValues || []), + ...mapPairListToKeyValPairs(dictionary.ast) + ] + } + } + } + }; + }, authwsse(_1, dictionary) { const auth = mapPairListToKeyValPairs(dictionary.ast, false); const userKey = _.find(auth, { name: 'username' }); diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js index 776cca7d5..d8a7b13a3 100644 --- a/packages/bruno-lang/v2/src/jsonToBru.js +++ b/packages/bruno-lang/v2/src/jsonToBru.js @@ -249,6 +249,35 @@ ${indentString(`auto_refresh_token: ${(auth?.oauth2?.autoRefreshToken ?? false). `; break; } + + if (auth?.oauth2?.additionalParameters) { + switch(auth?.oauth2?.additionalParameters) { + case 'authorizationHeaders' : + let authorizationHeaders = auth?.oauth2?.additionalParameters?.authorizationHeaders; + bru += `auth:oauth2:authorization_headers { +${enabled(authorizationHeaders) + .map((item) => `${item.name}: ${item.value}`) + .join('\n')} +}`; + break; + case 'authorizationQueryParams' : + let authorizationQueryParams = auth?.oauth2?.additionalParameters?.authorizationQueryParams; + bru += `auth:oauth2:authorization_queryparams { +${enabled(authorizationQueryParams) + .map((item) => `${item.name}: ${item.value}`) + .join('\n')} +}`; + break; + case 'authorizationBodyValues' : + let authorizationBodyValues = auth?.oauth2?.additionalParameters?.authorizationBodyValues; + bru += `auth:oauth2:authorization_queryparams { + ${enabled(authorizationBodyValues) + .map((item) => `${item.name}: ${item.value}`) + .join('\n')} + }`; + break; + } + } } if (auth && auth.apikey) { From b1911d80e9150f3b0e1654a6828ca283919ce400 Mon Sep 17 00:00:00 2001 From: lohxt1 Date: Thu, 3 Apr 2025 12:34:24 +0530 Subject: [PATCH 02/15] wip: oauth2 additional parameters --- .../OAuth2/AdditionalParams/StyledWrapper.js | 16 ++ .../Auth/OAuth2/AdditionalParams/index.js | 251 ++++++++---------- .../Auth/OAuth2/AuthorizationCode/index.js | 7 +- .../Auth/OAuth2/ClientCredentials/index.js | 7 +- .../Auth/OAuth2/PasswordCredentials/index.js | 6 +- .../bruno-app/src/utils/collections/index.js | 3 - packages/bruno-lang/v2/src/bruToJson.js | 127 ++------- .../bruno-lang/v2/src/collectionBruToJson.js | 112 +------- packages/bruno-lang/v2/src/jsonToBru.js | 127 +++++++-- .../bruno-lang/v2/src/jsonToCollectionBru.js | 108 ++++++++ packages/bruno-lang/v2/src/utils.js | 77 +++++- .../bruno-schema/src/collections/index.js | 27 ++ 12 files changed, 488 insertions(+), 380 deletions(-) create mode 100644 packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js new file mode 100644 index 000000000..ebb8ee46a --- /dev/null +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + .tabs { + .active { + border-bottom: solid 1px ${(props) => props.theme.input.border}; + } + } + .additional-parameter-sends-in-selector { + select { + height: 32px; + } + } +` + +export default StyledWrapper; \ No newline at end of file diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js index cdee10a49..1e13b676e 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js @@ -1,77 +1,53 @@ import { useDispatch } from "react-redux"; -import React, { useRef, forwardRef, useState } from 'react'; +import React, { forwardRef, useState } from 'react'; import get from 'lodash/get'; import { useTheme } from 'providers/Theme'; -import { IconPlus } from '@tabler/icons'; -import Dropdown from 'components/Dropdown'; +import { IconPlus, IconCaretDown, IconTrash } from '@tabler/icons'; import { cloneDeep } from "lodash"; +import SingleLineEditor from "components/SingleLineEditor/index"; +import StyledWrapper from "./StyledWrapper"; +import Table from "components/Table/index"; const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { const dispatch = useDispatch(); const { storedTheme } = useTheme(); - const dropdownTippyRef = useRef(); - const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); const [activeTab, setActiveTab] = useState('authorization'); const oAuth = get(request, 'auth.oauth2', {}); const { grantType, - callbackUrl, - authorizationUrl, - accessTokenUrl, - clientId, - clientSecret, - scope, - credentialsPlacement, - state, - pkce, - credentialsId, - tokenPlacement, - tokenHeaderPrefix, - tokenQueryKey, - refreshTokenUrl, - autoRefreshToken, - autoFetchToken, - additionalParams = {} + additionalParameters = {} } = oAuth; - const handleUpdateAdditionalParam = ({ paramType, key, paramIndex, value }) => { - const updatedAdditionalParams = cloneDeep(additionalParams); - - updatedAdditionalParams[paramType][paramIndex][key] = value; - + const updateAdditionalParams = ({ updatedAdditionalParams }) => { dispatch( updateAuth({ mode: 'oauth2', collectionUid: collection.uid, itemUid: item.uid, content: { - grantType, - callbackUrl, - authorizationUrl, - accessTokenUrl, - clientId, - clientSecret, - state, - scope, - pkce, - credentialsPlacement, - credentialsId, - tokenPlacement, - tokenHeaderPrefix, - tokenQueryKey, - refreshTokenUrl, - autoRefreshToken, - autoFetchToken, - additionalParams: updatedAdditionalParams, + ...oAuth, + additionalParameters: updatedAdditionalParams, } }) ); } + const handleUpdateAdditionalParam = ({ paramType, key, paramIndex, value }) => { + const updatedAdditionalParams = cloneDeep(additionalParameters); + updatedAdditionalParams[paramType][paramIndex][key] = value; + updateAdditionalParams({ updatedAdditionalParams }); + } + + const handleDeleteAdditionalParam = ({ paramType, paramIndex }) => { + const updatedAdditionalParams = cloneDeep(additionalParameters); + updatedAdditionalParams[paramType] = updatedAdditionalParams[paramType]?.filter((_, index) => index !== paramIndex); + updateAdditionalParams({ updatedAdditionalParams }); + } + const handleAddNewAdditionalParam = () => { const paramType = activeTab; - const updatedAdditionalParams = cloneDeep(additionalParams); + const updatedAdditionalParams = cloneDeep(additionalParameters); if (!updatedAdditionalParams?.[paramType]) { updatedAdditionalParams[paramType] = []; } @@ -80,61 +56,35 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { { name: '', value: '', - sendIn: 'header' + sendIn: 'headers', + enabled: true } ]; - - dispatch( - updateAuth({ - mode: 'oauth2', - collectionUid: collection.uid, - itemUid: item.uid, - content: { - grantType, - callbackUrl, - authorizationUrl, - accessTokenUrl, - clientId, - clientSecret, - state, - scope, - pkce, - credentialsPlacement, - credentialsId, - tokenPlacement, - tokenHeaderPrefix, - tokenQueryKey, - refreshTokenUrl, - autoRefreshToken, - autoFetchToken, - additionalParams: updatedAdditionalParams, - } - }) - ); + updateAdditionalParams({ updatedAdditionalParams }); } return ( -
-
-
Authorization
-
Token
-
Refresh
+ +
+
setActiveTab('authorization')}>Authorization
+
setActiveTab('token')}>Token
+
setActiveTab('refresh')}>Refresh
- - - - - - - - +
KeyValueSend In
- {additionalParams?.[activeTab]?.map((param, index) => + {additionalParameters?.[activeTab]?.map((param, index) => - - } placement="bottom-end"> -
{ - dropdownTippyRef.current.hide(); - handleUpdateAdditionalParam({ - paramType: activeTab, - key: 'sendIn', - paramIndex: index, - value: 'header' - }) - }} - > - Header +
+ )} -
+ handleUpdateAdditionalParam({ paramType: activeTab, key: 'name', @@ -148,7 +98,7 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { handleUpdateAdditionalParam({ paramType: activeTab, key: 'value', @@ -158,59 +108,86 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { collection={collection} /> +
+
-
{ - dropdownTippyRef.current.hide(); - handleUpdateAdditionalParam({ - paramType: activeTab, - key: 'sendIn', - paramIndex: index, - value: 'queryparams' - }) - }} - > - Query Params +
+
+ { + handleUpdateAdditionalParam({ + paramType: activeTab, + key: 'enabled', + paramIndex: index, + value: e.target.checked + }) + }} + /> +
-
{ - dropdownTippyRef.current.hide(); - handleUpdateAdditionalParam({ - paramType: activeTab, - key: 'sendIn', - paramIndex: index, - value: 'body' - }) - }} - > - Body -
- +
+
-
+ ) } -export default AdditionalParams; \ No newline at end of file +export default AdditionalParams; + +const Icon = forwardRef((props, ref) => { + const { value } = props + return ( +
+
+ {value} +
+
+ +
+
+ ); +}); + +const sendInOptionsMap = { + 'authorization_code': ['headers', 'queryparams'], + 'password': ['headers', 'queryparams', 'body'], + 'client_credentials': ['headers', 'queryparams', 'body'] +} \ No newline at end of file diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js index bc2feb019..5aadcd156 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js @@ -34,7 +34,8 @@ const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAu tokenQueryKey, refreshTokenUrl, autoRefreshToken, - autoFetchToken + autoFetchToken, + additionalParameters } = oAuth; const refreshTokenUrlAvailable = refreshTokenUrl?.trim() !== ''; @@ -84,6 +85,7 @@ const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAu refreshTokenUrl, autoRefreshToken, autoFetchToken, + additionalParameters, [key]: value, } }) @@ -111,6 +113,7 @@ const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAu tokenHeaderPrefix, tokenQueryKey, autoFetchToken, + additionalParameters, pkce: !Boolean(oAuth?.['pkce']) } }) @@ -327,7 +330,7 @@ const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAu
- + ); diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js index 98b3e4607..f4b01135b 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js @@ -9,6 +9,7 @@ import { inputsConfig } from './inputsConfig'; import Dropdown from 'components/Dropdown'; import Oauth2TokenViewer from '../Oauth2TokenViewer/index'; import Oauth2ActionButtons from '../Oauth2ActionButtons/index'; +import AdditionalParams from '../AdditionalParams/index'; const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAuth, collection }) => { const dispatch = useDispatch(); @@ -30,7 +31,8 @@ const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAu tokenQueryKey, refreshTokenUrl, autoRefreshToken, - autoFetchToken + autoFetchToken, + additionalParameters } = oAuth; const refreshTokenUrlAvailable = refreshTokenUrl?.trim() !== ''; @@ -77,6 +79,7 @@ const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAu refreshTokenUrl, autoRefreshToken, autoFetchToken, + additionalParameters, [key]: value } }) @@ -295,7 +298,7 @@ const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAu - + diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js index 47f6fc5b2..086e10335 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js @@ -9,6 +9,7 @@ import { inputsConfig } from './inputsConfig'; import Dropdown from 'components/Dropdown'; import Oauth2TokenViewer from '../Oauth2TokenViewer/index'; import Oauth2ActionButtons from '../Oauth2ActionButtons/index'; +import AdditionalParams from '../AdditionalParams/index'; const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, updateAuth, collection }) => { const dispatch = useDispatch(); @@ -32,7 +33,8 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update tokenQueryKey, refreshTokenUrl, autoRefreshToken, - autoFetchToken + autoFetchToken, + additionalParameters } = oAuth; const refreshTokenUrlAvailable = refreshTokenUrl?.trim() !== ''; @@ -80,6 +82,7 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update refreshTokenUrl, autoRefreshToken, autoFetchToken, + additionalParameters, [key]: value } }) @@ -298,6 +301,7 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update + ); diff --git a/packages/bruno-app/src/utils/collections/index.js b/packages/bruno-app/src/utils/collections/index.js index 73049b918..256874730 100644 --- a/packages/bruno-app/src/utils/collections/index.js +++ b/packages/bruno-app/src/utils/collections/index.js @@ -1,8 +1,6 @@ import {cloneDeep, isEqual, sortBy, filter, map, isString, findIndex, find, each, get } from 'lodash'; import { uuid } from 'utils/common'; import path from 'utils/common/path'; -import brunoCommon from '@usebruno/common'; -const { interpolate } = brunoCommon; const replaceTabsWithSpaces = (str, numSpaces = 2) => { if (!str || !str.length || !isString(str)) { @@ -650,7 +648,6 @@ export const transformRequestToSaveToFilesystem = (item) => { json: replaceTabsWithSpaces(itemToSave.request.body.json) }; } - return itemToSave; }; diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index 7c84c7e8a..7e61afe45 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -1,6 +1,6 @@ const ohm = require('ohm-js'); const _ = require('lodash'); -const { safeParseJson, outdentString } = require('./utils'); +const { safeParseJson, outdentString, mergeOauth2AdditionalParameters } = require('./utils'); /** * A Bru file is made up of blocks. @@ -604,143 +604,43 @@ const sem = grammar.createSemantics().addAttribute('ast', { }; }, oAuth2AuthorizationHeaders(_1, dictionary) { - const authorizationHeaders = [...mapPairListToKeyValPairs(dictionary.ast)]?.map(_ => ({ - ..._, - sendIn: 'headers' - })); return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - authorization: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.authorization || []), - ...authorizationHeaders - ] - } - } - } + oauth2_additional_parameters_authorization_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2AuthorizationQueryParams(_1, dictionary) { - const authorizationQueryParams = [...mapPairListToKeyValPairs(dictionary.ast)]?.map(_ => ({ - ..._, - sendIn: 'queryparams' - })); return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - authorization: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.authorization || []), - ...authorizationQueryParams - ] - } - } - } + oauth2_additional_parameters_authorization_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2TokenHeaders(_1, dictionary) { - const tokenHeaders = [...mapPairListToKeyValPairs(dictionary.ast)]?.map(_ => ({ - ..._, - sendIn: 'headers' - })); return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - token: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.token || []), - ...tokenHeaders - ] - } - } - } + oauth2_additional_parameters_token_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2TokenQueryParams(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - tokenQueryParams: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenQueryParams || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_token_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2TokenBodyValues(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - tokenBodyValues: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenBodyValues || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_token_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2RefreshHeaders(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - refreshHeaders: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshHeaders || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_refresh_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2RefreshQueryParams(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - refreshQueryParams: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshQueryParams || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_refresh_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2RefreshBodyValues(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - refreshBodyValues: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshBodyValues || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_refresh_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, authwsse(_1, dictionary) { @@ -930,11 +830,14 @@ const parser = (input) => { const match = grammar.match(input); if (match.succeeded()) { - return sem(match).ast; + let ast = sem(match).ast + + ast = mergeOauth2AdditionalParameters(ast); + + return ast; } else { throw new Error(match.message); } }; -module.exports = parser; - +module.exports = parser; \ No newline at end of file diff --git a/packages/bruno-lang/v2/src/collectionBruToJson.js b/packages/bruno-lang/v2/src/collectionBruToJson.js index 4c49fc39f..029aa337b 100644 --- a/packages/bruno-lang/v2/src/collectionBruToJson.js +++ b/packages/bruno-lang/v2/src/collectionBruToJson.js @@ -1,6 +1,6 @@ const ohm = require('ohm-js'); const _ = require('lodash'); -const { safeParseJson, outdentString } = require('./utils'); +const { safeParseJson, outdentString, mergeOauth2AdditionalParameters } = require('./utils'); const grammar = ohm.grammar(`Bru { BruFile = (meta | query | headers | auth | auths | vars | script | tests | docs | authOAuth2Configs)* @@ -365,130 +365,42 @@ const sem = grammar.createSemantics().addAttribute('ast', { }, oAuth2AuthorizationHeaders(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - authorizationHeaders: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.authorizationHeaders || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_authorization_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2AuthorizationQueryParams(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - authorizationQueryParams: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.authorizationQueryParams || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_authorization_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2TokenHeaders(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - tokenHeaders: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenHeaders || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_token_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2TokenQueryParams(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - tokenQueryParams: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenQueryParams || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_token_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2TokenBodyValues(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - tokenBodyValues: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.tokenBodyValues || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_token_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2RefreshHeaders(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - refreshHeaders: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshHeaders || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_refresh_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2RefreshQueryParams(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - refreshQueryParams: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshQueryParams || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_refresh_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oAuth2RefreshBodyValues(_1, dictionary) { return { - auth: { - oauth2: { - ...(dictionary?.ast?.auth?.oauth2 || {}), - additionalParameters: { - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters || {}), - refreshBodyValues: [ - ...(dictionary?.ast?.auth?.oauth2?.additionalParameters?.refreshBodyValues || []), - ...mapPairListToKeyValPairs(dictionary.ast) - ] - } - } - } + oauth2_additional_parameters_refresh_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, authwsse(_1, dictionary) { @@ -594,7 +506,11 @@ const parser = (input) => { const match = grammar.match(input); if (match.succeeded()) { - return sem(match).ast; + let ast = sem(match).ast; + + ast = mergeOauth2AdditionalParameters(ast); + + return ast; } else { throw new Error(match.message); } diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js index d8a7b13a3..0e848df41 100644 --- a/packages/bruno-lang/v2/src/jsonToBru.js +++ b/packages/bruno-lang/v2/src/jsonToBru.js @@ -251,31 +251,110 @@ ${indentString(`auto_refresh_token: ${(auth?.oauth2?.autoRefreshToken ?? false). } if (auth?.oauth2?.additionalParameters) { - switch(auth?.oauth2?.additionalParameters) { - case 'authorizationHeaders' : - let authorizationHeaders = auth?.oauth2?.additionalParameters?.authorizationHeaders; - bru += `auth:oauth2:authorization_headers { -${enabled(authorizationHeaders) - .map((item) => `${item.name}: ${item.value}`) - .join('\n')} -}`; - break; - case 'authorizationQueryParams' : - let authorizationQueryParams = auth?.oauth2?.additionalParameters?.authorizationQueryParams; - bru += `auth:oauth2:authorization_queryparams { -${enabled(authorizationQueryParams) - .map((item) => `${item.name}: ${item.value}`) - .join('\n')} -}`; - break; - case 'authorizationBodyValues' : - let authorizationBodyValues = auth?.oauth2?.additionalParameters?.authorizationBodyValues; - bru += `auth:oauth2:authorization_queryparams { - ${enabled(authorizationBodyValues) + const { authorization: authorizationParams, token: tokenParams, refresh: refreshParams } = auth?.oauth2?.additionalParameters; + const authorizationHeaders = authorizationParams?.filter(p => p?.sendIn == 'headers'); + if (authorizationHeaders?.length) { + bru += `auth:oauth2:authorization_headers { +${indentString( + enabled(authorizationHeaders) + .filter(item => item?.name?.length) .map((item) => `${item.name}: ${item.value}`) - .join('\n')} - }`; - break; + .join('\n') + )} +} + +`; + } + const authorizationQueryParams = authorizationParams?.filter(p => p?.sendIn == 'queryparams'); + if (authorizationQueryParams?.length) { + bru += `auth:oauth2:authorization_queryparams { +${indentString( + enabled(authorizationQueryParams) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const tokenHeaders = tokenParams?.filter(p => p?.sendIn == 'headers'); + if (tokenHeaders?.length) { + bru += `auth:oauth2:token_headers { +${indentString( + enabled(tokenHeaders) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const tokenQueryParams = tokenParams?.filter(p => p?.sendIn == 'queryparams'); + if (tokenQueryParams?.length) { + bru += `auth:oauth2:token_queryparams { +${indentString( + enabled(tokenQueryParams) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const tokenBodyValues = tokenParams?.filter(p => p?.sendIn == 'body'); + if (tokenBodyValues?.length) { + bru += `auth:oauth2:token_bodyvalues { +${indentString( + enabled(tokenBodyValues) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const refreshHeaders = refreshParams?.filter(p => p?.sendIn == 'headers'); + if (refreshHeaders?.length) { + bru += `auth:oauth2:refresh_headers { +${indentString( + enabled(refreshHeaders) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const refreshQueryParams = refreshParams?.filter(p => p?.sendIn == 'queryparams'); + if (refreshQueryParams?.length) { + bru += `auth:oauth2:refresh_queryparams { +${indentString( + enabled(refreshQueryParams) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const refreshBodyValues = refreshParams?.filter(p => p?.sendIn == 'body'); + if (refreshBodyValues?.length) { + bru += `auth:oauth2:refresh_bodyvalues { +${indentString( + enabled(refreshBodyValues) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; } } } diff --git a/packages/bruno-lang/v2/src/jsonToCollectionBru.js b/packages/bruno-lang/v2/src/jsonToCollectionBru.js index 2812798a5..b1dbfd481 100644 --- a/packages/bruno-lang/v2/src/jsonToCollectionBru.js +++ b/packages/bruno-lang/v2/src/jsonToCollectionBru.js @@ -215,6 +215,114 @@ ${indentString(`auto_refresh_token: ${(auth?.oauth2?.autoRefreshToken ?? false). `; break; } + + if (auth?.oauth2?.additionalParameters) { + const { authorization: authorizationParams, token: tokenParams, refresh: refreshParams } = auth?.oauth2?.additionalParameters; + const authorizationHeaders = authorizationParams?.filter(p => p?.sendIn == 'headers'); + if (authorizationHeaders?.length) { + bru += `auth:oauth2:authorization_headers { +${indentString( + enabled(authorizationHeaders) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const authorizationQueryParams = authorizationParams?.filter(p => p?.sendIn == 'queryparams'); + if (authorizationQueryParams?.length) { + bru += `auth:oauth2:authorization_queryparams { +${indentString( + enabled(authorizationQueryParams) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const tokenHeaders = tokenParams?.filter(p => p?.sendIn == 'headers'); + if (tokenHeaders?.length) { + bru += `auth:oauth2:token_headers { +${indentString( + enabled(tokenHeaders) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const tokenQueryParams = tokenParams?.filter(p => p?.sendIn == 'queryparams'); + if (tokenQueryParams?.length) { + bru += `auth:oauth2:token_queryparams { +${indentString( + enabled(tokenQueryParams) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const tokenBodyValues = tokenParams?.filter(p => p?.sendIn == 'body'); + if (tokenBodyValues?.length) { + bru += `auth:oauth2:token_bodyvalues { +${indentString( + enabled(tokenBodyValues) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const refreshHeaders = refreshParams?.filter(p => p?.sendIn == 'headers'); + if (refreshHeaders?.length) { + bru += `auth:oauth2:refresh_headers { +${indentString( + enabled(refreshHeaders) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const refreshQueryParams = refreshParams?.filter(p => p?.sendIn == 'queryparams'); + if (refreshQueryParams?.length) { + bru += `auth:oauth2:refresh_queryparams { +${indentString( + enabled(refreshQueryParams) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + const refreshBodyValues = refreshParams?.filter(p => p?.sendIn == 'body'); + if (refreshBodyValues?.length) { + bru += `auth:oauth2:refresh_bodyvalues { +${indentString( + enabled(refreshBodyValues) + .filter(item => item?.name?.length) + .map((item) => `${item.name}: ${item.value}`) + .join('\n') + )} +} + +`; + } + } } let reqvars = _.get(vars, 'req'); diff --git a/packages/bruno-lang/v2/src/utils.js b/packages/bruno-lang/v2/src/utils.js index 74b22c952..5be1d225e 100644 --- a/packages/bruno-lang/v2/src/utils.js +++ b/packages/bruno-lang/v2/src/utils.js @@ -29,8 +29,83 @@ const outdentString = (str) => { .join('\n'); }; +const mergeOauth2AdditionalParameters = (ast) => { + let additionalParameters = {}; + const authorizationHeaders = ast?.oauth2_additional_parameters_authorization_headers; + const authorizationQueryParams = ast?.oauth2_additional_parameters_authorization_headers; + const tokenHeaders = ast?.oauth2_additional_parameters_token_headers; + const tokenQueryParams = ast?.oauth2_additional_parameters_token_queryparams; + const tokenBodyValues = ast?.oauth2_additional_parameters_token_bodyvalues; + const refreshHeaders = ast?.oauth2_additional_parameters_refresh_headers; + const refreshQueryParams = ast?.oauth2_additional_parameters_refresh_queryparams; + const refreshBodyValues = ast?.oauth2_additional_parameters_refresh_bodyvalues; + + if (authorizationHeaders?.length || authorizationQueryParams?.length) { + additionalParameters['authorization'] = [] + } + if (authorizationHeaders?.length) { + additionalParameters['authorization'] = [ + ...authorizationHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) + ] + } + if (authorizationQueryParams?.length) { + additionalParameters['authorization'] = [ + ...authorizationQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) + ] + } + + if (tokenHeaders?.length || tokenQueryParams?.length || tokenBodyValues?.length) { + additionalParameters['token'] = [] + } + if (tokenHeaders?.length) { + additionalParameters['token'] = [ + ...tokenHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) + ] + } + if (tokenQueryParams?.length) { + additionalParameters['token'] = [ + ...tokenQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) + ] + } + if (tokenBodyValues?.length) { + additionalParameters['token'] = [ + ...tokenBodyValues?.map(_ => ({ ..._, sendIn: 'body' })) + ] + } + + if (refreshHeaders?.length || refreshQueryParams?.length || refreshBodyValues?.length) { + additionalParameters['refresh'] = [] + } + if (refreshHeaders?.length) { + additionalParameters['token'] = [ + ...refreshHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) + ] + } + if (refreshQueryParams?.length) { + additionalParameters['token'] = [ + ...refreshQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) + ] + } + if (refreshBodyValues?.length) { + additionalParameters['token'] = [ + ...refreshBodyValues?.map(_ => ({ ..._, sendIn: 'body' })) + ] + } + + console.log("mergeee >>>>>", ast?.auth, ast?.auth?.oauth2, additionalParameters); + + if(ast?.auth?.oauth2 && Object.keys(additionalParameters)?.length) { + ast.auth.oauth2.additionalParameters = additionalParameters; + } + + console.log("mergeee >>>>>", ast?.auth); + + return ast; +} + module.exports = { safeParseJson, indentString, - outdentString + outdentString, + mergeOauth2AdditionalParameters }; diff --git a/packages/bruno-schema/src/collections/index.js b/packages/bruno-schema/src/collections/index.js index 3914e6bfa..d59fafc32 100644 --- a/packages/bruno-schema/src/collections/index.js +++ b/packages/bruno-schema/src/collections/index.js @@ -157,6 +157,28 @@ const authApiKeySchema = Yup.object({ .noUnknown(true) .strict(); +const oauth2AuthorizationAdditionalParametersSchema = Yup.object({ + name: Yup.string().nullable(), + value: Yup.string().nullable(), + sendIn: Yup.string() + .oneOf(['headers', 'queryparams', 'body']) + .required('send in property is required'), + enabled: Yup.boolean() +}) + .noUnknown(true) + .strict(); + +const oauth2AdditionalParametersSchema = Yup.object({ + name: Yup.string().nullable(), + value: Yup.string().nullable(), + sendIn: Yup.string() + .oneOf(['headers', 'queryparams', 'body']) + .required('send in property is required'), + enabled: Yup.boolean() + }) + .noUnknown(true) + .strict(); + const oauth2Schema = Yup.object({ grantType: Yup.string() .oneOf(['client_credentials', 'password', 'authorization_code']) @@ -252,6 +274,11 @@ const oauth2Schema = Yup.object({ is: (val) => ['authorization_code'].includes(val), then: Yup.boolean().default(true), otherwise: Yup.boolean() + }), + additionalParameters: Yup.object({ + authorization: Yup.array().of(oauth2AuthorizationAdditionalParametersSchema).optional(), + token: Yup.array().of(oauth2AdditionalParametersSchema).optional(), + refresh: Yup.array().of(oauth2AdditionalParametersSchema).optional() }) }) .noUnknown(true) From 84cd91b798a6a30129af573e74e6ede503398b6d Mon Sep 17 00:00:00 2001 From: lohxt1 Date: Thu, 3 Apr 2025 12:37:17 +0530 Subject: [PATCH 03/15] updates --- packages/bruno-lang/v2/src/utils.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/bruno-lang/v2/src/utils.js b/packages/bruno-lang/v2/src/utils.js index 5be1d225e..d09c197aa 100644 --- a/packages/bruno-lang/v2/src/utils.js +++ b/packages/bruno-lang/v2/src/utils.js @@ -92,13 +92,9 @@ const mergeOauth2AdditionalParameters = (ast) => { ] } - console.log("mergeee >>>>>", ast?.auth, ast?.auth?.oauth2, additionalParameters); - if(ast?.auth?.oauth2 && Object.keys(additionalParameters)?.length) { ast.auth.oauth2.additionalParameters = additionalParameters; } - - console.log("mergeee >>>>>", ast?.auth); return ast; } From f06eb86574f972e2fcfe8f260bbb7b8f11d1c176 Mon Sep 17 00:00:00 2001 From: lohxt1 Date: Thu, 3 Apr 2025 13:48:39 +0530 Subject: [PATCH 04/15] updates --- packages/bruno-schema/src/collections/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bruno-schema/src/collections/index.js b/packages/bruno-schema/src/collections/index.js index d59fafc32..253d644cd 100644 --- a/packages/bruno-schema/src/collections/index.js +++ b/packages/bruno-schema/src/collections/index.js @@ -161,7 +161,7 @@ const oauth2AuthorizationAdditionalParametersSchema = Yup.object({ name: Yup.string().nullable(), value: Yup.string().nullable(), sendIn: Yup.string() - .oneOf(['headers', 'queryparams', 'body']) + .oneOf(['headers', 'queryparams']) .required('send in property is required'), enabled: Yup.boolean() }) From b9c2a423444a44448c8a278e42ba36c56d159466 Mon Sep 17 00:00:00 2001 From: naman-bruno Date: Thu, 3 Apr 2025 16:35:59 +0530 Subject: [PATCH 05/15] feat: added options to add additional params in oauth2 requests --- .../OAuth2/AdditionalParams/StyledWrapper.js | 33 +++- .../Auth/OAuth2/AdditionalParams/index.js | 148 +++++++++++++++--- .../Auth/OAuth2/AuthorizationCode/index.js | 7 +- .../Auth/OAuth2/ClientCredentials/index.js | 7 +- .../Auth/OAuth2/PasswordCredentials/index.js | 7 +- .../ipc/network/authorize-user-in-window.js | 10 +- packages/bruno-electron/src/utils/oauth2.js | 85 +++++++++- packages/bruno-lang/v2/src/bruToJson.js | 6 +- .../bruno-lang/v2/src/collectionBruToJson.js | 6 +- packages/bruno-lang/v2/src/utils.js | 13 +- 10 files changed, 278 insertions(+), 44 deletions(-) diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js index ebb8ee46a..cc8980abe 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js @@ -2,13 +2,42 @@ import styled from 'styled-components'; const StyledWrapper = styled.div` .tabs { - .active { - border-bottom: solid 1px ${(props) => props.theme.input.border}; + .tab { + cursor: pointer; + padding: 4px 8px !important; + font-size: 12px; + border-radius: 4px; + + &:hover { + background-color: ${(props) => props.theme.mode === 'dark' ? 'rgba(99, 102, 241, 0.1)' : 'rgba(99, 102, 241, 0.1)'}; + } + + &.active { + background-color: ${(props) => props.theme.mode === 'dark' ? 'rgba(99, 102, 241, 0.2)' : 'rgba(99, 102, 241, 0.1)'}; + color: ${(props) => props.theme.mode === 'dark' ? '#6366f1' : '#4f46e5'}; + font-weight: 500; + } } } + .additional-parameter-sends-in-selector { select { height: 32px; + width: 100%; + border: 1px solid ${(props) => props.theme.input.border}; + border-radius: 4px; + padding: 0 8px; + + &:focus { + outline: none; + border-color: ${(props) => props.theme.mode === 'dark' ? '#6366f1' : '#4f46e5'}; + } + } + } + + .add-additional-param-actions { + &:hover { + color: ${(props) => props.theme.mode === 'dark' ? '#6366f1' : '#4f46e5'}; } } ` diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js index 1e13b676e..b9b6f66bc 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js @@ -2,7 +2,7 @@ import { useDispatch } from "react-redux"; import React, { forwardRef, useState } from 'react'; import get from 'lodash/get'; import { useTheme } from 'providers/Theme'; -import { IconPlus, IconCaretDown, IconTrash } from '@tabler/icons'; +import { IconPlus, IconCaretDown, IconTrash, IconAdjustmentsHorizontal } from '@tabler/icons'; import { cloneDeep } from "lodash"; import SingleLineEditor from "components/SingleLineEditor/index"; import StyledWrapper from "./StyledWrapper"; @@ -19,7 +19,33 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { additionalParameters = {} } = oAuth; + const isEmptyParam = (param) => { + return !param.name.trim() && !param.value.trim(); + }; + + const hasEmptyRow = () => { + const tabParams = additionalParameters[activeTab] || []; + return tabParams.some(isEmptyParam); + }; + const updateAdditionalParams = ({ updatedAdditionalParams }) => { + const filteredParams = cloneDeep(updatedAdditionalParams); + + Object.keys(filteredParams).forEach(paramType => { + if (filteredParams[paramType]?.length) { + filteredParams[paramType] = filteredParams[paramType].filter(param => + param.name.trim() || param.value.trim() + ); + + if (filteredParams[paramType].length === 0) { + delete filteredParams[paramType]; + } + } else if (Array.isArray(filteredParams[paramType]) && filteredParams[paramType].length === 0) { + // Remove empty arrays + delete filteredParams[paramType]; + } + }); + dispatch( updateAuth({ mode: 'oauth2', @@ -27,7 +53,7 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { itemUid: item.uid, content: { ...oAuth, - additionalParameters: updatedAdditionalParams, + additionalParameters: Object.keys(filteredParams).length > 0 ? filteredParams : undefined } }) ); @@ -35,24 +61,56 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { const handleUpdateAdditionalParam = ({ paramType, key, paramIndex, value }) => { const updatedAdditionalParams = cloneDeep(additionalParameters); + + if (!updatedAdditionalParams[paramType]) { + updatedAdditionalParams[paramType] = []; + } + + if (!updatedAdditionalParams[paramType][paramIndex]) { + updatedAdditionalParams[paramType][paramIndex] = { + name: '', + value: '', + sendIn: 'headers', + enabled: true + }; + } + updatedAdditionalParams[paramType][paramIndex][key] = value; + + // Only filter when updating a parameter updateAdditionalParams({ updatedAdditionalParams }); } const handleDeleteAdditionalParam = ({ paramType, paramIndex }) => { const updatedAdditionalParams = cloneDeep(additionalParameters); - updatedAdditionalParams[paramType] = updatedAdditionalParams[paramType]?.filter((_, index) => index !== paramIndex); + + if (updatedAdditionalParams[paramType]?.length) { + updatedAdditionalParams[paramType] = updatedAdditionalParams[paramType].filter((_, index) => index !== paramIndex); + + // If the array is now empty, ensure we're not sending empty arrays + if (updatedAdditionalParams[paramType].length === 0) { + delete updatedAdditionalParams[paramType]; + } + } + updateAdditionalParams({ updatedAdditionalParams }); } const handleAddNewAdditionalParam = () => { - const paramType = activeTab; - const updatedAdditionalParams = cloneDeep(additionalParameters); - if (!updatedAdditionalParams?.[paramType]) { - updatedAdditionalParams[paramType] = []; + // Prevent adding multiple empty rows + if (hasEmptyRow()) { + return; } - updatedAdditionalParams[paramType] = [ - ...updatedAdditionalParams[paramType], + + const paramType = activeTab; + const localAdditionalParameters = cloneDeep(additionalParameters); + + if (!localAdditionalParameters[paramType]) { + localAdditionalParameters[paramType] = []; + } + + localAdditionalParameters[paramType] = [ + ...localAdditionalParameters[paramType], { name: '', value: '', @@ -60,10 +118,36 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { enabled: true } ]; - updateAdditionalParams({ updatedAdditionalParams }); + + // Don't filter here to allow the empty row to display in UI + // But don't permanently store it in state until it has values + dispatch( + updateAuth({ + mode: 'oauth2', + collectionUid: collection.uid, + itemUid: item.uid, + content: { + ...oAuth, + additionalParameters: localAdditionalParameters, + } + }) + ); } + + // Add a class to the Add Parameter button if it's disabled + const addButtonDisabled = hasEmptyRow(); + return ( +
+
+ +
+ + Additional Parameters + +
+
setActiveTab('authorization')}>Authorization
setActiveTab('token')}>Token
@@ -73,18 +157,17 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { headers={[ { name: 'Key', accessor: 'name', width: '30%' }, { name: 'Value', accessor: 'value', width: '30%' }, - { name: 'Sends In', accessor: 'sendIn', width: '150px' }, + { name: 'Send In', accessor: 'sendIn', width: '150px' }, { name: '', accessor: '', width: '15%' } ]} > - {additionalParameters?.[activeTab]?.map((param, index) => - + {(additionalParameters?.[activeTab] || []).map((param, index) => + handleUpdateAdditionalParam({ paramType: activeTab, key: 'name', @@ -96,9 +179,8 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { handleUpdateAdditionalParam({ paramType: activeTab, key: 'value', @@ -111,7 +193,7 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => {
{ @@ -163,8 +245,12 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { )} -
- +
+ + Add Parameter
) @@ -187,7 +273,19 @@ const Icon = forwardRef((props, ref) => { }); const sendInOptionsMap = { - 'authorization_code': ['headers', 'queryparams'], - 'password': ['headers', 'queryparams', 'body'], - 'client_credentials': ['headers', 'queryparams', 'body'] + 'authorization_code': { + 'authorization': ['headers', 'queryparams'], + 'token': ['headers', 'queryparams', 'body'], + 'refresh': ['headers', 'queryparams', 'body'] + }, + 'password': { + 'authorization': ['headers', 'queryparams'], + 'token': ['headers', 'queryparams', 'body'], + 'refresh': ['headers', 'queryparams', 'body'] + }, + 'client_credentials': { + 'authorization': ['headers', 'queryparams'], + 'token': ['headers', 'queryparams', 'body'], + 'refresh': ['headers', 'queryparams', 'body'] + } } \ No newline at end of file diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js index 5aadcd156..d61bbf013 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js @@ -330,7 +330,12 @@ const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAu
- +
); diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js index f4b01135b..f9fc99973 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js @@ -298,7 +298,12 @@ const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAu - + diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js index 086e10335..f12f50c92 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js @@ -301,7 +301,12 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update - + ); diff --git a/packages/bruno-electron/src/ipc/network/authorize-user-in-window.js b/packages/bruno-electron/src/ipc/network/authorize-user-in-window.js index 7d2e23abc..cb2903d7c 100644 --- a/packages/bruno-electron/src/ipc/network/authorize-user-in-window.js +++ b/packages/bruno-electron/src/ipc/network/authorize-user-in-window.js @@ -5,7 +5,7 @@ const matchesCallbackUrl = (url, callbackUrl) => { return url ? url.href.startsWith(callbackUrl.href) : false; }; -const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session }) => { +const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session, additionalHeaders = {} }) => { return new Promise(async (resolve, reject) => { let finalUrl = null; let debugInfo = { @@ -75,6 +75,14 @@ const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session }) => { webSession.webRequest.onBeforeSendHeaders((details, callback) => { const { id: requestId, requestHeaders, method, url } = details; + + if (details.resourceType === 'mainFrame' && Object.keys(additionalHeaders).length > 0) { + // Add our custom headers + for (const [name, value] of Object.entries(additionalHeaders)) { + requestHeaders[name] = value; + } + } + if (currentMainRequest?.requestId === requestId) { currentMainRequest.request = { url, diff --git a/packages/bruno-electron/src/utils/oauth2.js b/packages/bruno-electron/src/utils/oauth2.js index 882f39767..50b1f73ed 100644 --- a/packages/bruno-electron/src/utils/oauth2.js +++ b/packages/bruno-electron/src/utils/oauth2.js @@ -61,6 +61,7 @@ const getOAuth2TokenUsingAuthorizationCode = async ({ request, collectionUid, fo credentialsId, autoRefreshToken, autoFetchToken, + additionalParameters, } = oAuth; const url = requestCopy?.oauth2?.accessTokenUrl; if (!forceFetch) { @@ -140,6 +141,12 @@ const getOAuth2TokenUsingAuthorizationCode = async ({ request, collectionUid, fo if (scope) { data.scope = scope; } + + // Apply additional parameters to token request + if (additionalParameters?.token?.length) { + applyAdditionalParameters(requestCopy, data, additionalParameters.token); + } + requestCopy.data = qs.stringify(data); requestCopy.url = url; requestCopy.responseType = 'arraybuffer'; @@ -249,7 +256,7 @@ const getOAuth2TokenUsingAuthorizationCode = async ({ request, collectionUid, fo const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => { return new Promise(async (resolve, reject) => { const { oauth2 } = request; - const { callbackUrl, clientId, authorizationUrl, scope, state, pkce, accessTokenUrl } = oauth2; + const { callbackUrl, clientId, authorizationUrl, scope, state, pkce, accessTokenUrl, additionalParameters } = oauth2; const authorizationUrlWithQueryParams = new URL(authorizationUrl); authorizationUrlWithQueryParams.searchParams.append('response_type', 'code'); @@ -267,12 +274,23 @@ const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => { if (state) { authorizationUrlWithQueryParams.searchParams.append('state', state); } + if (additionalParameters?.authorization?.length) { + additionalParameters.authorization.forEach(param => { + if (param.enabled && param.name) { + if (param.sendIn === 'queryparams') { + authorizationUrlWithQueryParams.searchParams.append(param.name, param.value || ''); + } + } + }); + } + try { const authorizeUrl = authorizationUrlWithQueryParams.toString(); const { authorizationCode, debugInfo } = await authorizeUserInWindow({ authorizeUrl, callbackUrl, - session: oauth2Store.getSessionIdOfCollection({ collectionUid, url: accessTokenUrl }) + session: oauth2Store.getSessionIdOfCollection({ collectionUid, url: accessTokenUrl }), + additionalHeaders: getAdditionalHeaders(additionalParameters?.authorization) }); resolve({ authorizationCode, debugInfo }); } catch (err) { @@ -281,6 +299,21 @@ const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => { }); }; +const getAdditionalHeaders = (params) => { + if (!params || !params.length) { + return {}; + } + + const headers = {}; + params.forEach(param => { + if (param.enabled && param.name && param.sendIn === 'headers') { + headers[param.name] = param.value || ''; + } + }); + + return headers; +}; + // CLIENT CREDENTIALS const getOAuth2TokenUsingClientCredentials = async ({ request, collectionUid, forceFetch = false, certsAndProxyConfig }) => { @@ -294,6 +327,7 @@ const getOAuth2TokenUsingClientCredentials = async ({ request, collectionUid, fo credentialsId, autoRefreshToken, autoFetchToken, + additionalParameters, } = oAuth; const url = requestCopy?.oauth2?.accessTokenUrl; @@ -366,6 +400,10 @@ const getOAuth2TokenUsingClientCredentials = async ({ request, collectionUid, fo if (scope) { data.scope = scope; } + if (additionalParameters?.token?.length) { + applyAdditionalParameters(requestCopy, data, additionalParameters.token); + } + requestCopy.data = qs.stringify(data); requestCopy.url = url; requestCopy.responseType = 'arraybuffer'; @@ -480,6 +518,7 @@ const getOAuth2TokenUsingPasswordCredentials = async ({ request, collectionUid, credentialsId, autoRefreshToken, autoFetchToken, + additionalParameters, } = oAuth; const url = requestCopy?.oauth2?.accessTokenUrl; @@ -554,6 +593,10 @@ const getOAuth2TokenUsingPasswordCredentials = async ({ request, collectionUid, if (scope) { data.scope = scope; } + if (additionalParameters?.token?.length) { + applyAdditionalParameters(requestCopy, data, additionalParameters.token); + } + requestCopy.data = qs.stringify(data); requestCopy.url = url; requestCopy.responseType = 'arraybuffer'; @@ -671,6 +714,10 @@ const refreshOauth2Token = async ({ requestCopy, collectionUid, certsAndProxyCon if (clientSecret) { data.client_secret = clientSecret; } + if (oAuth.additionalParameters?.refresh?.length) { + applyAdditionalParameters(requestCopy, data, oAuth.additionalParameters.refresh); + } + requestCopy.method = 'POST'; requestCopy.headers['content-type'] = 'application/x-www-form-urlencoded'; requestCopy.headers['Accept'] = 'application/json'; @@ -678,7 +725,7 @@ const refreshOauth2Token = async ({ requestCopy, collectionUid, certsAndProxyCon requestCopy.url = url; requestCopy.responseType = 'arraybuffer'; - // Initialize variables to hold request and response data for debugging + // Initialize variables to hold request and response data for debugging let axiosRequestInfo = null; let axiosResponseInfo = null; let debugInfo = { data: [] }; @@ -797,6 +844,38 @@ const generateCodeChallenge = (codeVerifier) => { return base64Hash; }; +// Apply additional parameters to a request +const applyAdditionalParameters = (requestCopy, data, params) => { + if (!params || !params.length) { + return; + } + + params.forEach(param => { + if (!param.enabled || !param.name) { + return; + } + + switch (param.sendIn) { + case 'headers': + requestCopy.headers[param.name] = param.value || ''; + break; + case 'queryparams': + // For query params, add to URL + if (!requestCopy.url.includes('?')) { + requestCopy.url += '?'; + } else if (!requestCopy.url.endsWith('&') && !requestCopy.url.endsWith('?')) { + requestCopy.url += '&'; + } + requestCopy.url += `${encodeURIComponent(param.name)}=${encodeURIComponent(param.value || '')}`; + break; + case 'body': + // For body, add to data object + data[param.name] = param.value || ''; + break; + } + }); +}; + module.exports = { getOAuth2TokenUsingAuthorizationCode, getOAuth2AuthorizationCode, diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index 7e61afe45..9db992d9e 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -103,9 +103,9 @@ const grammar = ohm.grammar(`Bru { oAuth2TokenHeaders = "auth:oauth2:token_headers" dictionary oAuth2TokenQueryParams = "auth:oauth2:token_queryparams" dictionary oAuth2TokenBodyValues = "auth:oauth2:token_bodyvalues" dictionary - oAuth2RefreshHeaders = "auth:oauth2:authorization_headers" dictionary - oAuth2RefreshQueryParams = "auth:oauth2:authorization_queryparams" dictionary - oAuth2RefreshBodyValues = "auth:oauth2:authorization_bodyvalues" dictionary + oAuth2RefreshHeaders = "auth:oauth2:refresh_headers" dictionary + oAuth2RefreshQueryParams = "auth:oauth2:refresh_queryparams" dictionary + oAuth2RefreshBodyValues = "auth:oauth2:refresh_bodyvalues" dictionary body = "body" st* "{" nl* textblock tagend bodyjson = "body:json" st* "{" nl* textblock tagend diff --git a/packages/bruno-lang/v2/src/collectionBruToJson.js b/packages/bruno-lang/v2/src/collectionBruToJson.js index 029aa337b..178afd87a 100644 --- a/packages/bruno-lang/v2/src/collectionBruToJson.js +++ b/packages/bruno-lang/v2/src/collectionBruToJson.js @@ -41,9 +41,9 @@ const grammar = ohm.grammar(`Bru { oAuth2TokenHeaders = "auth:oauth2:token_headers" dictionary oAuth2TokenQueryParams = "auth:oauth2:token_queryparams" dictionary oAuth2TokenBodyValues = "auth:oauth2:token_bodyvalues" dictionary - oAuth2RefreshHeaders = "auth:oauth2:authorization_headers" dictionary - oAuth2RefreshQueryParams = "auth:oauth2:authorization_queryparams" dictionary - oAuth2RefreshBodyValues = "auth:oauth2:authorization_bodyvalues" dictionary + oAuth2RefreshHeaders = "auth:oauth2:refresh_headers" dictionary + oAuth2RefreshQueryParams = "auth:oauth2:refresh_queryparams" dictionary + oAuth2RefreshBodyValues = "auth:oauth2:refresh_bodyvalues" dictionary headers = "headers" dictionary diff --git a/packages/bruno-lang/v2/src/utils.js b/packages/bruno-lang/v2/src/utils.js index d09c197aa..64d377aee 100644 --- a/packages/bruno-lang/v2/src/utils.js +++ b/packages/bruno-lang/v2/src/utils.js @@ -32,7 +32,7 @@ const outdentString = (str) => { const mergeOauth2AdditionalParameters = (ast) => { let additionalParameters = {}; const authorizationHeaders = ast?.oauth2_additional_parameters_authorization_headers; - const authorizationQueryParams = ast?.oauth2_additional_parameters_authorization_headers; + const authorizationQueryParams = ast?.oauth2_additional_parameters_authorization_queryparams; const tokenHeaders = ast?.oauth2_additional_parameters_token_headers; const tokenQueryParams = ast?.oauth2_additional_parameters_token_queryparams; const tokenBodyValues = ast?.oauth2_additional_parameters_token_bodyvalues; @@ -50,6 +50,7 @@ const mergeOauth2AdditionalParameters = (ast) => { } if (authorizationQueryParams?.length) { additionalParameters['authorization'] = [ + ...additionalParameters['authorization'] || [], ...authorizationQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) ] } @@ -64,11 +65,13 @@ const mergeOauth2AdditionalParameters = (ast) => { } if (tokenQueryParams?.length) { additionalParameters['token'] = [ + ...additionalParameters['token'] || [], ...tokenQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) ] } if (tokenBodyValues?.length) { additionalParameters['token'] = [ + ...additionalParameters['token'] || [], ...tokenBodyValues?.map(_ => ({ ..._, sendIn: 'body' })) ] } @@ -77,17 +80,19 @@ const mergeOauth2AdditionalParameters = (ast) => { additionalParameters['refresh'] = [] } if (refreshHeaders?.length) { - additionalParameters['token'] = [ + additionalParameters['refresh'] = [ ...refreshHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) ] } if (refreshQueryParams?.length) { - additionalParameters['token'] = [ + additionalParameters['refresh'] = [ + ...additionalParameters['refresh'] || [], ...refreshQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) ] } if (refreshBodyValues?.length) { - additionalParameters['token'] = [ + additionalParameters['refresh'] = [ + ...additionalParameters['refresh'] || [], ...refreshBodyValues?.map(_ => ({ ..._, sendIn: 'body' })) ] } From dd7ff970903c37b98bd938e4f69a5ffe7f19f6a9 Mon Sep 17 00:00:00 2001 From: lohxt1 Date: Sun, 6 Apr 2025 19:01:23 +0530 Subject: [PATCH 06/15] fix(oauth2): improve additional parameters handling and ui updates ~ fix oauth2 additional parameters encoding and url handling ~ show authorization tab only for authorization_code grant type ~ set active tab based on grant type ~ update schema validation for grant type-specific parameters ~ add url tooltip in responsepane timeline ~ clean up variable naming and parameter handling --- .../Auth/OAuth2/AdditionalParams/index.js | 37 +++++++++---------- .../Timeline/TimelineItem/Request/index.js | 2 +- .../src/ipc/network/prepare-request.js | 18 ++++++--- packages/bruno-electron/src/utils/oauth2.js | 29 ++++++++------- packages/bruno-lang/v2/src/utils.js | 28 +++++++------- .../bruno-schema/src/collections/index.js | 6 ++- 6 files changed, 66 insertions(+), 54 deletions(-) diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js index b9b6f66bc..20c4923cd 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js @@ -11,7 +11,6 @@ import Table from "components/Table/index"; const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { const dispatch = useDispatch(); const { storedTheme } = useTheme(); - const [activeTab, setActiveTab] = useState('authorization'); const oAuth = get(request, 'auth.oauth2', {}); const { @@ -19,6 +18,8 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { additionalParameters = {} } = oAuth; + const [activeTab, setActiveTab] = useState(grantType == 'authorization_code' ? 'authorization' : 'token'); + const isEmptyParam = (param) => { return !param.name.trim() && !param.value.trim(); }; @@ -28,8 +29,8 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { return tabParams.some(isEmptyParam); }; - const updateAdditionalParams = ({ updatedAdditionalParams }) => { - const filteredParams = cloneDeep(updatedAdditionalParams); + const updateAdditionalParameters = ({ updatedAdditionalParameters }) => { + const filteredParams = cloneDeep(updatedAdditionalParameters); Object.keys(filteredParams).forEach(paramType => { if (filteredParams[paramType]?.length) { @@ -60,14 +61,14 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { } const handleUpdateAdditionalParam = ({ paramType, key, paramIndex, value }) => { - const updatedAdditionalParams = cloneDeep(additionalParameters); + const updatedAdditionalParameters = cloneDeep(additionalParameters); - if (!updatedAdditionalParams[paramType]) { - updatedAdditionalParams[paramType] = []; + if (!updatedAdditionalParameters[paramType]) { + updatedAdditionalParameters[paramType] = []; } - if (!updatedAdditionalParams[paramType][paramIndex]) { - updatedAdditionalParams[paramType][paramIndex] = { + if (!updatedAdditionalParameters[paramType][paramIndex]) { + updatedAdditionalParameters[paramType][paramIndex] = { name: '', value: '', sendIn: 'headers', @@ -75,25 +76,25 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { }; } - updatedAdditionalParams[paramType][paramIndex][key] = value; + updatedAdditionalParameters[paramType][paramIndex][key] = value; // Only filter when updating a parameter - updateAdditionalParams({ updatedAdditionalParams }); + updateAdditionalParameters({ updatedAdditionalParameters }); } const handleDeleteAdditionalParam = ({ paramType, paramIndex }) => { - const updatedAdditionalParams = cloneDeep(additionalParameters); + const updatedAdditionalParameters = cloneDeep(additionalParameters); - if (updatedAdditionalParams[paramType]?.length) { - updatedAdditionalParams[paramType] = updatedAdditionalParams[paramType].filter((_, index) => index !== paramIndex); + if (updatedAdditionalParameters[paramType]?.length) { + updatedAdditionalParameters[paramType] = updatedAdditionalParameters[paramType].filter((_, index) => index !== paramIndex); // If the array is now empty, ensure we're not sending empty arrays - if (updatedAdditionalParams[paramType].length === 0) { - delete updatedAdditionalParams[paramType]; + if (updatedAdditionalParameters[paramType].length === 0) { + delete updatedAdditionalParameters[paramType]; } } - updateAdditionalParams({ updatedAdditionalParams }); + updateAdditionalParameters({ updatedAdditionalParameters }); } const handleAddNewAdditionalParam = () => { @@ -149,7 +150,7 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => {
-
setActiveTab('authorization')}>Authorization
+ {grantType == 'authorization_code' &&
setActiveTab('authorization')}>Authorization
}
setActiveTab('token')}>Token
setActiveTab('refresh')}>Refresh
@@ -279,12 +280,10 @@ const sendInOptionsMap = { 'refresh': ['headers', 'queryparams', 'body'] }, 'password': { - 'authorization': ['headers', 'queryparams'], 'token': ['headers', 'queryparams', 'body'], 'refresh': ['headers', 'queryparams', 'body'] }, 'client_credentials': { - 'authorization': ['headers', 'queryparams'], 'token': ['headers', 'queryparams', 'body'], 'refresh': ['headers', 'queryparams', 'body'] } diff --git a/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Request/index.js b/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Request/index.js index 1cef8e9e5..a1d4cca22 100644 --- a/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Request/index.js +++ b/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Request/index.js @@ -26,7 +26,7 @@ const Request = ({ collection, request, item, width }) => {
{/* Method and URL */}
-
{url}
+
{url}
{/* Headers */} diff --git a/packages/bruno-electron/src/ipc/network/prepare-request.js b/packages/bruno-electron/src/ipc/network/prepare-request.js index 749e32a6d..686182ee6 100644 --- a/packages/bruno-electron/src/ipc/network/prepare-request.js +++ b/packages/bruno-electron/src/ipc/network/prepare-request.js @@ -87,7 +87,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenHeaderPrefix: get(collectionAuth, 'oauth2.tokenHeaderPrefix'), tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey'), autoFetchToken: get(collectionAuth, 'oauth2.autoFetchToken'), - autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken') + autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken'), + additionalParameters: get(collectionAuth, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; case 'authorization_code': @@ -108,7 +109,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenHeaderPrefix: get(collectionAuth, 'oauth2.tokenHeaderPrefix'), tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey'), autoFetchToken: get(collectionAuth, 'oauth2.autoFetchToken'), - autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken') + autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken'), + additionalParameters: get(collectionAuth, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; case 'client_credentials': @@ -125,7 +127,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenHeaderPrefix: get(collectionAuth, 'oauth2.tokenHeaderPrefix'), tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey'), autoFetchToken: get(collectionAuth, 'oauth2.autoFetchToken'), - autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken') + autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken'), + additionalParameters: get(collectionAuth, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; } @@ -185,7 +188,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenHeaderPrefix: get(request, 'auth.oauth2.tokenHeaderPrefix'), tokenQueryKey: get(request, 'auth.oauth2.tokenQueryKey'), autoFetchToken: get(request, 'auth.oauth2.autoFetchToken'), - autoRefreshToken: get(request, 'auth.oauth2.autoRefreshToken') + autoRefreshToken: get(request, 'auth.oauth2.autoRefreshToken'), + additionalParameters: get(request, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; case 'authorization_code': @@ -206,7 +210,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenHeaderPrefix: get(request, 'auth.oauth2.tokenHeaderPrefix'), tokenQueryKey: get(request, 'auth.oauth2.tokenQueryKey'), autoFetchToken: get(request, 'auth.oauth2.autoFetchToken'), - autoRefreshToken: get(request, 'auth.oauth2.autoRefreshToken') + autoRefreshToken: get(request, 'auth.oauth2.autoRefreshToken'), + additionalParameters: get(request, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; case 'client_credentials': @@ -223,7 +228,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenHeaderPrefix: get(request, 'auth.oauth2.tokenHeaderPrefix'), tokenQueryKey: get(request, 'auth.oauth2.tokenQueryKey'), autoFetchToken: get(request, 'auth.oauth2.autoFetchToken'), - autoRefreshToken: get(request, 'auth.oauth2.autoRefreshToken') + autoRefreshToken: get(request, 'auth.oauth2.autoRefreshToken'), + additionalParameters: get(request, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; } diff --git a/packages/bruno-electron/src/utils/oauth2.js b/packages/bruno-electron/src/utils/oauth2.js index 50b1f73ed..24cc2bfed 100644 --- a/packages/bruno-electron/src/utils/oauth2.js +++ b/packages/bruno-electron/src/utils/oauth2.js @@ -142,13 +142,13 @@ const getOAuth2TokenUsingAuthorizationCode = async ({ request, collectionUid, fo data.scope = scope; } + requestCopy.url = url; // Apply additional parameters to token request if (additionalParameters?.token?.length) { applyAdditionalParameters(requestCopy, data, additionalParameters.token); } requestCopy.data = qs.stringify(data); - requestCopy.url = url; requestCopy.responseType = 'arraybuffer'; // Initialize variables to hold request and response data for debugging @@ -400,12 +400,13 @@ const getOAuth2TokenUsingClientCredentials = async ({ request, collectionUid, fo if (scope) { data.scope = scope; } + + requestCopy.url = url; if (additionalParameters?.token?.length) { applyAdditionalParameters(requestCopy, data, additionalParameters.token); } requestCopy.data = qs.stringify(data); - requestCopy.url = url; requestCopy.responseType = 'arraybuffer'; // Initialize variables to hold request and response data for debugging @@ -593,12 +594,13 @@ const getOAuth2TokenUsingPasswordCredentials = async ({ request, collectionUid, if (scope) { data.scope = scope; } + + requestCopy.url = url; if (additionalParameters?.token?.length) { applyAdditionalParameters(requestCopy, data, additionalParameters.token); } requestCopy.data = qs.stringify(data); - requestCopy.url = url; requestCopy.responseType = 'arraybuffer'; // Initialize variables to hold request and response data for debugging @@ -714,6 +716,8 @@ const refreshOauth2Token = async ({ requestCopy, collectionUid, certsAndProxyCon if (clientSecret) { data.client_secret = clientSecret; } + + requestCopy.url = url; if (oAuth.additionalParameters?.refresh?.length) { applyAdditionalParameters(requestCopy, data, oAuth.additionalParameters.refresh); } @@ -722,7 +726,6 @@ const refreshOauth2Token = async ({ requestCopy, collectionUid, certsAndProxyCon requestCopy.headers['content-type'] = 'application/x-www-form-urlencoded'; requestCopy.headers['Accept'] = 'application/json'; requestCopy.data = qs.stringify(data); - requestCopy.url = url; requestCopy.responseType = 'arraybuffer'; // Initialize variables to hold request and response data for debugging @@ -845,11 +848,7 @@ const generateCodeChallenge = (codeVerifier) => { }; // Apply additional parameters to a request -const applyAdditionalParameters = (requestCopy, data, params) => { - if (!params || !params.length) { - return; - } - +const applyAdditionalParameters = (requestCopy, data, params = []) => { params.forEach(param => { if (!param.enabled || !param.name) { return; @@ -861,12 +860,14 @@ const applyAdditionalParameters = (requestCopy, data, params) => { break; case 'queryparams': // For query params, add to URL - if (!requestCopy.url.includes('?')) { - requestCopy.url += '?'; - } else if (!requestCopy.url.endsWith('&') && !requestCopy.url.endsWith('?')) { - requestCopy.url += '&'; + try { + let url = new URL(requestCopy.url); + url.searchParams.append(param.name, param.value); + requestCopy.url = url.href; + } + catch (error) { + console.error('invalid token/refresh url', requestCopy.url); } - requestCopy.url += `${encodeURIComponent(param.name)}=${encodeURIComponent(param.value || '')}`; break; case 'body': // For body, add to data object diff --git a/packages/bruno-lang/v2/src/utils.js b/packages/bruno-lang/v2/src/utils.js index 64d377aee..aaef783c4 100644 --- a/packages/bruno-lang/v2/src/utils.js +++ b/packages/bruno-lang/v2/src/utils.js @@ -40,19 +40,21 @@ const mergeOauth2AdditionalParameters = (ast) => { const refreshQueryParams = ast?.oauth2_additional_parameters_refresh_queryparams; const refreshBodyValues = ast?.oauth2_additional_parameters_refresh_bodyvalues; - if (authorizationHeaders?.length || authorizationQueryParams?.length) { - additionalParameters['authorization'] = [] - } - if (authorizationHeaders?.length) { - additionalParameters['authorization'] = [ - ...authorizationHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) - ] - } - if (authorizationQueryParams?.length) { - additionalParameters['authorization'] = [ - ...additionalParameters['authorization'] || [], - ...authorizationQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) - ] + if (ast?.auth?.oauth2?.grantType == 'authorization_code') { + if (authorizationHeaders?.length || authorizationQueryParams?.length) { + additionalParameters['authorization'] = [] + } + if (authorizationHeaders?.length) { + additionalParameters['authorization'] = [ + ...authorizationHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) + ] + } + if (authorizationQueryParams?.length) { + additionalParameters['authorization'] = [ + ...additionalParameters['authorization'] || [], + ...authorizationQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) + ] + } } if (tokenHeaders?.length || tokenQueryParams?.length || tokenBodyValues?.length) { diff --git a/packages/bruno-schema/src/collections/index.js b/packages/bruno-schema/src/collections/index.js index 253d644cd..936eee680 100644 --- a/packages/bruno-schema/src/collections/index.js +++ b/packages/bruno-schema/src/collections/index.js @@ -276,7 +276,11 @@ const oauth2Schema = Yup.object({ otherwise: Yup.boolean() }), additionalParameters: Yup.object({ - authorization: Yup.array().of(oauth2AuthorizationAdditionalParametersSchema).optional(), + authorization: Yup.mixed().when('grantType', { + is: 'authorization_code', + then: Yup.array().of(oauth2AuthorizationAdditionalParametersSchema).required(), + otherwise: Yup.mixed().nullable().optional() + }), token: Yup.array().of(oauth2AdditionalParametersSchema).optional(), refresh: Yup.array().of(oauth2AdditionalParametersSchema).optional() }) From 0e6c36f62c0625fd91ebc8ec67f147ce3f761388 Mon Sep 17 00:00:00 2001 From: lohit Date: Thu, 15 May 2025 23:19:50 +0530 Subject: [PATCH 07/15] fix: save disabled additional params rows --- packages/bruno-lang/v2/src/jsonToBru.js | 36 +++++++++---------- .../bruno-lang/v2/src/jsonToCollectionBru.js | 36 +++++++++---------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js index 0e848df41..8105f54b3 100644 --- a/packages/bruno-lang/v2/src/jsonToBru.js +++ b/packages/bruno-lang/v2/src/jsonToBru.js @@ -256,35 +256,33 @@ ${indentString(`auto_refresh_token: ${(auth?.oauth2?.autoRefreshToken ?? false). if (authorizationHeaders?.length) { bru += `auth:oauth2:authorization_headers { ${indentString( - enabled(authorizationHeaders) + authorizationHeaders .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } - `; } const authorizationQueryParams = authorizationParams?.filter(p => p?.sendIn == 'queryparams'); if (authorizationQueryParams?.length) { bru += `auth:oauth2:authorization_queryparams { ${indentString( - enabled(authorizationQueryParams) + authorizationQueryParams .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} -} - +} `; } const tokenHeaders = tokenParams?.filter(p => p?.sendIn == 'headers'); if (tokenHeaders?.length) { bru += `auth:oauth2:token_headers { ${indentString( - enabled(tokenHeaders) + tokenHeaders .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -295,9 +293,9 @@ ${indentString( if (tokenQueryParams?.length) { bru += `auth:oauth2:token_queryparams { ${indentString( - enabled(tokenQueryParams) + tokenQueryParams .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -308,9 +306,9 @@ ${indentString( if (tokenBodyValues?.length) { bru += `auth:oauth2:token_bodyvalues { ${indentString( - enabled(tokenBodyValues) + tokenBodyValues .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -321,9 +319,9 @@ ${indentString( if (refreshHeaders?.length) { bru += `auth:oauth2:refresh_headers { ${indentString( - enabled(refreshHeaders) + refreshHeaders .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -334,9 +332,9 @@ ${indentString( if (refreshQueryParams?.length) { bru += `auth:oauth2:refresh_queryparams { ${indentString( - enabled(refreshQueryParams) + refreshQueryParams .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -347,9 +345,9 @@ ${indentString( if (refreshBodyValues?.length) { bru += `auth:oauth2:refresh_bodyvalues { ${indentString( - enabled(refreshBodyValues) + refreshBodyValues .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } diff --git a/packages/bruno-lang/v2/src/jsonToCollectionBru.js b/packages/bruno-lang/v2/src/jsonToCollectionBru.js index b1dbfd481..46849289e 100644 --- a/packages/bruno-lang/v2/src/jsonToCollectionBru.js +++ b/packages/bruno-lang/v2/src/jsonToCollectionBru.js @@ -222,35 +222,33 @@ ${indentString(`auto_refresh_token: ${(auth?.oauth2?.autoRefreshToken ?? false). if (authorizationHeaders?.length) { bru += `auth:oauth2:authorization_headers { ${indentString( - enabled(authorizationHeaders) + authorizationHeaders .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } - `; } const authorizationQueryParams = authorizationParams?.filter(p => p?.sendIn == 'queryparams'); if (authorizationQueryParams?.length) { bru += `auth:oauth2:authorization_queryparams { ${indentString( - enabled(authorizationQueryParams) + authorizationQueryParams .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} -} - +} `; } const tokenHeaders = tokenParams?.filter(p => p?.sendIn == 'headers'); if (tokenHeaders?.length) { bru += `auth:oauth2:token_headers { ${indentString( - enabled(tokenHeaders) + tokenHeaders .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -261,9 +259,9 @@ ${indentString( if (tokenQueryParams?.length) { bru += `auth:oauth2:token_queryparams { ${indentString( - enabled(tokenQueryParams) + tokenQueryParams .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -274,9 +272,9 @@ ${indentString( if (tokenBodyValues?.length) { bru += `auth:oauth2:token_bodyvalues { ${indentString( - enabled(tokenBodyValues) + tokenBodyValues .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -287,9 +285,9 @@ ${indentString( if (refreshHeaders?.length) { bru += `auth:oauth2:refresh_headers { ${indentString( - enabled(refreshHeaders) + refreshHeaders .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -300,9 +298,9 @@ ${indentString( if (refreshQueryParams?.length) { bru += `auth:oauth2:refresh_queryparams { ${indentString( - enabled(refreshQueryParams) + refreshQueryParams .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } @@ -313,9 +311,9 @@ ${indentString( if (refreshBodyValues?.length) { bru += `auth:oauth2:refresh_bodyvalues { ${indentString( - enabled(refreshBodyValues) + refreshBodyValues .filter(item => item?.name?.length) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} } From b20de425982cd1087ced945f6d1ddf20d720fe66 Mon Sep 17 00:00:00 2001 From: lohit Date: Wed, 23 Jul 2025 20:40:54 +0530 Subject: [PATCH 08/15] Update authorize-user-in-window.js --- .../src/ipc/network/authorize-user-in-window.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bruno-electron/src/ipc/network/authorize-user-in-window.js b/packages/bruno-electron/src/ipc/network/authorize-user-in-window.js index cf92e7f3b..4c671fb62 100644 --- a/packages/bruno-electron/src/ipc/network/authorize-user-in-window.js +++ b/packages/bruno-electron/src/ipc/network/authorize-user-in-window.js @@ -5,7 +5,7 @@ const matchesCallbackUrl = (url, callbackUrl) => { return url ? url.href.startsWith(callbackUrl.href) : false; }; -const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session, grantType = 'authorization_code' }) => { +const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session, additionalHeaders = {}, grantType = 'authorization_code' }) => { return new Promise(async (resolve, reject) => { let finalUrl = null; let debugInfo = { @@ -219,4 +219,4 @@ const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session, grantType = }); }; -module.exports = { authorizeUserInWindow, matchesCallbackUrl }; \ No newline at end of file +module.exports = { authorizeUserInWindow, matchesCallbackUrl }; From ceab0b4dc163ecdac4e43d6541bd23589ac33c8f Mon Sep 17 00:00:00 2001 From: lohit-bruno Date: Wed, 13 Aug 2025 21:42:04 +0530 Subject: [PATCH 09/15] additional params updates --- .../Auth/OAuth2/AdditionalParams/index.js | 36 +- .../RequestPane/Auth/OAuth2/Implicit/index.js | 71 +--- .../Auth/OAuth2/Oauth2ActionButtons/index.js | 18 +- .../src/ipc/network/interpolate-vars.js | 33 ++ .../src/ipc/network/prepare-request.js | 6 +- packages/bruno-electron/src/utils/oauth2.js | 21 +- .../bruno-filestore/src/formats/bru/index.ts | 21 ++ .../fixtures/oauth2-additional-params.js | 116 ++++++ .../tests/oauth2-additional-params.spec.js | 45 +++ .../bru/utils/oauth2-additional-params.ts | 141 ++++++++ packages/bruno-lang/v2/src/bruToJson.js | 2 - .../bruno-lang/v2/src/collectionBruToJson.js | 2 - packages/bruno-lang/v2/src/jsonToBru.js | 16 +- .../bruno-lang/v2/src/jsonToCollectionBru.js | 16 +- .../v2/tests/oauth2-additional-params.spec.js | 329 ++++++++++++++++++ 15 files changed, 780 insertions(+), 93 deletions(-) create mode 100644 packages/bruno-filestore/src/formats/bru/tests/fixtures/oauth2-additional-params.js create mode 100644 packages/bruno-filestore/src/formats/bru/tests/oauth2-additional-params.spec.js create mode 100644 packages/bruno-filestore/src/formats/bru/utils/oauth2-additional-params.ts create mode 100644 packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js index 20c4923cd..0069c5203 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js @@ -18,7 +18,9 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { additionalParameters = {} } = oAuth; - const [activeTab, setActiveTab] = useState(grantType == 'authorization_code' ? 'authorization' : 'token'); + const [activeTab, setActiveTab] = useState( + (grantType == 'authorization_code' || grantType == 'implicit') ? 'authorization' : 'token' + ); const isEmptyParam = (param) => { return !param.name.trim() && !param.value.trim(); @@ -138,6 +140,29 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { // Add a class to the Add Parameter button if it's disabled const addButtonDisabled = hasEmptyRow(); + // Define available tabs for each grant type + const getAvailableTabs = (grantType) => { + const tabConfig = { + 'authorization_code': ['authorization', 'token', 'refresh'], + 'implicit': ['authorization'], + 'password': ['token', 'refresh'], + 'client_credentials': ['token', 'refresh'] + }; + return tabConfig[grantType] || ['token', 'refresh']; + }; + + const availableTabs = getAvailableTabs(grantType); + + const renderTab = (tabKey, tabLabel) => ( +
setActiveTab(tabKey)} + > + {tabLabel} +
+ ); + return (
@@ -150,9 +175,9 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => {
- {grantType == 'authorization_code' &&
setActiveTab('authorization')}>Authorization
} -
setActiveTab('token')}>Token
-
setActiveTab('refresh')}>Refresh
+ {availableTabs.includes('authorization') && renderTab('authorization', 'Authorization')} + {availableTabs.includes('token') && renderTab('token', 'Token')} + {availableTabs.includes('refresh') && renderTab('refresh', 'Refresh')}
(dropdownTippyRef.current = ref); - const [fetchingToken, toggleFetchingToken] = useState(false); const oAuth = get(request, 'auth.oauth2', {}); const { @@ -49,38 +47,6 @@ const OAuth2Implicit = ({ save, item = {}, request, handleRun, updateAuth, colle ); }); - const handleFetchOauth2Credentials = async () => { - let requestCopy = cloneDeep(request); - requestCopy.oauth2 = requestCopy?.auth.oauth2; - requestCopy.headers = {}; - toggleFetchingToken(true); - try { - const result = await dispatch(fetchOauth2Credentials({ - itemUid: item.uid, - request: requestCopy, - collection, - folderUid: folder?.uid || null, - forceGetToken: true - })); - - toggleFetchingToken(false); - - // Check if the result contains error or if access_token is missing - if (result?.error || !result?.access_token) { - const errorMessage = result?.error || 'No access token received from authorization server'; - toast.error(errorMessage); - return; - } - - toast.success('Token fetched successfully!'); - } - catch (error) { - console.error(error); - toggleFetchingToken(false); - toast.error(error?.message || 'An error occurred while fetching token!'); - } - } - const handleSave = () => { save(); }; const handleChange = (key, value) => { @@ -111,16 +77,6 @@ const OAuth2Implicit = ({ save, item = {}, request, handleRun, updateAuth, colle handleChange('autoFetchToken', e.target.checked); }; - const handleClearCache = (e) => { - dispatch(clearOauth2Cache({ collectionUid: collection?.uid, url: interpolatedAuthUrl, credentialsId })) - .then(() => { - toast.success('Cleared cache successfully'); - }) - .catch((err) => { - toast.error(err.message); - }); - }; - return ( @@ -262,18 +218,13 @@ const OAuth2Implicit = ({ save, item = {}, request, handleRun, updateAuth, colle -
- - -
+ +
); }; diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2ActionButtons/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2ActionButtons/index.js index de729fdd5..3d3dc697d 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2ActionButtons/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2ActionButtons/index.js @@ -99,12 +99,22 @@ const Oauth2ActionButtons = ({ item, request, collection, url: accessTokenUrl, c return (
- - {creds?.refresh_token ? : null} + {creds?.refresh_token ? + + : null} diff --git a/packages/bruno-electron/src/ipc/network/interpolate-vars.js b/packages/bruno-electron/src/ipc/network/interpolate-vars.js index 5d80cf567..34833e041 100644 --- a/packages/bruno-electron/src/ipc/network/interpolate-vars.js +++ b/packages/bruno-electron/src/ipc/network/interpolate-vars.js @@ -235,6 +235,39 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc default: break; } + + // Interpolate additional parameters for all OAuth2 grant types + if (request.oauth2.additionalParameters) { + // Interpolate authorization parameters + if (Array.isArray(request.oauth2.additionalParameters.authorization)) { + request.oauth2.additionalParameters.authorization.forEach(param => { + if (param && param.enabled !== false) { + param.name = _interpolate(param.name) || ''; + param.value = _interpolate(param.value) || ''; + } + }); + } + + // Interpolate token parameters + if (Array.isArray(request.oauth2.additionalParameters.token)) { + request.oauth2.additionalParameters.token.forEach(param => { + if (param && param.enabled !== false) { + param.name = _interpolate(param.name) || ''; + param.value = _interpolate(param.value) || ''; + } + }); + } + + // Interpolate refresh parameters + if (Array.isArray(request.oauth2.additionalParameters.refresh)) { + request.oauth2.additionalParameters.refresh.forEach(param => { + if (param && param.enabled !== false) { + param.name = _interpolate(param.name) || ''; + param.value = _interpolate(param.value) || ''; + } + }); + } + } } // interpolate vars for aws sigv4 auth diff --git a/packages/bruno-electron/src/ipc/network/prepare-request.js b/packages/bruno-electron/src/ipc/network/prepare-request.js index f5510a4aa..7bdb94a32 100644 --- a/packages/bruno-electron/src/ipc/network/prepare-request.js +++ b/packages/bruno-electron/src/ipc/network/prepare-request.js @@ -126,7 +126,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenPlacement: get(collectionAuth, 'oauth2.tokenPlacement'), tokenHeaderPrefix: get(collectionAuth, 'oauth2.tokenHeaderPrefix'), tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey'), - autoFetchToken: get(collectionAuth, 'oauth2.autoFetchToken') + autoFetchToken: get(collectionAuth, 'oauth2.autoFetchToken'), + additionalParameters: get(collectionAuth, 'oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; case 'client_credentials': @@ -242,7 +243,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenPlacement: get(request, 'auth.oauth2.tokenPlacement'), tokenHeaderPrefix: get(request, 'auth.oauth2.tokenHeaderPrefix'), tokenQueryKey: get(request, 'auth.oauth2.tokenQueryKey'), - autoFetchToken: get(request, 'auth.oauth2.autoFetchToken') + autoFetchToken: get(request, 'auth.oauth2.autoFetchToken'), + additionalParameters: get(request, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; case 'client_credentials': diff --git a/packages/bruno-electron/src/utils/oauth2.js b/packages/bruno-electron/src/utils/oauth2.js index 45b776097..072b36b08 100644 --- a/packages/bruno-electron/src/utils/oauth2.js +++ b/packages/bruno-electron/src/utils/oauth2.js @@ -638,7 +638,7 @@ const getOAuth2TokenUsingPasswordCredentials = async ({ request, collectionUid, const refreshOauth2Token = async ({ requestCopy, collectionUid, certsAndProxyConfig }) => { const oAuth = get(requestCopy, 'oauth2', {}); - const { clientId, clientSecret, credentialsId } = oAuth; + const { clientId, clientSecret, credentialsId, additionalParameters } = oAuth; const url = oAuth.refreshTokenUrl ? oAuth.refreshTokenUrl : oAuth.accessTokenUrl; const credentials = getStoredOauth2Credentials({ collectionUid, url, credentialsId }); @@ -663,8 +663,8 @@ const refreshOauth2Token = async ({ requestCopy, collectionUid, certsAndProxyCon }; axiosRequestConfig.url = url; axiosRequestConfig.responseType = 'arraybuffer'; - if (oAuth.additionalParameters?.refresh?.length) { - applyAdditionalParameters(axiosRequestConfig, data, oAuth.additionalParameters.refresh); + if (additionalParameters?.refresh?.length) { + applyAdditionalParameters(axiosRequestConfig, data, additionalParameters.refresh); } axiosRequestConfig.data = qs.stringify(data); let debugInfo = { data: [] }; @@ -740,7 +740,8 @@ const getOAuth2TokenUsingImplicitGrant = async ({ request, collectionUid, forceF state = '', callbackUrl, credentialsId = 'credentials', - autoFetchToken = true + autoFetchToken = true, + additionalParameters } = oauth2; // Validate required fields @@ -825,6 +826,15 @@ const getOAuth2TokenUsingImplicitGrant = async ({ request, collectionUid, forceF if (state) { authorizationUrlWithQueryParams.searchParams.append('state', state); } + if (additionalParameters?.authorization?.length) { + additionalParameters.authorization.forEach(param => { + if (param.enabled && param.name) { + if (param.sendIn === 'queryparams') { + authorizationUrlWithQueryParams.searchParams.append(param.name, param.value || ''); + } + } + }); + } const authorizeUrl = authorizationUrlWithQueryParams.toString(); @@ -833,7 +843,8 @@ const getOAuth2TokenUsingImplicitGrant = async ({ request, collectionUid, forceF authorizeUrl, callbackUrl, session: oauth2Store.getSessionIdOfCollection({ collectionUid, url: authorizationUrl }), - grantType: 'implicit' + grantType: 'implicit', + additionalHeaders: getAdditionalHeaders(additionalParameters?.authorization) }); if (!implicitTokens || !implicitTokens.access_token) { diff --git a/packages/bruno-filestore/src/formats/bru/index.ts b/packages/bruno-filestore/src/formats/bru/index.ts index e71017cdf..4647c0c60 100644 --- a/packages/bruno-filestore/src/formats/bru/index.ts +++ b/packages/bruno-filestore/src/formats/bru/index.ts @@ -7,6 +7,7 @@ import { collectionBruToJson as _collectionBruToJson, jsonToCollectionBru as _jsonToCollectionBru } from '@usebruno/lang'; +import { getOauth2AdditionalParameters } from './utils/oauth2-additional-params'; export const bruRequestToJson = (data: string | any, parsed: boolean = false): any => { try { @@ -46,6 +47,16 @@ export const bruRequestToJson = (data: string | any, parsed: boolean = false): a transformedJson.request.auth.mode = _.get(json, 'http.auth', 'none'); transformedJson.request.body.mode = _.get(json, 'http.body', 'none'); + // add oauth2 additional parameters if they exist + const hasOauth2GrantType = json?.auth?.oauth2?.grantType; + if (hasOauth2GrantType) { + const additionalParameters = getOauth2AdditionalParameters(json); + const hasAdditionalParameters = Object.keys(additionalParameters || {}).length > 0; + if (hasAdditionalParameters) { + transformedJson.request.auth.oauth2.additionalParameters = additionalParameters; + } + } + return transformedJson; } catch (e) { return Promise.reject(e); @@ -129,6 +140,16 @@ export const bruCollectionToJson = (data: string | any, parsed: boolean = false) } } + // add oauth2 additional parameters if they exist + const hasOauth2GrantType = json?.auth?.oauth2?.grantType; + if (hasOauth2GrantType) { + const additionalParameters = getOauth2AdditionalParameters(json); + const hasAdditionalParameters = Object.keys(additionalParameters).length > 0; + if (hasAdditionalParameters) { + transformedJson.request.auth.oauth2.additionalParameters = additionalParameters; + } + } + return transformedJson; } catch (error) { return Promise.reject(error); diff --git a/packages/bruno-filestore/src/formats/bru/tests/fixtures/oauth2-additional-params.js b/packages/bruno-filestore/src/formats/bru/tests/fixtures/oauth2-additional-params.js new file mode 100644 index 000000000..0fe31f485 --- /dev/null +++ b/packages/bruno-filestore/src/formats/bru/tests/fixtures/oauth2-additional-params.js @@ -0,0 +1,116 @@ +const getBruJsonWithAdditionalParams = (grantType) => ({ + "meta": { + "name": "OAuth2 Additional Params Test", + "type": "http", + "seq": 1 + }, + "http": { + "method": "get", + "url": "https://api.usebruno.com/protected" + }, + "auth": { + "oauth2": { + "grantType": grantType, + }, + }, + "oauth2_additional_parameters_authorization_headers": [ + { + "name": "auth-header", + "value": "auth-header-value", + "enabled": true + }, + { + "name": "disabled-auth-header", + "value": "disabled-auth-header-value", + "enabled": false + } + ], + "oauth2_additional_parameters_authorization_queryparams": [ + { + "name": "auth-query-param", + "value": "auth-query-param-value", + "enabled": true + }, + { + "name": "disabled-auth-query-param", + "value": "disabled-auth-query-param-value", + "enabled": false + } + ], + "oauth2_additional_parameters_token_headers": [ + { + "name": "token-header", + "value": "token-header-value", + "enabled": true + }, + { + "name": "disabled-token-header", + "value": "disabled-token-header-value", + "enabled": false + } + ], + "oauth2_additional_parameters_token_queryparams": [ + { + "name": "token-query-param", + "value": "token-query-param-value", + "enabled": true + }, + { + "name": "disabled-token-query-param", + "value": "disabled-token-query-param-value", + "enabled": false + } + ], + "oauth2_additional_parameters_token_bodyvalues": [ + { + "name": "token-body", + "value": "token-body-value", + "enabled": true + }, + { + "name": "disabled-token-body", + "value": "disabled-token-body-value", + "enabled": false + } + ], + "oauth2_additional_parameters_refresh_headers": [ + { + "name": "refresh-header", + "value": "refresh-header-value", + "enabled": true + }, + { + "name": "disabled-refresh-header", + "value": "disabled-refresh-header-value", + "enabled": false + } + ], + "oauth2_additional_parameters_refresh_queryparams": [ + { + "name": "refresh-query-param", + "value": "refresh-query-param-value", + "enabled": true + }, + { + "name": "disabled-refresh-query-param", + "value": "disabled-refresh-query-param-value", + "enabled": false + } + ], + "oauth2_additional_parameters_refresh_bodyvalues": [ + { + "name": "refresh-body", + "value": "refresh-body-value", + "enabled": true + }, + { + "name": "disabled-refresh-body", + "value": "disabled-refresh-body-value", + "enabled": false + } + ] +}) + +export { + getBruJsonWithAdditionalParams +}; diff --git a/packages/bruno-filestore/src/formats/bru/tests/oauth2-additional-params.spec.js b/packages/bruno-filestore/src/formats/bru/tests/oauth2-additional-params.spec.js new file mode 100644 index 000000000..751fcc745 --- /dev/null +++ b/packages/bruno-filestore/src/formats/bru/tests/oauth2-additional-params.spec.js @@ -0,0 +1,45 @@ +const { getOauth2AdditionalParameters } = require('../utils/oauth2-additional-params'); +const { bruRequestToJson, bruCollectionToJson } = require('../index'); +const { clientCredentialsBruJson, authorizationCodeBruJson, passwordCredentialsBruJson, implicitBruJson, getBruJsonWithAdditionalParams } = require('./fixtures/oauth2-additional-params'); + +describe('getOauth2AdditionalParameters', () => { + it('authorization_code', () => { + const additionalParameters = getOauth2AdditionalParameters(getBruJsonWithAdditionalParams('authorization_code')); + expect(additionalParameters.authorization).toHaveLength(4); + expect(additionalParameters.token).toHaveLength(6); + expect(additionalParameters.refresh).toHaveLength(6); + + expect(additionalParameters.authorization.map(p => p.sendIn).sort()).toEqual(['headers', 'headers', 'queryparams', 'queryparams']); + expect(additionalParameters.token.map(p => p.sendIn).sort()).toEqual(['body', 'body', 'headers', 'headers', 'queryparams', 'queryparams']); + expect(additionalParameters.refresh.map(p => p.sendIn).sort()).toEqual(['body', 'body', 'headers', 'headers', 'queryparams', 'queryparams']); + }); + + it('client_credentials', () => { + const additionalParameters = getOauth2AdditionalParameters(getBruJsonWithAdditionalParams('client_credentials')); + expect(additionalParameters.authorization).toBeUndefined(); + expect(additionalParameters.token).toHaveLength(6); + expect(additionalParameters.refresh).toHaveLength(6); + + expect(additionalParameters.token.map(p => p.sendIn).sort()).toEqual(['body', 'body', 'headers', 'headers', 'queryparams', 'queryparams']); + expect(additionalParameters.refresh.map(p => p.sendIn).sort()).toEqual(['body', 'body', 'headers', 'headers', 'queryparams', 'queryparams']); + }); + + it('password', () => { + const additionalParameters = getOauth2AdditionalParameters(getBruJsonWithAdditionalParams('password')); + expect(additionalParameters.authorization).toBeUndefined(); + expect(additionalParameters.token).toHaveLength(6); + expect(additionalParameters.refresh).toHaveLength(6); + + expect(additionalParameters.token.map(p => p.sendIn).sort()).toEqual(['body', 'body', 'headers', 'headers', 'queryparams', 'queryparams']); + expect(additionalParameters.refresh.map(p => p.sendIn).sort()).toEqual(['body', 'body', 'headers', 'headers', 'queryparams', 'queryparams']); + }); + + it('implicit', () => { + const additionalParameters = getOauth2AdditionalParameters(getBruJsonWithAdditionalParams('implicit')); + expect(additionalParameters.authorization).toHaveLength(4); + expect(additionalParameters.token).toBeUndefined(); + expect(additionalParameters.refresh).toBeUndefined(); + + expect(additionalParameters.authorization.map(p => p.sendIn).sort()).toEqual(['headers', 'headers', 'queryparams', 'queryparams']); + }); +}); \ No newline at end of file diff --git a/packages/bruno-filestore/src/formats/bru/utils/oauth2-additional-params.ts b/packages/bruno-filestore/src/formats/bru/utils/oauth2-additional-params.ts new file mode 100644 index 000000000..6bf57cefa --- /dev/null +++ b/packages/bruno-filestore/src/formats/bru/utils/oauth2-additional-params.ts @@ -0,0 +1,141 @@ +type T_Oauth2ParameterType = 'authorization' | 'token' | 'refresh'; +type T_Oauth2ParameterSendInType = 'headers' | 'queryparams' | 'body'; + +export interface T_OAuth2AdditionalParam { + name: string; + value: string; + enabled: boolean; + sendIn: T_Oauth2ParameterSendInType +} + +export interface T_OAuth2AdditionalParameters { + authorization?: T_OAuth2AdditionalParam[]; + token?: T_OAuth2AdditionalParam[]; + refresh?: T_OAuth2AdditionalParam[]; +} + +export interface T_Oauth2Auth { + grantType: string; + additionalParameters?: T_OAuth2AdditionalParameters; +} + +export interface T_BruJson { + auth: { + oauth2: T_Oauth2Auth; + }; + oauth2_additional_parameters_authorization_headers?: any[]; + oauth2_additional_parameters_authorization_queryparams?: any[]; + oauth2_additional_parameters_token_headers?: any[]; + oauth2_additional_parameters_token_queryparams?: any[]; + oauth2_additional_parameters_token_bodyvalues?: any[]; + oauth2_additional_parameters_refresh_headers?: any[]; + oauth2_additional_parameters_refresh_queryparams?: any[]; + oauth2_additional_parameters_refresh_bodyvalues?: any[]; +} + +interface T_Oauth2ParameterMapping { + type: T_Oauth2ParameterType; + sendIn: T_Oauth2ParameterSendInType; + source: keyof T_BruJson; +} + +const PARAMETER_MAPPINGS: T_Oauth2ParameterMapping[] = [ + // Authorization parameters (only for authorization_code grant type) + { type: 'authorization', sendIn: 'headers', source: 'oauth2_additional_parameters_authorization_headers' }, + { type: 'authorization', sendIn: 'queryparams', source: 'oauth2_additional_parameters_authorization_queryparams' }, + + // Token parameters (for all grant types) + { type: 'token', sendIn: 'headers', source: 'oauth2_additional_parameters_token_headers' }, + { type: 'token', sendIn: 'queryparams', source: 'oauth2_additional_parameters_token_queryparams' }, + { type: 'token', sendIn: 'body', source: 'oauth2_additional_parameters_token_bodyvalues' }, + + // Refresh parameters (for grant types that support refresh) + { type: 'refresh', sendIn: 'headers', source: 'oauth2_additional_parameters_refresh_headers' }, + { type: 'refresh', sendIn: 'queryparams', source: 'oauth2_additional_parameters_refresh_queryparams' }, + { type: 'refresh', sendIn: 'body', source: 'oauth2_additional_parameters_refresh_bodyvalues' }, +]; + +/** + * Maps source parameters to T_OAuth2AdditionalParam format + */ +const mapParametersFromSource = (sourceParams: any[], sendIn: T_Oauth2ParameterSendInType): T_OAuth2AdditionalParam[] => { + if (!sourceParams?.length) { + return []; + } + + return sourceParams.map(param => ({ + ...param, + sendIn + })); +}; + +/** + * Checks if a parameter type should be included based on grant type + */ +const shouldIncludeParameterType = (type: T_Oauth2ParameterType, grantType: string): boolean => { + // Authorization parameters are only valid for authorization_code grant type + if (type === 'authorization') { + return grantType === 'authorization_code' || grantType === 'implicit'; + } + + if (type === 'token' || type === 'refresh') { + return grantType !== 'implicit'; + } + + // Token and refresh parameters are valid for all grant types + return true; +}; + +/** + * Collects all parameters for a specific type (authorization, token, or refresh) + */ +const collectParametersForType = ( + json: T_BruJson, + type: T_Oauth2ParameterType, + grantType: string +): T_OAuth2AdditionalParam[] => { + if (!shouldIncludeParameterType(type, grantType)) { + return []; + } + + const relevantMappings = PARAMETER_MAPPINGS.filter(mapping => mapping.type === type); + const allParams: T_OAuth2AdditionalParam[] = []; + + for (const mapping of relevantMappings) { + const sourceParams = json[mapping.source] as any[]; + const mappedParams = mapParametersFromSource(sourceParams, mapping.sendIn); + allParams.push(...mappedParams); + } + + return allParams; +}; + +/** + * This function extracts OAuth2 additional parameters from various sources in the bru json data and organizes + * them into a structured format based on their usage context (authorization, token, refresh). + * + * @param json - json object containing OAuth2 configuration and additional parameters + * @returns OAuth2 additional parameters + */ +export const getOauth2AdditionalParameters = (json: T_BruJson): T_OAuth2AdditionalParameters => { + const grantType = json.auth.oauth2.grantType; + const additionalParameters: T_OAuth2AdditionalParameters = {}; + + try { + // Collect parameters for each type + const parameterTypes: T_Oauth2ParameterType[] = ['authorization', 'token', 'refresh']; + + for (const type of parameterTypes) { + const params = collectParametersForType(json, type, grantType); + if (params.length > 0) { + additionalParameters[type] = params; + } + } + } + catch(error) { + console.error(error); + console.error("Error while getting the oauth2 additional parameters!"); + } + + return additionalParameters; +}; \ No newline at end of file diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index 58667a485..7b766c7b7 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -884,8 +884,6 @@ const parser = (input) => { if (match.succeeded()) { let ast = sem(match).ast - ast = mergeOauth2AdditionalParameters(ast); - return ast; } else { throw new Error(match.message); diff --git a/packages/bruno-lang/v2/src/collectionBruToJson.js b/packages/bruno-lang/v2/src/collectionBruToJson.js index ed7836964..7efd1acbf 100644 --- a/packages/bruno-lang/v2/src/collectionBruToJson.js +++ b/packages/bruno-lang/v2/src/collectionBruToJson.js @@ -522,8 +522,6 @@ const parser = (input) => { if (match.succeeded()) { let ast = sem(match).ast; - ast = mergeOauth2AdditionalParameters(ast); - return ast; } else { throw new Error(match.message); diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js index d9f405a4f..e226f51e5 100644 --- a/packages/bruno-lang/v2/src/jsonToBru.js +++ b/packages/bruno-lang/v2/src/jsonToBru.js @@ -294,6 +294,7 @@ ${indentString( .join('\n') )} } + `; } const authorizationQueryParams = authorizationParams?.filter(p => p?.sendIn == 'queryparams'); @@ -305,7 +306,8 @@ ${indentString( .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} -} +} + `; } const tokenHeaders = tokenParams?.filter(p => p?.sendIn == 'headers'); @@ -318,7 +320,7 @@ ${indentString( .join('\n') )} } - + `; } const tokenQueryParams = tokenParams?.filter(p => p?.sendIn == 'queryparams'); @@ -331,7 +333,7 @@ ${indentString( .join('\n') )} } - + `; } const tokenBodyValues = tokenParams?.filter(p => p?.sendIn == 'body'); @@ -344,7 +346,7 @@ ${indentString( .join('\n') )} } - + `; } const refreshHeaders = refreshParams?.filter(p => p?.sendIn == 'headers'); @@ -357,7 +359,7 @@ ${indentString( .join('\n') )} } - + `; } const refreshQueryParams = refreshParams?.filter(p => p?.sendIn == 'queryparams'); @@ -370,7 +372,7 @@ ${indentString( .join('\n') )} } - + `; } const refreshBodyValues = refreshParams?.filter(p => p?.sendIn == 'body'); @@ -383,7 +385,7 @@ ${indentString( .join('\n') )} } - + `; } } diff --git a/packages/bruno-lang/v2/src/jsonToCollectionBru.js b/packages/bruno-lang/v2/src/jsonToCollectionBru.js index 68b021b06..1af07313b 100644 --- a/packages/bruno-lang/v2/src/jsonToCollectionBru.js +++ b/packages/bruno-lang/v2/src/jsonToCollectionBru.js @@ -247,6 +247,7 @@ ${indentString( .join('\n') )} } + `; } const authorizationQueryParams = authorizationParams?.filter(p => p?.sendIn == 'queryparams'); @@ -258,7 +259,8 @@ ${indentString( .map((item) => `${item.enabled ? '' : '~'}${item.name}: ${item.value}`) .join('\n') )} -} +} + `; } const tokenHeaders = tokenParams?.filter(p => p?.sendIn == 'headers'); @@ -271,7 +273,7 @@ ${indentString( .join('\n') )} } - + `; } const tokenQueryParams = tokenParams?.filter(p => p?.sendIn == 'queryparams'); @@ -284,7 +286,7 @@ ${indentString( .join('\n') )} } - + `; } const tokenBodyValues = tokenParams?.filter(p => p?.sendIn == 'body'); @@ -297,7 +299,7 @@ ${indentString( .join('\n') )} } - + `; } const refreshHeaders = refreshParams?.filter(p => p?.sendIn == 'headers'); @@ -310,7 +312,7 @@ ${indentString( .join('\n') )} } - + `; } const refreshQueryParams = refreshParams?.filter(p => p?.sendIn == 'queryparams'); @@ -323,7 +325,7 @@ ${indentString( .join('\n') )} } - + `; } const refreshBodyValues = refreshParams?.filter(p => p?.sendIn == 'body'); @@ -336,7 +338,7 @@ ${indentString( .join('\n') )} } - + `; } } diff --git a/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js b/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js new file mode 100644 index 000000000..674582114 --- /dev/null +++ b/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js @@ -0,0 +1,329 @@ +const bruToJson = require('../src/bruToJson'); +const collectionBruToJson = require('../src/collectionBruToJson'); + +describe('OAuth2 Additional Parameters - request level', () => { + it('should parse all oauth2 additional parameters config types together', () => { + const input = ` +meta { + name: OAuth2 Additional Params Test + type: http +} + +get { + url: https://api.usebruno.com/protected +} + +auth:oauth2 { + grant_type: authorization_code + client_id: bruno-client-id + client_secret: bruno-client-secret + authorization_url: https://auth.usebruno.com/oauth/authorize + access_token_url: https://auth.usebruno.com/oauth/token +} + +auth:oauth2:authorization_headers { + auth-header: auth-header-value + ~disabled-auth-header: disabled-auth-header-value +} + +auth:oauth2:authorization_queryparams { + auth-query-param: auth-query-param-value + ~disabled-auth-query-param: disabled-auth-query-param-value +} + +auth:oauth2:token_headers { + token-header: token-header-value + ~disabled-token-header: disabled-token-header-value +} + +auth:oauth2:token_queryparams { + token-query-param: token-query-param-value + ~disabled-token-query-param: disabled-token-query-param-value +} + +auth:oauth2:token_bodyvalues { + token-body: token-body-value + ~disabled-token-body: disabled-token-body-value +} + +auth:oauth2:refresh_headers { + refresh-header: refresh-header-value + ~disabled-refresh-header: disabled-refresh-header-value +} + +auth:oauth2:refresh_queryparams { + refresh-query-param: refresh-query-param-value + ~disabled-refresh-query-param: disabled-refresh-query-param-value +} + +auth:oauth2:refresh_bodyvalues { + refresh-body: refresh-body-value + ~disabled-refresh-body: disabled-refresh-body-value +} + `.trim(); + + const result = bruToJson(input); + + // Verify all config types are present + expect(result).toHaveProperty('oauth2_additional_parameters_authorization_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_authorization_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_token_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_token_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_token_bodyvalues'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_bodyvalues'); + + // Verify each has exactly one parameter + expect(result.oauth2_additional_parameters_authorization_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_authorization_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_token_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_token_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_token_bodyvalues).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_bodyvalues).toHaveLength(2); + + // Verify parameter values + expect(result.oauth2_additional_parameters_authorization_headers).toEqual([{ + name: 'auth-header', + value: 'auth-header-value', + enabled: true + }, { + name: 'disabled-auth-header', + value: 'disabled-auth-header-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_authorization_queryparams).toEqual([{ + name: 'auth-query-param', + value: 'auth-query-param-value', + enabled: true + }, { + name: 'disabled-auth-query-param', + value: 'disabled-auth-query-param-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_token_headers).toEqual([{ + name: 'token-header', + value: 'token-header-value', + enabled: true + }, { + name: 'disabled-token-header', + value: 'disabled-token-header-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_token_queryparams).toEqual([{ + name: 'token-query-param', + value: 'token-query-param-value', + enabled: true + }, { + name: 'disabled-token-query-param', + value: 'disabled-token-query-param-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_token_bodyvalues).toEqual([{ + name: 'token-body', + value: 'token-body-value', + enabled: true + }, { + name: 'disabled-token-body', + value: 'disabled-token-body-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_refresh_headers).toEqual([{ + name: 'refresh-header', + value: 'refresh-header-value', + enabled: true + }, { + name: 'disabled-refresh-header', + value: 'disabled-refresh-header-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_refresh_queryparams).toEqual([{ + name: 'refresh-query-param', + value: 'refresh-query-param-value', + enabled: true + }, { + name: 'disabled-refresh-query-param', + value: 'disabled-refresh-query-param-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_refresh_bodyvalues).toEqual([{ + name: 'refresh-body', + value: 'refresh-body-value', + enabled: true + }, { + name: 'disabled-refresh-body', + value: 'disabled-refresh-body-value', + enabled: false + }]); + }); +}); + +describe('OAuth2 Additional Parameters - collection/folder level', () => { + it('should parse all oauth2 additional parameters config types together', () => { + const input = ` +auth { + mode: oauth2 +} + +auth:oauth2 { + grant_type: authorization_code + client_id: bruno-client-id + client_secret: bruno-client-secret + authorization_url: https://auth.usebruno.com/oauth/authorize + access_token_url: https://auth.usebruno.com/oauth/token +} + +auth:oauth2:authorization_headers { + auth-header: auth-header-value + ~disabled-auth-header: disabled-auth-header-value +} + +auth:oauth2:authorization_queryparams { + auth-query-param: auth-query-param-value + ~disabled-auth-query-param: disabled-auth-query-param-value +} + +auth:oauth2:token_headers { + token-header: token-header-value + ~disabled-token-header: disabled-token-header-value +} + +auth:oauth2:token_queryparams { + token-query-param: token-query-param-value + ~disabled-token-query-param: disabled-token-query-param-value +} + +auth:oauth2:token_bodyvalues { + token-body: token-body-value + ~disabled-token-body: disabled-token-body-value +} + +auth:oauth2:refresh_headers { + refresh-header: refresh-header-value + ~disabled-refresh-header: disabled-refresh-header-value +} + +auth:oauth2:refresh_queryparams { + refresh-query-param: refresh-query-param-value + ~disabled-refresh-query-param: disabled-refresh-query-param-value +} + +auth:oauth2:refresh_bodyvalues { + refresh-body: refresh-body-value + ~disabled-refresh-body: disabled-refresh-body-value +} + `.trim(); + + const result = collectionBruToJson(input); + + // Verify all config types are present + expect(result).toHaveProperty('oauth2_additional_parameters_authorization_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_authorization_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_token_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_token_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_token_bodyvalues'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_bodyvalues'); + + // Verify each has exactly one parameter + expect(result.oauth2_additional_parameters_authorization_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_authorization_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_token_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_token_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_token_bodyvalues).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_bodyvalues).toHaveLength(2); + + // Verify parameter values + expect(result.oauth2_additional_parameters_authorization_headers).toEqual([{ + name: 'auth-header', + value: 'auth-header-value', + enabled: true + }, { + name: 'disabled-auth-header', + value: 'disabled-auth-header-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_authorization_queryparams).toEqual([{ + name: 'auth-query-param', + value: 'auth-query-param-value', + enabled: true + }, { + name: 'disabled-auth-query-param', + value: 'disabled-auth-query-param-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_token_headers).toEqual([{ + name: 'token-header', + value: 'token-header-value', + enabled: true + }, { + name: 'disabled-token-header', + value: 'disabled-token-header-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_token_queryparams).toEqual([{ + name: 'token-query-param', + value: 'token-query-param-value', + enabled: true + }, { + name: 'disabled-token-query-param', + value: 'disabled-token-query-param-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_token_bodyvalues).toEqual([{ + name: 'token-body', + value: 'token-body-value', + enabled: true + }, { + name: 'disabled-token-body', + value: 'disabled-token-body-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_refresh_headers).toEqual([{ + name: 'refresh-header', + value: 'refresh-header-value', + enabled: true + }, { + name: 'disabled-refresh-header', + value: 'disabled-refresh-header-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_refresh_queryparams).toEqual([{ + name: 'refresh-query-param', + value: 'refresh-query-param-value', + enabled: true + }, { + name: 'disabled-refresh-query-param', + value: 'disabled-refresh-query-param-value', + enabled: false + }]); + + expect(result.oauth2_additional_parameters_refresh_bodyvalues).toEqual([{ + name: 'refresh-body', + value: 'refresh-body-value', + enabled: true + }, { + name: 'disabled-refresh-body', + value: 'disabled-refresh-body-value', + enabled: false + }]); + }); +}); \ No newline at end of file From 7de3e6e3ff0500a4d9bc35a8517cebf14b1c6fbe Mon Sep 17 00:00:00 2001 From: lohit-bruno Date: Thu, 14 Aug 2025 15:04:45 +0530 Subject: [PATCH 10/15] review update fixes --- packages/bruno-electron/src/ipc/network/prepare-request.js | 6 +++--- packages/bruno-electron/src/utils/oauth2.js | 4 ++-- .../src/formats/bru/tests/oauth2-additional-params.spec.js | 2 +- packages/bruno-lang/v2/src/bruToJson.js | 2 +- packages/bruno-lang/v2/src/collectionBruToJson.js | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/bruno-electron/src/ipc/network/prepare-request.js b/packages/bruno-electron/src/ipc/network/prepare-request.js index 7bdb94a32..375422164 100644 --- a/packages/bruno-electron/src/ipc/network/prepare-request.js +++ b/packages/bruno-electron/src/ipc/network/prepare-request.js @@ -89,7 +89,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey'), autoFetchToken: get(collectionAuth, 'oauth2.autoFetchToken'), autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken'), - additionalParameters: get(collectionAuth, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) + additionalParameters: get(collectionAuth, 'oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; case 'authorization_code': @@ -111,7 +111,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey'), autoFetchToken: get(collectionAuth, 'oauth2.autoFetchToken'), autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken'), - additionalParameters: get(collectionAuth, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) + additionalParameters: get(collectionAuth, 'oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; case 'implicit': @@ -145,7 +145,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey'), autoFetchToken: get(collectionAuth, 'oauth2.autoFetchToken'), autoRefreshToken: get(collectionAuth, 'oauth2.autoRefreshToken'), - additionalParameters: get(collectionAuth, 'auth.oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) + additionalParameters: get(collectionAuth, 'oauth2.additionalParameters', { authorization: [], token: [], refresh: [] }) }; break; } diff --git a/packages/bruno-electron/src/utils/oauth2.js b/packages/bruno-electron/src/utils/oauth2.js index 072b36b08..bb9e8b6b6 100644 --- a/packages/bruno-electron/src/utils/oauth2.js +++ b/packages/bruno-electron/src/utils/oauth2.js @@ -243,7 +243,7 @@ const getOAuth2TokenUsingAuthorizationCode = async ({ request, collectionUid, fo } // Fetch new token process - const { authorizationCode, debugInfo } = await getOAuth2AuthorizationCode(requestCopy, codeChallenge, collectionUid); + let { authorizationCode, debugInfo } = await getOAuth2AuthorizationCode(requestCopy, codeChallenge, collectionUid); let axiosRequestConfig = {}; axiosRequestConfig.method = 'POST'; @@ -716,7 +716,7 @@ const applyAdditionalParameters = (requestCopy, data, params = []) => { // For query params, add to URL try { let url = new URL(requestCopy.url); - url.searchParams.append(param.name, param.value); + url.searchParams.append(param.name, param.value || ''); requestCopy.url = url.href; } catch (error) { diff --git a/packages/bruno-filestore/src/formats/bru/tests/oauth2-additional-params.spec.js b/packages/bruno-filestore/src/formats/bru/tests/oauth2-additional-params.spec.js index 751fcc745..707c6127c 100644 --- a/packages/bruno-filestore/src/formats/bru/tests/oauth2-additional-params.spec.js +++ b/packages/bruno-filestore/src/formats/bru/tests/oauth2-additional-params.spec.js @@ -1,6 +1,6 @@ const { getOauth2AdditionalParameters } = require('../utils/oauth2-additional-params'); const { bruRequestToJson, bruCollectionToJson } = require('../index'); -const { clientCredentialsBruJson, authorizationCodeBruJson, passwordCredentialsBruJson, implicitBruJson, getBruJsonWithAdditionalParams } = require('./fixtures/oauth2-additional-params'); +const { getBruJsonWithAdditionalParams } = require('./fixtures/oauth2-additional-params'); describe('getOauth2AdditionalParameters', () => { it('authorization_code', () => { diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index 7b766c7b7..d569d196a 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -1,6 +1,6 @@ const ohm = require('ohm-js'); const _ = require('lodash'); -const { safeParseJson, outdentString, mergeOauth2AdditionalParameters } = require('./utils'); +const { safeParseJson, outdentString } = require('./utils'); /** * A Bru file is made up of blocks. diff --git a/packages/bruno-lang/v2/src/collectionBruToJson.js b/packages/bruno-lang/v2/src/collectionBruToJson.js index 7efd1acbf..5a12e4302 100644 --- a/packages/bruno-lang/v2/src/collectionBruToJson.js +++ b/packages/bruno-lang/v2/src/collectionBruToJson.js @@ -1,6 +1,6 @@ const ohm = require('ohm-js'); const _ = require('lodash'); -const { safeParseJson, outdentString, mergeOauth2AdditionalParameters } = require('./utils'); +const { safeParseJson, outdentString } = require('./utils'); const grammar = ohm.grammar(`Bru { BruFile = (meta | query | headers | auth | auths | vars | script | tests | docs | authOAuth2Configs)* From 8d1f292b8325192f1acc09b6fe58e77896289cdc Mon Sep 17 00:00:00 2001 From: lohit-bruno Date: Tue, 19 Aug 2025 17:46:05 +0530 Subject: [PATCH 11/15] updates --- packages/bruno-electron/src/utils/oauth2.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/bruno-electron/src/utils/oauth2.js b/packages/bruno-electron/src/utils/oauth2.js index 493a60f70..61d3d80c3 100644 --- a/packages/bruno-electron/src/utils/oauth2.js +++ b/packages/bruno-electron/src/utils/oauth2.js @@ -269,7 +269,6 @@ const getOAuth2TokenUsingAuthorizationCode = async ({ request, collectionUid, fo data['code_verifier'] = codeVerifier; } - axiosRequestConfig.data = qs.stringify(data); axiosRequestConfig.url = url; axiosRequestConfig.responseType = 'arraybuffer'; // Apply additional parameters to token request From cd00c21781a0ca6d354c3d60ec2026f9d293ebf9 Mon Sep 17 00:00:00 2001 From: lohit-bruno Date: Wed, 20 Aug 2025 16:30:08 +0530 Subject: [PATCH 12/15] dsl updates --- packages/bruno-lang/v2/src/bruToJson.js | 44 +++++++++---------- .../bruno-lang/v2/src/collectionBruToJson.js | 44 +++++++++---------- packages/bruno-lang/v2/src/jsonToBru.js | 16 +++---- .../bruno-lang/v2/src/jsonToCollectionBru.js | 16 +++---- .../v2/tests/oauth2-additional-params.spec.js | 32 +++++++------- 5 files changed, 76 insertions(+), 76 deletions(-) diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index d569d196a..766835061 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -29,17 +29,17 @@ const { safeParseJson, outdentString } = require('./utils'); * */ const grammar = ohm.grammar(`Bru { - BruFile = (meta | http | query | params | headers | auths | bodies | varsandassert | script | tests | settings | docs | authOAuth2Configs)* - auths = authawsv4 | authbasic | authbearer | authdigest | authNTLM | authOAuth2 | authwsse | authapikey + BruFile = (meta | http | query | params | headers | auths | bodies | varsandassert | script | tests | settings | docs)* + auths = authawsv4 | authbasic | authbearer | authdigest | authNTLM | authOAuth2 | authwsse | authapikey | authOauth2Configs bodies = bodyjson | bodytext | bodyxml | bodysparql | bodygraphql | bodygraphqlvars | bodyforms | body bodyforms = bodyformurlencoded | bodymultipart | bodyfile params = paramspath | paramsquery // Oauth2 additional parameters - authOAuth2Configs = oAuth2AuthorizationConfig | oAuth2TokenConfig | oAuth2RefreshConfig - oAuth2AuthorizationConfig = oAuth2AuthorizationHeaders | oAuth2AuthorizationQueryParams - oAuth2TokenConfig = oAuth2TokenHeaders | oAuth2TokenQueryParams | oAuth2TokenBodyValues - oAuth2RefreshConfig = oAuth2RefreshHeaders | oAuth2RefreshQueryParams | oAuth2RefreshBodyValues + authOauth2Configs = oauth2AuthReqConfig | oauth2AccessTokenReqConfig | oauth2RefreshTokenReqConfig + oauth2AuthReqConfig = oauth2AuthReqHeaders | oauth2AuthReqQueryParams + oauth2AccessTokenReqConfig = oauth2AccessTokenReqHeaders | oauth2AccessTokenReqQueryParams | oauth2AccessTokenReqBody + oauth2RefreshTokenReqConfig = oauth2RefreshTokenReqHeaders | oauth2RefreshTokenReqQueryParams | oauth2RefreshTokenReqBody nl = "\\r"? "\\n" st = " " | "\\t" @@ -111,14 +111,14 @@ const grammar = ohm.grammar(`Bru { authwsse = "auth:wsse" dictionary authapikey = "auth:apikey" dictionary - oAuth2AuthorizationHeaders = "auth:oauth2:authorization_headers" dictionary - oAuth2AuthorizationQueryParams = "auth:oauth2:authorization_queryparams" dictionary - oAuth2TokenHeaders = "auth:oauth2:token_headers" dictionary - oAuth2TokenQueryParams = "auth:oauth2:token_queryparams" dictionary - oAuth2TokenBodyValues = "auth:oauth2:token_bodyvalues" dictionary - oAuth2RefreshHeaders = "auth:oauth2:refresh_headers" dictionary - oAuth2RefreshQueryParams = "auth:oauth2:refresh_queryparams" dictionary - oAuth2RefreshBodyValues = "auth:oauth2:refresh_bodyvalues" dictionary + oauth2AuthReqHeaders = "auth:oauth2:additional_params:auth_req:headers" dictionary + oauth2AuthReqQueryParams = "auth:oauth2:additional_params:auth_req:queryparams" dictionary + oauth2AccessTokenReqHeaders = "auth:oauth2:additional_params:access_token_req:headers" dictionary + oauth2AccessTokenReqQueryParams = "auth:oauth2:additional_params:access_token_req:queryparams" dictionary + oauth2AccessTokenReqBody = "auth:oauth2:additional_params:access_token_req:body" dictionary + oauth2RefreshTokenReqHeaders = "auth:oauth2:additional_params:refresh_token_req:headers" dictionary + oauth2RefreshTokenReqQueryParams = "auth:oauth2:additional_params:refresh_token_req:queryparams" dictionary + oauth2RefreshTokenReqBody = "auth:oauth2:additional_params:refresh_token_req:body" dictionary body = "body" st* "{" nl* textblock tagend bodyjson = "body:json" st* "{" nl* textblock tagend @@ -655,42 +655,42 @@ const sem = grammar.createSemantics().addAttribute('ast', { } }; }, - oAuth2AuthorizationHeaders(_1, dictionary) { + oauth2AuthReqHeaders(_1, dictionary) { return { oauth2_additional_parameters_authorization_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2AuthorizationQueryParams(_1, dictionary) { + oauth2AuthReqQueryParams(_1, dictionary) { return { oauth2_additional_parameters_authorization_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2TokenHeaders(_1, dictionary) { + oauth2AccessTokenReqHeaders(_1, dictionary) { return { oauth2_additional_parameters_token_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2TokenQueryParams(_1, dictionary) { + oauth2AccessTokenReqQueryParams(_1, dictionary) { return { oauth2_additional_parameters_token_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2TokenBodyValues(_1, dictionary) { + oauth2AccessTokenReqBody(_1, dictionary) { return { oauth2_additional_parameters_token_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2RefreshHeaders(_1, dictionary) { + oauth2RefreshTokenReqHeaders(_1, dictionary) { return { oauth2_additional_parameters_refresh_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2RefreshQueryParams(_1, dictionary) { + oauth2RefreshTokenReqQueryParams(_1, dictionary) { return { oauth2_additional_parameters_refresh_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2RefreshBodyValues(_1, dictionary) { + oauth2RefreshTokenReqBody(_1, dictionary) { return { oauth2_additional_parameters_refresh_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; diff --git a/packages/bruno-lang/v2/src/collectionBruToJson.js b/packages/bruno-lang/v2/src/collectionBruToJson.js index 5a12e4302..0c698e6ce 100644 --- a/packages/bruno-lang/v2/src/collectionBruToJson.js +++ b/packages/bruno-lang/v2/src/collectionBruToJson.js @@ -3,14 +3,14 @@ const _ = require('lodash'); const { safeParseJson, outdentString } = require('./utils'); const grammar = ohm.grammar(`Bru { - BruFile = (meta | query | headers | auth | auths | vars | script | tests | docs | authOAuth2Configs)* - auths = authawsv4 | authbasic | authbearer | authdigest | authNTLM |authOAuth2 | authwsse | authapikey + BruFile = (meta | query | headers | auth | auths | vars | script | tests | docs)* + auths = authawsv4 | authbasic | authbearer | authdigest | authNTLM |authOAuth2 | authwsse | authapikey | authOauth2Configs // Oauth2 additional parameters - authOAuth2Configs = oAuth2AuthorizationConfig | oAuth2TokenConfig | oAuth2RefreshConfig - oAuth2AuthorizationConfig = oAuth2AuthorizationHeaders | oAuth2AuthorizationQueryParams - oAuth2TokenConfig = oAuth2TokenHeaders | oAuth2TokenQueryParams | oAuth2TokenBodyValues - oAuth2RefreshConfig = oAuth2RefreshHeaders | oAuth2RefreshQueryParams | oAuth2RefreshBodyValues + authOauth2Configs = oauth2AuthReqConfig | oauth2AccessTokenReqConfig | oauth2RefreshTokenReqConfig + oauth2AuthReqConfig = oauth2AuthReqHeaders | oauth2AuthReqQueryParams + oauth2AccessTokenReqConfig = oauth2AccessTokenReqHeaders | oauth2AccessTokenReqQueryParams | oauth2AccessTokenReqBody + oauth2RefreshTokenReqConfig = oauth2RefreshTokenReqHeaders | oauth2RefreshTokenReqQueryParams | oauth2RefreshTokenReqBody nl = "\\r"? "\\n" st = " " | "\\t" @@ -36,14 +36,14 @@ const grammar = ohm.grammar(`Bru { auth = "auth" dictionary - oAuth2AuthorizationHeaders = "auth:oauth2:authorization_headers" dictionary - oAuth2AuthorizationQueryParams = "auth:oauth2:authorization_queryparams" dictionary - oAuth2TokenHeaders = "auth:oauth2:token_headers" dictionary - oAuth2TokenQueryParams = "auth:oauth2:token_queryparams" dictionary - oAuth2TokenBodyValues = "auth:oauth2:token_bodyvalues" dictionary - oAuth2RefreshHeaders = "auth:oauth2:refresh_headers" dictionary - oAuth2RefreshQueryParams = "auth:oauth2:refresh_queryparams" dictionary - oAuth2RefreshBodyValues = "auth:oauth2:refresh_bodyvalues" dictionary + oauth2AuthReqHeaders = "auth:oauth2:additional_params:auth_req:headers" dictionary + oauth2AuthReqQueryParams = "auth:oauth2:additional_params:auth_req:queryparams" dictionary + oauth2AccessTokenReqHeaders = "auth:oauth2:additional_params:access_token_req:headers" dictionary + oauth2AccessTokenReqQueryParams = "auth:oauth2:additional_params:access_token_req:queryparams" dictionary + oauth2AccessTokenReqBody = "auth:oauth2:additional_params:access_token_req:body" dictionary + oauth2RefreshTokenReqHeaders = "auth:oauth2:additional_params:refresh_token_req:headers" dictionary + oauth2RefreshTokenReqQueryParams = "auth:oauth2:additional_params:refresh_token_req:queryparams" dictionary + oauth2RefreshTokenReqBody = "auth:oauth2:additional_params:refresh_token_req:body" dictionary headers = "headers" dictionary @@ -377,42 +377,42 @@ const sem = grammar.createSemantics().addAttribute('ast', { } }; }, - oAuth2AuthorizationHeaders(_1, dictionary) { + oauth2AuthReqHeaders(_1, dictionary) { return { oauth2_additional_parameters_authorization_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2AuthorizationQueryParams(_1, dictionary) { + oauth2AuthReqQueryParams(_1, dictionary) { return { oauth2_additional_parameters_authorization_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2TokenHeaders(_1, dictionary) { + oauth2AccessTokenReqHeaders(_1, dictionary) { return { oauth2_additional_parameters_token_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2TokenQueryParams(_1, dictionary) { + oauth2AccessTokenReqQueryParams(_1, dictionary) { return { oauth2_additional_parameters_token_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2TokenBodyValues(_1, dictionary) { + oauth2AccessTokenReqBody(_1, dictionary) { return { oauth2_additional_parameters_token_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2RefreshHeaders(_1, dictionary) { + oauth2RefreshTokenReqHeaders(_1, dictionary) { return { oauth2_additional_parameters_refresh_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2RefreshQueryParams(_1, dictionary) { + oauth2RefreshTokenReqQueryParams(_1, dictionary) { return { oauth2_additional_parameters_refresh_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, - oAuth2RefreshBodyValues(_1, dictionary) { + oauth2RefreshTokenReqBody(_1, dictionary) { return { oauth2_additional_parameters_refresh_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js index e226f51e5..ec601fce1 100644 --- a/packages/bruno-lang/v2/src/jsonToBru.js +++ b/packages/bruno-lang/v2/src/jsonToBru.js @@ -286,7 +286,7 @@ ${indentString(`auto_fetch_token: ${(auth?.oauth2?.autoFetchToken ?? true).toStr const { authorization: authorizationParams, token: tokenParams, refresh: refreshParams } = auth?.oauth2?.additionalParameters; const authorizationHeaders = authorizationParams?.filter(p => p?.sendIn == 'headers'); if (authorizationHeaders?.length) { - bru += `auth:oauth2:authorization_headers { + bru += `auth:oauth2:additional_params:auth_req:headers { ${indentString( authorizationHeaders .filter(item => item?.name?.length) @@ -299,7 +299,7 @@ ${indentString( } const authorizationQueryParams = authorizationParams?.filter(p => p?.sendIn == 'queryparams'); if (authorizationQueryParams?.length) { - bru += `auth:oauth2:authorization_queryparams { + bru += `auth:oauth2:additional_params:auth_req:queryparams { ${indentString( authorizationQueryParams .filter(item => item?.name?.length) @@ -312,7 +312,7 @@ ${indentString( } const tokenHeaders = tokenParams?.filter(p => p?.sendIn == 'headers'); if (tokenHeaders?.length) { - bru += `auth:oauth2:token_headers { + bru += `auth:oauth2:additional_params:access_token_req:headers { ${indentString( tokenHeaders .filter(item => item?.name?.length) @@ -325,7 +325,7 @@ ${indentString( } const tokenQueryParams = tokenParams?.filter(p => p?.sendIn == 'queryparams'); if (tokenQueryParams?.length) { - bru += `auth:oauth2:token_queryparams { + bru += `auth:oauth2:additional_params:access_token_req:queryparams { ${indentString( tokenQueryParams .filter(item => item?.name?.length) @@ -338,7 +338,7 @@ ${indentString( } const tokenBodyValues = tokenParams?.filter(p => p?.sendIn == 'body'); if (tokenBodyValues?.length) { - bru += `auth:oauth2:token_bodyvalues { + bru += `auth:oauth2:additional_params:access_token_req:body { ${indentString( tokenBodyValues .filter(item => item?.name?.length) @@ -351,7 +351,7 @@ ${indentString( } const refreshHeaders = refreshParams?.filter(p => p?.sendIn == 'headers'); if (refreshHeaders?.length) { - bru += `auth:oauth2:refresh_headers { + bru += `auth:oauth2:additional_params:refresh_token_req:headers { ${indentString( refreshHeaders .filter(item => item?.name?.length) @@ -364,7 +364,7 @@ ${indentString( } const refreshQueryParams = refreshParams?.filter(p => p?.sendIn == 'queryparams'); if (refreshQueryParams?.length) { - bru += `auth:oauth2:refresh_queryparams { + bru += `auth:oauth2:additional_params:refresh_token_req:queryparams { ${indentString( refreshQueryParams .filter(item => item?.name?.length) @@ -377,7 +377,7 @@ ${indentString( } const refreshBodyValues = refreshParams?.filter(p => p?.sendIn == 'body'); if (refreshBodyValues?.length) { - bru += `auth:oauth2:refresh_bodyvalues { + bru += `auth:oauth2:additional_params:refresh_token_req:body { ${indentString( refreshBodyValues .filter(item => item?.name?.length) diff --git a/packages/bruno-lang/v2/src/jsonToCollectionBru.js b/packages/bruno-lang/v2/src/jsonToCollectionBru.js index 1af07313b..d5aa1c1e0 100644 --- a/packages/bruno-lang/v2/src/jsonToCollectionBru.js +++ b/packages/bruno-lang/v2/src/jsonToCollectionBru.js @@ -239,7 +239,7 @@ ${indentString(`auto_refresh_token: ${(auth?.oauth2?.autoRefreshToken ?? false). const { authorization: authorizationParams, token: tokenParams, refresh: refreshParams } = auth?.oauth2?.additionalParameters; const authorizationHeaders = authorizationParams?.filter(p => p?.sendIn == 'headers'); if (authorizationHeaders?.length) { - bru += `auth:oauth2:authorization_headers { + bru += `auth:oauth2:additional_params:auth_req:headers { ${indentString( authorizationHeaders .filter(item => item?.name?.length) @@ -252,7 +252,7 @@ ${indentString( } const authorizationQueryParams = authorizationParams?.filter(p => p?.sendIn == 'queryparams'); if (authorizationQueryParams?.length) { - bru += `auth:oauth2:authorization_queryparams { + bru += `auth:oauth2:additional_params:auth_req:queryparams { ${indentString( authorizationQueryParams .filter(item => item?.name?.length) @@ -265,7 +265,7 @@ ${indentString( } const tokenHeaders = tokenParams?.filter(p => p?.sendIn == 'headers'); if (tokenHeaders?.length) { - bru += `auth:oauth2:token_headers { + bru += `auth:oauth2:additional_params:access_token_req:headers { ${indentString( tokenHeaders .filter(item => item?.name?.length) @@ -278,7 +278,7 @@ ${indentString( } const tokenQueryParams = tokenParams?.filter(p => p?.sendIn == 'queryparams'); if (tokenQueryParams?.length) { - bru += `auth:oauth2:token_queryparams { + bru += `auth:oauth2:additional_params:access_token_req:queryparams { ${indentString( tokenQueryParams .filter(item => item?.name?.length) @@ -291,7 +291,7 @@ ${indentString( } const tokenBodyValues = tokenParams?.filter(p => p?.sendIn == 'body'); if (tokenBodyValues?.length) { - bru += `auth:oauth2:token_bodyvalues { + bru += `auth:oauth2:additional_params:access_token_req:body { ${indentString( tokenBodyValues .filter(item => item?.name?.length) @@ -304,7 +304,7 @@ ${indentString( } const refreshHeaders = refreshParams?.filter(p => p?.sendIn == 'headers'); if (refreshHeaders?.length) { - bru += `auth:oauth2:refresh_headers { + bru += `auth:oauth2:additional_params:refresh_token_req:headers { ${indentString( refreshHeaders .filter(item => item?.name?.length) @@ -317,7 +317,7 @@ ${indentString( } const refreshQueryParams = refreshParams?.filter(p => p?.sendIn == 'queryparams'); if (refreshQueryParams?.length) { - bru += `auth:oauth2:refresh_queryparams { + bru += `auth:oauth2:additional_params:refresh_token_req:queryparams { ${indentString( refreshQueryParams .filter(item => item?.name?.length) @@ -330,7 +330,7 @@ ${indentString( } const refreshBodyValues = refreshParams?.filter(p => p?.sendIn == 'body'); if (refreshBodyValues?.length) { - bru += `auth:oauth2:refresh_bodyvalues { + bru += `auth:oauth2:additional_params:refresh_token_req:body { ${indentString( refreshBodyValues .filter(item => item?.name?.length) diff --git a/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js b/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js index 674582114..c412b64cf 100644 --- a/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js +++ b/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js @@ -21,42 +21,42 @@ auth:oauth2 { access_token_url: https://auth.usebruno.com/oauth/token } -auth:oauth2:authorization_headers { +auth:oauth2:additional_params:auth_req:headers { auth-header: auth-header-value ~disabled-auth-header: disabled-auth-header-value } -auth:oauth2:authorization_queryparams { +auth:oauth2:additional_params:auth_req:queryparams { auth-query-param: auth-query-param-value ~disabled-auth-query-param: disabled-auth-query-param-value } -auth:oauth2:token_headers { +auth:oauth2:additional_params:access_token_req:headers { token-header: token-header-value ~disabled-token-header: disabled-token-header-value } -auth:oauth2:token_queryparams { +auth:oauth2:additional_params:access_token_req:queryparams { token-query-param: token-query-param-value ~disabled-token-query-param: disabled-token-query-param-value } -auth:oauth2:token_bodyvalues { +auth:oauth2:additional_params:access_token_req:body { token-body: token-body-value ~disabled-token-body: disabled-token-body-value } -auth:oauth2:refresh_headers { +auth:oauth2:additional_params:refresh_token_req:headers { refresh-header: refresh-header-value ~disabled-refresh-header: disabled-refresh-header-value } -auth:oauth2:refresh_queryparams { +auth:oauth2:additional_params:refresh_token_req:queryparams { refresh-query-param: refresh-query-param-value ~disabled-refresh-query-param: disabled-refresh-query-param-value } -auth:oauth2:refresh_bodyvalues { +auth:oauth2:additional_params:refresh_token_req:body { refresh-body: refresh-body-value ~disabled-refresh-body: disabled-refresh-body-value } @@ -182,42 +182,42 @@ auth:oauth2 { access_token_url: https://auth.usebruno.com/oauth/token } -auth:oauth2:authorization_headers { +auth:oauth2:additional_params:auth_req:headers { auth-header: auth-header-value ~disabled-auth-header: disabled-auth-header-value } -auth:oauth2:authorization_queryparams { +auth:oauth2:additional_params:auth_req:queryparams { auth-query-param: auth-query-param-value ~disabled-auth-query-param: disabled-auth-query-param-value } -auth:oauth2:token_headers { +auth:oauth2:additional_params:access_token_req:headers { token-header: token-header-value ~disabled-token-header: disabled-token-header-value } -auth:oauth2:token_queryparams { +auth:oauth2:additional_params:access_token_req:queryparams { token-query-param: token-query-param-value ~disabled-token-query-param: disabled-token-query-param-value } -auth:oauth2:token_bodyvalues { +auth:oauth2:additional_params:access_token_req:body { token-body: token-body-value ~disabled-token-body: disabled-token-body-value } -auth:oauth2:refresh_headers { +auth:oauth2:additional_params:refresh_token_req:headers { refresh-header: refresh-header-value ~disabled-refresh-header: disabled-refresh-header-value } -auth:oauth2:refresh_queryparams { +auth:oauth2:additional_params:refresh_token_req:queryparams { refresh-query-param: refresh-query-param-value ~disabled-refresh-query-param: disabled-refresh-query-param-value } -auth:oauth2:refresh_bodyvalues { +auth:oauth2:additional_params:refresh_token_req:body { refresh-body: refresh-body-value ~disabled-refresh-body: disabled-refresh-body-value } From 8dde2701f42421fa7f965fd4832f28479cfd826f Mon Sep 17 00:00:00 2001 From: lohit-bruno Date: Wed, 20 Aug 2025 16:32:52 +0530 Subject: [PATCH 13/15] ui updates --- .../OAuth2/AdditionalParams/StyledWrapper.js | 21 ++++++++++++++++++ .../Auth/OAuth2/AdditionalParams/index.js | 22 +++++-------------- .../Auth/OAuth2/AuthorizationCode/index.js | 11 +++++----- .../Auth/OAuth2/ClientCredentials/index.js | 11 +++++----- .../RequestPane/Auth/OAuth2/Implicit/index.js | 11 +++++----- .../Auth/OAuth2/PasswordCredentials/index.js | 11 +++++----- 6 files changed, 50 insertions(+), 37 deletions(-) diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js index cc8980abe..712367fd7 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/StyledWrapper.js @@ -19,6 +19,27 @@ const StyledWrapper = styled.div` } } } + + table { + width: 100%; + border-collapse: collapse; + font-weight: 600; + table-layout: fixed; + + thead, + td { + border: 1px solid ${(props) => props.theme.table.border}; + } + + thead { + color: ${(props) => props.theme.table.thead.color}; + font-size: 0.8125rem; + user-select: none; + } + td { + padding: 6px 10px; + } + } .additional-parameter-sends-in-selector { select { diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js index 0069c5203..4b56142e3 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js @@ -1,14 +1,14 @@ import { useDispatch } from "react-redux"; -import React, { forwardRef, useState } from 'react'; +import React, { useState } from 'react'; import get from 'lodash/get'; import { useTheme } from 'providers/Theme'; -import { IconPlus, IconCaretDown, IconTrash, IconAdjustmentsHorizontal } from '@tabler/icons'; +import { IconPlus, IconTrash, IconAdjustmentsHorizontal } from '@tabler/icons'; import { cloneDeep } from "lodash"; import SingleLineEditor from "components/SingleLineEditor/index"; import StyledWrapper from "./StyledWrapper"; import Table from "components/Table/index"; -const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { +const AdditionalParams = ({ item = {}, request, updateAuth, collection, handleSave }) => { const dispatch = useDispatch(); const { storedTheme } = useTheme(); @@ -201,6 +201,7 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { value })} collection={collection} + onSave={handleSave} />
@@ -214,6 +215,7 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { value })} collection={collection} + onSave={handleSave} /> @@ -284,20 +286,6 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection }) => { export default AdditionalParams; -const Icon = forwardRef((props, ref) => { - const { value } = props - return ( -
-
- {value} -
-
- -
-
- ); -}); - const sendInOptionsMap = { 'authorization_code': { 'authorization': ['headers', 'queryparams'], diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js index 207b3510b..7c890513e 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/index.js @@ -336,11 +336,12 @@ const OAuth2AuthorizationCode = ({ save, item = {}, request, handleRun, updateAu - diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js index 3ad22ae28..253adeac0 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/index.js @@ -293,11 +293,12 @@ const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAu - diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Implicit/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Implicit/index.js index 5b0b44ec4..9715aa3ce 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Implicit/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Implicit/index.js @@ -218,11 +218,12 @@ const OAuth2Implicit = ({ save, item = {}, request, handleRun, updateAuth, colle - diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js index 43bb35cbd..f048183e6 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js @@ -296,11 +296,12 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update - From ef12401d2e21c23f21996bc5712e5477bbf02f41 Mon Sep 17 00:00:00 2001 From: lohit-bruno Date: Wed, 20 Aug 2025 16:34:03 +0530 Subject: [PATCH 14/15] fetch/refresh token - collection/request variables usage fix --- .../providers/ReduxStore/slices/collections/actions.js | 2 +- packages/bruno-electron/src/ipc/collection.js | 10 ++++++---- packages/bruno-electron/src/utils/collection.js | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js index 7e3a758d3..60d8cfe96 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js @@ -1324,7 +1324,7 @@ export const refreshOauth2Credentials = (payload) => async (dispatch, getState) request.globalEnvironmentVariables = globalEnvironmentVariables; return new Promise((resolve, reject) => { window.ipcRenderer - .invoke('renderer:refresh-oauth2-credentials', { request, collection }) + .invoke('renderer:refresh-oauth2-credentials', { itemUid, request, collection }) .then(({ credentials, url, collectionUid, debugInfo, credentialsId }) => { dispatch( collectionAddOauth2CredentialsByUrl({ diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js index 0d51b2f92..30d0e6f84 100644 --- a/packages/bruno-electron/src/ipc/collection.js +++ b/packages/bruno-electron/src/ipc/collection.js @@ -985,9 +985,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection const processEnvVars = getProcessEnvVars(collectionUid); const partialItem = { uid: itemUid }; const requestTreePath = getTreePathFromCollectionToItem(collection, partialItem); - if (requestTreePath && requestTreePath.length > 0) { - mergeVars(collection, requestCopy, requestTreePath); - } + mergeVars(collection, requestCopy, requestTreePath); interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars); const certsAndProxyConfig = await getCertsAndProxyConfig({ @@ -1108,7 +1106,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } }); - ipcMain.handle('renderer:refresh-oauth2-credentials', async (event, { request, collection }) => { + ipcMain.handle('renderer:refresh-oauth2-credentials', async (event, { itemUid, request, collection }) => { try { if (request.oauth2) { let requestCopy = _.cloneDeep(request); @@ -1116,7 +1114,11 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection 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); + mergeVars(collection, requestCopy, requestTreePath); interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars); + const certsAndProxyConfig = await getCertsAndProxyConfig({ collectionUid, request: requestCopy, diff --git a/packages/bruno-electron/src/utils/collection.js b/packages/bruno-electron/src/utils/collection.js index b502fe4a5..6eb0a7ccc 100644 --- a/packages/bruno-electron/src/utils/collection.js +++ b/packages/bruno-electron/src/utils/collection.js @@ -47,7 +47,7 @@ const mergeHeaders = (collection, request, requestTreePath) => { request.headers = Array.from(headers, ([name, value]) => ({ name, value, enabled: true })); }; -const mergeVars = (collection, request, requestTreePath) => { +const mergeVars = (collection, request, requestTreePath = []) => { let reqVars = new Map(); let collectionRequestVars = get(collection, 'root.request.vars.req', []); let collectionVariables = {}; From 311a2329680f014d4549cdb66bb11ad53c5b3879 Mon Sep 17 00:00:00 2001 From: lohit-bruno Date: Wed, 20 Aug 2025 16:57:07 +0530 Subject: [PATCH 15/15] updates --- .../Auth/OAuth2/AdditionalParams/index.js | 2 +- .../fixtures/oauth2-additional-params.js | 16 ++-- .../bru/utils/oauth2-additional-params.ts | 32 +++---- packages/bruno-lang/v2/src/bruToJson.js | 16 ++-- .../bruno-lang/v2/src/collectionBruToJson.js | 16 ++-- packages/bruno-lang/v2/src/utils.js | 80 +--------------- .../v2/tests/oauth2-additional-params.spec.js | 96 +++++++++---------- 7 files changed, 90 insertions(+), 168 deletions(-) diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js index 4b56142e3..1d2f81bee 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AdditionalParams/index.js @@ -274,7 +274,7 @@ const AdditionalParams = ({ item = {}, request, updateAuth, collection, handleS
diff --git a/packages/bruno-filestore/src/formats/bru/tests/fixtures/oauth2-additional-params.js b/packages/bruno-filestore/src/formats/bru/tests/fixtures/oauth2-additional-params.js index 0fe31f485..c3498340c 100644 --- a/packages/bruno-filestore/src/formats/bru/tests/fixtures/oauth2-additional-params.js +++ b/packages/bruno-filestore/src/formats/bru/tests/fixtures/oauth2-additional-params.js @@ -13,7 +13,7 @@ const getBruJsonWithAdditionalParams = (grantType) => ({ "grantType": grantType, }, }, - "oauth2_additional_parameters_authorization_headers": [ + "oauth2_additional_parameters_auth_req_headers": [ { "name": "auth-header", "value": "auth-header-value", @@ -25,7 +25,7 @@ const getBruJsonWithAdditionalParams = (grantType) => ({ "enabled": false } ], - "oauth2_additional_parameters_authorization_queryparams": [ + "oauth2_additional_parameters_auth_req_queryparams": [ { "name": "auth-query-param", "value": "auth-query-param-value", @@ -37,7 +37,7 @@ const getBruJsonWithAdditionalParams = (grantType) => ({ "enabled": false } ], - "oauth2_additional_parameters_token_headers": [ + "oauth2_additional_parameters_access_token_req_headers": [ { "name": "token-header", "value": "token-header-value", @@ -49,7 +49,7 @@ const getBruJsonWithAdditionalParams = (grantType) => ({ "enabled": false } ], - "oauth2_additional_parameters_token_queryparams": [ + "oauth2_additional_parameters_access_token_req_queryparams": [ { "name": "token-query-param", "value": "token-query-param-value", @@ -61,7 +61,7 @@ const getBruJsonWithAdditionalParams = (grantType) => ({ "enabled": false } ], - "oauth2_additional_parameters_token_bodyvalues": [ + "oauth2_additional_parameters_access_token_req_bodyvalues": [ { "name": "token-body", "value": "token-body-value", @@ -73,7 +73,7 @@ const getBruJsonWithAdditionalParams = (grantType) => ({ "enabled": false } ], - "oauth2_additional_parameters_refresh_headers": [ + "oauth2_additional_parameters_refresh_token_req_headers": [ { "name": "refresh-header", "value": "refresh-header-value", @@ -85,7 +85,7 @@ const getBruJsonWithAdditionalParams = (grantType) => ({ "enabled": false } ], - "oauth2_additional_parameters_refresh_queryparams": [ + "oauth2_additional_parameters_refresh_token_req_queryparams": [ { "name": "refresh-query-param", "value": "refresh-query-param-value", @@ -97,7 +97,7 @@ const getBruJsonWithAdditionalParams = (grantType) => ({ "enabled": false } ], - "oauth2_additional_parameters_refresh_bodyvalues": [ + "oauth2_additional_parameters_refresh_token_req_bodyvalues": [ { "name": "refresh-body", "value": "refresh-body-value", diff --git a/packages/bruno-filestore/src/formats/bru/utils/oauth2-additional-params.ts b/packages/bruno-filestore/src/formats/bru/utils/oauth2-additional-params.ts index 6bf57cefa..54a613807 100644 --- a/packages/bruno-filestore/src/formats/bru/utils/oauth2-additional-params.ts +++ b/packages/bruno-filestore/src/formats/bru/utils/oauth2-additional-params.ts @@ -23,14 +23,14 @@ export interface T_BruJson { auth: { oauth2: T_Oauth2Auth; }; - oauth2_additional_parameters_authorization_headers?: any[]; - oauth2_additional_parameters_authorization_queryparams?: any[]; - oauth2_additional_parameters_token_headers?: any[]; - oauth2_additional_parameters_token_queryparams?: any[]; - oauth2_additional_parameters_token_bodyvalues?: any[]; - oauth2_additional_parameters_refresh_headers?: any[]; - oauth2_additional_parameters_refresh_queryparams?: any[]; - oauth2_additional_parameters_refresh_bodyvalues?: any[]; + oauth2_additional_parameters_auth_req_headers?: any[]; + oauth2_additional_parameters_auth_req_queryparams?: any[]; + oauth2_additional_parameters_access_token_req_headers?: any[]; + oauth2_additional_parameters_access_token_req_queryparams?: any[]; + oauth2_additional_parameters_access_token_req_bodyvalues?: any[]; + oauth2_additional_parameters_refresh_token_req_headers?: any[]; + oauth2_additional_parameters_refresh_token_req_queryparams?: any[]; + oauth2_additional_parameters_refresh_token_req_bodyvalues?: any[]; } interface T_Oauth2ParameterMapping { @@ -41,18 +41,18 @@ interface T_Oauth2ParameterMapping { const PARAMETER_MAPPINGS: T_Oauth2ParameterMapping[] = [ // Authorization parameters (only for authorization_code grant type) - { type: 'authorization', sendIn: 'headers', source: 'oauth2_additional_parameters_authorization_headers' }, - { type: 'authorization', sendIn: 'queryparams', source: 'oauth2_additional_parameters_authorization_queryparams' }, + { type: 'authorization', sendIn: 'headers', source: 'oauth2_additional_parameters_auth_req_headers' }, + { type: 'authorization', sendIn: 'queryparams', source: 'oauth2_additional_parameters_auth_req_queryparams' }, // Token parameters (for all grant types) - { type: 'token', sendIn: 'headers', source: 'oauth2_additional_parameters_token_headers' }, - { type: 'token', sendIn: 'queryparams', source: 'oauth2_additional_parameters_token_queryparams' }, - { type: 'token', sendIn: 'body', source: 'oauth2_additional_parameters_token_bodyvalues' }, + { type: 'token', sendIn: 'headers', source: 'oauth2_additional_parameters_access_token_req_headers' }, + { type: 'token', sendIn: 'queryparams', source: 'oauth2_additional_parameters_access_token_req_queryparams' }, + { type: 'token', sendIn: 'body', source: 'oauth2_additional_parameters_access_token_req_bodyvalues' }, // Refresh parameters (for grant types that support refresh) - { type: 'refresh', sendIn: 'headers', source: 'oauth2_additional_parameters_refresh_headers' }, - { type: 'refresh', sendIn: 'queryparams', source: 'oauth2_additional_parameters_refresh_queryparams' }, - { type: 'refresh', sendIn: 'body', source: 'oauth2_additional_parameters_refresh_bodyvalues' }, + { type: 'refresh', sendIn: 'headers', source: 'oauth2_additional_parameters_refresh_token_req_headers' }, + { type: 'refresh', sendIn: 'queryparams', source: 'oauth2_additional_parameters_refresh_token_req_queryparams' }, + { type: 'refresh', sendIn: 'body', source: 'oauth2_additional_parameters_refresh_token_req_bodyvalues' }, ]; /** diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index 766835061..134fc9aa7 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -657,42 +657,42 @@ const sem = grammar.createSemantics().addAttribute('ast', { }, oauth2AuthReqHeaders(_1, dictionary) { return { - oauth2_additional_parameters_authorization_headers: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_auth_req_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2AuthReqQueryParams(_1, dictionary) { return { - oauth2_additional_parameters_authorization_queryparams: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_auth_req_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2AccessTokenReqHeaders(_1, dictionary) { return { - oauth2_additional_parameters_token_headers: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_access_token_req_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2AccessTokenReqQueryParams(_1, dictionary) { return { - oauth2_additional_parameters_token_queryparams: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_access_token_req_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2AccessTokenReqBody(_1, dictionary) { return { - oauth2_additional_parameters_token_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_access_token_req_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2RefreshTokenReqHeaders(_1, dictionary) { return { - oauth2_additional_parameters_refresh_headers: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_refresh_token_req_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2RefreshTokenReqQueryParams(_1, dictionary) { return { - oauth2_additional_parameters_refresh_queryparams: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_refresh_token_req_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2RefreshTokenReqBody(_1, dictionary) { return { - oauth2_additional_parameters_refresh_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_refresh_token_req_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, authwsse(_1, dictionary) { diff --git a/packages/bruno-lang/v2/src/collectionBruToJson.js b/packages/bruno-lang/v2/src/collectionBruToJson.js index 0c698e6ce..f3925ad62 100644 --- a/packages/bruno-lang/v2/src/collectionBruToJson.js +++ b/packages/bruno-lang/v2/src/collectionBruToJson.js @@ -379,42 +379,42 @@ const sem = grammar.createSemantics().addAttribute('ast', { }, oauth2AuthReqHeaders(_1, dictionary) { return { - oauth2_additional_parameters_authorization_headers: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_auth_req_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2AuthReqQueryParams(_1, dictionary) { return { - oauth2_additional_parameters_authorization_queryparams: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_auth_req_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2AccessTokenReqHeaders(_1, dictionary) { return { - oauth2_additional_parameters_token_headers: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_access_token_req_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2AccessTokenReqQueryParams(_1, dictionary) { return { - oauth2_additional_parameters_token_queryparams: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_access_token_req_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2AccessTokenReqBody(_1, dictionary) { return { - oauth2_additional_parameters_token_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_access_token_req_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2RefreshTokenReqHeaders(_1, dictionary) { return { - oauth2_additional_parameters_refresh_headers: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_refresh_token_req_headers: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2RefreshTokenReqQueryParams(_1, dictionary) { return { - oauth2_additional_parameters_refresh_queryparams: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_refresh_token_req_queryparams: mapPairListToKeyValPairs(dictionary.ast) }; }, oauth2RefreshTokenReqBody(_1, dictionary) { return { - oauth2_additional_parameters_refresh_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) + oauth2_additional_parameters_refresh_token_req_bodyvalues: mapPairListToKeyValPairs(dictionary.ast) }; }, authwsse(_1, dictionary) { diff --git a/packages/bruno-lang/v2/src/utils.js b/packages/bruno-lang/v2/src/utils.js index aaef783c4..74b22c952 100644 --- a/packages/bruno-lang/v2/src/utils.js +++ b/packages/bruno-lang/v2/src/utils.js @@ -29,86 +29,8 @@ const outdentString = (str) => { .join('\n'); }; -const mergeOauth2AdditionalParameters = (ast) => { - let additionalParameters = {}; - const authorizationHeaders = ast?.oauth2_additional_parameters_authorization_headers; - const authorizationQueryParams = ast?.oauth2_additional_parameters_authorization_queryparams; - const tokenHeaders = ast?.oauth2_additional_parameters_token_headers; - const tokenQueryParams = ast?.oauth2_additional_parameters_token_queryparams; - const tokenBodyValues = ast?.oauth2_additional_parameters_token_bodyvalues; - const refreshHeaders = ast?.oauth2_additional_parameters_refresh_headers; - const refreshQueryParams = ast?.oauth2_additional_parameters_refresh_queryparams; - const refreshBodyValues = ast?.oauth2_additional_parameters_refresh_bodyvalues; - - if (ast?.auth?.oauth2?.grantType == 'authorization_code') { - if (authorizationHeaders?.length || authorizationQueryParams?.length) { - additionalParameters['authorization'] = [] - } - if (authorizationHeaders?.length) { - additionalParameters['authorization'] = [ - ...authorizationHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) - ] - } - if (authorizationQueryParams?.length) { - additionalParameters['authorization'] = [ - ...additionalParameters['authorization'] || [], - ...authorizationQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) - ] - } - } - - if (tokenHeaders?.length || tokenQueryParams?.length || tokenBodyValues?.length) { - additionalParameters['token'] = [] - } - if (tokenHeaders?.length) { - additionalParameters['token'] = [ - ...tokenHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) - ] - } - if (tokenQueryParams?.length) { - additionalParameters['token'] = [ - ...additionalParameters['token'] || [], - ...tokenQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) - ] - } - if (tokenBodyValues?.length) { - additionalParameters['token'] = [ - ...additionalParameters['token'] || [], - ...tokenBodyValues?.map(_ => ({ ..._, sendIn: 'body' })) - ] - } - - if (refreshHeaders?.length || refreshQueryParams?.length || refreshBodyValues?.length) { - additionalParameters['refresh'] = [] - } - if (refreshHeaders?.length) { - additionalParameters['refresh'] = [ - ...refreshHeaders?.map(_ => ({ ..._, sendIn: 'headers' })) - ] - } - if (refreshQueryParams?.length) { - additionalParameters['refresh'] = [ - ...additionalParameters['refresh'] || [], - ...refreshQueryParams?.map(_ => ({ ..._, sendIn: 'queryparams' })) - ] - } - if (refreshBodyValues?.length) { - additionalParameters['refresh'] = [ - ...additionalParameters['refresh'] || [], - ...refreshBodyValues?.map(_ => ({ ..._, sendIn: 'body' })) - ] - } - - if(ast?.auth?.oauth2 && Object.keys(additionalParameters)?.length) { - ast.auth.oauth2.additionalParameters = additionalParameters; - } - - return ast; -} - module.exports = { safeParseJson, indentString, - outdentString, - mergeOauth2AdditionalParameters + outdentString }; diff --git a/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js b/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js index c412b64cf..c38ea7ef0 100644 --- a/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js +++ b/packages/bruno-lang/v2/tests/oauth2-additional-params.spec.js @@ -65,27 +65,27 @@ auth:oauth2:additional_params:refresh_token_req:body { const result = bruToJson(input); // Verify all config types are present - expect(result).toHaveProperty('oauth2_additional_parameters_authorization_headers'); - expect(result).toHaveProperty('oauth2_additional_parameters_authorization_queryparams'); - expect(result).toHaveProperty('oauth2_additional_parameters_token_headers'); - expect(result).toHaveProperty('oauth2_additional_parameters_token_queryparams'); - expect(result).toHaveProperty('oauth2_additional_parameters_token_bodyvalues'); - expect(result).toHaveProperty('oauth2_additional_parameters_refresh_headers'); - expect(result).toHaveProperty('oauth2_additional_parameters_refresh_queryparams'); - expect(result).toHaveProperty('oauth2_additional_parameters_refresh_bodyvalues'); + expect(result).toHaveProperty('oauth2_additional_parameters_auth_req_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_auth_req_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_access_token_req_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_access_token_req_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_access_token_req_bodyvalues'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_token_req_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_token_req_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_token_req_bodyvalues'); // Verify each has exactly one parameter - expect(result.oauth2_additional_parameters_authorization_headers).toHaveLength(2); - expect(result.oauth2_additional_parameters_authorization_queryparams).toHaveLength(2); - expect(result.oauth2_additional_parameters_token_headers).toHaveLength(2); - expect(result.oauth2_additional_parameters_token_queryparams).toHaveLength(2); - expect(result.oauth2_additional_parameters_token_bodyvalues).toHaveLength(2); - expect(result.oauth2_additional_parameters_refresh_headers).toHaveLength(2); - expect(result.oauth2_additional_parameters_refresh_queryparams).toHaveLength(2); - expect(result.oauth2_additional_parameters_refresh_bodyvalues).toHaveLength(2); + expect(result.oauth2_additional_parameters_auth_req_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_auth_req_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_access_token_req_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_access_token_req_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_access_token_req_bodyvalues).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_token_req_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_token_req_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_token_req_bodyvalues).toHaveLength(2); // Verify parameter values - expect(result.oauth2_additional_parameters_authorization_headers).toEqual([{ + expect(result.oauth2_additional_parameters_auth_req_headers).toEqual([{ name: 'auth-header', value: 'auth-header-value', enabled: true @@ -95,7 +95,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_authorization_queryparams).toEqual([{ + expect(result.oauth2_additional_parameters_auth_req_queryparams).toEqual([{ name: 'auth-query-param', value: 'auth-query-param-value', enabled: true @@ -105,7 +105,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_token_headers).toEqual([{ + expect(result.oauth2_additional_parameters_access_token_req_headers).toEqual([{ name: 'token-header', value: 'token-header-value', enabled: true @@ -115,7 +115,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_token_queryparams).toEqual([{ + expect(result.oauth2_additional_parameters_access_token_req_queryparams).toEqual([{ name: 'token-query-param', value: 'token-query-param-value', enabled: true @@ -125,7 +125,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_token_bodyvalues).toEqual([{ + expect(result.oauth2_additional_parameters_access_token_req_bodyvalues).toEqual([{ name: 'token-body', value: 'token-body-value', enabled: true @@ -135,7 +135,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_refresh_headers).toEqual([{ + expect(result.oauth2_additional_parameters_refresh_token_req_headers).toEqual([{ name: 'refresh-header', value: 'refresh-header-value', enabled: true @@ -145,7 +145,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_refresh_queryparams).toEqual([{ + expect(result.oauth2_additional_parameters_refresh_token_req_queryparams).toEqual([{ name: 'refresh-query-param', value: 'refresh-query-param-value', enabled: true @@ -155,7 +155,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_refresh_bodyvalues).toEqual([{ + expect(result.oauth2_additional_parameters_refresh_token_req_bodyvalues).toEqual([{ name: 'refresh-body', value: 'refresh-body-value', enabled: true @@ -226,27 +226,27 @@ auth:oauth2:additional_params:refresh_token_req:body { const result = collectionBruToJson(input); // Verify all config types are present - expect(result).toHaveProperty('oauth2_additional_parameters_authorization_headers'); - expect(result).toHaveProperty('oauth2_additional_parameters_authorization_queryparams'); - expect(result).toHaveProperty('oauth2_additional_parameters_token_headers'); - expect(result).toHaveProperty('oauth2_additional_parameters_token_queryparams'); - expect(result).toHaveProperty('oauth2_additional_parameters_token_bodyvalues'); - expect(result).toHaveProperty('oauth2_additional_parameters_refresh_headers'); - expect(result).toHaveProperty('oauth2_additional_parameters_refresh_queryparams'); - expect(result).toHaveProperty('oauth2_additional_parameters_refresh_bodyvalues'); + expect(result).toHaveProperty('oauth2_additional_parameters_auth_req_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_auth_req_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_access_token_req_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_access_token_req_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_access_token_req_bodyvalues'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_token_req_headers'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_token_req_queryparams'); + expect(result).toHaveProperty('oauth2_additional_parameters_refresh_token_req_bodyvalues'); // Verify each has exactly one parameter - expect(result.oauth2_additional_parameters_authorization_headers).toHaveLength(2); - expect(result.oauth2_additional_parameters_authorization_queryparams).toHaveLength(2); - expect(result.oauth2_additional_parameters_token_headers).toHaveLength(2); - expect(result.oauth2_additional_parameters_token_queryparams).toHaveLength(2); - expect(result.oauth2_additional_parameters_token_bodyvalues).toHaveLength(2); - expect(result.oauth2_additional_parameters_refresh_headers).toHaveLength(2); - expect(result.oauth2_additional_parameters_refresh_queryparams).toHaveLength(2); - expect(result.oauth2_additional_parameters_refresh_bodyvalues).toHaveLength(2); + expect(result.oauth2_additional_parameters_auth_req_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_auth_req_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_access_token_req_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_access_token_req_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_access_token_req_bodyvalues).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_token_req_headers).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_token_req_queryparams).toHaveLength(2); + expect(result.oauth2_additional_parameters_refresh_token_req_bodyvalues).toHaveLength(2); // Verify parameter values - expect(result.oauth2_additional_parameters_authorization_headers).toEqual([{ + expect(result.oauth2_additional_parameters_auth_req_headers).toEqual([{ name: 'auth-header', value: 'auth-header-value', enabled: true @@ -256,7 +256,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_authorization_queryparams).toEqual([{ + expect(result.oauth2_additional_parameters_auth_req_queryparams).toEqual([{ name: 'auth-query-param', value: 'auth-query-param-value', enabled: true @@ -266,7 +266,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_token_headers).toEqual([{ + expect(result.oauth2_additional_parameters_access_token_req_headers).toEqual([{ name: 'token-header', value: 'token-header-value', enabled: true @@ -276,7 +276,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_token_queryparams).toEqual([{ + expect(result.oauth2_additional_parameters_access_token_req_queryparams).toEqual([{ name: 'token-query-param', value: 'token-query-param-value', enabled: true @@ -286,7 +286,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_token_bodyvalues).toEqual([{ + expect(result.oauth2_additional_parameters_access_token_req_bodyvalues).toEqual([{ name: 'token-body', value: 'token-body-value', enabled: true @@ -296,7 +296,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_refresh_headers).toEqual([{ + expect(result.oauth2_additional_parameters_refresh_token_req_headers).toEqual([{ name: 'refresh-header', value: 'refresh-header-value', enabled: true @@ -306,7 +306,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_refresh_queryparams).toEqual([{ + expect(result.oauth2_additional_parameters_refresh_token_req_queryparams).toEqual([{ name: 'refresh-query-param', value: 'refresh-query-param-value', enabled: true @@ -316,7 +316,7 @@ auth:oauth2:additional_params:refresh_token_req:body { enabled: false }]); - expect(result.oauth2_additional_parameters_refresh_bodyvalues).toEqual([{ + expect(result.oauth2_additional_parameters_refresh_token_req_bodyvalues).toEqual([{ name: 'refresh-body', value: 'refresh-body-value', enabled: true