Merge pull request #587 from ONLYOFFICE/feature/oauth2-rotation
Feature/oauth2 rotation
This commit is contained in:
commit
a06cb5159f
@ -112,7 +112,7 @@ const Layout = ({
|
||||
<DetailsNavigationHeader />
|
||||
) : currentPath === oauthCreatePath ||
|
||||
currentPath === oauthEditPath ? (
|
||||
<OAuthSectionHeader />
|
||||
<OAuthSectionHeader isEdit={currentPath === oauthEditPath} />
|
||||
) : (
|
||||
<SectionHeaderContent />
|
||||
)}
|
||||
|
@ -18,6 +18,9 @@ export interface OAuthProps {
|
||||
previewDialogVisible?: boolean;
|
||||
disableDialogVisible?: boolean;
|
||||
deleteDialogVisible?: boolean;
|
||||
generateDeveloperTokenDialogVisible?: boolean;
|
||||
revokeDeveloperTokenDialogVisible?: boolean;
|
||||
|
||||
isInit: boolean;
|
||||
setIsInit: (value: boolean) => void;
|
||||
}
|
||||
|
@ -28,17 +28,15 @@ const OAuthSectionHeader = ({ isEdit }: { isEdit: boolean }) => {
|
||||
<HeaderContainer>
|
||||
<Headline type="content" truncate>
|
||||
<div className="settings-section_header">
|
||||
<div className="header">
|
||||
<IconButton
|
||||
iconName={ArrowPathReactSvgUrl}
|
||||
size={17}
|
||||
isFill
|
||||
onClick={onBack}
|
||||
className="arrow-button"
|
||||
/>
|
||||
<IconButton
|
||||
iconName={ArrowPathReactSvgUrl}
|
||||
size={17}
|
||||
isFill
|
||||
onClick={onBack}
|
||||
className="arrow-button"
|
||||
/>
|
||||
|
||||
{isEdit ? t("EditApp") : t("NewApp")}
|
||||
</div>
|
||||
{isEdit ? t("EditApp") : t("NewApp")}
|
||||
</div>
|
||||
</Headline>
|
||||
</HeaderContainer>
|
||||
|
@ -18,6 +18,8 @@ import DisableDialog from "./sub-components/DisableDialog";
|
||||
import DeleteDialog from "./sub-components/DeleteDialog";
|
||||
import OAuthEmptyScreen from "./sub-components/EmptyScreen";
|
||||
import List from "./sub-components/List";
|
||||
import GenerateDeveloperTokenDialog from "./sub-components/GenerateDeveloperTokenDialog";
|
||||
import RevokeDeveloperTokenDialog from "./sub-components/RevokeDeveloperTokenDialog";
|
||||
|
||||
const MIN_LOADER_TIME = 500;
|
||||
|
||||
@ -35,6 +37,8 @@ const OAuth = ({
|
||||
setIsInit,
|
||||
disableDialogVisible,
|
||||
deleteDialogVisible,
|
||||
generateDeveloperTokenDialogVisible,
|
||||
revokeDeveloperTokenDialogVisible,
|
||||
}: OAuthProps) => {
|
||||
const { t } = useTranslation(["OAuth"]);
|
||||
|
||||
@ -102,6 +106,8 @@ const OAuth = ({
|
||||
{disableDialogVisible && <DisableDialog />}
|
||||
{previewDialogVisible && <PreviewDialog visible={previewDialogVisible} />}
|
||||
{deleteDialogVisible && <DeleteDialog />}
|
||||
{generateDeveloperTokenDialogVisible && <GenerateDeveloperTokenDialog />}
|
||||
{revokeDeveloperTokenDialogVisible && <RevokeDeveloperTokenDialog />}
|
||||
</OAuthContainer>
|
||||
);
|
||||
};
|
||||
@ -128,6 +134,8 @@ export default inject(
|
||||
setIsInit,
|
||||
disableDialogVisible,
|
||||
deleteDialogVisible,
|
||||
generateDeveloperTokenDialogVisible,
|
||||
revokeDeveloperTokenDialogVisible,
|
||||
} = oauthStore;
|
||||
return {
|
||||
viewAs,
|
||||
@ -143,6 +151,8 @@ export default inject(
|
||||
setIsInit,
|
||||
disableDialogVisible,
|
||||
deleteDialogVisible,
|
||||
generateDeveloperTokenDialogVisible,
|
||||
revokeDeveloperTokenDialogVisible,
|
||||
};
|
||||
},
|
||||
)(observer(OAuth));
|
||||
|
@ -2,6 +2,7 @@ import React from "react";
|
||||
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { SelectorAddButton } from "@docspace/shared/components/selector-add-button";
|
||||
import { globalColors } from "@docspace/shared/themes";
|
||||
|
||||
import { StyledInputGroup } from "../ClientForm.styled";
|
||||
|
||||
@ -55,7 +56,8 @@ const SelectGroup = ({
|
||||
color=""
|
||||
textAlign=""
|
||||
>
|
||||
{label} *
|
||||
{label}{" "}
|
||||
<span style={{ color: globalColors.lightErrorStatus }}> *</span>
|
||||
</Text>
|
||||
</div>
|
||||
<div className="select">
|
||||
|
@ -0,0 +1,211 @@
|
||||
import React from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import styled, { useTheme } from "styled-components";
|
||||
import { i18n } from "i18next";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import copy from "copy-to-clipboard";
|
||||
import moment from "moment-timezone";
|
||||
|
||||
import api from "@docspace/shared/api";
|
||||
import { IClientProps } from "@docspace/shared/utils/oauth/types";
|
||||
import {
|
||||
ModalDialog,
|
||||
ModalDialogType,
|
||||
} from "@docspace/shared/components/modal-dialog";
|
||||
import { Button, ButtonSize } from "@docspace/shared/components/button";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { TData } from "@docspace/shared/components/toast/Toast.type";
|
||||
import { InputBlock } from "@docspace/shared/components/input-block";
|
||||
import { InputSize, InputType } from "@docspace/shared/components/text-input";
|
||||
|
||||
import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url";
|
||||
|
||||
import { OAuthStoreProps } from "SRC_DIR/store/OAuthStore";
|
||||
import { UserStore } from "@docspace/shared/store/UserStore";
|
||||
import { globalColors } from "@docspace/shared/themes";
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.dates {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
type GenerateDeveloperTokenDialogProps = {
|
||||
client?: IClientProps;
|
||||
|
||||
email?: string;
|
||||
|
||||
setGenerateDeveloperTokenDialogVisible?: (value: boolean) => void;
|
||||
};
|
||||
|
||||
const getDate = (date: Date, i18nArg: i18n) => {
|
||||
return moment(date)
|
||||
.locale(i18nArg.language)
|
||||
.tz(window.timezone)
|
||||
.format("MMM D, YYYY, h:mm:ss A");
|
||||
};
|
||||
|
||||
const GenerateDeveloperTokenDialog = ({
|
||||
client,
|
||||
email,
|
||||
|
||||
setGenerateDeveloperTokenDialogVisible,
|
||||
}: GenerateDeveloperTokenDialogProps) => {
|
||||
const { i18n: i18nParam } = useTranslation(["OAuth", "Common"]);
|
||||
|
||||
const theme = useTheme();
|
||||
const [token, setToken] = React.useState("");
|
||||
const [dates, setDates] = React.useState({
|
||||
created: getDate(new Date(), i18nParam),
|
||||
expires: getDate(new Date(), i18nParam),
|
||||
});
|
||||
const [requestRunning, setRequestRunning] = React.useState(false);
|
||||
|
||||
const onGenerate = async () => {
|
||||
if (token || !client || requestRunning) return;
|
||||
|
||||
try {
|
||||
const { clientId, clientSecret, scopes } = client;
|
||||
|
||||
setRequestRunning(true);
|
||||
|
||||
const data = await api.oauth.generateDevelopToken(
|
||||
clientId,
|
||||
clientSecret,
|
||||
scopes,
|
||||
);
|
||||
|
||||
setRequestRunning(false);
|
||||
|
||||
if (!data) return;
|
||||
|
||||
const { access_token: accessToken, expires_in: expiresIn } = data;
|
||||
|
||||
const created = new Date();
|
||||
// convert sec to ms
|
||||
const expires = new Date(created.getTime() + expiresIn * 1000);
|
||||
|
||||
if (accessToken) {
|
||||
setToken(accessToken);
|
||||
copy(accessToken);
|
||||
setDates({
|
||||
created: getDate(created, i18nParam),
|
||||
expires: getDate(expires, i18nParam),
|
||||
});
|
||||
toastr.success("Copied");
|
||||
}
|
||||
} catch (e) {
|
||||
toastr.error(e as TData);
|
||||
}
|
||||
};
|
||||
|
||||
const onCopyClick = async () => {
|
||||
copy(token);
|
||||
toastr.success("Copied");
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
if (requestRunning) return;
|
||||
|
||||
setGenerateDeveloperTokenDialogVisible?.(false);
|
||||
};
|
||||
return (
|
||||
<ModalDialog
|
||||
visible
|
||||
onClose={onClose}
|
||||
displayType={ModalDialogType.modal}
|
||||
autoMaxHeight
|
||||
scale
|
||||
>
|
||||
<ModalDialog.Header>Generate developer token</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<StyledContainer>
|
||||
<Text>
|
||||
By generating an developer access token, you will be able to make
|
||||
API calls for your own account without going through the
|
||||
authorization flow. To obtain access tokens for other users, use the
|
||||
standard OAuth flow.
|
||||
</Text>
|
||||
<Text>
|
||||
For scoped apps, the token will have the same scope as the app.
|
||||
</Text>
|
||||
{token ? (
|
||||
<>
|
||||
<Text
|
||||
color={
|
||||
theme.isBase
|
||||
? globalColors.lightErrorStatus
|
||||
: globalColors.darkErrorStatus
|
||||
}
|
||||
>
|
||||
This access token can be used to access your account ({email})
|
||||
via the API. Don`t share your access token with anyone.
|
||||
</Text>
|
||||
<InputBlock
|
||||
value={token}
|
||||
scale
|
||||
isReadOnly
|
||||
isDisabled
|
||||
size={InputSize.base}
|
||||
iconName={CopyReactSvgUrl}
|
||||
onIconClick={onCopyClick}
|
||||
type={InputType.text}
|
||||
/>
|
||||
<Text className="dates">
|
||||
Created: {dates.created}
|
||||
<br />
|
||||
Expires: {dates.expires}{" "}
|
||||
</Text>
|
||||
</>
|
||||
) : null}
|
||||
</StyledContainer>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
label="Generate developer token"
|
||||
primary
|
||||
scale
|
||||
onClick={onGenerate}
|
||||
isDisabled={!!token}
|
||||
isLoading={requestRunning}
|
||||
size={ButtonSize.small}
|
||||
/>
|
||||
<Button
|
||||
label="Cancel"
|
||||
scale
|
||||
onClick={onClose}
|
||||
size={ButtonSize.small}
|
||||
isDisabled={requestRunning}
|
||||
/>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(
|
||||
({
|
||||
oauthStore,
|
||||
userStore,
|
||||
}: {
|
||||
oauthStore: OAuthStoreProps;
|
||||
userStore: UserStore;
|
||||
}) => {
|
||||
const { setGenerateDeveloperTokenDialogVisible, bufferSelection } =
|
||||
oauthStore;
|
||||
|
||||
const { user } = userStore;
|
||||
|
||||
return {
|
||||
setGenerateDeveloperTokenDialogVisible,
|
||||
client: bufferSelection,
|
||||
|
||||
email: user?.email,
|
||||
};
|
||||
},
|
||||
)(observer(GenerateDeveloperTokenDialog));
|
@ -0,0 +1,141 @@
|
||||
import React from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import api from "@docspace/shared/api";
|
||||
import { IClientProps } from "@docspace/shared/utils/oauth/types";
|
||||
import {
|
||||
ModalDialog,
|
||||
ModalDialogType,
|
||||
} from "@docspace/shared/components/modal-dialog";
|
||||
import { Button, ButtonSize } from "@docspace/shared/components/button";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { TData } from "@docspace/shared/components/toast/Toast.type";
|
||||
import { InputBlock } from "@docspace/shared/components/input-block";
|
||||
import { InputSize, InputType } from "@docspace/shared/components/text-input";
|
||||
|
||||
import { OAuthStoreProps } from "SRC_DIR/store/OAuthStore";
|
||||
import { UserStore } from "@docspace/shared/store/UserStore";
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
type GenerateDeveloperTokenDialogProps = {
|
||||
client?: IClientProps;
|
||||
|
||||
setRevokeDeveloperTokenDialogVisible?: (value: boolean) => void;
|
||||
};
|
||||
|
||||
const GenerateDeveloperTokenDialog = ({
|
||||
client,
|
||||
|
||||
setRevokeDeveloperTokenDialogVisible,
|
||||
}: GenerateDeveloperTokenDialogProps) => {
|
||||
// const {} = useTranslation(["OAuth", "Common"]);
|
||||
|
||||
const [token, setToken] = React.useState("");
|
||||
|
||||
const [requestRunning, setRequestRunning] = React.useState(false);
|
||||
|
||||
const onRevoke = async () => {
|
||||
if (!token || !client || requestRunning) return;
|
||||
|
||||
try {
|
||||
const { clientId, clientSecret } = client;
|
||||
|
||||
setRequestRunning(true);
|
||||
|
||||
await api.oauth.revokeDeveloperToken(token, clientId, clientSecret);
|
||||
|
||||
setRequestRunning(false);
|
||||
|
||||
setToken("");
|
||||
setRevokeDeveloperTokenDialogVisible?.(false);
|
||||
|
||||
toastr.success("Revoked");
|
||||
} catch (e) {
|
||||
toastr.error(e as TData);
|
||||
}
|
||||
};
|
||||
|
||||
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
|
||||
setToken(value);
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
if (requestRunning) return;
|
||||
|
||||
setRevokeDeveloperTokenDialogVisible?.(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalDialog
|
||||
visible
|
||||
onClose={onClose}
|
||||
displayType={ModalDialogType.modal}
|
||||
autoMaxHeight
|
||||
scale
|
||||
>
|
||||
<ModalDialog.Header>Revoke developer token</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<StyledContainer>
|
||||
<Text>Warning text</Text>
|
||||
<InputBlock
|
||||
value={token}
|
||||
scale
|
||||
placeholder="Enter developer token"
|
||||
type={InputType.text}
|
||||
size={InputSize.base}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</StyledContainer>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
label="Revoke"
|
||||
primary
|
||||
scale
|
||||
onClick={onRevoke}
|
||||
isDisabled={!token}
|
||||
isLoading={requestRunning}
|
||||
size={ButtonSize.small}
|
||||
/>
|
||||
<Button
|
||||
label="Cancel"
|
||||
scale
|
||||
onClick={onClose}
|
||||
size={ButtonSize.small}
|
||||
isDisabled={requestRunning}
|
||||
/>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(
|
||||
({
|
||||
oauthStore,
|
||||
userStore,
|
||||
}: {
|
||||
oauthStore: OAuthStoreProps;
|
||||
userStore: UserStore;
|
||||
}) => {
|
||||
const { setRevokeDeveloperTokenDialogVisible, bufferSelection } =
|
||||
oauthStore;
|
||||
|
||||
const { user } = userStore;
|
||||
|
||||
return {
|
||||
setRevokeDeveloperTokenDialogVisible,
|
||||
client: bufferSelection,
|
||||
|
||||
email: user?.email,
|
||||
};
|
||||
},
|
||||
)(observer(GenerateDeveloperTokenDialog));
|
@ -58,6 +58,12 @@ export interface OAuthStoreProps {
|
||||
resetDialogVisible: boolean;
|
||||
setResetDialogVisible: (value: boolean) => void;
|
||||
|
||||
generateDeveloperTokenDialogVisible: boolean;
|
||||
setGenerateDeveloperTokenDialogVisible: (value: boolean) => void;
|
||||
|
||||
revokeDeveloperTokenDialogVisible: boolean;
|
||||
setRevokeDeveloperTokenDialogVisible: (value: boolean) => void;
|
||||
|
||||
deleteDialogVisible: boolean;
|
||||
setDeleteDialogVisible: (value: boolean) => void;
|
||||
|
||||
@ -157,6 +163,10 @@ class OAuthStore implements OAuthStoreProps {
|
||||
|
||||
resetDialogVisible: boolean = false;
|
||||
|
||||
generateDeveloperTokenDialogVisible: boolean = false;
|
||||
|
||||
revokeDeveloperTokenDialogVisible: boolean = false;
|
||||
|
||||
selection: string[] = [];
|
||||
|
||||
bufferSelection: IClientProps | null = null;
|
||||
@ -216,6 +226,14 @@ class OAuthStore implements OAuthStoreProps {
|
||||
this.resetDialogVisible = value;
|
||||
};
|
||||
|
||||
setGenerateDeveloperTokenDialogVisible = (value: boolean) => {
|
||||
this.generateDeveloperTokenDialogVisible = value;
|
||||
};
|
||||
|
||||
setRevokeDeveloperTokenDialogVisible = (value: boolean) => {
|
||||
this.revokeDeveloperTokenDialogVisible = value;
|
||||
};
|
||||
|
||||
setClientSecret = (value: string) => {
|
||||
this.clientSecret = value;
|
||||
};
|
||||
@ -526,6 +544,8 @@ class OAuthStore implements OAuthStoreProps {
|
||||
this.setInfoDialogVisible(true);
|
||||
this.setDisableDialogVisible(false);
|
||||
this.setDeleteDialogVisible(false);
|
||||
this.setGenerateDeveloperTokenDialogVisible(false);
|
||||
this.setRevokeDeveloperTokenDialogVisible(false);
|
||||
};
|
||||
|
||||
const onRevoke = () => {
|
||||
@ -535,6 +555,8 @@ class OAuthStore implements OAuthStoreProps {
|
||||
this.setRevokeDialogVisible(true);
|
||||
this.setDisableDialogVisible(false);
|
||||
this.setDeleteDialogVisible(false);
|
||||
this.setGenerateDeveloperTokenDialogVisible(false);
|
||||
this.setRevokeDeveloperTokenDialogVisible(false);
|
||||
};
|
||||
|
||||
const onDisable = () => {
|
||||
@ -544,6 +566,30 @@ class OAuthStore implements OAuthStoreProps {
|
||||
this.setRevokeDialogVisible(false);
|
||||
this.setDisableDialogVisible(true);
|
||||
this.setDeleteDialogVisible(false);
|
||||
this.setGenerateDeveloperTokenDialogVisible(false);
|
||||
this.setRevokeDeveloperTokenDialogVisible(false);
|
||||
};
|
||||
|
||||
const onGenerateDeveloperToken = () => {
|
||||
this.setBufferSelection(clientId);
|
||||
this.setPreviewDialogVisible(false);
|
||||
this.setInfoDialogVisible(false);
|
||||
this.setRevokeDialogVisible(false);
|
||||
this.setDisableDialogVisible(false);
|
||||
this.setDeleteDialogVisible(false);
|
||||
this.setGenerateDeveloperTokenDialogVisible(true);
|
||||
this.setRevokeDeveloperTokenDialogVisible(false);
|
||||
};
|
||||
|
||||
const onRevokeDeveloperToken = () => {
|
||||
this.setBufferSelection(clientId);
|
||||
this.setPreviewDialogVisible(false);
|
||||
this.setInfoDialogVisible(false);
|
||||
this.setRevokeDialogVisible(false);
|
||||
this.setDisableDialogVisible(false);
|
||||
this.setDeleteDialogVisible(false);
|
||||
this.setGenerateDeveloperTokenDialogVisible(false);
|
||||
this.setRevokeDeveloperTokenDialogVisible(true);
|
||||
};
|
||||
|
||||
const openOption = {
|
||||
@ -598,6 +644,8 @@ class OAuthStore implements OAuthStoreProps {
|
||||
this.setRevokeDialogVisible(false);
|
||||
this.setDisableDialogVisible(false);
|
||||
this.setDeleteDialogVisible(true);
|
||||
this.setGenerateDeveloperTokenDialogVisible(false);
|
||||
this.setRevokeDeveloperTokenDialogVisible(false);
|
||||
};
|
||||
|
||||
const onShowPreview = () => {
|
||||
@ -607,6 +655,8 @@ class OAuthStore implements OAuthStoreProps {
|
||||
this.setRevokeDialogVisible(false);
|
||||
this.setDisableDialogVisible(false);
|
||||
this.setDeleteDialogVisible(false);
|
||||
this.setGenerateDeveloperTokenDialogVisible(false);
|
||||
this.setRevokeDeveloperTokenDialogVisible(false);
|
||||
};
|
||||
|
||||
const onEnable = async (status: boolean) => {
|
||||
@ -615,6 +665,8 @@ class OAuthStore implements OAuthStoreProps {
|
||||
this.setRevokeDialogVisible(false);
|
||||
this.setDisableDialogVisible(false);
|
||||
this.setDeleteDialogVisible(false);
|
||||
this.setGenerateDeveloperTokenDialogVisible(false);
|
||||
this.setRevokeDeveloperTokenDialogVisible(false);
|
||||
|
||||
if (isGroupContext) {
|
||||
try {
|
||||
@ -673,6 +725,20 @@ class OAuthStore implements OAuthStoreProps {
|
||||
onClick: onDisable,
|
||||
};
|
||||
|
||||
const generateDeveloperTokenOption = {
|
||||
key: "generate-token",
|
||||
icon: EnableReactSvgUrl,
|
||||
label: "Generate developer token",
|
||||
onClick: onGenerateDeveloperToken,
|
||||
};
|
||||
|
||||
const revokeDeveloperTokenOption = {
|
||||
key: "revoke-token",
|
||||
icon: EnableReactSvgUrl,
|
||||
label: "Revoke developer token",
|
||||
onClick: onRevokeDeveloperToken,
|
||||
};
|
||||
|
||||
const contextOptions = [
|
||||
{
|
||||
key: "Separator dropdownItem",
|
||||
@ -708,6 +774,9 @@ class OAuthStore implements OAuthStoreProps {
|
||||
contextOptions.unshift(enableOption);
|
||||
}
|
||||
|
||||
contextOptions.unshift(revokeDeveloperTokenOption);
|
||||
contextOptions.unshift(generateDeveloperTokenOption);
|
||||
|
||||
if (!isInfo) contextOptions.unshift(infoOption);
|
||||
contextOptions.unshift(authButtonOption);
|
||||
contextOptions.unshift(editOption);
|
||||
|
@ -33,12 +33,12 @@ export const initSSR = (headers: Record<string, string>) => {
|
||||
client.initSSR(headers);
|
||||
};
|
||||
|
||||
export const request = (
|
||||
export const request = <T>(
|
||||
options: TReqOption & AxiosRequestConfig,
|
||||
skipRedirect = false,
|
||||
isOAuth = false,
|
||||
) => {
|
||||
return client.request(options, skipRedirect, isOAuth);
|
||||
): Promise<T> | undefined => {
|
||||
return client.request<T>(options, skipRedirect, isOAuth);
|
||||
};
|
||||
|
||||
export const setWithCredentialsStatus = (state: boolean) => {
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
IClientReqDTO,
|
||||
TConsentData,
|
||||
TConsentList,
|
||||
TGenerateDeveloperToken,
|
||||
} from "../../utils/oauth/types";
|
||||
|
||||
export const getClient = async (clientId: string): Promise<IClientProps> => {
|
||||
@ -237,3 +238,38 @@ export const onOAuthCancel = (clientId: string, clientState: string) => {
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
export const generateDevelopToken = (
|
||||
client_id: string,
|
||||
client_secret: string,
|
||||
scopes: string[],
|
||||
): Promise<TGenerateDeveloperToken> | undefined => {
|
||||
const params = new URLSearchParams();
|
||||
params.append("grant_type", "personal_access_token");
|
||||
params.append("client_id", client_id);
|
||||
params.append("client_secret", client_secret);
|
||||
params.append("scope", scopes.join(" "));
|
||||
|
||||
return request<TGenerateDeveloperToken>(
|
||||
{ method: "post", url: "/oauth2/token", data: params },
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
export const revokeDeveloperToken = (
|
||||
token: string,
|
||||
client_id: string,
|
||||
client_secret: string,
|
||||
) => {
|
||||
const params = new URLSearchParams();
|
||||
params.append("token", token);
|
||||
params.append("client_id", client_id);
|
||||
params.append("client_secret", client_secret);
|
||||
|
||||
return request(
|
||||
{ method: "post", url: "/oauth2/revoke", data: params },
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
@ -663,7 +663,7 @@ const Dark: TTheme = {
|
||||
|
||||
input: {
|
||||
color: white,
|
||||
disableColor: grayDarkStrong,
|
||||
disableColor: grayDarkText,
|
||||
|
||||
backgroundColor: black,
|
||||
disableBackgroundColor: grayDarkStrong,
|
||||
|
@ -182,11 +182,11 @@ class AxiosClient {
|
||||
}
|
||||
};
|
||||
|
||||
request = (
|
||||
request = <T>(
|
||||
options: TReqOption & AxiosRequestConfig,
|
||||
skipRedirect = false,
|
||||
isOAuth = false,
|
||||
) => {
|
||||
): Promise<T> | undefined => {
|
||||
const onSuccess = (response: TRes) => {
|
||||
const error = this.getResponseError(response);
|
||||
|
||||
@ -295,7 +295,9 @@ class AxiosClient {
|
||||
|
||||
return Promise.reject(error);
|
||||
};
|
||||
return this.client?.(options).then(onSuccess).catch(onError);
|
||||
return this.client?.(options).then(onSuccess).catch(onError) as
|
||||
| Promise<T>
|
||||
| undefined;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -150,3 +150,10 @@ export type IClientListProps = List<IClientProps>;
|
||||
export type IClientListDTO = List<IClientResDTO>;
|
||||
|
||||
export type TConsentList = List<TConsentData>;
|
||||
|
||||
export type TGenerateDeveloperToken = {
|
||||
access_token: string;
|
||||
expires_in: number;
|
||||
scope: string;
|
||||
token_type: string;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user