Redirect URL for oAuth Auth code flow (#3232)

This commit is contained in:
Piyush 2021-02-26 12:28:47 +05:30 committed by GitHub
parent c38e58b3bc
commit 21a2a2bdf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 140 additions and 19 deletions

View File

@ -0,0 +1,60 @@
import React, { createRef, useState } from "react";
import styled from "styled-components";
import copy from "copy-to-clipboard";
import TextInput from "components/ads/TextInput";
import Button, { Category, Size } from "components/ads/Button";
const Wrapper = styled.div`
display: flex;
div {
flex-basis: calc(100% - 110px);
}
a {
flex-basis: 110px;
}
`;
const CopyToClipboard = (props: any) => {
const { copyText } = props;
const copyURLInput = createRef<HTMLInputElement>();
const [isCopied, setIsCopied] = useState(false);
const copyToClipboard = (url: string) => {
copy(url);
setIsCopied(true);
setTimeout(() => {
setIsCopied(false);
}, 3000);
};
const selectText = () => {
if (copyURLInput.current) {
copyURLInput.current.setSelectionRange(0, copyText.length);
}
};
return (
<Wrapper>
<TextInput
fill
ref={copyURLInput}
readOnly
onChange={() => {
selectText();
}}
defaultValue={copyText}
/>
<Button
text={isCopied ? "Copied" : "Copy"}
category={Category.tertiary}
onClick={() => {
copyToClipboard(copyText);
}}
size={Size.large}
/>
</Wrapper>
);
};
export default CopyToClipboard;

View File

@ -1,17 +1,21 @@
import React, { createRef, useState } from "react";
import styled from "styled-components";
import copy from "copy-to-clipboard";
import TextInput from "components/ads/TextInput";
import Button, { Category, Size } from "components/ads/Button";
import { BaseTextInput } from "components/designSystems/appsmith/TextInputComponent";
import { BaseButton } from "components/designSystems/blueprint/ButtonComponent";
const Wrapper = styled.div`
display: flex;
div {
flex-basis: calc(100% - 110px);
flex-basis: calc(100% - 90px);
}
a {
flex-basis: 110px;
input:disabled {
color: #555;
}
button {
flex-basis: 80px;
margin-left: 10px;
}
`;
@ -35,23 +39,20 @@ const CopyToClipboard = (props: any) => {
};
return (
<Wrapper>
<TextInput
<BaseTextInput
fill
ref={copyURLInput}
readOnly
disabled={true}
onChange={() => {
selectText();
}}
defaultValue={copyText}
/>
<Button
<BaseButton
text={isCopied ? "Copied" : "Copy"}
category={Category.tertiary}
onClick={() => {
copyToClipboard(copyText);
}}
size={Size.large}
/>
</Wrapper>
);

View File

@ -8,12 +8,21 @@ import { DropdownOption } from "widgets/DropdownWidget";
import { ControlType } from "constants/PropertyControlConstants";
import { theme } from "constants/DefaultTheme";
import FormLabel from "components/editorComponents/FormLabel";
import { Colors } from "constants/Colors";
const DropdownSelect = styled.div`
font-size: 14px;
width: 50vh;
`;
const StyledInfo = styled.span`
font-weight: normal;
line-height: normal;
color: ${Colors.DOVE_GRAY};
font-size: 12px;
margin-left: 1px;
`;
const customSelectStyles = {
option: (
styles: { [x: string]: any },
@ -40,12 +49,18 @@ const customSelectStyles = {
class DropDownControl extends BaseControl<DropDownControlProps> {
render() {
const { configProperty, options, label, isRequired } = this.props;
const { configProperty, options, label, isRequired, subtitle } = this.props;
return (
<div>
<FormLabel>
{label} {isRequired && "*"}
{subtitle && (
<>
<br />
<StyledInfo>{subtitle}</StyledInfo>
</>
)}
</FormLabel>
<DropdownSelect data-cy={configProperty}>
<DropdownField
@ -89,6 +104,7 @@ export interface DropDownControlProps extends ControlProps {
options: DropdownOption[];
placeholderText: string;
propertyValue: string;
subtitle?: string;
}
export default DropDownControl;

View File

@ -8,10 +8,10 @@ import { FormIcons } from "icons/FormIcons";
import { Colors } from "constants/Colors";
import styled from "styled-components";
const StyledInfo = styled.span`
export const StyledInfo = styled.span`
font-weight: normal;
line-height: normal;
color: ${Colors.CADET_BLUE};
color: ${Colors.DOVE_GRAY};
font-size: 12px;
margin-left: 1px;
`;
@ -20,30 +20,48 @@ export function InputText(props: {
label: string;
value: string;
isValid: boolean;
subtitle?: string;
validationMessage?: string;
placeholder?: string;
dataType?: string;
isRequired?: boolean;
name: string;
encrypted?: boolean;
disabled?: boolean;
}) {
const { name, placeholder, dataType, label, isRequired } = props;
const {
name,
placeholder,
dataType,
label,
isRequired,
disabled,
subtitle,
encrypted,
} = props;
return (
<div style={{ width: "50vh" }} data-cy={name}>
<FormLabel>
{label} {isRequired && "*"}{" "}
{props.encrypted && (
{encrypted && (
<>
<FormIcons.LOCK_ICON width={12} height={12} keepColors />
<StyledInfo>Encrypted</StyledInfo>
</>
)}
{subtitle && (
<>
<br />
<StyledInfo>{subtitle}</StyledInfo>
</>
)}
</FormLabel>
<TextField
name={name}
placeholder={placeholder}
type={dataType}
disabled={disabled || false}
showError
/>
</div>
@ -60,6 +78,8 @@ class InputTextControl extends BaseControl<InputControlProps> {
placeholderText,
dataType,
configProperty,
disabled,
subtitle,
} = this.props;
return (
@ -72,6 +92,8 @@ class InputTextControl extends BaseControl<InputControlProps> {
placeholder={placeholderText}
dataType={this.getType(dataType)}
encrypted={this.props.encrypted}
disabled={disabled}
subtitle={subtitle}
/>
);
}
@ -109,7 +131,9 @@ export interface InputControlProps extends ControlProps {
placeholderText: string;
inputType?: InputType;
dataType?: InputType;
subtitle?: string;
encrypted?: boolean;
disabled?: boolean;
}
export default InputTextControl;

View File

@ -16,7 +16,9 @@ import {
import { BaseButton } from "components/designSystems/blueprint/ButtonComponent";
import AnalyticsUtil from "utils/AnalyticsUtil";
import BackButton from "./BackButton";
import InputTextControl from "components/formControls/InputTextControl";
import InputTextControl, {
StyledInfo,
} from "components/formControls/InputTextControl";
import KeyValueInputControl from "components/formControls/KeyValueInputControl";
import DropDownControl from "components/formControls/DropDownControl";
import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper";
@ -50,6 +52,8 @@ import {
} from "constants/messages";
import Collapsible from "./Collapsible";
import _ from "lodash";
import FormLabel from "components/editorComponents/FormLabel";
import CopyToClipBoard from "components/designSystems/appsmith/CopyToClipBoard";
interface DatasourceRestApiEditorProps {
updateDatasource: (
@ -194,6 +198,7 @@ class DatasourceRestAPIEditor extends React.Component<Props> {
}
ensureOAuthDefaultsAreCorrect = () => {
if (!this.props.formData) return;
const { authentication } = this.props.formData;
if (!authentication || !authentication.grantType) {
@ -384,7 +389,8 @@ class DatasourceRestAPIEditor extends React.Component<Props> {
<FormInputContainer>
<DropDownControl
{...COMMON_INPUT_PROPS}
label="Send Appsmith signature header (X-APPSMITH-SIGNATURE)"
label="Send Appsmith signature header"
subtitle="Header key: X-APPSMITH-SIGNATURE"
configProperty="isSendSessionEnabled"
isRequired={true}
placeholderText=""
@ -570,6 +576,8 @@ class DatasourceRestAPIEditor extends React.Component<Props> {
"datasourceConfiguration.authentication.isAuthorized",
false,
);
const redirectURL =
window.location.origin + "/api/v1/datasources/authorize";
return (
<>
{this.renderOauth2Common()}
@ -581,6 +589,18 @@ class DatasourceRestAPIEditor extends React.Component<Props> {
placeholderText="https://example.com/login/oauth/authorize"
/>
</FormInputContainer>
<FormInputContainer>
<div style={{ width: "50vh" }}>
<FormLabel>
Redirect URL
<br />
<StyledInfo>
Url that the oauth server should redirect to
</StyledInfo>
</FormLabel>
<CopyToClipBoard copyText={redirectURL} />
</div>
</FormInputContainer>
<FormInputContainer>
<KeyValueInputControl
{...COMMON_INPUT_PROPS}

View File

@ -4,7 +4,7 @@ import { connect, useSelector } from "react-redux";
import { AppState } from "reducers";
import { getCurrentAppOrg } from "selectors/organizationSelectors";
import { ReduxActionTypes } from "constants/ReduxActionConstants";
import CopyToClipBoard from "components/designSystems/appsmith/CopyToClipBoard";
import CopyToClipBoard from "components/ads/CopyToClipBoard";
import {
isPermitted,
PERMISSION_TYPE,