Convert InteractiveAuthDialog to TS

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
pull/21833/head
Šimon Brandner 2021-09-05 16:57:36 +02:00
parent 0285bb555f
commit 5967811cda
No known key found for this signature in database
GPG Key ID: 55C211A1226CB17D
1 changed files with 74 additions and 65 deletions

View File

@ -17,69 +17,82 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import AccessibleButton from '../elements/AccessibleButton'; import AccessibleButton from '../elements/AccessibleButton';
import { ERROR_USER_CANCELLED } from "../../structures/InteractiveAuth"; import InteractiveAuth, { ERROR_USER_CANCELLED } from "../../structures/InteractiveAuth";
import { SSOAuthEntry } from "../auth/InteractiveAuthEntryComponents"; import { SSOAuthEntry } from "../auth/InteractiveAuthEntryComponents";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { MatrixClient } from "matrix-js-sdk/src/client";
import BaseDialog from "./BaseDialog";
import { IAuthData } from "matrix-js-sdk/src/interactive-auth";
interface IProps {
// matrix client to use for UI auth requests
matrixClient: MatrixClient;
// response from initial request. If not supplied, will do a request on
// mount.
authData?: {
flows: [];
params: {};
session: string;
};
// callback
makeRequest: (auth: IAuthData) => Promise<IAuthData>;
onFinished: (confirmed: boolean, result?) => void;
// Optional title and body to show when not showing a particular stage
title?: string;
body?: string;
// Optional title and body pairs for particular stages and phases within
// those stages. Object structure/example is:
// {
// "org.example.stage_type": {
// 1: {
// "body": "This is a body for phase 1" of org.example.stage_type,
// "title": "Title for phase 1 of org.example.stage_type"
// },
// 2: {
// "body": "This is a body for phase 2 of org.example.stage_type",
// "title": "Title for phase 2 of org.example.stage_type"
// "continueText": "Confirm identity with Example Auth",
// "continueKind": "danger"
// }
// }
// }
//
// Default is defined in _getDefaultDialogAesthetics()
aestheticsForStagePhases?: {};
}
interface IState {
authError: Error;
// See _onUpdateStagePhase()
uiaStage: number;
uiaStagePhase: number;
}
@replaceableComponent("views.dialogs.InteractiveAuthDialog") @replaceableComponent("views.dialogs.InteractiveAuthDialog")
export default class InteractiveAuthDialog extends React.Component { export default class InteractiveAuthDialog extends React.Component<IProps, IState> {
static propTypes = { constructor(props: IProps) {
// matrix client to use for UI auth requests super(props);
matrixClient: PropTypes.object.isRequired,
// response from initial request. If not supplied, will do a request on this.state = {
// mount. authError: null,
authData: PropTypes.shape({
flows: PropTypes.array,
params: PropTypes.object,
session: PropTypes.string,
}),
// callback // See _onUpdateStagePhase()
makeRequest: PropTypes.func.isRequired, uiaStage: null,
uiaStagePhase: null,
};
}
onFinished: PropTypes.func.isRequired, private getDefaultDialogAesthetics() {
// Optional title and body to show when not showing a particular stage
title: PropTypes.string,
body: PropTypes.string,
// Optional title and body pairs for particular stages and phases within
// those stages. Object structure/example is:
// {
// "org.example.stage_type": {
// 1: {
// "body": "This is a body for phase 1" of org.example.stage_type,
// "title": "Title for phase 1 of org.example.stage_type"
// },
// 2: {
// "body": "This is a body for phase 2 of org.example.stage_type",
// "title": "Title for phase 2 of org.example.stage_type"
// "continueText": "Confirm identity with Example Auth",
// "continueKind": "danger"
// }
// }
// }
//
// Default is defined in _getDefaultDialogAesthetics()
aestheticsForStagePhases: PropTypes.object,
};
state = {
authError: null,
// See _onUpdateStagePhase()
uiaStage: null,
uiaStagePhase: null,
};
_getDefaultDialogAesthetics() {
const ssoAesthetics = { const ssoAesthetics = {
[SSOAuthEntry.PHASE_PREAUTH]: { [SSOAuthEntry.PHASE_PREAUTH]: {
title: _t("Use Single Sign On to continue"), title: _t("Use Single Sign On to continue"),
@ -101,7 +114,7 @@ export default class InteractiveAuthDialog extends React.Component {
}; };
} }
_onAuthFinished = (success, result) => { private onAuthFinished = (success: boolean, result: Error): void => {
if (success) { if (success) {
this.props.onFinished(true, result); this.props.onFinished(true, result);
} else { } else {
@ -115,19 +128,16 @@ export default class InteractiveAuthDialog extends React.Component {
} }
}; };
_onUpdateStagePhase = (newStage, newPhase) => { private onUpdateStagePhase = (newStage, newPhase): void => {
// We copy the stage and stage phase params into state for title selection in render() // We copy the stage and stage phase params into state for title selection in render()
this.setState({ uiaStage: newStage, uiaStagePhase: newPhase }); this.setState({ uiaStage: newStage, uiaStagePhase: newPhase });
}; };
_onDismissClick = () => { private onDismissClick = (): void => {
this.props.onFinished(false); this.props.onFinished(false);
}; };
render() { public render(): JSX.Element {
const InteractiveAuth = sdk.getComponent("structures.InteractiveAuth");
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
// Let's pick a title, body, and other params text that we'll show to the user. The order // Let's pick a title, body, and other params text that we'll show to the user. The order
// is most specific first, so stagePhase > our props > defaults. // is most specific first, so stagePhase > our props > defaults.
@ -135,7 +145,7 @@ export default class InteractiveAuthDialog extends React.Component {
let body = this.state.authError ? null : this.props.body; let body = this.state.authError ? null : this.props.body;
let continueText = null; let continueText = null;
let continueKind = null; let continueKind = null;
const dialogAesthetics = this.props.aestheticsForStagePhases || this._getDefaultDialogAesthetics(); const dialogAesthetics = this.props.aestheticsForStagePhases || this.getDefaultDialogAesthetics();
if (!this.state.authError && dialogAesthetics) { if (!this.state.authError && dialogAesthetics) {
if (dialogAesthetics[this.state.uiaStage]) { if (dialogAesthetics[this.state.uiaStage]) {
const aesthetics = dialogAesthetics[this.state.uiaStage][this.state.uiaStagePhase]; const aesthetics = dialogAesthetics[this.state.uiaStage][this.state.uiaStagePhase];
@ -152,9 +162,9 @@ export default class InteractiveAuthDialog extends React.Component {
<div id='mx_Dialog_content'> <div id='mx_Dialog_content'>
<div role="alert">{ this.state.authError.message || this.state.authError.toString() }</div> <div role="alert">{ this.state.authError.message || this.state.authError.toString() }</div>
<br /> <br />
<AccessibleButton onClick={this._onDismissClick} <AccessibleButton onClick={this.onDismissClick}
className="mx_GeneralButton" className="mx_GeneralButton"
autoFocus="true" autoFocus={true}
> >
{ _t("Dismiss") } { _t("Dismiss") }
</AccessibleButton> </AccessibleButton>
@ -165,12 +175,11 @@ export default class InteractiveAuthDialog extends React.Component {
<div id='mx_Dialog_content'> <div id='mx_Dialog_content'>
{ body } { body }
<InteractiveAuth <InteractiveAuth
ref={this._collectInteractiveAuth}
matrixClient={this.props.matrixClient} matrixClient={this.props.matrixClient}
authData={this.props.authData} authData={this.props.authData}
makeRequest={this.props.makeRequest} makeRequest={this.props.makeRequest}
onAuthFinished={this._onAuthFinished} onAuthFinished={this.onAuthFinished}
onStagePhaseChange={this._onUpdateStagePhase} onStagePhaseChange={this.onUpdateStagePhase}
continueText={continueText} continueText={continueText}
continueKind={continueKind} continueKind={continueKind}
/> />