Merge pull request #390 from grubersjoe/gql-auth

feat: Add authentication for GraphQL requests
This commit is contained in:
Anoop M D 2023-10-05 20:21:58 +05:30 committed by GitHub
commit da9a6c434a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 11 deletions

View File

@ -6,6 +6,7 @@ import { IconRefresh, IconLoader2, IconBook, IconDownload } from '@tabler/icons'
import { useSelector, useDispatch } from 'react-redux';
import { updateRequestPaneTab } from 'providers/ReduxStore/slices/tabs';
import QueryEditor from 'components/RequestPane/QueryEditor';
import Auth from 'components/RequestPane/Auth';
import GraphQLVariables from 'components/RequestPane/GraphQLVariables';
import RequestHeaders from 'components/RequestPane/RequestHeaders';
import Vars from 'components/RequestPane/Vars';
@ -32,7 +33,14 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
const environment = findEnvironmentInCollection(collection, collection.activeEnvironmentUid);
let { schema, loadSchema, isLoading: isSchemaLoading, error: schemaError } = useGraphqlSchema(url, environment);
const request = item.draft ? item.draft.request : item.request;
let {
schema,
loadSchema,
isLoading: isSchemaLoading,
error: schemaError
} = useGraphqlSchema(url, environment, request, collection.collectionVariables);
const loadGqlSchema = () => {
if (!isSchemaLoading) {
@ -90,6 +98,9 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
case 'headers': {
return <RequestHeaders item={item} collection={collection} />;
}
case 'auth': {
return <Auth item={item} collection={collection} />;
}
case 'vars': {
return <Vars item={item} collection={collection} />;
}
@ -135,6 +146,9 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
<div className={getTabClassname('headers')} role="tab" onClick={() => selectTab('headers')}>
Headers
</div>
<div className={getTabClassname('auth')} role="tab" onClick={() => selectTab('auth')}>
Auth
</div>
<div className={getTabClassname('vars')} role="tab" onClick={() => selectTab('vars')}>
Vars
</div>

View File

@ -6,7 +6,7 @@ import { simpleHash } from 'utils/common';
const schemaHashPrefix = 'bruno.graphqlSchema';
const useGraphqlSchema = (endpoint, environment) => {
const useGraphqlSchema = (endpoint, environment, request, collectionVariables) => {
const localStorageKey = `${schemaHashPrefix}.${simpleHash(endpoint)}`;
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false);
@ -25,7 +25,7 @@ const useGraphqlSchema = (endpoint, environment) => {
const loadSchema = () => {
setIsLoading(true);
fetchGqlSchema(endpoint, environment)
fetchGqlSchema(endpoint, environment, request, collectionVariables)
.then((res) => res.data)
.then((s) => {
if (s && s.data) {

View File

@ -29,11 +29,14 @@ const sendHttpRequest = async (item, collection, environment, collectionVariable
});
};
export const fetchGqlSchema = async (endpoint, environment) => {
export const fetchGqlSchema = async (endpoint, environment, request, collectionVariables) => {
return new Promise((resolve, reject) => {
const { ipcRenderer } = window;
ipcRenderer.invoke('fetch-gql-schema', endpoint, environment).then(resolve).catch(reject);
ipcRenderer
.invoke('fetch-gql-schema', endpoint, environment, request, collectionVariables)
.then(resolve)
.catch(reject);
});
};

View File

@ -458,10 +458,10 @@ const registerNetworkIpc = (mainWindow) => {
});
});
ipcMain.handle('fetch-gql-schema', async (event, endpoint, environment) => {
ipcMain.handle('fetch-gql-schema', async (event, endpoint, environment, request, collectionVariables) => {
try {
const envVars = getEnvVars(environment);
const request = prepareGqlIntrospectionRequest(endpoint, envVars);
const preparedRequest = prepareGqlIntrospectionRequest(endpoint, envVars, request);
const preferences = getPreferences();
const sslVerification = get(preferences, 'request.sslVerification', true);
@ -472,7 +472,9 @@ const registerNetworkIpc = (mainWindow) => {
});
}
const response = await axios(request);
interpolateVars(preparedRequest, envVars, collectionVariables);
const response = await axios(preparedRequest);
return {
status: response.status,

View File

@ -1,12 +1,13 @@
const Mustache = require('mustache');
const { getIntrospectionQuery } = require('graphql');
const { get } = require('lodash');
// override the default escape function to prevent escaping
Mustache.escape = function (value) {
return value;
};
const prepareGqlIntrospectionRequest = (endpoint, envVars) => {
const prepareGqlIntrospectionRequest = (endpoint, envVars, request) => {
if (endpoint && endpoint.length) {
endpoint = Mustache.render(endpoint, envVars);
}
@ -15,7 +16,7 @@ const prepareGqlIntrospectionRequest = (endpoint, envVars) => {
query: introspectionQuery
};
const request = {
let axiosRequest = {
method: 'POST',
url: endpoint,
headers: {
@ -25,7 +26,20 @@ const prepareGqlIntrospectionRequest = (endpoint, envVars) => {
data: JSON.stringify(queryParams)
};
return request;
if (request.auth) {
if (request.auth.mode === 'basic') {
axiosRequest.auth = {
username: get(request, 'auth.basic.username'),
password: get(request, 'auth.basic.password')
};
}
if (request.auth.mode === 'bearer') {
axiosRequest.headers.authorization = `Bearer ${get(request, 'auth.bearer.token')}`;
}
}
return axiosRequest;
};
module.exports = prepareGqlIntrospectionRequest;