Skip to content

Commit

Permalink
feat(usebruno#1003): oauth2 support - resourceOwnerPasswordCredential…
Browse files Browse the repository at this point in the history
…s, authorization code, client credentials
  • Loading branch information
lohit-1 committed Feb 23, 2024
1 parent 117726a commit c690363
Show file tree
Hide file tree
Showing 43 changed files with 1,550 additions and 75 deletions.
207 changes: 143 additions & 64 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ const AuthMode = ({ item, collection }) => {
>
Digest Auth
</div>
<div
className="dropdown-item"
onClick={() => {
dropdownTippyRef.current.hide();
onModeChange('oauth2');
}}
>
OAuth 2.0
</div>
<div
className="dropdown-item"
onClick={() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
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 { saveRequest, sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import StyledWrapper from './StyledWrapper';
import { inputsConfig } from './inputsConfig';

const OAuth2AuthorizationCode = ({ 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 = async () => {
dispatch(sendRequest(item, collection.uid));
};

const handleSave = () => dispatch(saveRequest(item.uid, collection.uid));

const handleChange = (key, value) => {
dispatch(
updateAuth({
mode: 'oauth2',
collectionUid: collection.uid,
itemUid: item.uid,
content: {
grantType: 'authorization_code',
...oAuth,
[key]: value
}
})
);
};

return (
<StyledWrapper className="mt-2 flex w-full gap-4 flex-col">
{inputsConfig.map((input) => {
const { key, label } = input;
return (
<div className="flex flex-col w-full gap-1">
<label className="block font-medium">{label}</label>
<div className="single-line-editor-wrapper">
<SingleLineEditor
value={oAuth[key] || ''}
theme={storedTheme}
onSave={handleSave}
onChange={(val) => handleChange(key, val)}
onRun={() => {}}
collection={collection}
/>
</div>
</div>
);
})}
<button onClick={handleRun} className="submit btn btn-sm btn-secondary w-fit">
Get Authorization Code
</button>
</StyledWrapper>
);
};

export default OAuth2AuthorizationCode;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const inputsConfig = [
{
key: 'callbackUrl',
label: 'Callback URL'
},
{
key: 'authUrl',
label: 'Auth URL'
},
{
key: 'accessTokenUrl',
label: 'Access Token URL'
},
{
key: 'clientId',
label: 'Client ID'
},
{
key: 'clientSecret',
label: 'Client Secret'
},
{
key: 'scope',
label: 'Scope'
}
];

export { inputsConfig };
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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;
Original file line number Diff line number Diff line change
@@ -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 OAuth2ClientCredentials = ({ 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 handleClientIdChange = (clientId) => {
dispatch(
updateAuth({
mode: 'oauth2',
collectionUid: collection.uid,
itemUid: item.uid,
content: {
grantType: 'client_credentials',
clientId: clientId,
clientSecret: oAuth.clientSecret
}
})
);
};

const handleClientSecretChange = (clientSecret) => {
dispatch(
updateAuth({
mode: 'oauth2',
collectionUid: collection.uid,
itemUid: item.uid,
content: {
grantType: 'client_credentials',
clientId: oAuth.clientId,
clientSecret: clientSecret
}
})
);
};

return (
<StyledWrapper className="mt-2 w-full">
<label className="block font-medium mb-2">Client Id</label>
<div className="single-line-editor-wrapper mb-2">
<SingleLineEditor
value={oAuth.clientId || ''}
theme={storedTheme}
onSave={handleSave}
onChange={(val) => handleClientIdChange(val)}
onRun={handleRun}
collection={collection}
/>
</div>

<label className="block font-medium mb-2">Client Secret</label>
<div className="single-line-editor-wrapper">
<SingleLineEditor
value={oAuth.clientSecret || ''}
theme={storedTheme}
onSave={handleSave}
onChange={(val) => handleClientSecretChange(val)}
onRun={handleRun}
collection={collection}
/>
</div>
</StyledWrapper>
);
};

export default OAuth2ClientCredentials;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import styled from 'styled-components';

const Wrapper = styled.div`
font-size: 0.8125rem;
.grant-type-mode-selector {
padding: 0.5rem 0px;
border-radius: 3px;
border: solid 1px ${(props) => props.theme.input.border};
background-color: ${(props) => props.theme.input.bg};
.dropdown {
width: 100%;
div[data-tippy-root] {
width: 100%;
}
.tippy-box {
width: 100%;
max-width: none !important;
.tippy-content: {
width: 100%;
max-width: none !important;
}
}
}
.grant-type-label {
width: 100%;
color: ${(props) => props.theme.colors.text.yellow};
justify-content: space-between;
padding: 0 0.5rem;
}
.dropdown-item {
padding: 0.2rem 0.6rem !important;
}
.label-item {
padding: 0.2rem 0.6rem !important;
}
}
.caret {
color: rgb(140, 140, 140);
fill: rgb(140 140 140);
}
label {
font-size: 0.8125rem;
}
`;

export default Wrapper;
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { useRef, forwardRef } from 'react';
import get from 'lodash/get';
import Dropdown from 'components/Dropdown';
import { useDispatch } from 'react-redux';
import StyledWrapper from './StyledWrapper';
import { IconCaretDown } from '@tabler/icons';
import { updateAuth } from 'providers/ReduxStore/slices/collections';
import { humanizeGrantType } from 'utils/collections';

const GrantTypeSelector = ({ item, collection }) => {
const dispatch = useDispatch();
const dropdownTippyRef = useRef();
const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref);

const oAuth = item.draft ? get(item, 'draft.request.auth.oauth2', {}) : get(item, 'request.auth.oauth2', {});

const Icon = forwardRef((props, ref) => {
return (
<div ref={ref} className="flex items-center justify-end grant-type-label select-none">
{humanizeGrantType(oAuth?.grantType)} <IconCaretDown className="caret ml-1 mr-1" size={14} strokeWidth={2} />
</div>
);
});

const onGrantTypeChange = (grantType) => {
dispatch(
updateAuth({
mode: 'oauth2',
collectionUid: collection.uid,
itemUid: item.uid,
content: {
grantType
}
})
);
};

return (
<StyledWrapper>
<label className="block font-medium mb-2">Grant Type</label>
<div className="inline-flex items-center cursor-pointer grant-type-mode-selector w-full">
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement="bottom-end">
<div
className="dropdown-item"
onClick={() => {
dropdownTippyRef.current.hide();
onGrantTypeChange('resourceOwnerPasswordCredentials');
}}
>
Resource Owner Password Credentials
</div>
<div
className="dropdown-item"
onClick={() => {
dropdownTippyRef.current.hide();
onGrantTypeChange('authorization_code');
}}
>
Authorization Code
</div>
<div
className="dropdown-item"
onClick={() => {
dropdownTippyRef.current.hide();
onGrantTypeChange('client_credentials');
}}
>
Client Credentials
</div>
</Dropdown>
</div>
</StyledWrapper>
);
};
export default GrantTypeSelector;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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;
Loading

0 comments on commit c690363

Please sign in to comment.