mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-03-13 14:40:01 +01:00
add sso uia stage
This commit is contained in:
parent
e2dbf2e68b
commit
684c9285a6
4 changed files with 109 additions and 5 deletions
|
@ -3,7 +3,8 @@ import { AuthDict, AuthType, IAuthData, UIAFlow } from 'matrix-js-sdk';
|
||||||
import { getUIAFlowForStages } from '../utils/matrix-uia';
|
import { getUIAFlowForStages } from '../utils/matrix-uia';
|
||||||
import { useSupportedUIAFlows, useUIACompleted, useUIAFlow } from '../hooks/useUIAFlows';
|
import { useSupportedUIAFlows, useUIACompleted, useUIAFlow } from '../hooks/useUIAFlows';
|
||||||
import { UIAFlowOverlay } from './UIAFlowOverlay';
|
import { UIAFlowOverlay } from './UIAFlowOverlay';
|
||||||
import { PasswordStage } from './uia-stages';
|
import { PasswordStage, SSOStage } from './uia-stages';
|
||||||
|
import { useMatrixClient } from '../hooks/useMatrixClient';
|
||||||
|
|
||||||
export const SUPPORTED_IN_APP_UIA_STAGES = [AuthType.Password, AuthType.Sso];
|
export const SUPPORTED_IN_APP_UIA_STAGES = [AuthType.Password, AuthType.Sso];
|
||||||
|
|
||||||
|
@ -14,13 +15,13 @@ export const pickUIAFlow = (uiaFlows: UIAFlow[]): UIAFlow | undefined => {
|
||||||
};
|
};
|
||||||
|
|
||||||
type ActionUIAProps = {
|
type ActionUIAProps = {
|
||||||
userId: string;
|
|
||||||
authData: IAuthData;
|
authData: IAuthData;
|
||||||
ongoingFlow: UIAFlow;
|
ongoingFlow: UIAFlow;
|
||||||
action: (authDict: AuthDict) => void;
|
action: (authDict: AuthDict) => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
};
|
};
|
||||||
export function ActionUIA({ userId, authData, ongoingFlow, action, onCancel }: ActionUIAProps) {
|
export function ActionUIA({ authData, ongoingFlow, action, onCancel }: ActionUIAProps) {
|
||||||
|
const mx = useMatrixClient();
|
||||||
const completed = useUIACompleted(authData);
|
const completed = useUIACompleted(authData);
|
||||||
const { getStageToComplete } = useUIAFlow(authData, ongoingFlow);
|
const { getStageToComplete } = useUIAFlow(authData, ongoingFlow);
|
||||||
|
|
||||||
|
@ -35,7 +36,15 @@ export function ActionUIA({ userId, authData, ongoingFlow, action, onCancel }: A
|
||||||
>
|
>
|
||||||
{stageToComplete.type === AuthType.Password && (
|
{stageToComplete.type === AuthType.Password && (
|
||||||
<PasswordStage
|
<PasswordStage
|
||||||
userId={userId}
|
userId={mx.getUserId()!}
|
||||||
|
stageData={stageToComplete}
|
||||||
|
onCancel={onCancel}
|
||||||
|
submitAuthDict={action}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{stageToComplete.type === AuthType.Sso && stageToComplete.session && (
|
||||||
|
<SSOStage
|
||||||
|
ssoRedirectURL={mx.getFallbackAuthUrl(AuthType.Sso, stageToComplete.session)}
|
||||||
stageData={stageToComplete}
|
stageData={stageToComplete}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
submitAuthDict={action}
|
submitAuthDict={action}
|
||||||
|
|
95
src/app/components/uia-stages/SSOStage.tsx
Normal file
95
src/app/components/uia-stages/SSOStage.tsx
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
import { Box, Button, color, config, Dialog, Header, Icon, IconButton, Icons, Text } from 'folds';
|
||||||
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { AuthType } from 'matrix-js-sdk';
|
||||||
|
import { StageComponentProps } from './types';
|
||||||
|
|
||||||
|
export function SSOStage({
|
||||||
|
ssoRedirectURL,
|
||||||
|
stageData,
|
||||||
|
submitAuthDict,
|
||||||
|
onCancel,
|
||||||
|
}: StageComponentProps & {
|
||||||
|
ssoRedirectURL: string;
|
||||||
|
}) {
|
||||||
|
const { errorCode, error, session } = stageData;
|
||||||
|
const [ssoWindow, setSSOWindow] = useState<Window>();
|
||||||
|
|
||||||
|
const handleSubmit = useCallback(
|
||||||
|
() =>
|
||||||
|
submitAuthDict({
|
||||||
|
type: AuthType.Sso,
|
||||||
|
session,
|
||||||
|
}),
|
||||||
|
[submitAuthDict, session]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleContinue = () => {
|
||||||
|
const w = window.open(ssoRedirectURL, '_blank');
|
||||||
|
setSSOWindow(w ?? undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleMessage = (evt: MessageEvent) => {
|
||||||
|
if (ssoWindow && evt.data === 'authDone' && evt.source === ssoWindow) {
|
||||||
|
ssoWindow.close();
|
||||||
|
setSSOWindow(undefined);
|
||||||
|
handleSubmit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('message', handleMessage);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('message', handleMessage);
|
||||||
|
};
|
||||||
|
}, [ssoWindow, handleSubmit]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog>
|
||||||
|
<Header
|
||||||
|
style={{
|
||||||
|
padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
|
||||||
|
}}
|
||||||
|
variant="Surface"
|
||||||
|
size="500"
|
||||||
|
>
|
||||||
|
<Box grow="Yes">
|
||||||
|
<Text size="H4">SSO Login</Text>
|
||||||
|
</Box>
|
||||||
|
<IconButton size="300" onClick={onCancel} radii="300">
|
||||||
|
<Icon src={Icons.Cross} />
|
||||||
|
</IconButton>
|
||||||
|
</Header>
|
||||||
|
<Box
|
||||||
|
style={{ padding: `0 ${config.space.S400} ${config.space.S400}` }}
|
||||||
|
direction="Column"
|
||||||
|
gap="400"
|
||||||
|
>
|
||||||
|
<Text size="T200">
|
||||||
|
To perform this action you need to authenticate yourself by SSO login.
|
||||||
|
</Text>
|
||||||
|
{errorCode && (
|
||||||
|
<Box alignItems="Center" gap="100" style={{ color: color.Critical.Main }}>
|
||||||
|
<Icon size="50" src={Icons.Warning} filled />
|
||||||
|
<Text size="T200">
|
||||||
|
<b>{`${errorCode}: ${error}`}</b>
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{ssoWindow ? (
|
||||||
|
<Button variant="Primary" onClick={handleSubmit}>
|
||||||
|
<Text as="span" size="B400">
|
||||||
|
Continue
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button variant="Primary" onClick={handleContinue}>
|
||||||
|
<Text as="span" size="B400">
|
||||||
|
Continue with SSO
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
|
@ -4,4 +4,5 @@ export * from './EmailStage';
|
||||||
export * from './PasswordStage';
|
export * from './PasswordStage';
|
||||||
export * from './ReCaptchaStage';
|
export * from './ReCaptchaStage';
|
||||||
export * from './RegistrationTokenStage';
|
export * from './RegistrationTokenStage';
|
||||||
|
export * from './SSOStage';
|
||||||
export * from './TermsStage';
|
export * from './TermsStage';
|
||||||
|
|
|
@ -404,7 +404,6 @@ export function Sessions({ requestClose }: SessionsProps) {
|
||||||
>
|
>
|
||||||
{(ongoingFlow) => (
|
{(ongoingFlow) => (
|
||||||
<ActionUIA
|
<ActionUIA
|
||||||
userId={mx.getUserId()!}
|
|
||||||
authData={authData}
|
authData={authData}
|
||||||
ongoingFlow={ongoingFlow}
|
ongoingFlow={ongoingFlow}
|
||||||
action={deleteDevices}
|
action={deleteDevices}
|
||||||
|
|
Loading…
Reference in a new issue