mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-24 17:03:47 +01:00
feat: add support for state param for OAuth2 Authorization Code flow (#2330)
* feat: add support for state param * chore: revert package-lock.json * test: update tests with state param * chore: revert package-lock.json * chore: add state to missing places * Adding state to PKCE toggle --------- Co-authored-by: Kadam Dhananjay <kadamdhananjay@johndeere.com>
This commit is contained in:
parent
3ded960938
commit
32b1ba1c92
@ -22,7 +22,7 @@ const OAuth2AuthorizationCode = ({ collection }) => {
|
||||
|
||||
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
|
||||
|
||||
const { callbackUrl, authorizationUrl, accessTokenUrl, clientId, clientSecret, scope, pkce } = oAuth;
|
||||
const { callbackUrl, authorizationUrl, accessTokenUrl, clientId, clientSecret, scope, state, pkce } = oAuth;
|
||||
|
||||
const handleChange = (key, value) => {
|
||||
dispatch(
|
||||
@ -37,6 +37,7 @@ const OAuth2AuthorizationCode = ({ collection }) => {
|
||||
clientId,
|
||||
clientSecret,
|
||||
scope,
|
||||
state,
|
||||
pkce,
|
||||
[key]: value
|
||||
}
|
||||
@ -57,6 +58,7 @@ const OAuth2AuthorizationCode = ({ collection }) => {
|
||||
clientId,
|
||||
clientSecret,
|
||||
scope,
|
||||
state,
|
||||
pkce: !Boolean(oAuth?.['pkce'])
|
||||
}
|
||||
})
|
||||
|
@ -22,6 +22,10 @@ const inputsConfig = [
|
||||
{
|
||||
key: 'scope',
|
||||
label: 'Scope'
|
||||
},
|
||||
{
|
||||
key: 'state',
|
||||
label: 'State'
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -22,7 +22,7 @@ const OAuth2AuthorizationCode = ({ item, collection }) => {
|
||||
|
||||
const handleSave = () => dispatch(saveRequest(item.uid, collection.uid));
|
||||
|
||||
const { callbackUrl, authorizationUrl, accessTokenUrl, clientId, clientSecret, scope, pkce } = oAuth;
|
||||
const { callbackUrl, authorizationUrl, accessTokenUrl, clientId, clientSecret, scope, state, pkce } = oAuth;
|
||||
|
||||
const handleChange = (key, value) => {
|
||||
dispatch(
|
||||
@ -37,6 +37,7 @@ const OAuth2AuthorizationCode = ({ item, collection }) => {
|
||||
accessTokenUrl,
|
||||
clientId,
|
||||
clientSecret,
|
||||
state,
|
||||
scope,
|
||||
pkce,
|
||||
[key]: value
|
||||
@ -58,6 +59,7 @@ const OAuth2AuthorizationCode = ({ item, collection }) => {
|
||||
accessTokenUrl,
|
||||
clientId,
|
||||
clientSecret,
|
||||
state,
|
||||
scope,
|
||||
pkce: !Boolean(oAuth?.['pkce'])
|
||||
}
|
||||
|
@ -22,6 +22,10 @@ const inputsConfig = [
|
||||
{
|
||||
key: 'scope',
|
||||
label: 'Scope'
|
||||
},
|
||||
{
|
||||
key: 'state',
|
||||
label: 'State'
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -169,6 +169,7 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
|
||||
request.oauth2.clientId = _interpolate(request.oauth2.clientId) || '';
|
||||
request.oauth2.clientSecret = _interpolate(request.oauth2.clientSecret) || '';
|
||||
request.oauth2.scope = _interpolate(request.oauth2.scope) || '';
|
||||
request.oauth2.state = _interpolate(request.oauth2.state) || '';
|
||||
request.oauth2.pkce = _interpolate(request.oauth2.pkce) || false;
|
||||
break;
|
||||
case 'client_credentials':
|
||||
|
@ -23,14 +23,15 @@ const resolveOAuth2AuthorizationCodeAccessToken = async (request, collectionUid)
|
||||
let requestCopy = cloneDeep(request);
|
||||
const { authorizationCode } = await getOAuth2AuthorizationCode(requestCopy, codeChallenge, collectionUid);
|
||||
const oAuth = get(requestCopy, 'oauth2', {});
|
||||
const { clientId, clientSecret, callbackUrl, scope, pkce } = oAuth;
|
||||
const { clientId, clientSecret, callbackUrl, scope, state, pkce } = oAuth;
|
||||
const data = {
|
||||
grant_type: 'authorization_code',
|
||||
code: authorizationCode,
|
||||
redirect_uri: callbackUrl,
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
scope: scope
|
||||
scope: scope,
|
||||
state: state
|
||||
};
|
||||
if (pkce) {
|
||||
data['code_verifier'] = codeVerifier;
|
||||
@ -46,7 +47,7 @@ const resolveOAuth2AuthorizationCodeAccessToken = async (request, collectionUid)
|
||||
const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const { oauth2 } = request;
|
||||
const { callbackUrl, clientId, authorizationUrl, scope, pkce } = oauth2;
|
||||
const { callbackUrl, clientId, authorizationUrl, scope, state, pkce } = oauth2;
|
||||
|
||||
let oauth2QueryParams =
|
||||
(authorizationUrl.indexOf('?') > -1 ? '&' : '?') + `client_id=${clientId}&response_type=code`;
|
||||
@ -59,6 +60,10 @@ const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {
|
||||
if (pkce) {
|
||||
oauth2QueryParams += `&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
||||
}
|
||||
if (state) {
|
||||
oauth2QueryParams += `&state=${state}`;
|
||||
}
|
||||
|
||||
const authorizationUrlWithQueryParams = authorizationUrl + oauth2QueryParams;
|
||||
try {
|
||||
const oauth2Store = new Oauth2Store();
|
||||
|
@ -112,6 +112,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
clientSecret: get(request, 'auth.oauth2.clientSecret'),
|
||||
scope: get(request, 'auth.oauth2.scope'),
|
||||
state: get(request, 'auth.oauth2.state'),
|
||||
pkce: get(request, 'auth.oauth2.pkce')
|
||||
};
|
||||
break;
|
||||
|
@ -444,6 +444,7 @@ const sem = grammar.createSemantics().addAttribute('ast', {
|
||||
const clientIdKey = _.find(auth, { name: 'client_id' });
|
||||
const clientSecretKey = _.find(auth, { name: 'client_secret' });
|
||||
const scopeKey = _.find(auth, { name: 'scope' });
|
||||
const stateKey = _.find(auth, { name: 'state' });
|
||||
const pkceKey = _.find(auth, { name: 'pkce' });
|
||||
return {
|
||||
auth: {
|
||||
@ -467,6 +468,7 @@ const sem = grammar.createSemantics().addAttribute('ast', {
|
||||
clientId: clientIdKey ? clientIdKey.value : '',
|
||||
clientSecret: clientSecretKey ? clientSecretKey.value : '',
|
||||
scope: scopeKey ? scopeKey.value : '',
|
||||
state: stateKey ? stateKey.value : '',
|
||||
pkce: pkceKey ? JSON.parse(pkceKey?.value || false) : false
|
||||
}
|
||||
: grantTypeKey?.value && grantTypeKey?.value == 'client_credentials'
|
||||
|
@ -254,6 +254,7 @@ const sem = grammar.createSemantics().addAttribute('ast', {
|
||||
const clientIdKey = _.find(auth, { name: 'client_id' });
|
||||
const clientSecretKey = _.find(auth, { name: 'client_secret' });
|
||||
const scopeKey = _.find(auth, { name: 'scope' });
|
||||
const stateKey = _.find(auth, { name: 'state' });
|
||||
const pkceKey = _.find(auth, { name: 'pkce' });
|
||||
return {
|
||||
auth: {
|
||||
@ -277,6 +278,7 @@ const sem = grammar.createSemantics().addAttribute('ast', {
|
||||
clientId: clientIdKey ? clientIdKey.value : '',
|
||||
clientSecret: clientSecretKey ? clientSecretKey.value : '',
|
||||
scope: scopeKey ? scopeKey.value : '',
|
||||
state: stateKey ? stateKey.value : '',
|
||||
pkce: pkceKey ? JSON.parse(pkceKey?.value || false) : false
|
||||
}
|
||||
: grantTypeKey?.value && grantTypeKey?.value == 'client_credentials'
|
||||
|
@ -180,6 +180,7 @@ ${indentString(`access_token_url: ${auth?.oauth2?.accessTokenUrl || ''}`)}
|
||||
${indentString(`client_id: ${auth?.oauth2?.clientId || ''}`)}
|
||||
${indentString(`client_secret: ${auth?.oauth2?.clientSecret || ''}`)}
|
||||
${indentString(`scope: ${auth?.oauth2?.scope || ''}`)}
|
||||
${indentString(`state: ${auth?.oauth2?.state || ''}`)}
|
||||
${indentString(`pkce: ${(auth?.oauth2?.pkce || false).toString()}`)}
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,7 @@ ${indentString(`access_token_url: ${auth?.oauth2?.accessTokenUrl || ''}`)}
|
||||
${indentString(`client_id: ${auth?.oauth2?.clientId || ''}`)}
|
||||
${indentString(`client_secret: ${auth?.oauth2?.clientSecret || ''}`)}
|
||||
${indentString(`scope: ${auth?.oauth2?.scope || ''}`)}
|
||||
${indentString(`state: ${auth?.oauth2?.state || ''}`)}
|
||||
${indentString(`pkce: ${(auth?.oauth2?.pkce || false).toString()}`)}
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@ auth:oauth2 {
|
||||
client_id: client_id_1
|
||||
client_secret: client_secret_1
|
||||
scope: read write
|
||||
state: 807061d5f0be
|
||||
pkce: false
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@
|
||||
"callbackUrl": "http://localhost:8080/api/auth/oauth2/authorization_code/callback",
|
||||
"accessTokenUrl": "http://localhost:8080/api/auth/oauth2/authorization_code/token",
|
||||
"scope": "read write",
|
||||
"state": "807061d5f0be",
|
||||
"pkce": false
|
||||
}
|
||||
},
|
||||
|
@ -163,6 +163,11 @@ const oauth2Schema = Yup.object({
|
||||
then: Yup.string().nullable(),
|
||||
otherwise: Yup.string().nullable().strip()
|
||||
}),
|
||||
state: Yup.string().when('grantType', {
|
||||
is: (val) => ['authorization_code'].includes(val),
|
||||
then: Yup.string().nullable(),
|
||||
otherwise: Yup.string().nullable().strip()
|
||||
}),
|
||||
pkce: Yup.boolean().when('grantType', {
|
||||
is: (val) => ['authorization_code'].includes(val),
|
||||
then: Yup.boolean().default(false),
|
||||
|
Loading…
Reference in New Issue
Block a user