diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/ClientCredentials/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/ClientCredentials/index.js
index d69122b48..59a9bdeec 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/ClientCredentials/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/ClientCredentials/index.js
@@ -7,6 +7,8 @@ import { saveCollectionRoot, sendCollectionOauth2Request } from 'providers/Redux
import StyledWrapper from './StyledWrapper';
import { inputsConfig } from './inputsConfig';
import { updateCollectionAuth } from 'providers/ReduxStore/slices/collections/index';
+import { clearOauth2Cache } from 'utils/network';
+import toast from 'react-hot-toast';
const OAuth2ClientCredentials = ({ collection }) => {
const dispatch = useDispatch();
@@ -39,6 +41,16 @@ const OAuth2ClientCredentials = ({ collection }) => {
);
};
+ const handleClearCache = (e) => {
+ clearOauth2Cache(collection?.uid)
+ .then(() => {
+ toast.success('cleared cache successfully');
+ })
+ .catch((err) => {
+ toast.error(err.message);
+ });
+ };
+
return (
{inputsConfig.map((input) => {
@@ -60,9 +72,14 @@ const OAuth2ClientCredentials = ({ collection }) => {
);
})}
-
+
+
+
+
);
};
diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/PasswordCredentials/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/PasswordCredentials/index.js
index d2d9eed1f..b07ceb72a 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/PasswordCredentials/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/PasswordCredentials/index.js
@@ -7,6 +7,8 @@ import { saveCollectionRoot, sendCollectionOauth2Request } from 'providers/Redux
import StyledWrapper from './StyledWrapper';
import { inputsConfig } from './inputsConfig';
import { updateCollectionAuth } from 'providers/ReduxStore/slices/collections/index';
+import { clearOauth2Cache } from 'utils/network';
+import toast from 'react-hot-toast';
const OAuth2AuthorizationCode = ({ item, collection }) => {
const dispatch = useDispatch();
@@ -41,6 +43,16 @@ const OAuth2AuthorizationCode = ({ item, collection }) => {
);
};
+ const handleClearCache = (e) => {
+ clearOauth2Cache(collection?.uid)
+ .then(() => {
+ toast.success('cleared cache successfully');
+ })
+ .catch((err) => {
+ toast.error(err.message);
+ });
+ };
+
return (
{inputsConfig.map((input) => {
@@ -62,9 +74,14 @@ const OAuth2AuthorizationCode = ({ item, collection }) => {
);
})}
-
+
+
+
+
);
};
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 a43c8f0ad..9c9f1553d 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
@@ -7,6 +7,8 @@ import { updateAuth } from 'providers/ReduxStore/slices/collections';
import { saveRequest, sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import StyledWrapper from './StyledWrapper';
import { inputsConfig } from './inputsConfig';
+import { clearOauth2Cache } from 'utils/network';
+import toast from 'react-hot-toast';
const OAuth2ClientCredentials = ({ item, collection }) => {
const dispatch = useDispatch();
@@ -40,6 +42,16 @@ const OAuth2ClientCredentials = ({ item, collection }) => {
);
};
+ const handleClearCache = (e) => {
+ clearOauth2Cache(collection?.uid)
+ .then(() => {
+ toast.success('cleared cache successfully');
+ })
+ .catch((err) => {
+ toast.error(err.message);
+ });
+ };
+
return (
{inputsConfig.map((input) => {
@@ -62,9 +74,14 @@ const OAuth2ClientCredentials = ({ item, collection }) => {
);
})}
-
+
+
+
+
);
};
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 4ec8c1faa..543a17164 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
@@ -7,6 +7,8 @@ import { updateAuth } from 'providers/ReduxStore/slices/collections';
import { saveRequest, sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import StyledWrapper from './StyledWrapper';
import { inputsConfig } from './inputsConfig';
+import { clearOauth2Cache } from 'utils/network';
+import toast from 'react-hot-toast';
const OAuth2AuthorizationCode = ({ item, collection }) => {
const dispatch = useDispatch();
@@ -42,6 +44,16 @@ const OAuth2AuthorizationCode = ({ item, collection }) => {
);
};
+ const handleClearCache = (e) => {
+ clearOauth2Cache(collection?.uid)
+ .then(() => {
+ toast.success('cleared cache successfully');
+ })
+ .catch((err) => {
+ toast.error(err.message);
+ });
+ };
+
return (
{inputsConfig.map((input) => {
@@ -64,9 +76,14 @@ const OAuth2AuthorizationCode = ({ item, collection }) => {
);
})}
-
+
+
+
+
);
};
diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js
index 6a438ece4..407aeef39 100644
--- a/packages/bruno-electron/src/ipc/network/index.js
+++ b/packages/bruno-electron/src/ipc/network/index.js
@@ -268,22 +268,22 @@ const configureRequest = async (
if (request.oauth2) {
let requestCopy = cloneDeep(request);
interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars);
- let accessToken;
+ let credentials;
switch (request?.oauth2?.grantType) {
case 'authorization_code': {
- ({ accessToken } = await oauth2AuthorizeWithAuthorizationCode(requestCopy, collectionUid));
+ ({ credentials } = await oauth2AuthorizeWithAuthorizationCode(requestCopy, collectionUid));
break;
}
case 'client_credentials': {
- ({ accessToken } = await oauth2AuthorizeWithClientCredentials(requestCopy, collectionUid));
+ ({ credentials } = await oauth2AuthorizeWithClientCredentials(requestCopy, collectionUid));
break;
}
case 'password': {
- ({ accessToken } = await oauth2AuthorizeWithPasswordCredentials(requestCopy, collectionUid));
+ ({ credentials } = await oauth2AuthorizeWithPasswordCredentials(requestCopy, collectionUid));
break;
}
}
- request.headers['Authorization'] = `Bearer ${accessToken}`;
+ request.headers['Authorization'] = `Bearer ${credentials.access_token}`;
}
if (request.awsv4config) {
diff --git a/packages/bruno-electron/src/ipc/network/interpolate-vars.js b/packages/bruno-electron/src/ipc/network/interpolate-vars.js
index 90b072658..e8ec60e25 100644
--- a/packages/bruno-electron/src/ipc/network/interpolate-vars.js
+++ b/packages/bruno-electron/src/ipc/network/interpolate-vars.js
@@ -160,14 +160,6 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
request.oauth2.clientId = clientId;
request.oauth2.clientSecret = clientSecret;
request.oauth2.scope = scope;
- request.data = {
- grant_type: 'password',
- username,
- password,
- client_id: clientId,
- client_secret: clientSecret,
- scope
- };
break;
case 'authorization_code':
request.oauth2.callbackUrl = _interpolate(request.oauth2.callbackUrl) || '';
@@ -187,12 +179,6 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
request.oauth2.clientId = clientId;
request.oauth2.clientSecret = clientSecret;
request.oauth2.scope = scope;
- request.data = {
- grant_type: 'client_credentials',
- client_id: clientId,
- client_secret: clientSecret,
- scope
- };
break;
default:
break;
diff --git a/packages/bruno-electron/src/ipc/network/oauth2-helper.js b/packages/bruno-electron/src/ipc/network/oauth2-helper.js
index 3c8489fa3..4a447675e 100644
--- a/packages/bruno-electron/src/ipc/network/oauth2-helper.js
+++ b/packages/bruno-electron/src/ipc/network/oauth2-helper.js
@@ -4,6 +4,8 @@ const { authorizeUserInWindow } = require('./authorize-user-in-window');
const Oauth2Store = require('../../store/oauth2');
const { makeAxiosInstance } = require('./axios-instance');
+const oauth2Store = new Oauth2Store();
+
const generateCodeVerifier = () => {
return crypto.randomBytes(22).toString('hex');
};
@@ -15,9 +17,27 @@ const generateCodeChallenge = (codeVerifier) => {
return base64Hash.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
};
+const getPersistedOauth2Credentials = (collectionUid) => {
+ const collectionOauthStore = oauth2Store.getOauth2DataOfCollection(collectionUid);
+ const cachedCredentials = collectionOauthStore.credentials;
+ return { cachedCredentials };
+};
+
+const persistOauth2Credentials = (credentials, collectionUid) => {
+ const collectionOauthStore = oauth2Store.getOauth2DataOfCollection(collectionUid);
+ collectionOauthStore.credentials = credentials;
+ oauth2Store.updateOauth2DataOfCollection(collectionUid, collectionOauthStore);
+};
+
// AUTHORIZATION CODE
const oauth2AuthorizeWithAuthorizationCode = async (request, collectionUid) => {
+ const { cachedCredentials } = getPersistedOauth2Credentials(collectionUid);
+ if (cachedCredentials?.access_token) {
+ console.log('Reusing Stored access token');
+ return { credentials: cachedCredentials };
+ }
+
let codeVerifier = generateCodeVerifier();
let codeChallenge = generateCodeChallenge(codeVerifier);
@@ -36,17 +56,16 @@ const oauth2AuthorizeWithAuthorizationCode = async (request, collectionUid) => {
data['code_verifier'] = codeVerifier;
}
- const url = requestCopy?.oauth2?.accessTokenUrl;
-
request.method = 'POST';
request.headers['content-type'] = 'application/x-www-form-urlencoded';
request.data = data;
- request.url = url;
+ request.url = request?.oauth2?.accessTokenUrl;
const axiosInstance = makeAxiosInstance();
- let response = await axiosInstance(request);
- let accessToken = JSON.parse(response.data).access_token;
- return { accessToken };
+ const response = await axiosInstance(request);
+ const credentials = JSON.parse(response.data);
+ persistOauth2Credentials(credentials, collectionUid);
+ return { credentials };
};
const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {
@@ -71,7 +90,6 @@ const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {
authorizationUrlWithQueryParams.searchParams.append('state', state);
}
try {
- const oauth2Store = new Oauth2Store();
const { authorizationCode } = await authorizeUserInWindow({
authorizeUrl: authorizationUrlWithQueryParams.toString(),
callbackUrl,
@@ -86,7 +104,13 @@ const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {
// CLIENT CREDENTIALS
-const oauth2AuthorizeWithClientCredentials = async (request) => {
+const oauth2AuthorizeWithClientCredentials = async (request, collectionUid) => {
+ const { cachedCredentials } = getPersistedOauth2Credentials(collectionUid);
+ if (cachedCredentials?.access_token) {
+ console.log('Reusing Stored access token');
+ return { credentials: cachedCredentials };
+ }
+
let requestCopy = cloneDeep(request);
const oAuth = get(requestCopy, 'oauth2', {});
const { clientId, clientSecret, scope } = oAuth;
@@ -102,18 +126,24 @@ const oauth2AuthorizeWithClientCredentials = async (request) => {
request.method = 'POST';
request.headers['content-type'] = 'application/x-www-form-urlencoded';
request.data = data;
- request.url = requestCopy?.oauth2?.accessTokenUrl;
+ request.url = request?.oauth2?.accessTokenUrl;
const axiosInstance = makeAxiosInstance();
let response = await axiosInstance(request);
- let accessToken = JSON.parse(response.data).access_token;
-
- return { accessToken };
+ let credentials = JSON.parse(response.data);
+ persistOauth2Credentials(credentials, collectionUid);
+ return { credentials };
};
// PASSWORD CREDENTIALS
-const oauth2AuthorizeWithPasswordCredentials = async (request) => {
+const oauth2AuthorizeWithPasswordCredentials = async (request, collectionUid) => {
+ const { cachedCredentials } = getPersistedOauth2Credentials(collectionUid);
+ if (cachedCredentials?.access_token) {
+ console.log('Reusing Stored access token');
+ return { credentials: cachedCredentials };
+ }
+
const oAuth = get(request, 'oauth2', {});
const { username, password, clientId, clientSecret, scope } = oAuth;
const data = {
@@ -134,8 +164,9 @@ const oauth2AuthorizeWithPasswordCredentials = async (request) => {
const axiosInstance = makeAxiosInstance();
let response = await axiosInstance(request);
- let accessToken = JSON.parse(response.data).access_token;
- return { accessToken };
+ let credentials = JSON.parse(response.data);
+ persistOauth2Credentials(credentials, collectionUid);
+ return { credentials };
};
module.exports = {
oauth2AuthorizeWithAuthorizationCode,
diff --git a/packages/bruno-electron/src/store/oauth2.js b/packages/bruno-electron/src/store/oauth2.js
index b0a2255b5..b24c560aa 100644
--- a/packages/bruno-electron/src/store/oauth2.js
+++ b/packages/bruno-electron/src/store/oauth2.js
@@ -85,6 +85,7 @@ class Oauth2Store {
let oauth2DataForCollection = this.getOauth2DataOfCollection(collectionUid);
delete oauth2DataForCollection.sessionId;
+ delete oauth2DataForCollection.credentials;
let updatedOauth2Data = oauth2Data.filter((d) => d.collectionUid !== collectionUid);
updatedOauth2Data.push({ ...oauth2DataForCollection });