mirror of https://github.com/vector-im/riot-web
Convert InteractiveAuthDialog to TS
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>pull/21833/head
parent
0285bb555f
commit
5967811cda
|
@ -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}
|
||||||
/>
|
/>
|
Loading…
Reference in New Issue