mirror of
https://github.com/usebruno/bruno.git
synced 2025-06-21 04:08:01 +02:00
feat(#119): bearer auth support completed
This commit is contained in:
parent
2e600838b2
commit
48e4e60696
@ -4,8 +4,7 @@ const Wrapper = styled.div`
|
|||||||
font-size: 0.8125rem;
|
font-size: 0.8125rem;
|
||||||
|
|
||||||
.auth-mode-selector {
|
.auth-mode-selector {
|
||||||
background: ${(props) => props.theme.requestTabPanel.bodyModeSelect.color};
|
background: transparent;
|
||||||
border-radius: 3px;
|
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
padding: 0.2rem 0.6rem !important;
|
padding: 0.2rem 0.6rem !important;
|
||||||
|
@ -15,8 +15,8 @@ const AuthMode = ({ item, collection }) => {
|
|||||||
|
|
||||||
const Icon = forwardRef((props, ref) => {
|
const Icon = forwardRef((props, ref) => {
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className="flex items-center justify-center pl-3 py-1 select-none">
|
<div ref={ref} className="flex items-center justify-center text-yellow-600 select-none">
|
||||||
{humanizeRequestAuthMode(authMode)} <IconCaretDown className="caret ml-2 mr-2" size={14} strokeWidth={2} />
|
{humanizeRequestAuthMode(authMode)} <IconCaretDown className="caret ml-1 mr-1" size={14} strokeWidth={2} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
.single-line-editor-wrapper {
|
||||||
|
padding: 0.15rem 0.4rem;
|
||||||
|
border: ${(props) => props.theme.sidebar.search.border};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Wrapper;
|
@ -0,0 +1,52 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import get from 'lodash/get';
|
||||||
|
import { useTheme } from 'providers/Theme';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import SingleLineEditor from 'components/SingleLineEditor';
|
||||||
|
import { updateBearerToken } from 'providers/ReduxStore/slices/collections';
|
||||||
|
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
|
const BearerAuth = ({ onTokenChange, item, collection }) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { storedTheme } = useTheme();
|
||||||
|
|
||||||
|
const bearerToken = item.draft
|
||||||
|
? get(item, 'draft.request.auth.bearer.token')
|
||||||
|
: get(item, 'request.auth.bearer.token');
|
||||||
|
|
||||||
|
const handleRun = () => dispatch(sendRequest(item, collection.uid));
|
||||||
|
const handleSave = () => dispatch(saveRequest(item.uid, collection.uid));
|
||||||
|
|
||||||
|
const handleTokenChange = (token) => {
|
||||||
|
dispatch(
|
||||||
|
updateBearerToken({
|
||||||
|
collectionUid: collection.uid,
|
||||||
|
itemUid: item.uid,
|
||||||
|
content: {
|
||||||
|
token: token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledWrapper className="mt-2 w-full">
|
||||||
|
<label htmlFor="bearerToken" className="block font-medium mb-2">
|
||||||
|
Token
|
||||||
|
</label>
|
||||||
|
<div className="single-line-editor-wrapper">
|
||||||
|
<SingleLineEditor
|
||||||
|
value={bearerToken}
|
||||||
|
theme={storedTheme}
|
||||||
|
onSave={handleSave}
|
||||||
|
onChange={(val) => handleTokenChange(val)}
|
||||||
|
onRun={handleRun}
|
||||||
|
collection={collection}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</StyledWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BearerAuth;
|
@ -1,32 +1,30 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import { useDispatch } from 'react-redux';
|
import AuthMode from './AuthMode';
|
||||||
import { updateRequestBody } from 'providers/ReduxStore/slices/collections';
|
import BearerAuth from './BearerAuth';
|
||||||
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const RequestBody = ({ item, collection }) => {
|
const Auth = ({ item, collection }) => {
|
||||||
const dispatch = useDispatch();
|
|
||||||
const authMode = item.draft ? get(item, 'draft.request.auth.mode') : get(item, 'request.auth.mode');
|
const authMode = item.draft ? get(item, 'draft.request.auth.mode') : get(item, 'request.auth.mode');
|
||||||
|
|
||||||
const onEdit = (value) => {
|
const getAuthView = () => {
|
||||||
// dispatch(
|
switch (authMode) {
|
||||||
// updateRequestBody({
|
case 'basic': {
|
||||||
// content: value,
|
|
||||||
// itemUid: item.uid,
|
|
||||||
// collectionUid: collection.uid
|
|
||||||
// })
|
|
||||||
// );
|
|
||||||
};
|
|
||||||
|
|
||||||
if (authMode === 'basic') {
|
|
||||||
return <div>Basic Auth</div>;
|
return <div>Basic Auth</div>;
|
||||||
}
|
}
|
||||||
|
case 'bearer': {
|
||||||
if (authMode === 'bearer') {
|
return <BearerAuth collection={collection} item={item} />;
|
||||||
return <div>Bearer Token</div>;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <StyledWrapper className="w-full">No Auth</StyledWrapper>;
|
|
||||||
};
|
};
|
||||||
export default RequestBody;
|
|
||||||
|
return (
|
||||||
|
<StyledWrapper className="w-full">
|
||||||
|
<div className="flex flex-grow justify-start items-center">
|
||||||
|
<AuthMode item={item} collection={collection} />
|
||||||
|
</div>
|
||||||
|
{getAuthView()}
|
||||||
|
</StyledWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Auth;
|
||||||
|
@ -108,13 +108,10 @@ const HttpRequestPane = ({ item, collection, leftPaneWidth }) => {
|
|||||||
<RequestBodyMode item={item} collection={collection} />
|
<RequestBodyMode item={item} collection={collection} />
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{focusedTab.requestPaneTab === 'auth' ? (
|
|
||||||
<div className="flex flex-grow justify-end items-center">
|
|
||||||
<AuthMode item={item} collection={collection} />
|
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
<section
|
||||||
</div>
|
className={`flex w-full ${['script', 'vars', 'auth'].includes(focusedTab.requestPaneTab) ? '' : 'mt-5'}`}
|
||||||
<section className={`flex w-full ${['script', 'vars'].includes(focusedTab.requestPaneTab) ? '' : 'mt-5'}`}>
|
>
|
||||||
{getTabPanel(focusedTab.requestPaneTab)}
|
{getTabPanel(focusedTab.requestPaneTab)}
|
||||||
</section>
|
</section>
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
|
@ -12,7 +12,6 @@ import {
|
|||||||
getItemsToResequence,
|
getItemsToResequence,
|
||||||
moveCollectionItemToRootOfCollection,
|
moveCollectionItemToRootOfCollection,
|
||||||
findCollectionByUid,
|
findCollectionByUid,
|
||||||
recursivelyGetAllItemUids,
|
|
||||||
transformRequestToSaveToFilesystem,
|
transformRequestToSaveToFilesystem,
|
||||||
findParentItemInCollection,
|
findParentItemInCollection,
|
||||||
findEnvironmentInCollection,
|
findEnvironmentInCollection,
|
||||||
|
@ -322,6 +322,26 @@ export const collectionsSlice = createSlice({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
updateBearerToken: (state, action) => {
|
||||||
|
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||||
|
|
||||||
|
if (collection) {
|
||||||
|
const item = findItemInCollection(collection, action.payload.itemUid);
|
||||||
|
|
||||||
|
if (item && isItemARequest(item)) {
|
||||||
|
if (!item.draft) {
|
||||||
|
item.draft = cloneDeep(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.draft.request.auth = item.draft.request.auth || {};
|
||||||
|
switch (item.draft.request.auth.mode) {
|
||||||
|
case 'bearer':
|
||||||
|
item.draft.request.auth.bearer = action.payload.content;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
addQueryParam: (state, action) => {
|
addQueryParam: (state, action) => {
|
||||||
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||||
|
|
||||||
@ -1188,6 +1208,7 @@ export const {
|
|||||||
collectionClicked,
|
collectionClicked,
|
||||||
collectionFolderClicked,
|
collectionFolderClicked,
|
||||||
requestUrlChanged,
|
requestUrlChanged,
|
||||||
|
updateBearerToken,
|
||||||
addQueryParam,
|
addQueryParam,
|
||||||
updateQueryParam,
|
updateQueryParam,
|
||||||
deleteQueryParam,
|
deleteQueryParam,
|
||||||
|
@ -355,6 +355,7 @@ export const transformRequestToSaveToFilesystem = (item) => {
|
|||||||
url: _item.request.url,
|
url: _item.request.url,
|
||||||
params: [],
|
params: [],
|
||||||
headers: [],
|
headers: [],
|
||||||
|
auth: _item.request.auth,
|
||||||
body: _item.request.body,
|
body: _item.request.body,
|
||||||
script: _item.request.script,
|
script: _item.request.script,
|
||||||
vars: _item.request.vars,
|
vars: _item.request.vars,
|
||||||
|
@ -18,6 +18,20 @@ const prepareRequest = (request) => {
|
|||||||
headers: headers
|
headers: headers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Authentication
|
||||||
|
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')}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (request.body.mode === 'json') {
|
if (request.body.mode === 'json') {
|
||||||
if (!contentTypeDefined) {
|
if (!contentTypeDefined) {
|
||||||
axiosRequest.headers['content-type'] = 'application/json';
|
axiosRequest.headers['content-type'] = 'application/json';
|
||||||
|
@ -34,6 +34,11 @@ const jsonToBru = (json) => {
|
|||||||
body: ${http.body}`;
|
body: ${http.body}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (http.auth && http.auth.length) {
|
||||||
|
bru += `
|
||||||
|
auth: ${http.auth}`;
|
||||||
|
}
|
||||||
|
|
||||||
bru += `
|
bru += `
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ meta {
|
|||||||
get {
|
get {
|
||||||
url: https://api.textlocal.in/send
|
url: https://api.textlocal.in/send
|
||||||
body: json
|
body: json
|
||||||
|
auth: bearer
|
||||||
}
|
}
|
||||||
|
|
||||||
query {
|
query {
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"http": {
|
"http": {
|
||||||
"method": "get",
|
"method": "get",
|
||||||
"url": "https://api.textlocal.in/send",
|
"url": "https://api.textlocal.in/send",
|
||||||
"body": "json"
|
"body": "json",
|
||||||
|
"auth": "bearer"
|
||||||
},
|
},
|
||||||
"query": [
|
"query": [
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@ describe('bruToJson', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('jsonToBru', () => {
|
describe('jsonToBru', () => {
|
||||||
it('should parse the bru file', () => {
|
it('should parse the json file', () => {
|
||||||
const input = require('./fixtures/request.json');
|
const input = require('./fixtures/request.json');
|
||||||
const expected = fs.readFileSync(path.join(__dirname, 'fixtures', 'request.bru'), 'utf8');
|
const expected = fs.readFileSync(path.join(__dirname, 'fixtures', 'request.bru'), 'utf8');
|
||||||
const output = jsonToBru(input);
|
const output = jsonToBru(input);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user