Client:OAuth2: add revoke dialog

This commit is contained in:
Timofey Boyko 2023-11-15 11:24:58 +03:00
parent 0a4cb47576
commit 5b5011ce8b
5 changed files with 165 additions and 7 deletions

View File

@ -31,6 +31,11 @@
"RegisterNewApp": "Register a new application",
"Reset": "Reset",
"Revoke": "Revoke",
"RevokeConsent": "Revoke consent",
"RevokeConsentDescription": "Once you revoke the consent to use the ONLYOFFICE DocSpace auth data in the service {{name}}, ONLYOFFICE DocSpace will automatically stop logging into {{name}}. Your account in {{name}} will not be deleted.",
"RevokeConsentDescriptionGroup": "Once you revoke the consent to use the ONLYOFFICE DocSpace auth data in the services, ONLYOFFICE DocSpace will automatically stop logging. Your accounts will not be deleted.",
"RevokeConsentLogin": "If you want to renew an automatic login into {{name}} using ONLYOFFICE DocSpace, you will be asked to grant access to your DocSpace account data.",
"RevokeConsentLoginGroup": "If you want to renew an automatic login using ONLYOFFICE DocSpace, you will be asked to grant access to your DocSpace account data.",
"Secret": "Secret",
"Scopes": "Scopes",
"SignIn": "Sign in with DocSpace",

View File

@ -181,7 +181,7 @@ const InfoDialog = ({
return (
<ModalDialog visible={visible} displayType={"aside"} onClose={onClose}>
<ModalDialog.Header>Info</ModalDialog.Header>
<ModalDialog.Header>{t("Common:Info")}</ModalDialog.Header>
<ModalDialog.Body>
<StyledContainer
showDescription={showDescription}

View File

@ -19,6 +19,7 @@ import { StyledContainer } from "./styled-authorized-apps";
import TableView from "./sub-components/TableView";
import RowView from "./sub-components/RowView";
import RevokeDialog from "./sub-components/RevokeDialog";
interface AuthorizedAppsProps {
consents?: IClientProps[];
@ -31,6 +32,12 @@ interface AuthorizedAppsProps {
infoDialogVisible: boolean;
fetchScopes?: () => Promise<void>;
revokeDialogVisible: boolean;
setRevokeDialogVisible: (value: boolean) => void;
selection: string[];
bufferSelection: IClientProps;
revokeClient: (value: string[]) => Promise<void>;
}
const AuthorizedApps = ({
@ -41,6 +48,11 @@ const AuthorizedApps = ({
currentDeviceType,
infoDialogVisible,
fetchScopes,
revokeDialogVisible,
setRevokeDialogVisible,
selection,
bufferSelection,
revokeClient,
}: AuthorizedAppsProps) => {
const { t } = useTranslation(["OAuth"]);
@ -89,6 +101,16 @@ const AuthorizedApps = ({
{infoDialogVisible && (
<InfoDialog visible={infoDialogVisible} isProfile />
)}
{revokeDialogVisible && (
<RevokeDialog
visible={revokeDialogVisible}
onClose={() => setRevokeDialogVisible(false)}
currentDeviceType={currentDeviceType}
onRevoke={revokeClient}
selection={selection}
bufferSelection={bufferSelection}
/>
)}
</StyledContainer>
);
};
@ -102,6 +124,12 @@ export default inject(
viewAs,
setViewAs,
infoDialogVisible,
revokeDialogVisible,
setRevokeDialogVisible,
selection,
bufferSelection,
revokeClient,
} = oauthStore;
const { currentDeviceType } = auth.settingsStore;
@ -114,6 +142,11 @@ export default inject(
currentDeviceType,
infoDialogVisible,
fetchScopes,
revokeDialogVisible,
setRevokeDialogVisible,
selection,
bufferSelection,
revokeClient,
};
}
)(observer(AuthorizedApps));

View File

@ -0,0 +1,112 @@
import React from "react";
import { useTranslation, Trans } from "react-i18next";
//@ts-ignore
import ModalDialog from "@docspace/components/modal-dialog";
import Text from "@docspace/components/text";
import Button from "@docspace/components/button";
import { DeviceUnionType } from "@docspace/common/hooks/useViewEffect";
import { IClientProps } from "@docspace/common/utils/oauth/interfaces";
interface RevokeDialogProps {
visible: boolean;
onClose: () => void;
selection: string[];
bufferSelection: IClientProps;
onRevoke: (value: string[]) => Promise<void>;
currentDeviceType: DeviceUnionType;
}
const RevokeDialog = ({
visible,
onRevoke,
onClose,
selection,
bufferSelection,
currentDeviceType,
}: RevokeDialogProps) => {
const { t } = useTranslation(["OAuth", "Common"]);
const [isRequestRunning, setIsRequestRunning] = React.useState(false);
const isMobile = currentDeviceType === "mobile";
const isGroup = selection.length > 1;
const name = bufferSelection?.name;
const firstDesc = isGroup ? (
t("RevokeConsentDescriptionGroup")
) : (
<Trans t={t} i18nKey="RevokeConsentDescription" ns="OAuth">
Once you revoke the consent to use the ONLYOFFICE DocSpace auth data in
the service {{ name }}, ONLYOFFICE DocSpace will automatically stop
logging into {{ name }}. Your account in {{ name }} will not be deleted.
</Trans>
);
const secondDesc = isGroup ? (
t("RevokeConsentLogin")
) : (
<Trans t={t} i18nKey="RevokeConsentLogin" ns="OAuth">
If you want to renew an automatic login into {{ name }} using ONLYOFFICE
DocSpace, you will be asked to grant access to your DocSpace account data.
</Trans>
);
const onRevokeAction = async () => {
setIsRequestRunning(true);
if (isGroup) {
await onRevoke(selection);
} else {
await onRevoke([bufferSelection.clientId]);
}
setIsRequestRunning(false);
onClose();
};
const onCloseAction = () => {
if (isRequestRunning) return;
onClose();
};
return (
<ModalDialog
visible={visible}
isLarge
autoMaxHeight
withFooterBorder={isMobile}
onClose={onCloseAction}
displayType={"modal"}
>
<ModalDialog.Header>{t("RevokeConsent")}</ModalDialog.Header>
<ModalDialog.Body>
{/* @ts-ignore */}
<Text style={{ marginBottom: "16px" }}>{firstDesc}</Text>
{/* @ts-ignore */}
<Text>{secondDesc}</Text>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
// @ts-ignore
label={t("Revoke")}
primary
scale={isMobile}
size={"normal"}
isLoading={isRequestRunning}
onClick={onRevokeAction}
/>
<Button
// @ts-ignore
label={t("Common:CancelButton")}
scale={isMobile}
size={"normal"}
isDisabled={isRequestRunning}
onClick={onCloseAction}
/>
</ModalDialog.Footer>
</ModalDialog>
);
};
export default RevokeDialog;

View File

@ -45,6 +45,9 @@ export interface OAuthStoreProps {
infoDialogVisible: boolean;
setInfoDialogVisible: (value: boolean) => void;
revokeDialogVisible: boolean;
setRevokeDialogVisible: (value: boolean) => void;
previewDialogVisible: boolean;
setPreviewDialogVisible: (value: boolean) => void;
@ -137,11 +140,17 @@ class OAuthStore implements OAuthStoreProps {
isInit: boolean = false;
revokeDialogVisible: boolean = false;
constructor(authStore: any) {
this.authStore = authStore;
makeAutoObservable(this);
}
setRevokeDialogVisible = (value: boolean) => {
this.revokeDialogVisible = value;
};
setIsInit = (value: boolean) => {
this.isInit = value;
};
@ -419,7 +428,7 @@ class OAuthStore implements OAuthStoreProps {
) => {
const { clientId } = item;
const isGroupContext = this.selection.length;
const isGroupContext = this.selection.length > 1;
const onShowInfo = () => {
this.setBufferSelection(clientId);
@ -428,11 +437,10 @@ class OAuthStore implements OAuthStoreProps {
};
const onRevoke = () => {
if (!isGroupContext) {
this.revokeClient([clientId]);
} else {
this.revokeClient(this.selection);
}
if (!isGroupContext) this.setBufferSelection(clientId);
this.setPreviewDialogVisible(false);
this.setInfoDialogVisible(false);
this.setRevokeDialogVisible(true);
};
const openOption = {