add dialog to select authentication method for UIA
This commit is contained in:
parent
613d6006ca
commit
cbe5c79e24
3 changed files with 98 additions and 4 deletions
|
|
@ -1,5 +1,20 @@
|
|||
import React, { ReactNode } from 'react';
|
||||
import { AuthResponse, AuthType, UIAFlow } from '../utils/matrix-uia';
|
||||
import React, { ReactNode, useState } from 'react';
|
||||
import {
|
||||
config,
|
||||
Dialog,
|
||||
Header,
|
||||
Text,
|
||||
IconButton,
|
||||
Box,
|
||||
Icon,
|
||||
Icons,
|
||||
Button,
|
||||
OverlayBackdrop,
|
||||
Overlay,
|
||||
OverlayCenter,
|
||||
} from 'folds';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { AuthResponse, AuthType, getUIAFlowForStages, UIAFlow } from '../utils/matrix-uia';
|
||||
import { useSupportedUIAFlows, useUIACompleted, useUIAFlow } from '../hooks/useUIAFlows';
|
||||
import { UIAFlowOverlay } from './UIAFlowOverlay';
|
||||
import { OAuthStage, PasswordStage, SSOStage } from './uia-stages';
|
||||
|
|
@ -57,20 +72,97 @@ export function ActionUIA({ authData, ongoingFlow, action, onCancel }: ActionUIA
|
|||
);
|
||||
}
|
||||
|
||||
function UIAFlowPicker({
|
||||
flows,
|
||||
onCancel,
|
||||
onSelect,
|
||||
}: {
|
||||
flows: UIAFlow[];
|
||||
onCancel: () => void;
|
||||
onSelect: (flow: UIAFlow) => void;
|
||||
}) {
|
||||
const passwordFlow = getUIAFlowForStages(flows, [AuthType.Password]);
|
||||
const ssoFlow = getUIAFlowForStages(flows, [AuthType.Sso]);
|
||||
|
||||
return (
|
||||
<Overlay open backdrop={<OverlayBackdrop />}>
|
||||
<OverlayCenter>
|
||||
<FocusTrap focusTrapOptions={{ initialFocus: false, escapeDeactivates: false }}>
|
||||
<Dialog>
|
||||
<Header
|
||||
style={{
|
||||
padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
|
||||
}}
|
||||
variant="Surface"
|
||||
size="500"
|
||||
>
|
||||
<Box grow="Yes">
|
||||
<Text size="H4">Authentication</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={onCancel} radii="300">
|
||||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Box
|
||||
as="form"
|
||||
style={{ padding: `0 ${config.space.S400} ${config.space.S400}` }}
|
||||
direction="Column"
|
||||
gap="400"
|
||||
>
|
||||
<Box direction="Column" gap="400">
|
||||
<Text size="T200">Choose an authentication method to perform this action.</Text>
|
||||
</Box>
|
||||
<Box direction="Column" gap="200">
|
||||
{passwordFlow && (
|
||||
<Button variant="Primary" type="button" onClick={() => onSelect(passwordFlow)}>
|
||||
<Text as="span" size="B400">
|
||||
Continue with Password
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
{ssoFlow && (
|
||||
<Button
|
||||
variant="Secondary"
|
||||
fill="Soft"
|
||||
type="button"
|
||||
onClick={() => onSelect(ssoFlow)}
|
||||
>
|
||||
<Text as="span" size="B400">
|
||||
Continue with SSO
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Dialog>
|
||||
</FocusTrap>
|
||||
</OverlayCenter>
|
||||
</Overlay>
|
||||
);
|
||||
}
|
||||
|
||||
type ActionUIAFlowsLoaderProps = {
|
||||
authData: AuthResponse;
|
||||
onCancel: () => void;
|
||||
unsupported: () => ReactNode;
|
||||
children: (ongoingFlow: UIAFlow) => ReactNode;
|
||||
};
|
||||
export function ActionUIAFlowsLoader({
|
||||
authData,
|
||||
onCancel,
|
||||
unsupported,
|
||||
children,
|
||||
}: ActionUIAFlowsLoaderProps) {
|
||||
const supportedFlows = useSupportedUIAFlows(authData.flows ?? [], SUPPORTED_IN_APP_UIA_STAGES);
|
||||
const ongoingFlow = supportedFlows.length > 0 ? supportedFlows[0] : undefined;
|
||||
const [ongoingFlow, setOngoingFlow] = useState(
|
||||
supportedFlows.length === 1 ? supportedFlows[0] : undefined
|
||||
);
|
||||
|
||||
if (!ongoingFlow) return unsupported();
|
||||
if (supportedFlows.length === 0) return unsupported();
|
||||
|
||||
if (!ongoingFlow) {
|
||||
return <UIAFlowPicker flows={supportedFlows} onCancel={onCancel} onSelect={setOngoingFlow} />;
|
||||
}
|
||||
|
||||
return children(ongoingFlow);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ function SetupVerification({ onComplete }: SetupVerificationProps) {
|
|||
{uiaData && (
|
||||
<ActionUIAFlowsLoader
|
||||
authData={uiaData}
|
||||
onCancel={handleCancel}
|
||||
unsupported={() => (
|
||||
<Text size="T200" style={{ color: color.Critical.Main }}>
|
||||
Authentication steps to perform this action are not supported by client.
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ export function OtherDevices({ devices, refreshDeviceList, showVerification }: O
|
|||
{authData && (
|
||||
<ActionUIAFlowsLoader
|
||||
authData={authData}
|
||||
onCancel={handleCancelAuth}
|
||||
unsupported={() => (
|
||||
<Text size="T200">
|
||||
Authentication steps to perform this action are not supported by client.
|
||||
|
|
|
|||
Loading…
Reference in a new issue