Merge pull request #6299 from matrix-org/dbkr/tsify_setupencryptionbody

Convert some Key Verification classes to TypeScript
This commit is contained in:
David Baker 2021-07-01 15:33:15 +01:00 committed by GitHub
commit fdef1f9b68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 191 deletions

View file

@ -48,6 +48,7 @@ limitations under the License.
.mx_cryptoEvent_buttons {
align-items: center;
display: flex;
gap: 5px;
}
.mx_cryptoEvent_state {

View file

@ -1,5 +1,5 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2020-2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -15,33 +15,43 @@ limitations under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg';
import Modal from '../../../Modal';
import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog';
import * as sdk from '../../../index';
import { SetupEncryptionStore, Phase } from '../../../stores/SetupEncryptionStore';
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { ISecretStorageKeyInfo } from 'matrix-js-sdk';
import EncryptionPanel from "../../views/right_panel/EncryptionPanel";
import AccessibleButton from '../../views/elements/AccessibleButton';
import Spinner from '../../views/elements/Spinner';
import { IKeyBackupInfo } from "matrix-js-sdk/src/crypto/keybackup";
import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
function keyHasPassphrase(keyInfo) {
return (
function keyHasPassphrase(keyInfo: ISecretStorageKeyInfo): boolean {
return Boolean(
keyInfo.passphrase &&
keyInfo.passphrase.salt &&
keyInfo.passphrase.iterations
keyInfo.passphrase.iterations,
);
}
@replaceableComponent("structures.auth.SetupEncryptionBody")
export default class SetupEncryptionBody extends React.Component {
static propTypes = {
onFinished: PropTypes.func.isRequired,
};
interface IProps {
onFinished: (boolean) => void;
}
constructor() {
super();
interface IState {
phase: Phase;
verificationRequest: VerificationRequest;
backupInfo: IKeyBackupInfo;
}
@replaceableComponent("structures.auth.SetupEncryptionBody")
export default class SetupEncryptionBody extends React.Component<IProps, IState> {
constructor(props) {
super(props);
const store = SetupEncryptionStore.sharedInstance();
store.on("update", this._onStoreUpdate);
store.on("update", this.onStoreUpdate);
store.start();
this.state = {
phase: store.phase,
@ -53,10 +63,10 @@ export default class SetupEncryptionBody extends React.Component {
};
}
_onStoreUpdate = () => {
private onStoreUpdate = () => {
const store = SetupEncryptionStore.sharedInstance();
if (store.phase === Phase.Finished) {
this.props.onFinished();
this.props.onFinished(true);
return;
}
this.setState({
@ -66,18 +76,18 @@ export default class SetupEncryptionBody extends React.Component {
});
};
componentWillUnmount() {
public componentWillUnmount() {
const store = SetupEncryptionStore.sharedInstance();
store.off("update", this._onStoreUpdate);
store.off("update", this.onStoreUpdate);
store.stop();
}
_onUsePassphraseClick = async () => {
private onUsePassphraseClick = async () => {
const store = SetupEncryptionStore.sharedInstance();
store.usePassPhrase();
}
};
_onVerifyClick = () => {
private onVerifyClick = () => {
const cli = MatrixClientPeg.get();
const userId = cli.getUserId();
const requestPromise = cli.requestVerification(userId);
@ -91,42 +101,44 @@ export default class SetupEncryptionBody extends React.Component {
request.cancel();
},
});
}
};
onSkipClick = () => {
private onSkipClick = () => {
const store = SetupEncryptionStore.sharedInstance();
store.skip();
}
};
onSkipConfirmClick = () => {
private onSkipConfirmClick = () => {
const store = SetupEncryptionStore.sharedInstance();
store.skipConfirm();
}
};
onSkipBackClick = () => {
private onSkipBackClick = () => {
const store = SetupEncryptionStore.sharedInstance();
store.returnAfterSkip();
}
};
onDoneClick = () => {
private onDoneClick = () => {
const store = SetupEncryptionStore.sharedInstance();
store.done();
}
};
render() {
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
private onEncryptionPanelClose = () => {
this.props.onFinished(false);
};
public render() {
const {
phase,
} = this.state;
if (this.state.verificationRequest) {
const EncryptionPanel = sdk.getComponent("views.right_panel.EncryptionPanel");
return <EncryptionPanel
layout="dialog"
verificationRequest={this.state.verificationRequest}
onClose={this.props.onFinished}
onClose={this.onEncryptionPanelClose}
member={MatrixClientPeg.get().getUser(this.state.verificationRequest.otherUserId)}
isRoomEncrypted={false}
/>;
} else if (phase === Phase.Intro) {
const store = SetupEncryptionStore.sharedInstance();
@ -139,14 +151,14 @@ export default class SetupEncryptionBody extends React.Component {
let useRecoveryKeyButton;
if (recoveryKeyPrompt) {
useRecoveryKeyButton = <AccessibleButton kind="link" onClick={this._onUsePassphraseClick}>
useRecoveryKeyButton = <AccessibleButton kind="link" onClick={this.onUsePassphraseClick}>
{recoveryKeyPrompt}
</AccessibleButton>;
}
let verifyButton;
if (store.hasDevicesToVerifyAgainst) {
verifyButton = <AccessibleButton kind="primary" onClick={this._onVerifyClick}>
verifyButton = <AccessibleButton kind="primary" onClick={this.onVerifyClick}>
{ _t("Use another login") }
</AccessibleButton>;
}
@ -217,7 +229,6 @@ export default class SetupEncryptionBody extends React.Component {
</div>
);
} else if (phase === Phase.Busy || phase === Phase.Loading) {
const Spinner = sdk.getComponent('views.elements.Spinner');
return <Spinner />;
} else {
console.log(`SetupEncryptionBody: Unknown phase ${phase}`);

View file

@ -1,121 +0,0 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
import Modal from '../../../Modal';
import { replaceableComponent } from '../../../utils/replaceableComponent';
import VerificationRequestDialog from './VerificationRequestDialog';
import BaseDialog from './BaseDialog';
import DialogButtons from '../elements/DialogButtons';
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import * as sdk from '../../../index';
@replaceableComponent("views.dialogs.NewSessionReviewDialog")
export default class NewSessionReviewDialog extends React.PureComponent {
static propTypes = {
userId: PropTypes.string.isRequired,
device: PropTypes.object.isRequired,
onFinished: PropTypes.func.isRequired,
}
onCancelClick = () => {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog("Verification failed", "insecure", ErrorDialog, {
headerImage: require("../../../../res/img/e2e/warning.svg"),
title: _t("Your account is not secure"),
description: <div>
{_t("One of the following may be compromised:")}
<ul>
<li>{_t("Your password")}</li>
<li>{_t("Your homeserver")}</li>
<li>{_t("This session, or the other session")}</li>
<li>{_t("The internet connection either session is using")}</li>
</ul>
<div>
{_t("We recommend you change your password and Security Key in Settings immediately")}
</div>
</div>,
onFinished: () => this.props.onFinished(false),
});
}
onContinueClick = () => {
const { userId, device } = this.props;
const cli = MatrixClientPeg.get();
const requestPromise = cli.requestVerification(
userId,
[device.deviceId],
);
this.props.onFinished(true);
Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, {
verificationRequestPromise: requestPromise,
member: cli.getUser(userId),
onFinished: async () => {
const request = await requestPromise;
request.cancel();
},
});
}
render() {
const { device } = this.props;
const icon = <span className="mx_NewSessionReviewDialog_headerIcon mx_E2EIcon_warning"></span>;
const titleText = _t("New session");
const title = <h2 className="mx_NewSessionReviewDialog_header">
{icon}
{titleText}
</h2>;
return (
<BaseDialog
title={title}
onFinished={this.props.onFinished}
>
<div className="mx_NewSessionReviewDialog_body">
<p>{_t(
"Use this session to verify your new one, " +
"granting it access to encrypted messages:",
)}</p>
<div className="mx_NewSessionReviewDialog_deviceInfo">
<div>
<span className="mx_NewSessionReviewDialog_deviceName">
{device.getDisplayName()}
</span> <span className="mx_NewSessionReviewDialog_deviceID">
({device.deviceId})
</span>
</div>
</div>
<p>{_t(
"If you didnt sign in to this session, " +
"your account may be compromised.",
)}</p>
<DialogButtons
cancelButton={_t("This wasn't me")}
cancelButtonClass="danger"
primaryButton={_t("Continue")}
onCancel={this.onCancelClick}
onPrimaryButtonClick={this.onContinueClick}
/>
</div>
</BaseDialog>
);
}
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2020-2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -15,27 +15,33 @@ limitations under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { MatrixClientPeg } from '../../../MatrixClientPeg';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler';
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
import BaseDialog from "./BaseDialog";
import EncryptionPanel from "../right_panel/EncryptionPanel";
import { User } from 'matrix-js-sdk';
interface IProps {
verificationRequest: VerificationRequest;
verificationRequestPromise: Promise<VerificationRequest>;
onFinished: () => void;
member: User;
}
interface IState {
verificationRequest: VerificationRequest;
}
@replaceableComponent("views.dialogs.VerificationRequestDialog")
export default class VerificationRequestDialog extends React.Component {
static propTypes = {
verificationRequest: PropTypes.object,
verificationRequestPromise: PropTypes.object,
onFinished: PropTypes.func.isRequired,
member: PropTypes.string,
};
constructor(...args) {
super(...args);
this.state = {};
if (this.props.verificationRequest) {
this.state.verificationRequest = this.props.verificationRequest;
} else if (this.props.verificationRequestPromise) {
export default class VerificationRequestDialog extends React.Component<IProps, IState> {
constructor(props) {
super(props);
this.state = {
verificationRequest: this.props.verificationRequest,
};
if (this.props.verificationRequestPromise) {
this.props.verificationRequestPromise.then(r => {
this.setState({ verificationRequest: r });
});
@ -43,8 +49,6 @@ export default class VerificationRequestDialog extends React.Component {
}
render() {
const BaseDialog = sdk.getComponent("views.dialogs.BaseDialog");
const EncryptionPanel = sdk.getComponent("views.right_panel.EncryptionPanel");
const request = this.state.verificationRequest;
const otherUserId = request && request.otherUserId;
const member = this.props.member ||
@ -65,6 +69,7 @@ export default class VerificationRequestDialog extends React.Component {
verificationRequestPromise={this.props.verificationRequestPromise}
onClose={this.props.onFinished}
member={member}
isRoomEncrypted={false}
/>
</BaseDialog>;
}

View file

@ -154,7 +154,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
<AccessibleButton kind="danger" onClick={this.onRejectClicked}>
{_t("Decline")}
</AccessibleButton>
<AccessibleButton onClick={this.onAcceptClicked}>
<AccessibleButton kind="primary" onClick={this.onAcceptClicked}>
{_t("Accept")}
</AccessibleButton>
</div>);

View file

@ -39,9 +39,8 @@ interface IProps {
member: RoomMember | User;
onClose: () => void;
verificationRequest: VerificationRequest;
verificationRequestPromise: Promise<VerificationRequest>;
verificationRequestPromise?: Promise<VerificationRequest>;
layout: string;
inDialog: boolean;
isRoomEncrypted: boolean;
}

View file

@ -16,7 +16,6 @@ limitations under the License.
import React from "react";
import * as sdk from "../../../index";
import { _t } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg';
import { RightPanelPhases } from "../../../stores/RightPanelStorePhases";
@ -30,6 +29,7 @@ import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/reque
import { DeviceInfo } from "matrix-js-sdk/src/crypto/deviceinfo";
import { Action } from "../../../dispatcher/actions";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import VerificationRequestDialog from "../dialogs/VerificationRequestDialog";
interface IProps {
toastKey: string;
@ -123,7 +123,6 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
},
});
} else {
const VerificationRequestDialog = sdk.getComponent("views.dialogs.VerificationRequestDialog");
Modal.createTrackedDialog('Incoming Verification', '', VerificationRequestDialog, {
verificationRequest: request,
onFinished: () => {

View file

@ -2342,15 +2342,6 @@
"Message edits": "Message edits",
"Modal Widget": "Modal Widget",
"Data on this screen is shared with %(widgetDomain)s": "Data on this screen is shared with %(widgetDomain)s",
"Your account is not secure": "Your account is not secure",
"Your password": "Your password",
"This session, or the other session": "This session, or the other session",
"The internet connection either session is using": "The internet connection either session is using",
"We recommend you change your password and Security Key in Settings immediately": "We recommend you change your password and Security Key in Settings immediately",
"New session": "New session",
"Use this session to verify your new one, granting it access to encrypted messages:": "Use this session to verify your new one, granting it access to encrypted messages:",
"If you didnt sign in to this session, your account may be compromised.": "If you didnt sign in to this session, your account may be compromised.",
"This wasn't me": "This wasn't me",
"Doesn't look like a valid email address": "Doesn't look like a valid email address",
"Continuing without email": "Continuing without email",
"Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account</b>.": "Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account</b>.",