Merge pull request #6299 from matrix-org/dbkr/tsify_setupencryptionbody
Convert some Key Verification classes to TypeScript
This commit is contained in:
commit
fdef1f9b68
8 changed files with 76 additions and 191 deletions
|
@ -48,6 +48,7 @@ limitations under the License.
|
|||
.mx_cryptoEvent_buttons {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.mx_cryptoEvent_state {
|
||||
|
|
|
@ -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}`);
|
|
@ -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 didn’t 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>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
export default class VerificationRequestDialog extends React.Component<IProps, IState> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
verificationRequest: this.props.verificationRequest,
|
||||
};
|
||||
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.state = {};
|
||||
if (this.props.verificationRequest) {
|
||||
this.state.verificationRequest = this.props.verificationRequest;
|
||||
} else if (this.props.verificationRequestPromise) {
|
||||
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>;
|
||||
}
|
|
@ -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>);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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: () => {
|
||||
|
|
|
@ -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 didn’t sign in to this session, your account may be compromised.": "If you didn’t 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>.",
|
||||
|
|
Loading…
Reference in a new issue