diff --git a/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/index.js b/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/index.js
index 8eb4fee90..f26aa8651 100644
--- a/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/index.js
+++ b/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/index.js
@@ -71,6 +71,15 @@ const AuthMode = ({ item, collection }) => {
>
Digest Auth
+
{
+ dropdownTippyRef.current.hide();
+ onModeChange('oauth2');
+ }}
+ >
+ OAuth
+
{
diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/StyledWrapper.js
new file mode 100644
index 000000000..c2bb5d207
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/StyledWrapper.js
@@ -0,0 +1,16 @@
+import styled from 'styled-components';
+
+const Wrapper = styled.div`
+ label {
+ font-size: 0.8125rem;
+ }
+
+ .single-line-editor-wrapper {
+ padding: 0.15rem 0.4rem;
+ border-radius: 3px;
+ border: solid 1px ${(props) => props.theme.input.border};
+ background-color: ${(props) => props.theme.input.bg};
+ }
+`;
+
+export default Wrapper;
diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/index.js
new file mode 100644
index 000000000..ec1dae40d
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/index.js
@@ -0,0 +1,78 @@
+import React from 'react';
+import get from 'lodash/get';
+import { useTheme } from 'providers/Theme';
+import { useDispatch } from 'react-redux';
+import SingleLineEditor from 'components/SingleLineEditor';
+import { updateAuth } from 'providers/ReduxStore/slices/collections';
+import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
+import StyledWrapper from './StyledWrapper';
+
+const OAuth2 = ({ item, collection }) => {
+ const dispatch = useDispatch();
+ const { storedTheme } = useTheme();
+
+ const oAuth = item.draft ? get(item, 'draft.request.auth.oauth2', {}) : get(item, 'request.auth.oauth2', {});
+
+ const handleRun = () => dispatch(sendRequest(item, collection.uid));
+ const handleSave = () => dispatch(saveRequest(item.uid, collection.uid));
+
+ const handleUsernameChange = (username) => {
+ dispatch(
+ updateAuth({
+ mode: 'oauth2',
+ collectionUid: collection.uid,
+ itemUid: item.uid,
+ content: {
+ grantType: oAuth.grantType,
+ username: username,
+ password: oAuth.password
+ }
+ })
+ );
+ };
+
+ const handlePasswordChange = (password) => {
+ dispatch(
+ updateAuth({
+ mode: 'oauth2',
+ collectionUid: collection.uid,
+ itemUid: item.uid,
+ content: {
+ grantType: oAuth.grantType,
+ username: oAuth.username,
+ password: password
+ }
+ })
+ );
+ };
+
+ return (
+
+
+
+ handleUsernameChange(val)}
+ onRun={handleRun}
+ collection={collection}
+ />
+
+
+
+
+ handlePasswordChange(val)}
+ onRun={handleRun}
+ collection={collection}
+ />
+
+
+ );
+};
+
+export default OAuth2;
diff --git a/packages/bruno-app/src/components/RequestPane/Auth/index.js b/packages/bruno-app/src/components/RequestPane/Auth/index.js
index bd388737e..ba1ee2700 100644
--- a/packages/bruno-app/src/components/RequestPane/Auth/index.js
+++ b/packages/bruno-app/src/components/RequestPane/Auth/index.js
@@ -5,11 +5,14 @@ import AwsV4Auth from './AwsV4Auth';
import BearerAuth from './BearerAuth';
import BasicAuth from './BasicAuth';
import DigestAuth from './DigestAuth';
+import OAuth2 from './OAuth2';
import StyledWrapper from './StyledWrapper';
const Auth = ({ item, collection }) => {
const authMode = item.draft ? get(item, 'draft.request.auth.mode') : get(item, 'request.auth.mode');
+ console.log(item);
+
const getAuthView = () => {
switch (authMode) {
case 'awsv4': {
@@ -24,6 +27,9 @@ const Auth = ({ item, collection }) => {
case 'digest': {
return
;
}
+ case 'oauth2': {
+ return
;
+ }
}
};
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
index f464e5130..57dde52f3 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
@@ -415,6 +415,10 @@ export const collectionsSlice = createSlice({
item.draft.request.auth.mode = 'digest';
item.draft.request.auth.digest = action.payload.content;
break;
+ case 'oauth2':
+ item.draft.request.auth.mode = 'oauth2';
+ item.draft.request.auth.oauth2 = action.payload.content;
+ break;
}
}
}
diff --git a/packages/bruno-app/src/utils/collections/index.js b/packages/bruno-app/src/utils/collections/index.js
index 05dd0fb43..681194f87 100644
--- a/packages/bruno-app/src/utils/collections/index.js
+++ b/packages/bruno-app/src/utils/collections/index.js
@@ -498,6 +498,10 @@ export const humanizeRequestAuthMode = (mode) => {
label = 'Digest Auth';
break;
}
+ case 'oauth2': {
+ label = 'OAuth 2.0';
+ break;
+ }
}
return label;
diff --git a/packages/bruno-electron/src/ipc/network/prepare-request.js b/packages/bruno-electron/src/ipc/network/prepare-request.js
index 761984e65..7e978b673 100644
--- a/packages/bruno-electron/src/ipc/network/prepare-request.js
+++ b/packages/bruno-electron/src/ipc/network/prepare-request.js
@@ -64,6 +64,17 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
username: get(request, 'auth.digest.username'),
password: get(request, 'auth.digest.password')
};
+ break;
+ case 'oauth2':
+ const grantType = get(request, 'auth.oauth2.grantType');
+ if (grantType === 'resourceOwnerPasswordCredentials') {
+ axiosRequest.data = {
+ grant_type: grantType,
+ username: get(request, 'auth.oauth2.username'),
+ password: get(request, 'auth.oauth2.password')
+ };
+ }
+ break;
}
}
diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js
index fbe289974..533839b14 100644
--- a/packages/bruno-lang/v2/src/bruToJson.js
+++ b/packages/bruno-lang/v2/src/bruToJson.js
@@ -23,7 +23,7 @@ const { outdentString } = require('../../v1/src/utils');
*/
const grammar = ohm.grammar(`Bru {
BruFile = (meta | http | query | headers | auths | bodies | varsandassert | script | tests | docs)*
- auths = authawsv4 | authbasic | authbearer | authdigest
+ auths = authawsv4 | authbasic | authbearer | authdigest | authOAuth2
bodies = bodyjson | bodytext | bodyxml | bodysparql | bodygraphql | bodygraphqlvars | bodyforms | body
bodyforms = bodyformurlencoded | bodymultipart
@@ -80,6 +80,7 @@ const grammar = ohm.grammar(`Bru {
authbasic = "auth:basic" dictionary
authbearer = "auth:bearer" dictionary
authdigest = "auth:digest" dictionary
+ authOAuth2 = "auth:oauth2" dictionary
body = "body" st* "{" nl* textblock tagend
bodyjson = "body:json" st* "{" nl* textblock tagend
@@ -366,6 +367,21 @@ const sem = grammar.createSemantics().addAttribute('ast', {
}
};
},
+ authOAuth2(_1, dictionary) {
+ const auth = mapPairListToKeyValPairs(dictionary.ast, false);
+ const grantTypeKey = _.find(auth, { name: 'grantType' });
+ const usernameKey = _.find(auth, { name: 'username' });
+ const passwordKey = _.find(auth, { name: 'password' });
+ return {
+ auth: {
+ oauth2: {
+ grantType: grantTypeKey ? grantTypeKey.value : '',
+ username: usernameKey ? usernameKey.value : '',
+ password: passwordKey ? passwordKey.value : ''
+ }
+ }
+ };
+ },
bodyformurlencoded(_1, dictionary) {
return {
body: {
diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js
index f4959500a..e1b0dbeae 100644
--- a/packages/bruno-lang/v2/src/jsonToBru.js
+++ b/packages/bruno-lang/v2/src/jsonToBru.js
@@ -87,6 +87,16 @@ const jsonToBru = (json) => {
bru += '\n}\n\n';
}
+ if (auth && auth.oauth2) {
+ bru += `auth:oauth2 {
+${indentString(`grantType: ${auth.oauth2.grantType}`)}
+${indentString(`username: ${auth.oauth2.username}`)}
+${indentString(`password: ${auth.oauth2.password}`)}
+}
+
+`;
+ }
+
if (auth && auth.awsv4) {
bru += `auth:awsv4 {
${indentString(`accessKeyId: ${auth.awsv4.accessKeyId}`)}
diff --git a/packages/bruno-lang/v2/tests/fixtures/request.bru b/packages/bruno-lang/v2/tests/fixtures/request.bru
index 4855506a6..26044dc5c 100644
--- a/packages/bruno-lang/v2/tests/fixtures/request.bru
+++ b/packages/bruno-lang/v2/tests/fixtures/request.bru
@@ -22,6 +22,12 @@ headers {
~transaction-id: {{transactionId}}
}
+auth:oauth2 {
+ grantType: resourceOwnerPasswordCredentials
+ username: john
+ password: secret
+}
+
auth:awsv4 {
accessKeyId: A12345678
secretAccessKey: thisisasecret
diff --git a/packages/bruno-lang/v2/tests/fixtures/request.json b/packages/bruno-lang/v2/tests/fixtures/request.json
index c23c46474..c70e96945 100644
--- a/packages/bruno-lang/v2/tests/fixtures/request.json
+++ b/packages/bruno-lang/v2/tests/fixtures/request.json
@@ -45,6 +45,11 @@
}
],
"auth": {
+ "oauth2": {
+ "grantType": "resourceOwnerPasswordCredentials",
+ "username": "john",
+ "password": "secret"
+ },
"awsv4": {
"accessKeyId": "A12345678",
"secretAccessKey": "thisisasecret",
diff --git a/packages/bruno-schema/src/collections/index.js b/packages/bruno-schema/src/collections/index.js
index 37e6629af..3b0d37106 100644
--- a/packages/bruno-schema/src/collections/index.js
+++ b/packages/bruno-schema/src/collections/index.js
@@ -101,12 +101,23 @@ const authDigestSchema = Yup.object({
.noUnknown(true)
.strict();
+const oAuth2Schema = Yup.object({
+ grantType: Yup.string()
+ .oneOf(['clientCredentials', 'resourceOwnerPasswordCredentials'])
+ .required('grantType is required'),
+ username: Yup.string().nullable(),
+ password: Yup.string().nullable()
+})
+ .noUnknown(true)
+ .strict();
+
const authSchema = Yup.object({
- mode: Yup.string().oneOf(['none', 'awsv4', 'basic', 'bearer', 'digest']).required('mode is required'),
+ mode: Yup.string().oneOf(['none', 'awsv4', 'basic', 'bearer', 'digest', 'oauth2']).required('mode is required'),
awsv4: authAwsV4Schema.nullable(),
basic: authBasicSchema.nullable(),
bearer: authBearerSchema.nullable(),
- digest: authDigestSchema.nullable()
+ digest: authDigestSchema.nullable(),
+ oauth2: oAuth2Schema.nullable()
})
.noUnknown(true)
.strict();