Merge branch 'develop' into bwindels/customtags-featureflag

This commit is contained in:
Bruno Windels 2019-02-08 12:12:43 +00:00
commit 3c5fb61350
12 changed files with 62 additions and 255 deletions

View file

@ -19,6 +19,8 @@ import sdk from '../../../../index';
import MatrixClientPeg from '../../../../MatrixClientPeg';
import Modal from '../../../../Modal';
import { MatrixClient } from 'matrix-js-sdk';
import { _t } from '../../../../languageHandler';
const RESTORE_TYPE_PASSPHRASE = 0;
@ -88,7 +90,7 @@ export default React.createClass({
});
try {
const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithPassword(
this.state.passPhrase, undefined, undefined, this.state.backupInfo.version,
this.state.passPhrase, undefined, undefined, this.state.backupInfo,
);
this.setState({
loading: false,
@ -107,11 +109,11 @@ export default React.createClass({
this.setState({
loading: true,
restoreError: null,
restoreType: RESTORE_TYPE_PASSPHRASE,
restoreType: RESTORE_TYPE_RECOVERYKEY,
});
try {
const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithRecoveryKey(
this.state.recoveryKey, undefined, undefined, this.state.backupInfo.version,
this.state.recoveryKey, undefined, undefined, this.state.backupInfo,
);
this.setState({
loading: false,
@ -185,32 +187,31 @@ export default React.createClass({
title = _t("Error");
content = _t("Unable to load backup status");
} else if (this.state.restoreError) {
title = _t("Error");
content = _t("Unable to restore backup");
if (this.state.restoreError.errcode === MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY) {
if (this.state.restoreType === RESTORE_TYPE_RECOVERYKEY) {
title = _t("Recovery Key Mismatch");
content = <div>
<p>{_t(
"Backup could not be decrypted with this key: " +
"please verify that you entered the correct recovery key.",
)}</p>
</div>;
} else {
title = _t("Incorrect Recovery Passphrase");
content = <div>
<p>{_t(
"Backup could not be decrypted with this passphrase: " +
"please verify that you entered the correct recovery passphrase.",
)}</p>
</div>;
}
} else {
title = _t("Error");
content = _t("Unable to restore backup");
}
} else if (this.state.backupInfo === null) {
title = _t("Error");
content = _t("No backup found!");
} else if (
this.state.recoverInfo &&
this.state.recoverInfo.imported === 0 &&
this.state.recoverInfo.total > 0
) {
title = _t("Error Restoring Backup");
if (this.state.restoreType === RESTORE_TYPE_RECOVERYKEY) {
content = <div>
<p>{_t(
"Backup could not be decrypted with this key: " +
"please verify that you entered the correct recovery key.",
)}</p>
</div>;
} else {
content = <div>
<p>{_t(
"Backup could not be decrypted with this passphrase: " +
"please verify that you entered the correct recovery passphrase.",
)}</p>
</div>;
}
} else if (this.state.recoverInfo) {
title = _t("Backup Restored");
let failedToDecrypt;

View file

@ -1,103 +0,0 @@
/*
Copyright 2019 New Vector Ltd.
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 classnames from 'classnames';
import sdk from '../../../index';
class HexVerifyPair extends React.Component {
static propTypes = {
text: PropTypes.string.isRequired,
index: PropTypes.number,
verified: PropTypes.bool,
onChange: PropTypes.func.isRequired,
}
_onClick = () => {
this.setState({verified: !this.props.verified});
this.props.onChange(this.props.index, !this.props.verified);
}
render() {
const classNames = {
mx_HexVerify_pair: true,
mx_HexVerify_pair_verified: this.props.verified,
};
const AccessibleButton = sdk.getComponent('views.elements.AccessibleButton');
return <AccessibleButton className={classnames(classNames)}
onClick={this._onClick}
>
{this.props.text}
</AccessibleButton>;
}
}
/*
* Helps a user verify a hexadecimal code matches one displayed
* elsewhere (eg. on a different device)
*/
export default class HexVerify extends React.Component {
static propTypes = {
text: PropTypes.string.isRequired,
onVerifiedStateChange: PropTypes.func,
}
static defaultProps = {
onVerifiedStateChange: function() {},
}
constructor(props) {
super(props);
this.state = {
pairsVerified: [],
};
for (let i = 0; i < props.text.length; i += 2) {
this.state.pairsVerified.push(false);
}
}
_onPairChange = (index, newVal) => {
const oldVerified = this.state.pairsVerified.reduce((acc, val) => {
return acc && val;
}, true);
const newPairsVerified = this.state.pairsVerified.slice(0);
newPairsVerified[index] = newVal;
const newVerified = newPairsVerified.reduce((acc, val) => {
return acc && val;
}, true);
this.setState({pairsVerified: newPairsVerified});
if (oldVerified !== newVerified) {
this.props.onVerifiedStateChange(newVerified);
}
}
render() {
const pairs = [];
for (let i = 0; i < this.props.text.length / 2; ++i) {
pairs.push(<HexVerifyPair key={i} index={i}
text={this.props.text.substr(i * 2, 2)}
verified={this.state.pairsVerified[i]}
onChange={this._onPairChange}
/>);
}
return <div className="mx_HexVerify">
{pairs}
</div>;
}
}

View file

@ -250,19 +250,26 @@ export default class KeyBackupPanel extends React.PureComponent {
backupSigStatuses = _t("Backup is not signed by any of your devices");
}
let trustedLocally;
if (this.state.backupSigStatus.trusted_locally) {
trustedLocally = _t("This backup is trusted because it has been restored on this device");
}
return <div>
{_t("Backup version: ")}{this.state.backupInfo.version}<br />
{_t("Algorithm: ")}{this.state.backupInfo.algorithm}<br />
{clientBackupStatus}<br />
<div>{_t("Backup version: ")}{this.state.backupInfo.version}</div>
<div>{_t("Algorithm: ")}{this.state.backupInfo.algorithm}</div>
<div>{clientBackupStatus}</div>
{uploadStatus}
<div>{backupSigStatuses}</div><br />
<br />
<AccessibleButton kind="primary" onClick={this._restoreBackup}>
{ _t("Restore backup") }
</AccessibleButton>&nbsp;&nbsp;&nbsp;
<AccessibleButton kind="danger" onClick={this._deleteBackup}>
{ _t("Delete backup") }
</AccessibleButton>
<div>{backupSigStatuses}</div>
<div>{trustedLocally}</div>
<p>
<AccessibleButton kind="primary" onClick={this._restoreBackup}>
{ _t("Restore backup") }
</AccessibleButton>&nbsp;&nbsp;&nbsp;
<AccessibleButton kind="danger" onClick={this._deleteBackup}>
{ _t("Delete backup") }
</AccessibleButton>
</p>
</div>;
} else {
return <div>

View file

@ -18,9 +18,7 @@ import React from 'react';
import {_t} from "../../../../languageHandler";
import PropTypes from "prop-types";
import SettingsStore, {SettingLevel} from "../../../../settings/SettingsStore";
import MatrixClientPeg from "../../../../MatrixClientPeg";
import LabelledToggleSwitch from "../../elements/LabelledToggleSwitch";
const Modal = require("../../../../Modal");
const sdk = require("../../../../index");
export class LabsSettingToggle extends React.Component {
@ -28,38 +26,7 @@ export class LabsSettingToggle extends React.Component {
featureId: PropTypes.string.isRequired,
};
async _onLazyLoadChanging(enabling) {
// don't prevent turning LL off when not supported
if (enabling) {
const supported = await MatrixClientPeg.get().doesServerSupportLazyLoading();
if (!supported) {
await new Promise((resolve) => {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
Modal.createDialog(QuestionDialog, {
title: _t("Lazy loading members not supported"),
description:
<div>
{ _t("Lazy loading is not supported by your " +
"current homeserver.") }
</div>,
button: _t("OK"),
onFinished: resolve,
});
});
return false;
}
}
return true;
}
_onChange = async (checked) => {
if (this.props.featureId === "feature_lazyloading") {
const confirmed = await this._onLazyLoadChanging(checked);
if (!confirmed) {
return;
}
}
await SettingsStore.setFeatureEnabled(this.props.featureId, checked);
this.forceUpdate();
};

View file

@ -28,19 +28,11 @@ export default class VerificationShowSas extends React.Component {
constructor() {
super();
this.state = {
sasVerified: false,
};
}
_onVerifiedStateChange = (newVal) => {
this.setState({sasVerified: newVal});
}
render() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const HexVerify = sdk.getComponent('views.elements.HexVerify');
return <div>
return <div className="mx_VerificationShowSas">
<p>{_t(
"Verify this user by confirming the following number appears on their screen.",
)}</p>
@ -48,15 +40,11 @@ export default class VerificationShowSas extends React.Component {
"For maximum security, we recommend you do this in person or use another " +
"trusted means of communication.",
)}</p>
<HexVerify text={this.props.sas}
onVerifiedStateChange={this._onVerifiedStateChange}
/>
<p>{_t(
"To continue, click on each pair to confirm it's correct.",
)}</p>
<div className="mx_VerificationShowSas_sas">
{this.props.sas}
</div>
<DialogButtons onPrimaryButtonClick={this.props.onDone}
primaryButton={_t("Continue")}
primaryDisabled={!this.state.sasVerified}
hasCancel={true}
onCancel={this.props.onCancel}
/>